Skip to content

Commit 089821b

Browse files
committed
Add accordion to demo clients
1 parent f177b14 commit 089821b

File tree

4 files changed

+175
-101
lines changed

4 files changed

+175
-101
lines changed

src/Pages/Index.cshtml

Lines changed: 106 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -49,109 +49,117 @@
4949
or use them in the <a href="https://github.com/duendesoftware/samples">IdentityServer sample projects</a>.
5050
</p>
5151

52-
<div id="accordion">
52+
<div id="accordion" class="mb-3">
5353
@foreach (var clients in Config.Clients.GroupBy(it => it.ClientId.Split('.', StringSplitOptions.TrimEntries).First()))
5454
{
55-
<h3 id="[email protected]">@DemoServerUtilities.HumanizeClientIdPrefix(clients.Key)</h3>
56-
@if (clients.Key == "m2m")
57-
{
58-
<p>
59-
Machine-to-machine communication can be done using <a href="https://docs.duendesoftware.com/identityserver/v7/quickstarts/1_client_credentials/">client credentials</a>.
60-
</p>
61-
<ul>
62-
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#client-credentials">Sample using client credentials</a></li>
63-
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#jwt-based-client-authentication">Sample using client credentials (JWT-based)</a></li>
64-
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/misc/#dpop">Sample using DPoP</a></li>
65-
</ul>
66-
}
67-
else if (clients.Key == "interactive")
68-
{
69-
<p>
70-
Interactive clients use <a href="https://docs.duendesoftware.com/identityserver/v7/quickstarts/2_interactive/">interactive user authentication via the OpenID Connect protocol</a>.
71-
</p>
72-
<ul>
73-
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#mvc-client-sample">Sample MVC client application</a></li>
74-
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#mvc-client-with-jar-and-jwt-based-authentication">Sample MVC client application (JAR and JWT)</a></li>
75-
</ul>
76-
}
77-
78-
<div class="row">
79-
@foreach(var client in clients)
80-
{
81-
<div class="col-12 col-lg-6">
82-
<div class="card border-dark m-3">
83-
<div class="card-body bg-light">
84-
<h5 class="card-title">@client.ClientId</h5>
85-
<h6 class="card-subtitle mb-2 text-muted">@client.ClientName</h6>
86-
</div>
87-
<div class="card-body">
88-
<div class="card-text">
89-
Client ID: <code>@client.ClientId</code><br/>
90-
Grant type: @DemoServerUtilities.HumanizeAllowedGrantTypes(client.AllowedGrantTypes)
91-
@if (client.RequireRequestObject)
92-
{
93-
<text> - requires JAR</text>
94-
}
95-
<br/>
96-
97-
@if (client.RequirePkce)
98-
{
99-
<text>Requires PKCE</text>
100-
<br/>
101-
}
102-
@if (client.RequireDPoP)
103-
{
104-
switch (client.DPoPValidationMode)
105-
{
106-
case DPoPTokenExpirationValidationMode.Nonce:
107-
@:Requires the use of DPoP and nonce
108-
break;
109-
default:
110-
@:Requires the use of DPoP
111-
break;
112-
}
113-
114-
<br/>
115-
}
116-
117-
@if (client.ClientSecrets.Any())
118-
{
119-
<text>Client secret:</text>
120-
@foreach (var clientSecret in client.ClientSecrets)
121-
{
122-
switch (clientSecret.Type)
123-
{
124-
case IdentityServerConstants.SecretTypes.SharedSecret:
125-
<code>secret</code>
126-
break;
127-
case IdentityServerConstants.SecretTypes.JsonWebKey:
128-
<a href="#sample-keys">private key JWT</a>
129-
break;
130-
default:
131-
@clientSecret.Type
132-
break;
133-
}
134-
}
135-
136-
<br/>
137-
}
138-
139-
Access token lifetime: @DemoServerUtilities.HumanizeLifetime(TimeSpan.FromSeconds(client.AccessTokenLifetime))<br/>
140-
141-
Allowed scopes:
142-
@foreach (var scope in client.AllowedScopes.Where(it => !it.Contains("resource") && !it.Contains("scope") && !it.Contains("transaction")))
143-
{
144-
<code>@scope</code>
145-
}
146-
@if (client.AllowOfflineAccess)
147-
{
148-
<code>offline_access</code>
149-
}
55+
<div class="card">
56+
<div id="[email protected]" class="card-header bg-white shadow-sm border-0">
57+
<h6 class="mb-0 font-weight-bold"><a href="#" data-toggle="collapse" data-target="#[email protected]" aria-controls="[email protected]" class="d-block position-relative text-dark text-uppercase collapsible-link py-2">@DemoServerUtilities.HumanizeClientIdPrefix(clients.Key)</a></h6>
58+
</div>
59+
<div id="[email protected]" aria-labelledby="[email protected]" data-parent="#accordion" class="collapse">
60+
<div class="card-body">
61+
@if (clients.Key == "m2m")
62+
{
63+
<p>
64+
Machine-to-machine communication can be done using <a href="https://docs.duendesoftware.com/identityserver/v7/quickstarts/1_client_credentials/">client credentials</a>.
65+
</p>
66+
<ul>
67+
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#client-credentials">Sample using client credentials</a></li>
68+
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#jwt-based-client-authentication">Sample using client credentials (JWT-based)</a></li>
69+
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/misc/#dpop">Sample using DPoP</a></li>
70+
</ul>
71+
}
72+
else if (clients.Key == "interactive")
73+
{
74+
<p>
75+
Interactive clients use <a href="https://docs.duendesoftware.com/identityserver/v7/quickstarts/2_interactive/">interactive user authentication via the OpenID Connect protocol</a>.
76+
</p>
77+
<ul>
78+
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#mvc-client-sample">Sample MVC client application</a></li>
79+
<li><a href="https://docs.duendesoftware.com/identityserver/v7/samples/basics/#mvc-client-with-jar-and-jwt-based-authentication">Sample MVC client application (JAR and JWT)</a></li>
80+
</ul>
81+
}
82+
83+
<div class="row">
84+
@foreach (var client in clients)
85+
{
86+
<div class="col-12 col-lg-6">
87+
<div class="card border-light m-3">
88+
<div class="card-body bg-light">
89+
<h5 class="card-title">@client.ClientId</h5>
90+
<h6 class="card-subtitle mb-2 text-muted">@client.ClientName</h6>
91+
</div>
92+
<div class="card-body">
93+
<div class="card-text">
94+
Client ID: <code>@client.ClientId</code><br/>
95+
Grant type: @DemoServerUtilities.HumanizeAllowedGrantTypes(client.AllowedGrantTypes)
96+
@if (client.RequireRequestObject)
97+
{
98+
<text> - requires JAR</text>
99+
}
100+
<br/>
101+
102+
@if (client.RequirePkce)
103+
{
104+
<text>Requires PKCE</text>
105+
<br/>
106+
}
107+
@if (client.RequireDPoP)
108+
{
109+
switch (client.DPoPValidationMode)
110+
{
111+
case DPoPTokenExpirationValidationMode.Nonce:
112+
@:Requires the use of DPoP and nonce
113+
break;
114+
default:
115+
@:Requires the use of DPoP
116+
break;
117+
}
118+
119+
<br/>
120+
}
121+
122+
@if (client.ClientSecrets.Any())
123+
{
124+
<text>Client secret:</text>
125+
@foreach (var clientSecret in client.ClientSecrets)
126+
{
127+
switch (clientSecret.Type)
128+
{
129+
case IdentityServerConstants.SecretTypes.SharedSecret:
130+
<code>secret</code>
131+
break;
132+
case IdentityServerConstants.SecretTypes.JsonWebKey:
133+
<a href="#sample-keys">private key JWT</a>
134+
break;
135+
default:
136+
@clientSecret.Type
137+
break;
138+
}
139+
}
140+
141+
<br/>
142+
}
143+
144+
Access token lifetime: @DemoServerUtilities.HumanizeLifetime(TimeSpan.FromSeconds(client.AccessTokenLifetime))<br/>
145+
146+
Allowed scopes:
147+
@foreach (var scope in client.AllowedScopes.Where(it => !it.Contains("resource") && !it.Contains("scope") && !it.Contains("transaction")))
148+
{
149+
<code>@scope</code>
150+
}
151+
@if (client.AllowOfflineAccess)
152+
{
153+
<code>offline_access</code>
154+
}
155+
</div>
156+
</div>
157+
</div>
150158
</div>
151-
</div>
159+
}
152160
</div>
153161
</div>
154-
}
162+
</div>
155163
</div>
156164
}
157165
</div>

src/wwwroot/css/site.css

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
1-
.welcome-page .logo {
1+
.welcome-page .logo {
22
width: 64px;
33
}
44

5+
/* Accordion styles */
6+
.collapsible-link::before {
7+
content: "";
8+
width: 14px;
9+
height: 2px;
10+
background: #333;
11+
position: absolute;
12+
top: calc(50% - 1px);
13+
right: 1rem;
14+
display: block;
15+
transition: all 0.3s;
16+
}
17+
18+
.collapsible-link::after {
19+
content: "";
20+
width: 2px;
21+
height: 14px;
22+
background: #333;
23+
position: absolute;
24+
top: calc(50% - 7px);
25+
right: calc(1rem + 6px);
26+
display: block;
27+
transition: all 0.3s;
28+
}
29+
30+
.collapsible-link[aria-expanded=true]::after {
31+
transform: rotate(90deg) translateX(-1px);
32+
}
33+
34+
.collapsible-link[aria-expanded=true]::before {
35+
transform: rotate(180deg);
36+
}
37+
538
.icon-banner {
639
width: 32px;
740
}
@@ -31,4 +64,4 @@
3164
}
3265
.grants-page .card label {
3366
font-weight: bold;
34-
}
67+
}

src/wwwroot/css/site.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wwwroot/css/site.scss

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,39 @@
44
}
55
}
66

7+
/* Accordion styles */
8+
.collapsible-link::before {
9+
content: '';
10+
width: 14px;
11+
height: 2px;
12+
background: #333;
13+
position: absolute;
14+
top: calc(50% - 1px);
15+
right: 1rem;
16+
display: block;
17+
transition: all 0.3s;
18+
}
19+
20+
.collapsible-link::after {
21+
content: '';
22+
width: 2px;
23+
height: 14px;
24+
background: #333;
25+
position: absolute;
26+
top: calc(50% - 7px);
27+
right: calc(1rem + 6px);
28+
display: block;
29+
transition: all 0.3s;
30+
}
31+
32+
.collapsible-link[aria-expanded='true']::after {
33+
transform: rotate(90deg) translateX(-1px);
34+
}
35+
36+
.collapsible-link[aria-expanded='true']::before {
37+
transform: rotate(180deg);
38+
}
39+
740
.icon-banner {
841
width: 32px;
942
}

0 commit comments

Comments
 (0)