strapi-plugin-oidc 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -2
- package/dist/admin/{index-C0GkDnGG.js → index-BITZIRCD.js} +12 -18
- package/dist/admin/{index-D_0jCOLk.js → index-CLDWnBI9.js} +191 -113
- package/dist/admin/{index-BuuCScSN.mjs → index-YOG9buUz.mjs} +12 -18
- package/dist/admin/{index-DwpTg1-J.mjs → index-p9ncVp1G.mjs} +192 -114
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +340 -149
- package/dist/server/index.mjs +340 -149
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
<img src="https://raw.githubusercontent.com/edmogeor/strapi-plugin-oidc/main/assets/icon.png" width="140" alt="OIDC Login for Strapi Logo"/>
|
|
3
3
|
<h1>OIDC Login for Strapi</h1>
|
|
4
4
|
<p>
|
|
5
|
+
<a href="https://www.npmjs.com/package/strapi-plugin-oidc">
|
|
6
|
+
<img src="https://img.shields.io/npm/v/strapi-plugin-oidc.svg" alt="npm version">
|
|
7
|
+
</a>
|
|
5
8
|
<a href="https://github.com/edmogeor/strapi-plugin-oidc/actions/workflows/test.yml">
|
|
6
|
-
<img src="https://github.com/edmogeor/strapi-plugin-oidc/actions/workflows/test.yml/badge.svg" alt="Tests">
|
|
9
|
+
<img src="https://github.com/edmogeor/strapi-plugin-oidc/actions/workflows/test.yml/badge.svg?branch=main" alt="Tests">
|
|
7
10
|
</a>
|
|
8
11
|
</p>
|
|
9
12
|
</div>
|
|
@@ -67,13 +70,22 @@ module.exports = ({ env }) => ({
|
|
|
67
70
|
|
|
68
71
|
Make sure to replace the placeholder values (e.g., `[Client ID from OpenID Provider]`) with the actual connection details from your chosen OIDC identity provider.
|
|
69
72
|
|
|
73
|
+
## How to Login
|
|
74
|
+
|
|
75
|
+
Once configured, you can initiate the OIDC login flow by navigating to:
|
|
76
|
+
`http://<your-strapi-domain>/strapi-plugin-oidc/oidc`
|
|
77
|
+
|
|
78
|
+
(e.g., `http://localhost:1337/strapi-plugin-oidc/oidc` for local development).
|
|
79
|
+
|
|
80
|
+
When the **Enforce OIDC Login** option is enabled in the Admin Settings, the standard Strapi admin login page will be automatically redirected to this URL.
|
|
81
|
+
|
|
70
82
|
## Admin Settings
|
|
71
83
|
|
|
72
84
|
Once the plugin is installed and configured, you can manage the OIDC settings from the Strapi Admin Panel under **Settings** > **OIDC Plugin**.
|
|
73
85
|
|
|
74
86
|
- **Whitelist Management**: Restrict login to specific users by adding their email addresses to the whitelist. You can also whitelist entire email domains (e.g., `*@company.com`). If the whitelist is empty, any user who successfully authenticates via your OIDC provider will be able to log in and an account will be automatically created for them.
|
|
75
87
|
- **Default Role Assignment**: Select the default Strapi admin role that will be assigned to newly created users when they log in for the first time via OIDC.
|
|
76
|
-
- **Enforce OIDC Login**: When enabled, the default Strapi email and password login form will be disabled, forcing all administrators to log in using your OIDC provider. _(Note: This option is automatically disabled and grayed out if your whitelist is empty to prevent accidentally locking everyone out of the admin panel)._
|
|
88
|
+
- **Enforce OIDC Login**: When enabled, the default Strapi email and password login form will be disabled and the standard login will be redirected to the OIDC login URL, forcing all administrators to log in using your OIDC provider. _(Note: This option is automatically disabled and grayed out if your whitelist is empty to prevent accidentally locking everyone out of the admin panel)._
|
|
77
89
|
|
|
78
90
|
## Credits & Changes
|
|
79
91
|
|
|
@@ -85,7 +97,9 @@ This plugin is a hard fork of the original [`strapi-plugin-sso`](https://github.
|
|
|
85
97
|
- Redesigned the Whitelist and Role management UI (switched to native Strapi cards, added pagination, etc.).
|
|
86
98
|
- Added an OIDC logout redirect URL.
|
|
87
99
|
- Added an option to "Enforce OIDC login" with an admin toggle (automatically disabled if the whitelist is empty).
|
|
100
|
+
- Added configurable "Remember Me" duration for sessions (`REMEMBER_ME_DAYS`).
|
|
88
101
|
- Migrated the testing framework to Vitest and added comprehensive test coverage for controllers and services.
|
|
89
102
|
- Cleaned up dead code and unused dependencies to improve maintainability.
|
|
90
103
|
- Upgraded to use newer versions of Node.js.
|
|
104
|
+
- Added styled success and error pages.
|
|
91
105
|
- Added misc. quality of life improvements and bug fixes.
|
|
@@ -55,7 +55,7 @@ const index = {
|
|
|
55
55
|
defaultMessage: "Configuration"
|
|
56
56
|
},
|
|
57
57
|
Component: async () => {
|
|
58
|
-
return await Promise.resolve().then(() => require("./index-
|
|
58
|
+
return await Promise.resolve().then(() => require("./index-CLDWnBI9.js"));
|
|
59
59
|
},
|
|
60
60
|
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
61
61
|
}
|
|
@@ -77,24 +77,18 @@ const index = {
|
|
|
77
77
|
if (currentPath.endsWith("/auth/login")) {
|
|
78
78
|
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
79
79
|
}
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const originalReplaceState = window.history.replaceState;
|
|
90
|
-
window.history.replaceState = function(...args) {
|
|
91
|
-
const url = args[2];
|
|
92
|
-
if (url && typeof url === "string" && url.endsWith("/auth/login")) {
|
|
93
|
-
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
return originalReplaceState.apply(window.history, args);
|
|
80
|
+
const interceptHistory = (originalMethod) => {
|
|
81
|
+
return function(...args) {
|
|
82
|
+
const url = args[2];
|
|
83
|
+
if (url && typeof url === "string" && url.endsWith("/auth/login")) {
|
|
84
|
+
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
return originalMethod.apply(window.history, args);
|
|
88
|
+
};
|
|
97
89
|
};
|
|
90
|
+
window.history.pushState = interceptHistory(window.history.pushState);
|
|
91
|
+
window.history.replaceState = interceptHistory(window.history.replaceState);
|
|
98
92
|
}
|
|
99
93
|
}
|
|
100
94
|
} catch (error) {
|
|
@@ -7,7 +7,7 @@ const react = require("react");
|
|
|
7
7
|
const designSystem = require("@strapi/design-system");
|
|
8
8
|
const icons = require("@strapi/icons");
|
|
9
9
|
const reactIntl = require("react-intl");
|
|
10
|
-
const index = require("./index-
|
|
10
|
+
const index = require("./index-BITZIRCD.js");
|
|
11
11
|
const en = require("./en-jFPbEFeK.js");
|
|
12
12
|
const styled = require("styled-components");
|
|
13
13
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
@@ -28,19 +28,22 @@ function Role({ oidcRoles, roles, onChangeRole }) {
|
|
|
28
28
|
{
|
|
29
29
|
withTags: true,
|
|
30
30
|
placeholder: formatMessage(getTrad("roles.placeholder")),
|
|
31
|
-
value: oidcRole
|
|
31
|
+
value: oidcRole.role ? oidcRole.role.map((r) => String(r)) : [],
|
|
32
32
|
onChange: (value) => {
|
|
33
33
|
if (value && value.length > 0) {
|
|
34
|
-
onChangeRole(value, oidcRole
|
|
34
|
+
onChangeRole(value, oidcRole.oauth_type);
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
-
children: roles.map((role) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MultiSelectOption, { value: role.id
|
|
37
|
+
children: roles.map((role) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.MultiSelectOption, { value: String(role.id), children: role.name }, role.id))
|
|
38
38
|
}
|
|
39
|
-
) }, oidcRole
|
|
39
|
+
) }, oidcRole.oauth_type)) })
|
|
40
40
|
] });
|
|
41
41
|
}
|
|
42
42
|
const CustomTable = styled__default.default(designSystem.Table)`
|
|
43
|
-
th,
|
|
43
|
+
th,
|
|
44
|
+
td,
|
|
45
|
+
th span,
|
|
46
|
+
td span {
|
|
44
47
|
font-size: 1.3rem !important;
|
|
45
48
|
}
|
|
46
49
|
`;
|
|
@@ -54,7 +57,15 @@ const LocalizedDate = ({ date }) => {
|
|
|
54
57
|
minute: "2-digit"
|
|
55
58
|
}).format(new Date(date));
|
|
56
59
|
};
|
|
57
|
-
function Whitelist({
|
|
60
|
+
function Whitelist({
|
|
61
|
+
users,
|
|
62
|
+
roles,
|
|
63
|
+
oidcRoles = [],
|
|
64
|
+
useWhitelist,
|
|
65
|
+
loading,
|
|
66
|
+
onSave,
|
|
67
|
+
onDelete
|
|
68
|
+
}) {
|
|
58
69
|
const [email, setEmail] = react.useState("");
|
|
59
70
|
const [selectedRoles, setSelectedRoles] = react.useState([]);
|
|
60
71
|
const [page, setPage] = react.useState(1);
|
|
@@ -65,9 +76,7 @@ function Whitelist({ users, roles, oidcRoles = [], useWhitelist, loading, onSave
|
|
|
65
76
|
const onSaveEmail = react.useCallback(async () => {
|
|
66
77
|
const emailText = email.trim();
|
|
67
78
|
if (users.some((user) => user.email === emailText)) {
|
|
68
|
-
alert(
|
|
69
|
-
formatMessage(getTrad("whitelist.error.unique"))
|
|
70
|
-
);
|
|
79
|
+
alert(formatMessage(getTrad("whitelist.error.unique")));
|
|
71
80
|
} else {
|
|
72
81
|
await onSave(emailText, selectedRoles);
|
|
73
82
|
setEmail("");
|
|
@@ -126,61 +135,103 @@ function Whitelist({ users, roles, oidcRoles = [], useWhitelist, loading, onSave
|
|
|
126
135
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { paddingRight: 0 }, children: " " })
|
|
127
136
|
] }) }),
|
|
128
137
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: users.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { colSpan: 5, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatMessage(getTrad("whitelist.table.empty")) }) }) }) }) : paginatedUsers.map((user, index2) => {
|
|
129
|
-
|
|
130
|
-
const r = roles.find((ro) => ro.id
|
|
138
|
+
const getRoleNames = (roleIds) => roleIds.map((roleId) => {
|
|
139
|
+
const r = roles.find((ro) => String(ro.id) === String(roleId));
|
|
131
140
|
return r ? r.name : roleId;
|
|
132
141
|
}).join(", ");
|
|
142
|
+
let userRolesNames = getRoleNames(user.roles || []);
|
|
133
143
|
if (!userRolesNames) {
|
|
134
144
|
const defaultRolesIds = oidcRoles.reduce((acc, oidc) => {
|
|
135
|
-
if (oidc.role)
|
|
136
|
-
acc.push(...oidc.role);
|
|
137
|
-
}
|
|
145
|
+
if (oidc.role) acc.push(...oidc.role);
|
|
138
146
|
return acc;
|
|
139
147
|
}, []);
|
|
140
|
-
userRolesNames = defaultRolesIds
|
|
141
|
-
const r = roles.find((ro) => ro.id.toString() === roleId.toString());
|
|
142
|
-
return r ? r.name : roleId;
|
|
143
|
-
}).join(", ");
|
|
148
|
+
userRolesNames = getRoleNames(defaultRolesIds);
|
|
144
149
|
}
|
|
145
150
|
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
|
|
146
151
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: index2 + 1 + (page - 1) * PAGE_SIZE }),
|
|
147
152
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: user.email }),
|
|
148
153
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: userRolesNames || "-" }),
|
|
149
154
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(LocalizedDate, { date: user.createdAt }) }),
|
|
150
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { paddingRight: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { paddingRight: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
156
|
+
designSystem.Flex,
|
|
157
|
+
{
|
|
158
|
+
justifyContent: "flex-end",
|
|
159
|
+
onClick: (e) => e.stopPropagation(),
|
|
160
|
+
style: { width: "100%" },
|
|
161
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Root, { children: [
|
|
162
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
163
|
+
designSystem.IconButton,
|
|
164
|
+
{
|
|
165
|
+
label: formatMessage(getTrad("whitelist.delete.label")),
|
|
166
|
+
withTooltip: false,
|
|
167
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
|
|
168
|
+
}
|
|
169
|
+
) }),
|
|
170
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
|
|
171
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage(getTrad("whitelist.delete.title")) }),
|
|
172
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { fill: "danger600" }), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 2, children: [
|
|
173
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { id: "confirm-description", children: formatMessage(getTrad("whitelist.delete.description")) }) }),
|
|
174
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: user.email }) }),
|
|
175
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(getTrad("whitelist.delete.note")) }) })
|
|
176
|
+
] }) }),
|
|
177
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
|
|
178
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, variant: "tertiary", children: formatMessage(getTrad("page.cancel")) }) }),
|
|
179
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
180
|
+
designSystem.Button,
|
|
181
|
+
{
|
|
182
|
+
fullWidth: true,
|
|
183
|
+
variant: "danger-light",
|
|
184
|
+
onClick: () => onDelete(user.email),
|
|
185
|
+
children: formatMessage(getTrad("page.ok"))
|
|
186
|
+
}
|
|
187
|
+
) })
|
|
188
|
+
] })
|
|
189
|
+
] })
|
|
162
190
|
] })
|
|
163
|
-
|
|
164
|
-
|
|
191
|
+
}
|
|
192
|
+
) })
|
|
165
193
|
] }, user.email);
|
|
166
194
|
}) })
|
|
167
195
|
] }),
|
|
168
196
|
pageCount > 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Pagination, { activePage: page, pageCount, children: [
|
|
169
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
198
|
+
designSystem.PreviousLink,
|
|
199
|
+
{
|
|
200
|
+
href: "#",
|
|
201
|
+
onClick: (e) => {
|
|
202
|
+
e.preventDefault();
|
|
203
|
+
setPage((p) => Math.max(1, p - 1));
|
|
204
|
+
},
|
|
205
|
+
children: "Go to previous page"
|
|
206
|
+
}
|
|
207
|
+
),
|
|
208
|
+
Array.from({ length: pageCount }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
209
|
+
designSystem.PageLink,
|
|
210
|
+
{
|
|
211
|
+
number: i + 1,
|
|
212
|
+
href: "#",
|
|
213
|
+
onClick: (e) => {
|
|
214
|
+
e.preventDefault();
|
|
215
|
+
setPage(i + 1);
|
|
216
|
+
},
|
|
217
|
+
children: [
|
|
218
|
+
"Go to page ",
|
|
219
|
+
i + 1
|
|
220
|
+
]
|
|
221
|
+
},
|
|
178
222
|
i + 1
|
|
179
|
-
|
|
180
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
223
|
+
)),
|
|
224
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
225
|
+
designSystem.NextLink,
|
|
226
|
+
{
|
|
227
|
+
href: "#",
|
|
228
|
+
onClick: (e) => {
|
|
229
|
+
e.preventDefault();
|
|
230
|
+
setPage((p) => Math.min(pageCount, p + 1));
|
|
231
|
+
},
|
|
232
|
+
children: "Go to next page"
|
|
233
|
+
}
|
|
234
|
+
)
|
|
184
235
|
] }) }) })
|
|
185
236
|
] }) });
|
|
186
237
|
}
|
|
@@ -301,9 +352,12 @@ function CustomSwitch({ checked, onChange, label, disabled }) {
|
|
|
301
352
|
label && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: disabled ? "neutral500" : "neutral800", children: label })
|
|
302
353
|
] });
|
|
303
354
|
}
|
|
304
|
-
function
|
|
305
|
-
const {
|
|
355
|
+
function useOidcSettings() {
|
|
356
|
+
const { get, put } = admin.useFetchClient();
|
|
306
357
|
const [loading, setLoading] = react.useState(false);
|
|
358
|
+
const [showSuccess, setSuccess] = react.useState(false);
|
|
359
|
+
const [showError, setError] = react.useState(false);
|
|
360
|
+
const [showMatched, setMatched] = react.useState(0);
|
|
307
361
|
const [initialOidcRoles, setInitialOIDCRoles] = react.useState([]);
|
|
308
362
|
const [oidcRoles, setOIDCRoles] = react.useState([]);
|
|
309
363
|
const [roles, setRoles] = react.useState([]);
|
|
@@ -313,10 +367,6 @@ function HomePage$1() {
|
|
|
313
367
|
const [enforceOIDC, setEnforceOIDC] = react.useState(false);
|
|
314
368
|
const [initialUsers, setInitialUsers] = react.useState([]);
|
|
315
369
|
const [users, setUsers] = react.useState([]);
|
|
316
|
-
const [showSuccess, setSuccess] = react.useState(false);
|
|
317
|
-
const [showError, setError] = react.useState(false);
|
|
318
|
-
const [showMatched, setMatched] = react.useState(0);
|
|
319
|
-
const { get, put, post, del } = admin.useFetchClient();
|
|
320
370
|
react.useEffect(() => {
|
|
321
371
|
get(`/strapi-plugin-oidc/oidc-roles`).then((response) => {
|
|
322
372
|
setOIDCRoles(response.data);
|
|
@@ -333,31 +383,51 @@ function HomePage$1() {
|
|
|
333
383
|
setEnforceOIDC(response.data.enforceOIDC);
|
|
334
384
|
setInitialEnforceOIDC(response.data.enforceOIDC);
|
|
335
385
|
});
|
|
336
|
-
}, [
|
|
386
|
+
}, [get]);
|
|
337
387
|
const onChangeRole = (values, oidcId) => {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
388
|
+
const updatedRoles = oidcRoles.map(
|
|
389
|
+
(role) => role.oauth_type === oidcId ? { ...role, role: values } : role
|
|
390
|
+
);
|
|
391
|
+
setOIDCRoles(updatedRoles);
|
|
392
|
+
};
|
|
393
|
+
const onRegisterWhitelist = async (email, selectedRoles) => {
|
|
394
|
+
const newUser = { email, roles: selectedRoles, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
395
|
+
setUsers([...users, newUser]);
|
|
396
|
+
};
|
|
397
|
+
const onDeleteWhitelist = async (email) => {
|
|
398
|
+
const updatedUsers = users.filter((u) => u.email !== email);
|
|
399
|
+
setUsers(updatedUsers);
|
|
400
|
+
if (useWhitelist && updatedUsers.length === 0) {
|
|
401
|
+
setEnforceOIDC(false);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
const onToggleWhitelist = (e) => {
|
|
405
|
+
const checked = e.target.checked;
|
|
406
|
+
setUseWhitelist(checked);
|
|
407
|
+
if (checked && users.length === 0) {
|
|
408
|
+
setEnforceOIDC(false);
|
|
342
409
|
}
|
|
343
|
-
setOIDCRoles(oidcRoles.slice());
|
|
344
410
|
};
|
|
411
|
+
const onToggleEnforce = (e) => {
|
|
412
|
+
setEnforceOIDC(e.target.checked);
|
|
413
|
+
};
|
|
414
|
+
const isDirty = useWhitelist !== initialUseWhitelist || enforceOIDC !== initialEnforceOIDC || JSON.stringify(oidcRoles) !== JSON.stringify(initialOidcRoles) || JSON.stringify(users) !== JSON.stringify(initialUsers);
|
|
345
415
|
const onSaveAll = async () => {
|
|
346
416
|
setLoading(true);
|
|
347
417
|
try {
|
|
348
418
|
await put("/strapi-plugin-oidc/oidc-roles", {
|
|
349
419
|
roles: oidcRoles.map((role) => ({
|
|
350
|
-
|
|
351
|
-
role: role
|
|
420
|
+
oauth_type: role.oauth_type,
|
|
421
|
+
role: role.role
|
|
352
422
|
}))
|
|
353
423
|
});
|
|
424
|
+
const syncResponse = await put("/strapi-plugin-oidc/whitelist/sync", {
|
|
425
|
+
users: users.map((u) => ({ email: u.email, roles: u.roles }))
|
|
426
|
+
});
|
|
354
427
|
await put("/strapi-plugin-oidc/whitelist/settings", {
|
|
355
428
|
useWhitelist,
|
|
356
429
|
enforceOIDC
|
|
357
430
|
});
|
|
358
|
-
const syncResponse = await put("/strapi-plugin-oidc/whitelist/sync", {
|
|
359
|
-
users: users.map((u) => ({ email: u.email, roles: u.roles }))
|
|
360
|
-
});
|
|
361
431
|
setInitialOIDCRoles(JSON.parse(JSON.stringify(oidcRoles)));
|
|
362
432
|
setInitialUseWhitelist(useWhitelist);
|
|
363
433
|
setInitialEnforceOIDC(enforceOIDC);
|
|
@@ -365,43 +435,51 @@ function HomePage$1() {
|
|
|
365
435
|
setUsers(getResponse.data.whitelistUsers);
|
|
366
436
|
setInitialUsers(JSON.parse(JSON.stringify(getResponse.data.whitelistUsers)));
|
|
367
437
|
});
|
|
368
|
-
if (syncResponse.data
|
|
438
|
+
if (syncResponse.data?.matchedExistingUsersCount > 0) {
|
|
369
439
|
setMatched(syncResponse.data.matchedExistingUsersCount);
|
|
370
|
-
setTimeout(() =>
|
|
371
|
-
setMatched(0);
|
|
372
|
-
}, 3e3);
|
|
440
|
+
setTimeout(() => setMatched(0), 3e3);
|
|
373
441
|
} else {
|
|
374
442
|
setSuccess(true);
|
|
375
|
-
setTimeout(() =>
|
|
376
|
-
setSuccess(false);
|
|
377
|
-
}, 3e3);
|
|
443
|
+
setTimeout(() => setSuccess(false), 3e3);
|
|
378
444
|
}
|
|
379
445
|
} catch (e) {
|
|
380
446
|
console.error(e);
|
|
381
447
|
setError(true);
|
|
382
|
-
setTimeout(() =>
|
|
383
|
-
setError(false);
|
|
384
|
-
}, 3e3);
|
|
448
|
+
setTimeout(() => setError(false), 3e3);
|
|
385
449
|
} finally {
|
|
386
450
|
setLoading(false);
|
|
387
451
|
}
|
|
388
452
|
};
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
453
|
+
return {
|
|
454
|
+
state: {
|
|
455
|
+
loading,
|
|
456
|
+
showSuccess,
|
|
457
|
+
showError,
|
|
458
|
+
showMatched,
|
|
459
|
+
oidcRoles,
|
|
460
|
+
roles,
|
|
461
|
+
useWhitelist,
|
|
462
|
+
enforceOIDC,
|
|
463
|
+
initialEnforceOIDC,
|
|
464
|
+
users,
|
|
465
|
+
isDirty
|
|
466
|
+
},
|
|
467
|
+
actions: {
|
|
468
|
+
setSuccess,
|
|
469
|
+
setError,
|
|
470
|
+
setMatched,
|
|
471
|
+
onChangeRole,
|
|
472
|
+
onRegisterWhitelist,
|
|
473
|
+
onDeleteWhitelist,
|
|
474
|
+
onToggleWhitelist,
|
|
475
|
+
onToggleEnforce,
|
|
476
|
+
onSaveAll
|
|
477
|
+
}
|
|
403
478
|
};
|
|
404
|
-
|
|
479
|
+
}
|
|
480
|
+
function HomePage$1() {
|
|
481
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
482
|
+
const { state, actions } = useOidcSettings();
|
|
405
483
|
return /* @__PURE__ */ jsxRuntime.jsxs(admin.Page.Protect, { permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }], children: [
|
|
406
484
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
407
485
|
admin.Layouts.Header,
|
|
@@ -410,18 +488,18 @@ function HomePage$1() {
|
|
|
410
488
|
subtitle: formatMessage(getTrad("page.title"))
|
|
411
489
|
}
|
|
412
490
|
),
|
|
413
|
-
showSuccess && /* @__PURE__ */ jsxRuntime.jsx(SuccessAlertMessage, { onClose: () => setSuccess(false) }),
|
|
414
|
-
showError && /* @__PURE__ */ jsxRuntime.jsx(ErrorAlertMessage, { onClose: () => setError(false) }),
|
|
415
|
-
showMatched > 0 && /* @__PURE__ */ jsxRuntime.jsx(MatchedUserAlertMessage, { count: showMatched, onClose: () => setMatched(0) }),
|
|
491
|
+
state.showSuccess && /* @__PURE__ */ jsxRuntime.jsx(SuccessAlertMessage, { onClose: () => actions.setSuccess(false) }),
|
|
492
|
+
state.showError && /* @__PURE__ */ jsxRuntime.jsx(ErrorAlertMessage, { onClose: () => actions.setError(false) }),
|
|
493
|
+
state.showMatched > 0 && /* @__PURE__ */ jsxRuntime.jsx(MatchedUserAlertMessage, { count: state.showMatched, onClose: () => actions.setMatched(0) }),
|
|
416
494
|
/* @__PURE__ */ jsxRuntime.jsx(admin.Layouts.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
417
495
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { background: "neutral0", hasRadius: true, shadow: "filterShadow", padding: 6, children: [
|
|
418
496
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage(getTrad("roles.title")) }) }),
|
|
419
497
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
420
498
|
Role,
|
|
421
499
|
{
|
|
422
|
-
roles,
|
|
423
|
-
oidcRoles,
|
|
424
|
-
onChangeRole
|
|
500
|
+
roles: state.roles,
|
|
501
|
+
oidcRoles: state.oidcRoles,
|
|
502
|
+
onChangeRole: actions.onChangeRole
|
|
425
503
|
}
|
|
426
504
|
)
|
|
427
505
|
] }),
|
|
@@ -431,22 +509,22 @@ function HomePage$1() {
|
|
|
431
509
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
432
510
|
CustomSwitch,
|
|
433
511
|
{
|
|
434
|
-
checked: useWhitelist,
|
|
435
|
-
onChange: onToggleWhitelist,
|
|
436
|
-
label: useWhitelist ? formatMessage(getTrad("whitelist.toggle.enabled")) : formatMessage(getTrad("whitelist.toggle.disabled"))
|
|
512
|
+
checked: state.useWhitelist,
|
|
513
|
+
onChange: actions.onToggleWhitelist,
|
|
514
|
+
label: state.useWhitelist ? formatMessage(getTrad("whitelist.toggle.enabled")) : formatMessage(getTrad("whitelist.toggle.disabled"))
|
|
437
515
|
}
|
|
438
516
|
)
|
|
439
517
|
] }),
|
|
440
518
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
441
519
|
Whitelist,
|
|
442
520
|
{
|
|
443
|
-
loading,
|
|
444
|
-
users,
|
|
445
|
-
roles,
|
|
446
|
-
oidcRoles,
|
|
447
|
-
useWhitelist,
|
|
448
|
-
onSave: onRegisterWhitelist,
|
|
449
|
-
onDelete: onDeleteWhitelist
|
|
521
|
+
loading: state.loading,
|
|
522
|
+
users: state.users,
|
|
523
|
+
roles: state.roles,
|
|
524
|
+
oidcRoles: state.oidcRoles,
|
|
525
|
+
useWhitelist: state.useWhitelist,
|
|
526
|
+
onSave: actions.onRegisterWhitelist,
|
|
527
|
+
onDelete: actions.onDeleteWhitelist
|
|
450
528
|
}
|
|
451
529
|
)
|
|
452
530
|
] }),
|
|
@@ -456,14 +534,14 @@ function HomePage$1() {
|
|
|
456
534
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
457
535
|
CustomSwitch,
|
|
458
536
|
{
|
|
459
|
-
checked: enforceOIDC,
|
|
460
|
-
onChange: onToggleEnforce,
|
|
461
|
-
disabled: useWhitelist && users.length === 0,
|
|
462
|
-
label: enforceOIDC ? formatMessage(getTrad("enforce.toggle.enabled")) : formatMessage(getTrad("enforce.toggle.disabled"))
|
|
537
|
+
checked: state.enforceOIDC,
|
|
538
|
+
onChange: actions.onToggleEnforce,
|
|
539
|
+
disabled: state.useWhitelist && state.users.length === 0,
|
|
540
|
+
label: state.enforceOIDC ? formatMessage(getTrad("enforce.toggle.enabled")) : formatMessage(getTrad("enforce.toggle.disabled"))
|
|
463
541
|
}
|
|
464
542
|
)
|
|
465
543
|
] }),
|
|
466
|
-
enforceOIDC && enforceOIDC !== initialEnforceOIDC && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "danger100", padding: 3, hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
|
|
544
|
+
state.enforceOIDC && state.enforceOIDC !== state.initialEnforceOIDC && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "danger100", padding: 3, hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
|
|
467
545
|
/* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, { fill: "danger600" }),
|
|
468
546
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", children: formatMessage(getTrad("enforce.warning")) })
|
|
469
547
|
] }) })
|
|
@@ -472,9 +550,9 @@ function HomePage$1() {
|
|
|
472
550
|
designSystem.Button,
|
|
473
551
|
{
|
|
474
552
|
size: "L",
|
|
475
|
-
onClick: onSaveAll,
|
|
476
|
-
disabled: !isDirty || loading,
|
|
477
|
-
loading,
|
|
553
|
+
onClick: actions.onSaveAll,
|
|
554
|
+
disabled: !state.isDirty || state.loading,
|
|
555
|
+
loading: state.loading,
|
|
478
556
|
children: formatMessage(getTrad("page.save"))
|
|
479
557
|
}
|
|
480
558
|
) })
|
|
@@ -54,7 +54,7 @@ const index = {
|
|
|
54
54
|
defaultMessage: "Configuration"
|
|
55
55
|
},
|
|
56
56
|
Component: async () => {
|
|
57
|
-
return await import("./index-
|
|
57
|
+
return await import("./index-p9ncVp1G.mjs");
|
|
58
58
|
},
|
|
59
59
|
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
60
60
|
}
|
|
@@ -76,24 +76,18 @@ const index = {
|
|
|
76
76
|
if (currentPath.endsWith("/auth/login")) {
|
|
77
77
|
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
78
78
|
}
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const originalReplaceState = window.history.replaceState;
|
|
89
|
-
window.history.replaceState = function(...args) {
|
|
90
|
-
const url = args[2];
|
|
91
|
-
if (url && typeof url === "string" && url.endsWith("/auth/login")) {
|
|
92
|
-
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
return originalReplaceState.apply(window.history, args);
|
|
79
|
+
const interceptHistory = (originalMethod) => {
|
|
80
|
+
return function(...args) {
|
|
81
|
+
const url = args[2];
|
|
82
|
+
if (url && typeof url === "string" && url.endsWith("/auth/login")) {
|
|
83
|
+
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
return originalMethod.apply(window.history, args);
|
|
87
|
+
};
|
|
96
88
|
};
|
|
89
|
+
window.history.pushState = interceptHistory(window.history.pushState);
|
|
90
|
+
window.history.replaceState = interceptHistory(window.history.replaceState);
|
|
97
91
|
}
|
|
98
92
|
}
|
|
99
93
|
} catch (error) {
|