Skip to content

Commit 8665806

Browse files
Checklist in SSO configuration documentation (#2882)
* Add checklist in SSO guide * Add `<Checklist>` component (#2883) * Create check-list component * Use new Checklist component in SSO configuration guide * Alternate design, version A * Alternate design, version B * Use alternate design B with fill effect from design C * Adjust checkbox design * Replace SSO guide content with new component * Increase vertical padding for the list * Improve checklist and add relevant links --------- Co-authored-by: Pierre Wizla <[email protected]>
1 parent 4d40750 commit 8665806

File tree

6 files changed

+242
-0
lines changed

6 files changed

+242
-0
lines changed

docusaurus/docs/cms/configurations/guides/configure-sso.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ export default ({ env }) => ({
7171

7272
## Setting up provider configuration
7373

74+
Parts of the documentation below assume that some steps have been done previously both in Strapi and in your identity provider. If these steps are skipped, the login button might appear on the Strapi login page but the flow will fail with a redirect or "invalid client" error. Make sure to follow all the steps of the checklist before moving onto the rest of the documentation.
75+
76+
<Checklist title="SSO setup checklist">
77+
<ChecklistItem>[Enable SSO in Strapi](/cms/features/sso#admin-panel-settings) <br/> Go to <em>Global settings > Single Sign-On</em> in the admin panel and set up the feature (e.g. toggle auto-registration and choose the default role).</ChecklistItem>
78+
<ChecklistItem>Register Strapi in your identity provider <br/> In the provider's dashboard (e.g. Azure AD, Okta, Google, GitHub), create a new OAuth/OIDC application for Strapi. Copy the client ID and client secret generated by the provider.</ChecklistItem>
79+
<ChecklistItem>[Add the Strapi callback URL to the provider](#the-createstrategy-factory) <br/> Set the redirect/callback URL in the provider configuration to the value generated by <code>{"strapi.admin.services.passport.getStrategyCallbackURL('<provider_uid>')"}</code> (e.g. <code>/admin/connect/google</code> if the UID is <code>google</code>). The provider must accept this URL or the login will be blocked.</ChecklistItem>
80+
<ChecklistItem>[Provide credentials to Strapi](#configuring-the-provider) <br/> Add the client ID and client secret as environment variables (e.g. <code>GOOGLE_CLIENT_ID</code>/<code>GOOGLE_CLIENT_SECRET</code>) so they can be read in <code>{"/config/admin.js|ts"}</code>.</ChecklistItem>
81+
<ChecklistItem>[Configure the provider in code](#configuring-the-provider) <br/> Import the provider's Passport strategy and add it to <code>auth.providers</code>.</ChecklistItem>
82+
<ChecklistItem>Rebuild and restart Strapi <br/> Run <code>yarn build && yarn develop</code> or <code>npm run build && npm run develop</code> so the new provider appears on the login page. If the admin panel is hosted separately, also ensure the <code>url</code> setting matches the deployed admin URL (see [Host, port and path](/cms/admin-panel-customization/host-port-path).</ChecklistItem>
83+
</Checklist>
84+
7485
A provider's configuration is a JavaScript object built with the following properties:
7586

7687
| Name | Required | Type | Description |
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { useState, useId } from 'react';
2+
import clsx from 'clsx';
3+
4+
export function ChecklistItem({ children }) {
5+
const id = useId();
6+
const [checked, setChecked] = useState(false);
7+
8+
return (
9+
<li className="checklist__item">
10+
<label className="checklist__label" htmlFor={id}>
11+
<input
12+
type="checkbox"
13+
id={id}
14+
className="checklist__input"
15+
checked={checked}
16+
onChange={() => setChecked(!checked)}
17+
/>
18+
<span className="checklist__checkbox" aria-hidden="true" />
19+
<span className="checklist__text">{children}</span>
20+
</label>
21+
</li>
22+
);
23+
}
24+
25+
export default function Checklist({
26+
title = 'Checklist',
27+
children,
28+
className,
29+
...rest
30+
}) {
31+
return (
32+
<div className={clsx('checklist', className)} {...rest}>
33+
<div className="checklist__header">{title}</div>
34+
<ul className="checklist__list" role="list">
35+
{children}
36+
</ul>
37+
</div>
38+
);
39+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Checklist, { ChecklistItem } from './Checklist';
2+
3+
export { ChecklistItem };
4+
export default Checklist;

docusaurus/src/scss/__index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
@use 'breadcrumbs.scss';
2424
@use 'breaking-change-id-card.scss';
2525
@use 'card.scss';
26+
@use 'checklist.scss';
2627
@use 'code.scss';
2728
@use 'code-block.scss';
2829
@use 'columns.scss';

docusaurus/src/scss/checklist.scss

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/** Component: Checklist */
2+
@use 'mixins' as *;
3+
4+
.checklist {
5+
--checklist-header-font-size: 11px;
6+
--checklist-header-line-height: 16px;
7+
--checklist-header-font-weight: 600;
8+
--checklist-content-font-size: 14px;
9+
--checklist-content-line-height: 20px;
10+
11+
border: 1px solid var(--strapi-neutral-150);
12+
border-radius: 4px;
13+
background-color: var(--strapi-neutral-0);
14+
overflow: hidden;
15+
margin-bottom: 40px;
16+
17+
&__header {
18+
background-color: var(--strapi-neutral-100);
19+
color: var(--strapi-neutral-600);
20+
text-transform: uppercase;
21+
font-size: var(--checklist-header-font-size) !important;
22+
line-height: var(--checklist-header-line-height);
23+
font-weight: var(--checklist-header-font-weight);
24+
padding: 8px 16px 6px;
25+
letter-spacing: 0.4px;
26+
border-bottom: 1px solid var(--strapi-neutral-150);
27+
}
28+
29+
&__list {
30+
list-style: none;
31+
margin: 0;
32+
padding: 12px 0;
33+
}
34+
35+
&__item {
36+
padding: 0;
37+
38+
&::before {
39+
display: none;
40+
}
41+
}
42+
43+
&__label {
44+
display: flex;
45+
align-items: flex-start;
46+
padding: 8px 16px;
47+
cursor: pointer;
48+
gap: 12px;
49+
}
50+
51+
&__input {
52+
position: absolute;
53+
opacity: 0;
54+
width: 0;
55+
height: 0;
56+
pointer-events: none;
57+
}
58+
59+
&__checkbox {
60+
flex-shrink: 0;
61+
width: 16px;
62+
height: 16px;
63+
border: 1.5px solid var(--strapi-neutral-300);
64+
border-radius: 50%;
65+
background-color: transparent;
66+
position: relative;
67+
top: 3px;
68+
transition: all 0.2s ease;
69+
70+
&::before {
71+
content: '';
72+
position: absolute;
73+
inset: -1.5px;
74+
background-color: var(--strapi-primary-600);
75+
transform: scale(0);
76+
transition: transform 0.15s ease;
77+
border-radius: 50%;
78+
z-index: 1;
79+
}
80+
81+
&::after {
82+
content: '';
83+
position: absolute;
84+
left: 4px;
85+
top: 2px;
86+
width: 3px;
87+
height: 6px;
88+
border: solid white;
89+
border-width: 0 2px 2px 0;
90+
transform: rotate(45deg);
91+
opacity: 0;
92+
transition: opacity 0.1s ease 0.05s;
93+
z-index: 2;
94+
}
95+
}
96+
97+
&__input:checked + &__checkbox {
98+
border-color: transparent;
99+
100+
&::before {
101+
transform: scale(1);
102+
}
103+
104+
&::after {
105+
opacity: 1;
106+
}
107+
}
108+
109+
&__input:focus-visible + &__checkbox {
110+
outline: 2px solid var(--strapi-primary-500);
111+
outline-offset: 2px;
112+
}
113+
114+
&__text {
115+
flex: 1;
116+
color: var(--strapi-neutral-800);
117+
font-size: var(--checklist-content-font-size);
118+
line-height: var(--checklist-content-line-height);
119+
word-break: break-word;
120+
121+
code {
122+
background-color: var(--strapi-neutral-100);
123+
color: var(--strapi-neutral-700);
124+
border: 1px solid var(--strapi-neutral-200);
125+
border-radius: 3px;
126+
padding: 1px 4px;
127+
font-size: 13px;
128+
word-break: break-all;
129+
}
130+
131+
a {
132+
color: var(--strapi-primary-600);
133+
text-decoration: none;
134+
135+
&:hover {
136+
text-decoration: underline;
137+
}
138+
}
139+
}
140+
}
141+
142+
@include dark {
143+
.checklist {
144+
background-color: #212134;
145+
border-color: #4a4a6a;
146+
147+
&__header {
148+
background-color: var(--strapi-neutral-150);
149+
color: var(--strapi-neutral-400);
150+
border-color: #4a4a6a;
151+
}
152+
153+
&__checkbox {
154+
background-color: transparent;
155+
border-color: #6a6a8a;
156+
157+
&::before {
158+
background-color: var(--strapi-primary-500);
159+
}
160+
}
161+
162+
&__label:hover .checklist__checkbox {
163+
border-color: var(--strapi-primary-400);
164+
}
165+
166+
&__input:checked + .checklist__checkbox {
167+
border-color: var(--strapi-primary-500);
168+
}
169+
170+
&__text {
171+
color: #DCDCE4;
172+
173+
code {
174+
background-color: var(--strapi-neutral-150);
175+
color: #DCDCE4;
176+
border-color: #4a4a6a;
177+
}
178+
179+
a {
180+
color: var(--strapi-primary-500);
181+
}
182+
}
183+
}
184+
}

docusaurus/src/theme/MDXComponents.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { ExternalLink } from '../components/ExternalLink';
3838
import BreakingChangeIdCard from '../components/BreakingChangeIdCard';
3939
import MermaidWithFallback from '../components/MermaidWithFallback.js';
4040
import IdentityCard, { IdentityCardItem } from '../components/IdentityCard';
41+
import Checklist, { ChecklistItem } from '../components/Checklist';
4142
// Debug component for testing, for instance the AIToolbar configuration
4243
import DebugComponent from '../components/DebugComponent';
4344

@@ -91,6 +92,8 @@ export default {
9192
Icon,
9293
ExternalLink,
9394
BreakingChangeIdCard,
95+
Checklist,
96+
ChecklistItem,
9497
IdentityCard,
9598
IdentityCardItem,
9699
Tldr,

0 commit comments

Comments
 (0)