strapi-plugin-oidc 1.1.1 → 1.2.0
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/dist/admin/{index-B2lPDW7A.js → index-BzRgsk9F.js} +2 -3
- package/dist/admin/{index-CxxsmBsC.mjs → index-D2Fm7gNJ.mjs} +1 -2
- package/dist/admin/index-XREqyWao.js +254 -0
- package/dist/admin/index-bfZQKCve.mjs +255 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +59 -8
- package/dist/server/index.mjs +59 -8
- package/package.json +1 -1
- package/dist/admin/en-8UlbiAHW.js +0 -42
- package/dist/admin/en-DInn-mdh.mjs +0 -42
- package/dist/admin/index-BsP7WM7b.mjs +0 -153
- package/dist/admin/index-Dj2m6xLY.js +0 -152
|
@@ -7,8 +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-
|
|
11
|
-
const en = require("./en-8UlbiAHW.js");
|
|
10
|
+
const index = require("./index-XREqyWao.js");
|
|
12
11
|
const styled = require("styled-components");
|
|
13
12
|
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
|
|
14
13
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
@@ -16,7 +15,7 @@ function getTrad(id) {
|
|
|
16
15
|
const pluginIdWithId = `${index.pluginId}.${id}`;
|
|
17
16
|
return {
|
|
18
17
|
id: pluginIdWithId,
|
|
19
|
-
defaultMessage: en
|
|
18
|
+
defaultMessage: index.en[id] || pluginIdWithId
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
21
|
function Role({ oidcRoles, roles, onChangeRole }) {
|
|
@@ -5,8 +5,7 @@ import { useState, useCallback, useEffect, memo } from "react";
|
|
|
5
5
|
import { Typography, Flex, Box, MultiSelect, MultiSelectOption, Field, Button, Divider, Thead, Tr, Th, Tbody, Td, Dialog, IconButton, Pagination, PreviousLink, PageLink, NextLink, Table, Alert } from "@strapi/design-system";
|
|
6
6
|
import { Plus, Trash, WarningCircle } from "@strapi/icons";
|
|
7
7
|
import { useIntl } from "react-intl";
|
|
8
|
-
import { p as pluginId } from "./index-
|
|
9
|
-
import en from "./en-DInn-mdh.mjs";
|
|
8
|
+
import { e as en, p as pluginId } from "./index-bfZQKCve.mjs";
|
|
10
9
|
import styled from "styled-components";
|
|
11
10
|
function getTrad(id) {
|
|
12
11
|
const pluginIdWithId = `${pluginId}.${id}`;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const react = require("react");
|
|
3
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
4
|
+
const v = glob[path];
|
|
5
|
+
if (v) {
|
|
6
|
+
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
7
|
+
}
|
|
8
|
+
return new Promise((_, reject) => {
|
|
9
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
10
|
+
reject.bind(
|
|
11
|
+
null,
|
|
12
|
+
new Error(
|
|
13
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
14
|
+
)
|
|
15
|
+
)
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const name$1 = "strapi-plugin-oidc";
|
|
20
|
+
const strapi = { "displayName": "OIDC Plugin" };
|
|
21
|
+
const pluginPkg = {
|
|
22
|
+
name: name$1,
|
|
23
|
+
strapi
|
|
24
|
+
};
|
|
25
|
+
const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, "");
|
|
26
|
+
function getTranslation(id) {
|
|
27
|
+
return `${pluginId}.${id}`;
|
|
28
|
+
}
|
|
29
|
+
function Initializer({ setPlugin }) {
|
|
30
|
+
const ref = react.useRef();
|
|
31
|
+
ref.current = setPlugin;
|
|
32
|
+
react.useEffect(() => {
|
|
33
|
+
if (ref.current) {
|
|
34
|
+
ref.current(pluginId);
|
|
35
|
+
}
|
|
36
|
+
}, []);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const en = {
|
|
40
|
+
"global.plugins.strapi-plugin-oidc": "OIDC Plugin",
|
|
41
|
+
"page.title": "Configure OIDC default role(s) and access controls.",
|
|
42
|
+
"roles.notes": "Select the default role(s) assigned to new users upon their first login. This setting does not affect existing users.",
|
|
43
|
+
"page.save": "Save Changes",
|
|
44
|
+
"page.save.success": "Updated settings",
|
|
45
|
+
"page.save.error": "Update failed.",
|
|
46
|
+
"page.add": "Add",
|
|
47
|
+
"page.cancel": "Cancel",
|
|
48
|
+
"page.ok": "OK",
|
|
49
|
+
"roles.title": "Default Role(s)",
|
|
50
|
+
"roles.placeholder": "Select default role(s)",
|
|
51
|
+
"whitelist.title": "Whitelist",
|
|
52
|
+
"whitelist.error.unique": "Already registered email address.",
|
|
53
|
+
"whitelist.enabled": "Whitelist is currently enabled.",
|
|
54
|
+
"whitelist.disabled": "Whitelist is currently disabled.",
|
|
55
|
+
"whitelist.description": "Restrict OIDC authentication to specific email addresses and optionally assign them custom role(s).",
|
|
56
|
+
"whitelist.user_exists": "User already exists, matching existing role(s)",
|
|
57
|
+
"whitelist.users_exists": "Users already exist, matching existing role(s)",
|
|
58
|
+
"whitelist.table.no": "No.",
|
|
59
|
+
"whitelist.table.email": "Email",
|
|
60
|
+
"whitelist.table.created": "Created At",
|
|
61
|
+
"whitelist.delete.title": "Confirmation",
|
|
62
|
+
"whitelist.delete.description": "Are you sure you want to delete:",
|
|
63
|
+
"whitelist.delete.note": "This will not delete the user account in Strapi.",
|
|
64
|
+
"whitelist.toggle.enabled": "Enabled",
|
|
65
|
+
"whitelist.toggle.disabled": "Disabled",
|
|
66
|
+
"whitelist.email.placeholder": "Email address",
|
|
67
|
+
"whitelist.roles.placeholder": "Select specific role(s)",
|
|
68
|
+
"whitelist.table.roles": "Role(s)",
|
|
69
|
+
"whitelist.table.roles.default": "Default",
|
|
70
|
+
"whitelist.table.empty": "No email addresses",
|
|
71
|
+
"whitelist.delete.label": "Delete",
|
|
72
|
+
"page.title.oidc": "OIDC",
|
|
73
|
+
"enforce.title": "Enforce OIDC Login",
|
|
74
|
+
"enforce.toggle.enabled": "Enabled",
|
|
75
|
+
"enforce.toggle.disabled": "Disabled",
|
|
76
|
+
"enforce.warning": "Make sure OIDC is setup correctly before saving changes, you won't be able to login normally.",
|
|
77
|
+
"login.sso": "Login via SSO"
|
|
78
|
+
};
|
|
79
|
+
const en$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
80
|
+
__proto__: null,
|
|
81
|
+
default: en
|
|
82
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
83
|
+
const name = pluginPkg.strapi.displayName;
|
|
84
|
+
const index = {
|
|
85
|
+
register(app) {
|
|
86
|
+
app.addSettingsLink(
|
|
87
|
+
{
|
|
88
|
+
id: "oidc",
|
|
89
|
+
intlLabel: {
|
|
90
|
+
id: `${pluginId}.settings.section`,
|
|
91
|
+
defaultMessage: "OIDC"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "configuration",
|
|
96
|
+
to: `/settings/${pluginId}`,
|
|
97
|
+
intlLabel: {
|
|
98
|
+
id: `${pluginId}.settings.configuration`,
|
|
99
|
+
defaultMessage: "Configuration"
|
|
100
|
+
},
|
|
101
|
+
Component: async () => {
|
|
102
|
+
return await Promise.resolve().then(() => require("./index-BzRgsk9F.js"));
|
|
103
|
+
},
|
|
104
|
+
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
app.registerPlugin({
|
|
108
|
+
id: pluginId,
|
|
109
|
+
initializer: Initializer,
|
|
110
|
+
name
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
bootstrap() {
|
|
114
|
+
let isLogoutInProgress = false;
|
|
115
|
+
let historyPatched = false;
|
|
116
|
+
const ENFORCE_CACHE_KEY = "strapi_oidc_enforced";
|
|
117
|
+
const isAuthRoute = (path) => /\/auth\/(login|register|forgot-password|reset-password)/.test(path);
|
|
118
|
+
const patchHistory = () => {
|
|
119
|
+
if (historyPatched) return;
|
|
120
|
+
historyPatched = true;
|
|
121
|
+
const interceptHistory = (originalMethod) => {
|
|
122
|
+
return function(...args) {
|
|
123
|
+
const url = args[2];
|
|
124
|
+
if (url && typeof url === "string") {
|
|
125
|
+
const urlWithoutQuery = url.split("?")[0].split("#")[0];
|
|
126
|
+
if (isAuthRoute(urlWithoutQuery)) {
|
|
127
|
+
if (isLogoutInProgress) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return originalMethod.apply(window.history, args);
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
window.history.pushState = interceptHistory(window.history.pushState);
|
|
138
|
+
window.history.replaceState = interceptHistory(window.history.replaceState);
|
|
139
|
+
if (isAuthRoute(window.location.pathname)) {
|
|
140
|
+
window.location.replace("/strapi-plugin-oidc/oidc");
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
let ssoButtonInjected = false;
|
|
144
|
+
let ssoObserver = null;
|
|
145
|
+
const injectSSOButton = () => {
|
|
146
|
+
if (ssoButtonInjected) return;
|
|
147
|
+
if (!isAuthRoute(window.location.pathname)) return;
|
|
148
|
+
if (document.getElementById("strapi-oidc-sso-btn")) return;
|
|
149
|
+
const submitButton = document.querySelector('form button[type="submit"]');
|
|
150
|
+
if (!submitButton?.parentNode) return;
|
|
151
|
+
const btn = document.createElement("button");
|
|
152
|
+
btn.id = "strapi-oidc-sso-btn";
|
|
153
|
+
btn.type = "button";
|
|
154
|
+
btn.className = submitButton.className;
|
|
155
|
+
btn.style.marginTop = "8px";
|
|
156
|
+
btn.onclick = () => {
|
|
157
|
+
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
158
|
+
};
|
|
159
|
+
const innerSpan = submitButton.querySelector("span");
|
|
160
|
+
const span = document.createElement("span");
|
|
161
|
+
if (innerSpan) span.className = innerSpan.className;
|
|
162
|
+
span.textContent = en["login.sso"];
|
|
163
|
+
btn.appendChild(span);
|
|
164
|
+
submitButton.parentNode.insertBefore(btn, submitButton.nextSibling);
|
|
165
|
+
ssoButtonInjected = true;
|
|
166
|
+
};
|
|
167
|
+
const startSSOButtonObserver = () => {
|
|
168
|
+
if (ssoObserver) return;
|
|
169
|
+
injectSSOButton();
|
|
170
|
+
ssoObserver = new MutationObserver(() => {
|
|
171
|
+
if (isAuthRoute(window.location.pathname)) injectSSOButton();
|
|
172
|
+
});
|
|
173
|
+
ssoObserver.observe(document.body, { childList: true, subtree: true });
|
|
174
|
+
};
|
|
175
|
+
const stopSSOButtonObserver = () => {
|
|
176
|
+
ssoObserver?.disconnect();
|
|
177
|
+
ssoObserver = null;
|
|
178
|
+
document.getElementById("strapi-oidc-sso-btn")?.remove();
|
|
179
|
+
ssoButtonInjected = false;
|
|
180
|
+
};
|
|
181
|
+
if (localStorage.getItem(ENFORCE_CACHE_KEY) === "1") {
|
|
182
|
+
patchHistory();
|
|
183
|
+
}
|
|
184
|
+
const checkEnforceOIDC = async () => {
|
|
185
|
+
try {
|
|
186
|
+
const response = await window.fetch("/strapi-plugin-oidc/settings/public");
|
|
187
|
+
if (response.ok) {
|
|
188
|
+
const data = await response.json();
|
|
189
|
+
if (data.enforceOIDC) {
|
|
190
|
+
localStorage.setItem(ENFORCE_CACHE_KEY, "1");
|
|
191
|
+
stopSSOButtonObserver();
|
|
192
|
+
patchHistory();
|
|
193
|
+
} else {
|
|
194
|
+
localStorage.removeItem(ENFORCE_CACHE_KEY);
|
|
195
|
+
startSSOButtonObserver();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error("Failed to check OIDC enforcement setting:", error);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
checkEnforceOIDC();
|
|
203
|
+
const originalFetch = window.fetch;
|
|
204
|
+
window.fetch = async (...args) => {
|
|
205
|
+
const url = typeof args[0] === "string" ? args[0] : args[0].url;
|
|
206
|
+
const isLogout = url && url.endsWith("/admin/logout") && args[1]?.method?.toUpperCase() === "POST";
|
|
207
|
+
if (isLogout) {
|
|
208
|
+
isLogoutInProgress = true;
|
|
209
|
+
}
|
|
210
|
+
const response = await originalFetch(...args);
|
|
211
|
+
if (isLogout && response.ok) {
|
|
212
|
+
window.localStorage.removeItem("jwtToken");
|
|
213
|
+
window.localStorage.removeItem("isLoggedIn");
|
|
214
|
+
window.sessionStorage.removeItem("jwtToken");
|
|
215
|
+
window.sessionStorage.removeItem("isLoggedIn");
|
|
216
|
+
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
|
217
|
+
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
|
|
218
|
+
window.location.href = "/strapi-plugin-oidc/logout";
|
|
219
|
+
return new Promise(() => {
|
|
220
|
+
});
|
|
221
|
+
} else if (isLogout) {
|
|
222
|
+
isLogoutInProgress = false;
|
|
223
|
+
}
|
|
224
|
+
return response;
|
|
225
|
+
};
|
|
226
|
+
},
|
|
227
|
+
async registerTrads({ locales }) {
|
|
228
|
+
const importedTrads = await Promise.all(
|
|
229
|
+
locales.map((locale) => {
|
|
230
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => en$1) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
|
231
|
+
const newData = Object.fromEntries(
|
|
232
|
+
Object.entries(data).map(([key, value]) => [
|
|
233
|
+
key.startsWith("global.") ? key : getTranslation(key),
|
|
234
|
+
value
|
|
235
|
+
])
|
|
236
|
+
);
|
|
237
|
+
return {
|
|
238
|
+
data: newData,
|
|
239
|
+
locale
|
|
240
|
+
};
|
|
241
|
+
}).catch(() => {
|
|
242
|
+
return {
|
|
243
|
+
data: {},
|
|
244
|
+
locale
|
|
245
|
+
};
|
|
246
|
+
});
|
|
247
|
+
})
|
|
248
|
+
);
|
|
249
|
+
return Promise.resolve(importedTrads);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
exports.en = en;
|
|
253
|
+
exports.index = index;
|
|
254
|
+
exports.pluginId = pluginId;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
3
|
+
const v = glob[path];
|
|
4
|
+
if (v) {
|
|
5
|
+
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
6
|
+
}
|
|
7
|
+
return new Promise((_, reject) => {
|
|
8
|
+
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
9
|
+
reject.bind(
|
|
10
|
+
null,
|
|
11
|
+
new Error(
|
|
12
|
+
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
13
|
+
)
|
|
14
|
+
)
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
const name$1 = "strapi-plugin-oidc";
|
|
19
|
+
const strapi = { "displayName": "OIDC Plugin" };
|
|
20
|
+
const pluginPkg = {
|
|
21
|
+
name: name$1,
|
|
22
|
+
strapi
|
|
23
|
+
};
|
|
24
|
+
const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, "");
|
|
25
|
+
function getTranslation(id) {
|
|
26
|
+
return `${pluginId}.${id}`;
|
|
27
|
+
}
|
|
28
|
+
function Initializer({ setPlugin }) {
|
|
29
|
+
const ref = useRef();
|
|
30
|
+
ref.current = setPlugin;
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (ref.current) {
|
|
33
|
+
ref.current(pluginId);
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const en = {
|
|
39
|
+
"global.plugins.strapi-plugin-oidc": "OIDC Plugin",
|
|
40
|
+
"page.title": "Configure OIDC default role(s) and access controls.",
|
|
41
|
+
"roles.notes": "Select the default role(s) assigned to new users upon their first login. This setting does not affect existing users.",
|
|
42
|
+
"page.save": "Save Changes",
|
|
43
|
+
"page.save.success": "Updated settings",
|
|
44
|
+
"page.save.error": "Update failed.",
|
|
45
|
+
"page.add": "Add",
|
|
46
|
+
"page.cancel": "Cancel",
|
|
47
|
+
"page.ok": "OK",
|
|
48
|
+
"roles.title": "Default Role(s)",
|
|
49
|
+
"roles.placeholder": "Select default role(s)",
|
|
50
|
+
"whitelist.title": "Whitelist",
|
|
51
|
+
"whitelist.error.unique": "Already registered email address.",
|
|
52
|
+
"whitelist.enabled": "Whitelist is currently enabled.",
|
|
53
|
+
"whitelist.disabled": "Whitelist is currently disabled.",
|
|
54
|
+
"whitelist.description": "Restrict OIDC authentication to specific email addresses and optionally assign them custom role(s).",
|
|
55
|
+
"whitelist.user_exists": "User already exists, matching existing role(s)",
|
|
56
|
+
"whitelist.users_exists": "Users already exist, matching existing role(s)",
|
|
57
|
+
"whitelist.table.no": "No.",
|
|
58
|
+
"whitelist.table.email": "Email",
|
|
59
|
+
"whitelist.table.created": "Created At",
|
|
60
|
+
"whitelist.delete.title": "Confirmation",
|
|
61
|
+
"whitelist.delete.description": "Are you sure you want to delete:",
|
|
62
|
+
"whitelist.delete.note": "This will not delete the user account in Strapi.",
|
|
63
|
+
"whitelist.toggle.enabled": "Enabled",
|
|
64
|
+
"whitelist.toggle.disabled": "Disabled",
|
|
65
|
+
"whitelist.email.placeholder": "Email address",
|
|
66
|
+
"whitelist.roles.placeholder": "Select specific role(s)",
|
|
67
|
+
"whitelist.table.roles": "Role(s)",
|
|
68
|
+
"whitelist.table.roles.default": "Default",
|
|
69
|
+
"whitelist.table.empty": "No email addresses",
|
|
70
|
+
"whitelist.delete.label": "Delete",
|
|
71
|
+
"page.title.oidc": "OIDC",
|
|
72
|
+
"enforce.title": "Enforce OIDC Login",
|
|
73
|
+
"enforce.toggle.enabled": "Enabled",
|
|
74
|
+
"enforce.toggle.disabled": "Disabled",
|
|
75
|
+
"enforce.warning": "Make sure OIDC is setup correctly before saving changes, you won't be able to login normally.",
|
|
76
|
+
"login.sso": "Login via SSO"
|
|
77
|
+
};
|
|
78
|
+
const en$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
79
|
+
__proto__: null,
|
|
80
|
+
default: en
|
|
81
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
82
|
+
const name = pluginPkg.strapi.displayName;
|
|
83
|
+
const index = {
|
|
84
|
+
register(app) {
|
|
85
|
+
app.addSettingsLink(
|
|
86
|
+
{
|
|
87
|
+
id: "oidc",
|
|
88
|
+
intlLabel: {
|
|
89
|
+
id: `${pluginId}.settings.section`,
|
|
90
|
+
defaultMessage: "OIDC"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "configuration",
|
|
95
|
+
to: `/settings/${pluginId}`,
|
|
96
|
+
intlLabel: {
|
|
97
|
+
id: `${pluginId}.settings.configuration`,
|
|
98
|
+
defaultMessage: "Configuration"
|
|
99
|
+
},
|
|
100
|
+
Component: async () => {
|
|
101
|
+
return await import("./index-D2Fm7gNJ.mjs");
|
|
102
|
+
},
|
|
103
|
+
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
app.registerPlugin({
|
|
107
|
+
id: pluginId,
|
|
108
|
+
initializer: Initializer,
|
|
109
|
+
name
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
bootstrap() {
|
|
113
|
+
let isLogoutInProgress = false;
|
|
114
|
+
let historyPatched = false;
|
|
115
|
+
const ENFORCE_CACHE_KEY = "strapi_oidc_enforced";
|
|
116
|
+
const isAuthRoute = (path) => /\/auth\/(login|register|forgot-password|reset-password)/.test(path);
|
|
117
|
+
const patchHistory = () => {
|
|
118
|
+
if (historyPatched) return;
|
|
119
|
+
historyPatched = true;
|
|
120
|
+
const interceptHistory = (originalMethod) => {
|
|
121
|
+
return function(...args) {
|
|
122
|
+
const url = args[2];
|
|
123
|
+
if (url && typeof url === "string") {
|
|
124
|
+
const urlWithoutQuery = url.split("?")[0].split("#")[0];
|
|
125
|
+
if (isAuthRoute(urlWithoutQuery)) {
|
|
126
|
+
if (isLogoutInProgress) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return originalMethod.apply(window.history, args);
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
window.history.pushState = interceptHistory(window.history.pushState);
|
|
137
|
+
window.history.replaceState = interceptHistory(window.history.replaceState);
|
|
138
|
+
if (isAuthRoute(window.location.pathname)) {
|
|
139
|
+
window.location.replace("/strapi-plugin-oidc/oidc");
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
let ssoButtonInjected = false;
|
|
143
|
+
let ssoObserver = null;
|
|
144
|
+
const injectSSOButton = () => {
|
|
145
|
+
if (ssoButtonInjected) return;
|
|
146
|
+
if (!isAuthRoute(window.location.pathname)) return;
|
|
147
|
+
if (document.getElementById("strapi-oidc-sso-btn")) return;
|
|
148
|
+
const submitButton = document.querySelector('form button[type="submit"]');
|
|
149
|
+
if (!submitButton?.parentNode) return;
|
|
150
|
+
const btn = document.createElement("button");
|
|
151
|
+
btn.id = "strapi-oidc-sso-btn";
|
|
152
|
+
btn.type = "button";
|
|
153
|
+
btn.className = submitButton.className;
|
|
154
|
+
btn.style.marginTop = "8px";
|
|
155
|
+
btn.onclick = () => {
|
|
156
|
+
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
157
|
+
};
|
|
158
|
+
const innerSpan = submitButton.querySelector("span");
|
|
159
|
+
const span = document.createElement("span");
|
|
160
|
+
if (innerSpan) span.className = innerSpan.className;
|
|
161
|
+
span.textContent = en["login.sso"];
|
|
162
|
+
btn.appendChild(span);
|
|
163
|
+
submitButton.parentNode.insertBefore(btn, submitButton.nextSibling);
|
|
164
|
+
ssoButtonInjected = true;
|
|
165
|
+
};
|
|
166
|
+
const startSSOButtonObserver = () => {
|
|
167
|
+
if (ssoObserver) return;
|
|
168
|
+
injectSSOButton();
|
|
169
|
+
ssoObserver = new MutationObserver(() => {
|
|
170
|
+
if (isAuthRoute(window.location.pathname)) injectSSOButton();
|
|
171
|
+
});
|
|
172
|
+
ssoObserver.observe(document.body, { childList: true, subtree: true });
|
|
173
|
+
};
|
|
174
|
+
const stopSSOButtonObserver = () => {
|
|
175
|
+
ssoObserver?.disconnect();
|
|
176
|
+
ssoObserver = null;
|
|
177
|
+
document.getElementById("strapi-oidc-sso-btn")?.remove();
|
|
178
|
+
ssoButtonInjected = false;
|
|
179
|
+
};
|
|
180
|
+
if (localStorage.getItem(ENFORCE_CACHE_KEY) === "1") {
|
|
181
|
+
patchHistory();
|
|
182
|
+
}
|
|
183
|
+
const checkEnforceOIDC = async () => {
|
|
184
|
+
try {
|
|
185
|
+
const response = await window.fetch("/strapi-plugin-oidc/settings/public");
|
|
186
|
+
if (response.ok) {
|
|
187
|
+
const data = await response.json();
|
|
188
|
+
if (data.enforceOIDC) {
|
|
189
|
+
localStorage.setItem(ENFORCE_CACHE_KEY, "1");
|
|
190
|
+
stopSSOButtonObserver();
|
|
191
|
+
patchHistory();
|
|
192
|
+
} else {
|
|
193
|
+
localStorage.removeItem(ENFORCE_CACHE_KEY);
|
|
194
|
+
startSSOButtonObserver();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error("Failed to check OIDC enforcement setting:", error);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
checkEnforceOIDC();
|
|
202
|
+
const originalFetch = window.fetch;
|
|
203
|
+
window.fetch = async (...args) => {
|
|
204
|
+
const url = typeof args[0] === "string" ? args[0] : args[0].url;
|
|
205
|
+
const isLogout = url && url.endsWith("/admin/logout") && args[1]?.method?.toUpperCase() === "POST";
|
|
206
|
+
if (isLogout) {
|
|
207
|
+
isLogoutInProgress = true;
|
|
208
|
+
}
|
|
209
|
+
const response = await originalFetch(...args);
|
|
210
|
+
if (isLogout && response.ok) {
|
|
211
|
+
window.localStorage.removeItem("jwtToken");
|
|
212
|
+
window.localStorage.removeItem("isLoggedIn");
|
|
213
|
+
window.sessionStorage.removeItem("jwtToken");
|
|
214
|
+
window.sessionStorage.removeItem("isLoggedIn");
|
|
215
|
+
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
|
216
|
+
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
|
|
217
|
+
window.location.href = "/strapi-plugin-oidc/logout";
|
|
218
|
+
return new Promise(() => {
|
|
219
|
+
});
|
|
220
|
+
} else if (isLogout) {
|
|
221
|
+
isLogoutInProgress = false;
|
|
222
|
+
}
|
|
223
|
+
return response;
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
async registerTrads({ locales }) {
|
|
227
|
+
const importedTrads = await Promise.all(
|
|
228
|
+
locales.map((locale) => {
|
|
229
|
+
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => en$1) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
|
230
|
+
const newData = Object.fromEntries(
|
|
231
|
+
Object.entries(data).map(([key, value]) => [
|
|
232
|
+
key.startsWith("global.") ? key : getTranslation(key),
|
|
233
|
+
value
|
|
234
|
+
])
|
|
235
|
+
);
|
|
236
|
+
return {
|
|
237
|
+
data: newData,
|
|
238
|
+
locale
|
|
239
|
+
};
|
|
240
|
+
}).catch(() => {
|
|
241
|
+
return {
|
|
242
|
+
data: {},
|
|
243
|
+
locale
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
})
|
|
247
|
+
);
|
|
248
|
+
return Promise.resolve(importedTrads);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
export {
|
|
252
|
+
en as e,
|
|
253
|
+
index as i,
|
|
254
|
+
pluginId as p
|
|
255
|
+
};
|
package/dist/admin/index.js
CHANGED
package/dist/admin/index.mjs
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -10,8 +10,25 @@ const strapiUtils__default = /* @__PURE__ */ _interopDefault(strapiUtils);
|
|
|
10
10
|
const generator__default = /* @__PURE__ */ _interopDefault(generator);
|
|
11
11
|
function register$1() {
|
|
12
12
|
}
|
|
13
|
+
function getExpiredCookieOptions(strapi2, ctx) {
|
|
14
|
+
const isProduction = strapi2.config.get("environment") === "production";
|
|
15
|
+
return {
|
|
16
|
+
httpOnly: true,
|
|
17
|
+
secure: isProduction && ctx.request.secure,
|
|
18
|
+
path: strapi2.config.get("admin.auth.cookie.path", "/admin"),
|
|
19
|
+
domain: strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain"),
|
|
20
|
+
sameSite: strapi2.config.get("admin.auth.cookie.sameSite", "lax"),
|
|
21
|
+
maxAge: 0,
|
|
22
|
+
expires: /* @__PURE__ */ new Date(0)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function clearAuthCookies(strapi2, ctx) {
|
|
26
|
+
const options2 = getExpiredCookieOptions(strapi2, ctx);
|
|
27
|
+
ctx.cookies.set("strapi_admin_refresh", "", options2);
|
|
28
|
+
ctx.cookies.set("oidc_authenticated", "", options2);
|
|
29
|
+
}
|
|
13
30
|
async function bootstrap({ strapi: strapi2 }) {
|
|
14
|
-
|
|
31
|
+
const enforceOidcMiddleware = async (ctx, next) => {
|
|
15
32
|
const adminUrl = strapi2.config.get("admin.url", "/admin");
|
|
16
33
|
const authRoutes = [
|
|
17
34
|
`${adminUrl}/login`,
|
|
@@ -20,9 +37,10 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
20
37
|
`${adminUrl}/reset-password`
|
|
21
38
|
];
|
|
22
39
|
const isPostAuth = authRoutes.includes(ctx.request.path) && ctx.request.method === "POST";
|
|
23
|
-
const
|
|
40
|
+
const isTokenRefresh = ctx.request.path === `${adminUrl}/token/refresh` && ctx.request.method === "POST";
|
|
41
|
+
const isHtmlRequest = ctx.request.accepts("html", "json") === "html" && !ctx.request.path.match(/\.[a-zA-Z0-9]+$/);
|
|
24
42
|
const isGetAdminHtml = ctx.request.method === "GET" && ctx.request.path.startsWith(adminUrl) && isHtmlRequest;
|
|
25
|
-
if (isPostAuth || isGetAdminHtml) {
|
|
43
|
+
if (isPostAuth || isTokenRefresh || isGetAdminHtml) {
|
|
26
44
|
try {
|
|
27
45
|
const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
|
|
28
46
|
const settings = await whitelistService2.getSettings();
|
|
@@ -40,8 +58,27 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
40
58
|
};
|
|
41
59
|
return;
|
|
42
60
|
}
|
|
61
|
+
const hasOidcSession = !!ctx.cookies.get("oidc_authenticated");
|
|
62
|
+
if (isTokenRefresh && !hasOidcSession) {
|
|
63
|
+
ctx.status = 401;
|
|
64
|
+
ctx.body = {
|
|
65
|
+
data: null,
|
|
66
|
+
error: {
|
|
67
|
+
status: 401,
|
|
68
|
+
name: "UnauthorizedError",
|
|
69
|
+
message: "Session was not created via OIDC. Please log in again.",
|
|
70
|
+
details: {}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
43
75
|
if (isGetAdminHtml) {
|
|
44
|
-
const hasRefreshCookie = ctx.cookies.get("strapi_admin_refresh");
|
|
76
|
+
const hasRefreshCookie = !!ctx.cookies.get("strapi_admin_refresh");
|
|
77
|
+
if (hasRefreshCookie && !hasOidcSession) {
|
|
78
|
+
clearAuthCookies(strapi2, ctx);
|
|
79
|
+
ctx.redirect("/strapi-plugin-oidc/oidc");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
45
82
|
if (!hasRefreshCookie) {
|
|
46
83
|
ctx.redirect("/strapi-plugin-oidc/oidc");
|
|
47
84
|
return;
|
|
@@ -53,7 +90,12 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
53
90
|
}
|
|
54
91
|
}
|
|
55
92
|
await next();
|
|
56
|
-
}
|
|
93
|
+
};
|
|
94
|
+
if (strapi2.server.app && Array.isArray(strapi2.server.app.middleware)) {
|
|
95
|
+
strapi2.server.app.middleware.unshift(enforceOidcMiddleware);
|
|
96
|
+
} else {
|
|
97
|
+
strapi2.server.use(enforceOidcMiddleware);
|
|
98
|
+
}
|
|
57
99
|
const actions = [
|
|
58
100
|
{
|
|
59
101
|
section: "plugins",
|
|
@@ -336,7 +378,9 @@ async function oidcSignInCallback(ctx) {
|
|
|
336
378
|
async function logout(ctx) {
|
|
337
379
|
const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
|
|
338
380
|
const logoutUrl = config2.OIDC_LOGOUT_URL;
|
|
339
|
-
|
|
381
|
+
const isOidcSession = !!ctx.cookies.get("oidc_authenticated");
|
|
382
|
+
clearAuthCookies(strapi, ctx);
|
|
383
|
+
if (logoutUrl && isOidcSession) {
|
|
340
384
|
ctx.redirect(logoutUrl);
|
|
341
385
|
} else {
|
|
342
386
|
const adminPanelUrl = strapi.config.get("admin.url", "/admin");
|
|
@@ -912,6 +956,7 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
912
956
|
cookieOptions.expires = new Date(Date.now() + durationInMs);
|
|
913
957
|
}
|
|
914
958
|
ctx.cookies.set("strapi_admin_refresh", refreshToken, cookieOptions);
|
|
959
|
+
ctx.cookies.set("oidc_authenticated", "1", cookieOptions);
|
|
915
960
|
const accessResult = await sessionManager("admin").generateAccessToken(refreshToken);
|
|
916
961
|
if ("error" in accessResult) {
|
|
917
962
|
throw new Error(accessResult.error);
|
|
@@ -972,16 +1017,24 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
972
1017
|
name: "strapi-plugin-oidc"
|
|
973
1018
|
});
|
|
974
1019
|
const getWhitelistQuery = () => strapi2.query("plugin::strapi-plugin-oidc.whitelists");
|
|
1020
|
+
let settingsCache = null;
|
|
1021
|
+
const SETTINGS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
975
1022
|
return {
|
|
976
1023
|
async getSettings() {
|
|
1024
|
+
const now = Date.now();
|
|
1025
|
+
if (settingsCache && now - settingsCache.ts < SETTINGS_CACHE_TTL_MS) {
|
|
1026
|
+
return settingsCache.value;
|
|
1027
|
+
}
|
|
977
1028
|
let settings = await getPluginStore().get({ key: "settings" });
|
|
978
1029
|
if (!settings) {
|
|
979
1030
|
settings = { useWhitelist: true, enforceOIDC: false };
|
|
980
1031
|
await getPluginStore().set({ key: "settings", value: settings });
|
|
981
1032
|
}
|
|
1033
|
+
settingsCache = { value: settings, ts: now };
|
|
982
1034
|
return settings;
|
|
983
1035
|
},
|
|
984
1036
|
async setSettings(settings) {
|
|
1037
|
+
settingsCache = null;
|
|
985
1038
|
await getPluginStore().set({ key: "settings", value: settings });
|
|
986
1039
|
},
|
|
987
1040
|
async getUsers() {
|
|
@@ -999,14 +1052,12 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
999
1052
|
},
|
|
1000
1053
|
async checkWhitelistForEmail(email) {
|
|
1001
1054
|
const settings = await this.getSettings();
|
|
1002
|
-
console.log("checkWhitelistForEmail settings:", settings);
|
|
1003
1055
|
if (!settings.useWhitelist) {
|
|
1004
1056
|
return null;
|
|
1005
1057
|
}
|
|
1006
1058
|
const result = await getWhitelistQuery().findOne({
|
|
1007
1059
|
where: { email }
|
|
1008
1060
|
});
|
|
1009
|
-
console.log("checkWhitelistForEmail result:", result);
|
|
1010
1061
|
if (!result) {
|
|
1011
1062
|
throw new Error("Not present in whitelist");
|
|
1012
1063
|
}
|
package/dist/server/index.mjs
CHANGED
|
@@ -4,8 +4,25 @@ import strapiUtils from "@strapi/utils";
|
|
|
4
4
|
import generator from "generate-password";
|
|
5
5
|
function register$1() {
|
|
6
6
|
}
|
|
7
|
+
function getExpiredCookieOptions(strapi2, ctx) {
|
|
8
|
+
const isProduction = strapi2.config.get("environment") === "production";
|
|
9
|
+
return {
|
|
10
|
+
httpOnly: true,
|
|
11
|
+
secure: isProduction && ctx.request.secure,
|
|
12
|
+
path: strapi2.config.get("admin.auth.cookie.path", "/admin"),
|
|
13
|
+
domain: strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain"),
|
|
14
|
+
sameSite: strapi2.config.get("admin.auth.cookie.sameSite", "lax"),
|
|
15
|
+
maxAge: 0,
|
|
16
|
+
expires: /* @__PURE__ */ new Date(0)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function clearAuthCookies(strapi2, ctx) {
|
|
20
|
+
const options2 = getExpiredCookieOptions(strapi2, ctx);
|
|
21
|
+
ctx.cookies.set("strapi_admin_refresh", "", options2);
|
|
22
|
+
ctx.cookies.set("oidc_authenticated", "", options2);
|
|
23
|
+
}
|
|
7
24
|
async function bootstrap({ strapi: strapi2 }) {
|
|
8
|
-
|
|
25
|
+
const enforceOidcMiddleware = async (ctx, next) => {
|
|
9
26
|
const adminUrl = strapi2.config.get("admin.url", "/admin");
|
|
10
27
|
const authRoutes = [
|
|
11
28
|
`${adminUrl}/login`,
|
|
@@ -14,9 +31,10 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
14
31
|
`${adminUrl}/reset-password`
|
|
15
32
|
];
|
|
16
33
|
const isPostAuth = authRoutes.includes(ctx.request.path) && ctx.request.method === "POST";
|
|
17
|
-
const
|
|
34
|
+
const isTokenRefresh = ctx.request.path === `${adminUrl}/token/refresh` && ctx.request.method === "POST";
|
|
35
|
+
const isHtmlRequest = ctx.request.accepts("html", "json") === "html" && !ctx.request.path.match(/\.[a-zA-Z0-9]+$/);
|
|
18
36
|
const isGetAdminHtml = ctx.request.method === "GET" && ctx.request.path.startsWith(adminUrl) && isHtmlRequest;
|
|
19
|
-
if (isPostAuth || isGetAdminHtml) {
|
|
37
|
+
if (isPostAuth || isTokenRefresh || isGetAdminHtml) {
|
|
20
38
|
try {
|
|
21
39
|
const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
|
|
22
40
|
const settings = await whitelistService2.getSettings();
|
|
@@ -34,8 +52,27 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
34
52
|
};
|
|
35
53
|
return;
|
|
36
54
|
}
|
|
55
|
+
const hasOidcSession = !!ctx.cookies.get("oidc_authenticated");
|
|
56
|
+
if (isTokenRefresh && !hasOidcSession) {
|
|
57
|
+
ctx.status = 401;
|
|
58
|
+
ctx.body = {
|
|
59
|
+
data: null,
|
|
60
|
+
error: {
|
|
61
|
+
status: 401,
|
|
62
|
+
name: "UnauthorizedError",
|
|
63
|
+
message: "Session was not created via OIDC. Please log in again.",
|
|
64
|
+
details: {}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
37
69
|
if (isGetAdminHtml) {
|
|
38
|
-
const hasRefreshCookie = ctx.cookies.get("strapi_admin_refresh");
|
|
70
|
+
const hasRefreshCookie = !!ctx.cookies.get("strapi_admin_refresh");
|
|
71
|
+
if (hasRefreshCookie && !hasOidcSession) {
|
|
72
|
+
clearAuthCookies(strapi2, ctx);
|
|
73
|
+
ctx.redirect("/strapi-plugin-oidc/oidc");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
39
76
|
if (!hasRefreshCookie) {
|
|
40
77
|
ctx.redirect("/strapi-plugin-oidc/oidc");
|
|
41
78
|
return;
|
|
@@ -47,7 +84,12 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
47
84
|
}
|
|
48
85
|
}
|
|
49
86
|
await next();
|
|
50
|
-
}
|
|
87
|
+
};
|
|
88
|
+
if (strapi2.server.app && Array.isArray(strapi2.server.app.middleware)) {
|
|
89
|
+
strapi2.server.app.middleware.unshift(enforceOidcMiddleware);
|
|
90
|
+
} else {
|
|
91
|
+
strapi2.server.use(enforceOidcMiddleware);
|
|
92
|
+
}
|
|
51
93
|
const actions = [
|
|
52
94
|
{
|
|
53
95
|
section: "plugins",
|
|
@@ -330,7 +372,9 @@ async function oidcSignInCallback(ctx) {
|
|
|
330
372
|
async function logout(ctx) {
|
|
331
373
|
const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
|
|
332
374
|
const logoutUrl = config2.OIDC_LOGOUT_URL;
|
|
333
|
-
|
|
375
|
+
const isOidcSession = !!ctx.cookies.get("oidc_authenticated");
|
|
376
|
+
clearAuthCookies(strapi, ctx);
|
|
377
|
+
if (logoutUrl && isOidcSession) {
|
|
334
378
|
ctx.redirect(logoutUrl);
|
|
335
379
|
} else {
|
|
336
380
|
const adminPanelUrl = strapi.config.get("admin.url", "/admin");
|
|
@@ -906,6 +950,7 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
906
950
|
cookieOptions.expires = new Date(Date.now() + durationInMs);
|
|
907
951
|
}
|
|
908
952
|
ctx.cookies.set("strapi_admin_refresh", refreshToken, cookieOptions);
|
|
953
|
+
ctx.cookies.set("oidc_authenticated", "1", cookieOptions);
|
|
909
954
|
const accessResult = await sessionManager("admin").generateAccessToken(refreshToken);
|
|
910
955
|
if ("error" in accessResult) {
|
|
911
956
|
throw new Error(accessResult.error);
|
|
@@ -966,16 +1011,24 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
966
1011
|
name: "strapi-plugin-oidc"
|
|
967
1012
|
});
|
|
968
1013
|
const getWhitelistQuery = () => strapi2.query("plugin::strapi-plugin-oidc.whitelists");
|
|
1014
|
+
let settingsCache = null;
|
|
1015
|
+
const SETTINGS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
969
1016
|
return {
|
|
970
1017
|
async getSettings() {
|
|
1018
|
+
const now = Date.now();
|
|
1019
|
+
if (settingsCache && now - settingsCache.ts < SETTINGS_CACHE_TTL_MS) {
|
|
1020
|
+
return settingsCache.value;
|
|
1021
|
+
}
|
|
971
1022
|
let settings = await getPluginStore().get({ key: "settings" });
|
|
972
1023
|
if (!settings) {
|
|
973
1024
|
settings = { useWhitelist: true, enforceOIDC: false };
|
|
974
1025
|
await getPluginStore().set({ key: "settings", value: settings });
|
|
975
1026
|
}
|
|
1027
|
+
settingsCache = { value: settings, ts: now };
|
|
976
1028
|
return settings;
|
|
977
1029
|
},
|
|
978
1030
|
async setSettings(settings) {
|
|
1031
|
+
settingsCache = null;
|
|
979
1032
|
await getPluginStore().set({ key: "settings", value: settings });
|
|
980
1033
|
},
|
|
981
1034
|
async getUsers() {
|
|
@@ -993,14 +1046,12 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
993
1046
|
},
|
|
994
1047
|
async checkWhitelistForEmail(email) {
|
|
995
1048
|
const settings = await this.getSettings();
|
|
996
|
-
console.log("checkWhitelistForEmail settings:", settings);
|
|
997
1049
|
if (!settings.useWhitelist) {
|
|
998
1050
|
return null;
|
|
999
1051
|
}
|
|
1000
1052
|
const result = await getWhitelistQuery().findOne({
|
|
1001
1053
|
where: { email }
|
|
1002
1054
|
});
|
|
1003
|
-
console.log("checkWhitelistForEmail result:", result);
|
|
1004
1055
|
if (!result) {
|
|
1005
1056
|
throw new Error("Not present in whitelist");
|
|
1006
1057
|
}
|
package/package.json
CHANGED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const en = {
|
|
4
|
-
"global.plugins.strapi-plugin-oidc": "OIDC Plugin",
|
|
5
|
-
"page.title": "Configure OIDC default role(s) and access controls.",
|
|
6
|
-
"roles.notes": "Select the default role(s) assigned to new users upon their first login. This setting does not affect existing users.",
|
|
7
|
-
"page.save": "Save Changes",
|
|
8
|
-
"page.save.success": "Updated settings",
|
|
9
|
-
"page.save.error": "Update failed.",
|
|
10
|
-
"page.add": "Add",
|
|
11
|
-
"page.cancel": "Cancel",
|
|
12
|
-
"page.ok": "OK",
|
|
13
|
-
"roles.title": "Default Role(s)",
|
|
14
|
-
"roles.placeholder": "Select default role(s)",
|
|
15
|
-
"whitelist.title": "Whitelist",
|
|
16
|
-
"whitelist.error.unique": "Already registered email address.",
|
|
17
|
-
"whitelist.enabled": "Whitelist is currently enabled.",
|
|
18
|
-
"whitelist.disabled": "Whitelist is currently disabled.",
|
|
19
|
-
"whitelist.description": "Restrict OIDC authentication to specific email addresses and optionally assign them custom role(s).",
|
|
20
|
-
"whitelist.user_exists": "User already exists, matching existing role(s)",
|
|
21
|
-
"whitelist.users_exists": "Users already exist, matching existing role(s)",
|
|
22
|
-
"whitelist.table.no": "No.",
|
|
23
|
-
"whitelist.table.email": "Email",
|
|
24
|
-
"whitelist.table.created": "Created At",
|
|
25
|
-
"whitelist.delete.title": "Confirmation",
|
|
26
|
-
"whitelist.delete.description": "Are you sure you want to delete:",
|
|
27
|
-
"whitelist.delete.note": "This will not delete the user account in Strapi.",
|
|
28
|
-
"whitelist.toggle.enabled": "Enabled",
|
|
29
|
-
"whitelist.toggle.disabled": "Disabled",
|
|
30
|
-
"whitelist.email.placeholder": "Email address",
|
|
31
|
-
"whitelist.roles.placeholder": "Select specific role(s)",
|
|
32
|
-
"whitelist.table.roles": "Role(s)",
|
|
33
|
-
"whitelist.table.roles.default": "Default",
|
|
34
|
-
"whitelist.table.empty": "No email addresses",
|
|
35
|
-
"whitelist.delete.label": "Delete",
|
|
36
|
-
"page.title.oidc": "OIDC",
|
|
37
|
-
"enforce.title": "Enforce OIDC Login",
|
|
38
|
-
"enforce.toggle.enabled": "Enabled",
|
|
39
|
-
"enforce.toggle.disabled": "Disabled",
|
|
40
|
-
"enforce.warning": "Make sure OIDC is setup correctly before saving changes, you won't be able to login normally."
|
|
41
|
-
};
|
|
42
|
-
exports.default = en;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
const en = {
|
|
2
|
-
"global.plugins.strapi-plugin-oidc": "OIDC Plugin",
|
|
3
|
-
"page.title": "Configure OIDC default role(s) and access controls.",
|
|
4
|
-
"roles.notes": "Select the default role(s) assigned to new users upon their first login. This setting does not affect existing users.",
|
|
5
|
-
"page.save": "Save Changes",
|
|
6
|
-
"page.save.success": "Updated settings",
|
|
7
|
-
"page.save.error": "Update failed.",
|
|
8
|
-
"page.add": "Add",
|
|
9
|
-
"page.cancel": "Cancel",
|
|
10
|
-
"page.ok": "OK",
|
|
11
|
-
"roles.title": "Default Role(s)",
|
|
12
|
-
"roles.placeholder": "Select default role(s)",
|
|
13
|
-
"whitelist.title": "Whitelist",
|
|
14
|
-
"whitelist.error.unique": "Already registered email address.",
|
|
15
|
-
"whitelist.enabled": "Whitelist is currently enabled.",
|
|
16
|
-
"whitelist.disabled": "Whitelist is currently disabled.",
|
|
17
|
-
"whitelist.description": "Restrict OIDC authentication to specific email addresses and optionally assign them custom role(s).",
|
|
18
|
-
"whitelist.user_exists": "User already exists, matching existing role(s)",
|
|
19
|
-
"whitelist.users_exists": "Users already exist, matching existing role(s)",
|
|
20
|
-
"whitelist.table.no": "No.",
|
|
21
|
-
"whitelist.table.email": "Email",
|
|
22
|
-
"whitelist.table.created": "Created At",
|
|
23
|
-
"whitelist.delete.title": "Confirmation",
|
|
24
|
-
"whitelist.delete.description": "Are you sure you want to delete:",
|
|
25
|
-
"whitelist.delete.note": "This will not delete the user account in Strapi.",
|
|
26
|
-
"whitelist.toggle.enabled": "Enabled",
|
|
27
|
-
"whitelist.toggle.disabled": "Disabled",
|
|
28
|
-
"whitelist.email.placeholder": "Email address",
|
|
29
|
-
"whitelist.roles.placeholder": "Select specific role(s)",
|
|
30
|
-
"whitelist.table.roles": "Role(s)",
|
|
31
|
-
"whitelist.table.roles.default": "Default",
|
|
32
|
-
"whitelist.table.empty": "No email addresses",
|
|
33
|
-
"whitelist.delete.label": "Delete",
|
|
34
|
-
"page.title.oidc": "OIDC",
|
|
35
|
-
"enforce.title": "Enforce OIDC Login",
|
|
36
|
-
"enforce.toggle.enabled": "Enabled",
|
|
37
|
-
"enforce.toggle.disabled": "Disabled",
|
|
38
|
-
"enforce.warning": "Make sure OIDC is setup correctly before saving changes, you won't be able to login normally."
|
|
39
|
-
};
|
|
40
|
-
export {
|
|
41
|
-
en as default
|
|
42
|
-
};
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { useRef, useEffect } from "react";
|
|
2
|
-
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
3
|
-
const v = glob[path];
|
|
4
|
-
if (v) {
|
|
5
|
-
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
6
|
-
}
|
|
7
|
-
return new Promise((_, reject) => {
|
|
8
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
9
|
-
reject.bind(
|
|
10
|
-
null,
|
|
11
|
-
new Error(
|
|
12
|
-
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
13
|
-
)
|
|
14
|
-
)
|
|
15
|
-
);
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
const name$1 = "strapi-plugin-oidc";
|
|
19
|
-
const strapi = { "displayName": "OIDC Plugin" };
|
|
20
|
-
const pluginPkg = {
|
|
21
|
-
name: name$1,
|
|
22
|
-
strapi
|
|
23
|
-
};
|
|
24
|
-
const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, "");
|
|
25
|
-
function getTranslation(id) {
|
|
26
|
-
return `${pluginId}.${id}`;
|
|
27
|
-
}
|
|
28
|
-
function Initializer({ setPlugin }) {
|
|
29
|
-
const ref = useRef();
|
|
30
|
-
ref.current = setPlugin;
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (ref.current) {
|
|
33
|
-
ref.current(pluginId);
|
|
34
|
-
}
|
|
35
|
-
}, []);
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
const name = pluginPkg.strapi.displayName;
|
|
39
|
-
const index = {
|
|
40
|
-
register(app) {
|
|
41
|
-
app.addSettingsLink(
|
|
42
|
-
{
|
|
43
|
-
id: "oidc",
|
|
44
|
-
intlLabel: {
|
|
45
|
-
id: `${pluginId}.settings.section`,
|
|
46
|
-
defaultMessage: "OIDC"
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "configuration",
|
|
51
|
-
to: `/settings/${pluginId}`,
|
|
52
|
-
intlLabel: {
|
|
53
|
-
id: `${pluginId}.settings.configuration`,
|
|
54
|
-
defaultMessage: "Configuration"
|
|
55
|
-
},
|
|
56
|
-
Component: async () => {
|
|
57
|
-
return await import("./index-CxxsmBsC.mjs");
|
|
58
|
-
},
|
|
59
|
-
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
60
|
-
}
|
|
61
|
-
);
|
|
62
|
-
app.registerPlugin({
|
|
63
|
-
id: pluginId,
|
|
64
|
-
initializer: Initializer,
|
|
65
|
-
name
|
|
66
|
-
});
|
|
67
|
-
},
|
|
68
|
-
bootstrap() {
|
|
69
|
-
let isLogoutInProgress = false;
|
|
70
|
-
const isAuthRoute = (path) => /\/auth\/(login|register|forgot-password|reset-password)/.test(path);
|
|
71
|
-
const checkEnforceOIDC = async () => {
|
|
72
|
-
try {
|
|
73
|
-
const response = await window.fetch("/strapi-plugin-oidc/settings/public");
|
|
74
|
-
if (response.ok) {
|
|
75
|
-
const data = await response.json();
|
|
76
|
-
if (data.enforceOIDC) {
|
|
77
|
-
const interceptHistory = (originalMethod) => {
|
|
78
|
-
return function(...args) {
|
|
79
|
-
const url = args[2];
|
|
80
|
-
if (url && typeof url === "string") {
|
|
81
|
-
const urlWithoutQuery = url.split("?")[0].split("#")[0];
|
|
82
|
-
if (isAuthRoute(urlWithoutQuery) && !isLogoutInProgress) {
|
|
83
|
-
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return originalMethod.apply(window.history, args);
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
window.history.pushState = interceptHistory(window.history.pushState);
|
|
91
|
-
window.history.replaceState = interceptHistory(window.history.replaceState);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.error("Failed to check OIDC enforcement setting:", error);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
checkEnforceOIDC();
|
|
99
|
-
const originalFetch = window.fetch;
|
|
100
|
-
window.fetch = async (...args) => {
|
|
101
|
-
const url = typeof args[0] === "string" ? args[0] : args[0].url;
|
|
102
|
-
const isLogout = url && url.endsWith("/admin/logout") && args[1]?.method?.toUpperCase() === "POST";
|
|
103
|
-
if (isLogout) {
|
|
104
|
-
isLogoutInProgress = true;
|
|
105
|
-
}
|
|
106
|
-
const response = await originalFetch(...args);
|
|
107
|
-
if (isLogout && response.ok) {
|
|
108
|
-
window.localStorage.removeItem("jwtToken");
|
|
109
|
-
window.localStorage.removeItem("isLoggedIn");
|
|
110
|
-
window.sessionStorage.removeItem("jwtToken");
|
|
111
|
-
window.sessionStorage.removeItem("isLoggedIn");
|
|
112
|
-
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
|
113
|
-
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
|
|
114
|
-
document.cookie = "strapi_admin_refresh=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
|
115
|
-
document.cookie = "strapi_admin_refresh=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
|
|
116
|
-
window.location.href = "/strapi-plugin-oidc/logout";
|
|
117
|
-
return new Promise(() => {
|
|
118
|
-
});
|
|
119
|
-
} else if (isLogout) {
|
|
120
|
-
isLogoutInProgress = false;
|
|
121
|
-
}
|
|
122
|
-
return response;
|
|
123
|
-
};
|
|
124
|
-
},
|
|
125
|
-
async registerTrads({ locales }) {
|
|
126
|
-
const importedTrads = await Promise.all(
|
|
127
|
-
locales.map((locale) => {
|
|
128
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-DInn-mdh.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
|
129
|
-
const newData = Object.fromEntries(
|
|
130
|
-
Object.entries(data).map(([key, value]) => [
|
|
131
|
-
key.startsWith("global.") ? key : getTranslation(key),
|
|
132
|
-
value
|
|
133
|
-
])
|
|
134
|
-
);
|
|
135
|
-
return {
|
|
136
|
-
data: newData,
|
|
137
|
-
locale
|
|
138
|
-
};
|
|
139
|
-
}).catch(() => {
|
|
140
|
-
return {
|
|
141
|
-
data: {},
|
|
142
|
-
locale
|
|
143
|
-
};
|
|
144
|
-
});
|
|
145
|
-
})
|
|
146
|
-
);
|
|
147
|
-
return Promise.resolve(importedTrads);
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
export {
|
|
151
|
-
index as i,
|
|
152
|
-
pluginId as p
|
|
153
|
-
};
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
const react = require("react");
|
|
3
|
-
const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
|
|
4
|
-
const v = glob[path];
|
|
5
|
-
if (v) {
|
|
6
|
-
return typeof v === "function" ? v() : Promise.resolve(v);
|
|
7
|
-
}
|
|
8
|
-
return new Promise((_, reject) => {
|
|
9
|
-
(typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
|
|
10
|
-
reject.bind(
|
|
11
|
-
null,
|
|
12
|
-
new Error(
|
|
13
|
-
"Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
|
|
14
|
-
)
|
|
15
|
-
)
|
|
16
|
-
);
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
const name$1 = "strapi-plugin-oidc";
|
|
20
|
-
const strapi = { "displayName": "OIDC Plugin" };
|
|
21
|
-
const pluginPkg = {
|
|
22
|
-
name: name$1,
|
|
23
|
-
strapi
|
|
24
|
-
};
|
|
25
|
-
const pluginId = pluginPkg.name.replace(/^@strapi\/plugin-/i, "");
|
|
26
|
-
function getTranslation(id) {
|
|
27
|
-
return `${pluginId}.${id}`;
|
|
28
|
-
}
|
|
29
|
-
function Initializer({ setPlugin }) {
|
|
30
|
-
const ref = react.useRef();
|
|
31
|
-
ref.current = setPlugin;
|
|
32
|
-
react.useEffect(() => {
|
|
33
|
-
if (ref.current) {
|
|
34
|
-
ref.current(pluginId);
|
|
35
|
-
}
|
|
36
|
-
}, []);
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
const name = pluginPkg.strapi.displayName;
|
|
40
|
-
const index = {
|
|
41
|
-
register(app) {
|
|
42
|
-
app.addSettingsLink(
|
|
43
|
-
{
|
|
44
|
-
id: "oidc",
|
|
45
|
-
intlLabel: {
|
|
46
|
-
id: `${pluginId}.settings.section`,
|
|
47
|
-
defaultMessage: "OIDC"
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: "configuration",
|
|
52
|
-
to: `/settings/${pluginId}`,
|
|
53
|
-
intlLabel: {
|
|
54
|
-
id: `${pluginId}.settings.configuration`,
|
|
55
|
-
defaultMessage: "Configuration"
|
|
56
|
-
},
|
|
57
|
-
Component: async () => {
|
|
58
|
-
return await Promise.resolve().then(() => require("./index-B2lPDW7A.js"));
|
|
59
|
-
},
|
|
60
|
-
permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
|
|
61
|
-
}
|
|
62
|
-
);
|
|
63
|
-
app.registerPlugin({
|
|
64
|
-
id: pluginId,
|
|
65
|
-
initializer: Initializer,
|
|
66
|
-
name
|
|
67
|
-
});
|
|
68
|
-
},
|
|
69
|
-
bootstrap() {
|
|
70
|
-
let isLogoutInProgress = false;
|
|
71
|
-
const isAuthRoute = (path) => /\/auth\/(login|register|forgot-password|reset-password)/.test(path);
|
|
72
|
-
const checkEnforceOIDC = async () => {
|
|
73
|
-
try {
|
|
74
|
-
const response = await window.fetch("/strapi-plugin-oidc/settings/public");
|
|
75
|
-
if (response.ok) {
|
|
76
|
-
const data = await response.json();
|
|
77
|
-
if (data.enforceOIDC) {
|
|
78
|
-
const interceptHistory = (originalMethod) => {
|
|
79
|
-
return function(...args) {
|
|
80
|
-
const url = args[2];
|
|
81
|
-
if (url && typeof url === "string") {
|
|
82
|
-
const urlWithoutQuery = url.split("?")[0].split("#")[0];
|
|
83
|
-
if (isAuthRoute(urlWithoutQuery) && !isLogoutInProgress) {
|
|
84
|
-
window.location.href = "/strapi-plugin-oidc/oidc";
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return originalMethod.apply(window.history, args);
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
window.history.pushState = interceptHistory(window.history.pushState);
|
|
92
|
-
window.history.replaceState = interceptHistory(window.history.replaceState);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch (error) {
|
|
96
|
-
console.error("Failed to check OIDC enforcement setting:", error);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
checkEnforceOIDC();
|
|
100
|
-
const originalFetch = window.fetch;
|
|
101
|
-
window.fetch = async (...args) => {
|
|
102
|
-
const url = typeof args[0] === "string" ? args[0] : args[0].url;
|
|
103
|
-
const isLogout = url && url.endsWith("/admin/logout") && args[1]?.method?.toUpperCase() === "POST";
|
|
104
|
-
if (isLogout) {
|
|
105
|
-
isLogoutInProgress = true;
|
|
106
|
-
}
|
|
107
|
-
const response = await originalFetch(...args);
|
|
108
|
-
if (isLogout && response.ok) {
|
|
109
|
-
window.localStorage.removeItem("jwtToken");
|
|
110
|
-
window.localStorage.removeItem("isLoggedIn");
|
|
111
|
-
window.sessionStorage.removeItem("jwtToken");
|
|
112
|
-
window.sessionStorage.removeItem("isLoggedIn");
|
|
113
|
-
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
|
114
|
-
document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
|
|
115
|
-
document.cookie = "strapi_admin_refresh=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
|
116
|
-
document.cookie = "strapi_admin_refresh=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
|
|
117
|
-
window.location.href = "/strapi-plugin-oidc/logout";
|
|
118
|
-
return new Promise(() => {
|
|
119
|
-
});
|
|
120
|
-
} else if (isLogout) {
|
|
121
|
-
isLogoutInProgress = false;
|
|
122
|
-
}
|
|
123
|
-
return response;
|
|
124
|
-
};
|
|
125
|
-
},
|
|
126
|
-
async registerTrads({ locales }) {
|
|
127
|
-
const importedTrads = await Promise.all(
|
|
128
|
-
locales.map((locale) => {
|
|
129
|
-
return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("./en-8UlbiAHW.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
|
|
130
|
-
const newData = Object.fromEntries(
|
|
131
|
-
Object.entries(data).map(([key, value]) => [
|
|
132
|
-
key.startsWith("global.") ? key : getTranslation(key),
|
|
133
|
-
value
|
|
134
|
-
])
|
|
135
|
-
);
|
|
136
|
-
return {
|
|
137
|
-
data: newData,
|
|
138
|
-
locale
|
|
139
|
-
};
|
|
140
|
-
}).catch(() => {
|
|
141
|
-
return {
|
|
142
|
-
data: {},
|
|
143
|
-
locale
|
|
144
|
-
};
|
|
145
|
-
});
|
|
146
|
-
})
|
|
147
|
-
);
|
|
148
|
-
return Promise.resolve(importedTrads);
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
exports.index = index;
|
|
152
|
-
exports.pluginId = pluginId;
|