strapi-plugin-oidc 1.2.4 → 1.3.2
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 +20 -25
- package/dist/admin/{index-CYL_geya.js → index-BqyGGX8X.js} +82 -114
- package/dist/admin/{index-BD7cK7Hf.mjs → index-CFmg9Kxl.mjs} +58 -90
- package/dist/admin/{index-Cxj6lwW7.js → index-Cse9ex24.js} +78 -119
- package/dist/admin/{index-B2dKk7YS.mjs → index-D1ypRUlq.mjs} +79 -120
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +77 -57
- package/dist/server/index.mjs +77 -57
- package/package.json +1 -2
package/dist/server/index.mjs
CHANGED
|
@@ -4,22 +4,19 @@ import strapiUtils from "@strapi/utils";
|
|
|
4
4
|
import generator from "generate-password";
|
|
5
5
|
function register$1() {
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
maxAge: 0,
|
|
16
|
-
expires: /* @__PURE__ */ new Date(0)
|
|
17
|
-
};
|
|
7
|
+
function getEnforceOIDCConfig(strapi2) {
|
|
8
|
+
const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
|
|
9
|
+
const val = config2.OIDC_ENFORCE;
|
|
10
|
+
if (val === null || val === void 0) return null;
|
|
11
|
+
if (typeof val === "boolean") return val;
|
|
12
|
+
if (val === "true") return true;
|
|
13
|
+
if (val === "false") return false;
|
|
14
|
+
return null;
|
|
18
15
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
function resolveEnforceOIDC(strapi2, dbValue) {
|
|
17
|
+
const configValue = getEnforceOIDCConfig(strapi2);
|
|
18
|
+
if (configValue !== null) return configValue;
|
|
19
|
+
return dbValue ?? false;
|
|
23
20
|
}
|
|
24
21
|
async function bootstrap({ strapi: strapi2 }) {
|
|
25
22
|
const enforceOidcMiddleware = async (ctx, next) => {
|
|
@@ -32,13 +29,12 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
32
29
|
];
|
|
33
30
|
const isPostAuth = authRoutes.includes(ctx.request.path) && ctx.request.method === "POST";
|
|
34
31
|
const isTokenRefresh = ctx.request.path === `${adminUrl}/token/refresh` && ctx.request.method === "POST";
|
|
35
|
-
|
|
36
|
-
const isGetAdminHtml = ctx.request.method === "GET" && ctx.request.path.startsWith(adminUrl) && isHtmlRequest;
|
|
37
|
-
if (isPostAuth || isTokenRefresh || isGetAdminHtml) {
|
|
32
|
+
if (isPostAuth || isTokenRefresh) {
|
|
38
33
|
try {
|
|
39
34
|
const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
|
|
40
35
|
const settings = await whitelistService2.getSettings();
|
|
41
|
-
|
|
36
|
+
const enforceOIDC = resolveEnforceOIDC(strapi2, settings?.enforceOIDC);
|
|
37
|
+
if (enforceOIDC) {
|
|
42
38
|
if (isPostAuth) {
|
|
43
39
|
ctx.status = 403;
|
|
44
40
|
ctx.body = {
|
|
@@ -66,18 +62,6 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
66
62
|
};
|
|
67
63
|
return;
|
|
68
64
|
}
|
|
69
|
-
if (isGetAdminHtml) {
|
|
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
|
-
}
|
|
76
|
-
if (!hasRefreshCookie) {
|
|
77
|
-
ctx.redirect("/strapi-plugin-oidc/oidc");
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
65
|
}
|
|
82
66
|
} catch (err) {
|
|
83
67
|
strapi2.log.error("Error checking OIDC enforcement in middleware:", err);
|
|
@@ -105,6 +89,21 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
105
89
|
}
|
|
106
90
|
];
|
|
107
91
|
await strapi2.admin.services.permission.actionProvider.registerMany(actions);
|
|
92
|
+
const enforceOIDCConfig = getEnforceOIDCConfig(strapi2);
|
|
93
|
+
if (enforceOIDCConfig !== null) {
|
|
94
|
+
try {
|
|
95
|
+
const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
|
|
96
|
+
const settings = await whitelistService2.getSettings();
|
|
97
|
+
if (settings.enforceOIDC !== enforceOIDCConfig) {
|
|
98
|
+
await whitelistService2.setSettings({ ...settings, enforceOIDC: enforceOIDCConfig });
|
|
99
|
+
strapi2.log.info(
|
|
100
|
+
`[strapi-plugin-oidc] OIDC_ENFORCE=${enforceOIDCConfig} written to database settings`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
} catch (err) {
|
|
104
|
+
strapi2.log.error("[strapi-plugin-oidc] Failed to sync OIDC_ENFORCE to database:", err);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
108
107
|
try {
|
|
109
108
|
const oidcRoleCount = await strapi2.query("plugin::strapi-plugin-oidc.roles").count({
|
|
110
109
|
where: { oauth_type: "4" }
|
|
@@ -152,8 +151,6 @@ function destroy() {
|
|
|
152
151
|
const config = {
|
|
153
152
|
default: {
|
|
154
153
|
REMEMBER_ME: false,
|
|
155
|
-
REMEMBER_ME_DAYS: 30,
|
|
156
|
-
// 30 days
|
|
157
154
|
OIDC_REDIRECT_URI: "http://localhost:1337/strapi-plugin-oidc/oidc/callback",
|
|
158
155
|
OIDC_CLIENT_ID: "",
|
|
159
156
|
OIDC_CLIENT_SECRET: "",
|
|
@@ -165,7 +162,10 @@ const config = {
|
|
|
165
162
|
OIDC_GRANT_TYPE: "authorization_code",
|
|
166
163
|
OIDC_FAMILY_NAME_FIELD: "family_name",
|
|
167
164
|
OIDC_GIVEN_NAME_FIELD: "given_name",
|
|
168
|
-
OIDC_LOGOUT_URL: ""
|
|
165
|
+
OIDC_LOGOUT_URL: "",
|
|
166
|
+
OIDC_SSO_BUTTON_TEXT: "Login via SSO",
|
|
167
|
+
OIDC_ENFORCE: null
|
|
168
|
+
// null = use DB setting; true/false = override DB (useful for lockout recovery)
|
|
169
169
|
},
|
|
170
170
|
validator() {
|
|
171
171
|
}
|
|
@@ -200,6 +200,23 @@ const contentTypes = {
|
|
|
200
200
|
roles,
|
|
201
201
|
whitelists
|
|
202
202
|
};
|
|
203
|
+
function getExpiredCookieOptions(strapi2, ctx) {
|
|
204
|
+
const isProduction = strapi2.config.get("environment") === "production";
|
|
205
|
+
return {
|
|
206
|
+
httpOnly: true,
|
|
207
|
+
secure: isProduction && ctx.request.secure,
|
|
208
|
+
path: strapi2.config.get("admin.auth.cookie.path", "/admin"),
|
|
209
|
+
domain: strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain"),
|
|
210
|
+
sameSite: strapi2.config.get("admin.auth.cookie.sameSite", "lax"),
|
|
211
|
+
maxAge: 0,
|
|
212
|
+
expires: /* @__PURE__ */ new Date(0)
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function clearAuthCookies(strapi2, ctx) {
|
|
216
|
+
const options2 = getExpiredCookieOptions(strapi2, ctx);
|
|
217
|
+
ctx.cookies.set("strapi_admin_refresh", "", options2);
|
|
218
|
+
ctx.cookies.set("oidc_authenticated", "", { ...options2, path: "/" });
|
|
219
|
+
}
|
|
203
220
|
function configValidation() {
|
|
204
221
|
const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
|
|
205
222
|
const requiredKeys = [
|
|
@@ -339,6 +356,8 @@ async function oidcSignInCallback(ctx) {
|
|
|
339
356
|
}
|
|
340
357
|
const oidcState = ctx.cookies.get("oidc_state");
|
|
341
358
|
const codeVerifier = ctx.cookies.get("oidc_code_verifier");
|
|
359
|
+
ctx.cookies.set("oidc_state", null);
|
|
360
|
+
ctx.cookies.set("oidc_code_verifier", null);
|
|
342
361
|
if (!ctx.query.state || ctx.query.state !== oidcState) {
|
|
343
362
|
return ctx.send(oauthService2.renderSignUpError("Invalid state"));
|
|
344
363
|
}
|
|
@@ -419,14 +438,13 @@ async function info(ctx) {
|
|
|
419
438
|
const whitelistUsers = await whitelistService2.getUsers();
|
|
420
439
|
ctx.body = {
|
|
421
440
|
useWhitelist: settings.useWhitelist,
|
|
422
|
-
enforceOIDC: settings.enforceOIDC
|
|
423
|
-
|
|
424
|
-
ssoButtonText: settings.ssoButtonText || "Login via SSO",
|
|
441
|
+
enforceOIDC: resolveEnforceOIDC(strapi, settings.enforceOIDC),
|
|
442
|
+
enforceOIDCConfig: getEnforceOIDCConfig(strapi),
|
|
425
443
|
whitelistUsers
|
|
426
444
|
};
|
|
427
445
|
}
|
|
428
446
|
async function updateSettings(ctx) {
|
|
429
|
-
let { useWhitelist, enforceOIDC
|
|
447
|
+
let { useWhitelist, enforceOIDC } = ctx.request.body;
|
|
430
448
|
const whitelistService2 = strapi.plugin("strapi-plugin-oidc").service("whitelist");
|
|
431
449
|
if (useWhitelist && enforceOIDC) {
|
|
432
450
|
const users = await whitelistService2.getUsers();
|
|
@@ -434,16 +452,16 @@ async function updateSettings(ctx) {
|
|
|
434
452
|
enforceOIDC = false;
|
|
435
453
|
}
|
|
436
454
|
}
|
|
437
|
-
await whitelistService2.setSettings({ useWhitelist, enforceOIDC
|
|
438
|
-
ctx.body = { useWhitelist, enforceOIDC
|
|
455
|
+
await whitelistService2.setSettings({ useWhitelist, enforceOIDC });
|
|
456
|
+
ctx.body = { useWhitelist, enforceOIDC };
|
|
439
457
|
}
|
|
440
458
|
async function publicSettings(ctx) {
|
|
441
459
|
const whitelistService2 = strapi.plugin("strapi-plugin-oidc").service("whitelist");
|
|
442
460
|
const settings = await whitelistService2.getSettings();
|
|
461
|
+
const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
|
|
443
462
|
ctx.body = {
|
|
444
|
-
enforceOIDC: settings.enforceOIDC
|
|
445
|
-
|
|
446
|
-
ssoButtonText: settings.ssoButtonText || "Login via SSO"
|
|
463
|
+
enforceOIDC: resolveEnforceOIDC(strapi, settings.enforceOIDC),
|
|
464
|
+
ssoButtonText: config2.OIDC_SSO_BUTTON_TEXT
|
|
447
465
|
};
|
|
448
466
|
}
|
|
449
467
|
async function register(ctx) {
|
|
@@ -928,13 +946,11 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
928
946
|
const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
|
|
929
947
|
const REMEMBER_ME = config2["REMEMBER_ME"];
|
|
930
948
|
const rememberMe = !!REMEMBER_ME;
|
|
931
|
-
const { token: refreshToken } = await sessionManager(
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
}
|
|
937
|
-
);
|
|
949
|
+
const { token: refreshToken, absoluteExpiresAt } = await sessionManager(
|
|
950
|
+
"admin"
|
|
951
|
+
).generateRefreshToken(userId, deviceId, {
|
|
952
|
+
type: rememberMe ? "refresh" : "session"
|
|
953
|
+
});
|
|
938
954
|
const isProduction = strapi2.config.get("environment") === "production";
|
|
939
955
|
const domain = strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain");
|
|
940
956
|
const path = strapi2.config.get("admin.auth.cookie.path", "/admin");
|
|
@@ -948,10 +964,16 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
948
964
|
sameSite
|
|
949
965
|
};
|
|
950
966
|
if (rememberMe) {
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
967
|
+
const idleLifespanSec = strapi2.config.get(
|
|
968
|
+
"admin.auth.sessions.idleRefreshTokenLifespan",
|
|
969
|
+
1209600
|
|
970
|
+
// 14 days — Strapi default
|
|
971
|
+
);
|
|
972
|
+
const idleMs = idleLifespanSec * 1e3;
|
|
973
|
+
const absoluteMs = new Date(absoluteExpiresAt).getTime() - Date.now();
|
|
974
|
+
const ms = Math.min(idleMs, absoluteMs);
|
|
975
|
+
cookieOptions.maxAge = ms;
|
|
976
|
+
cookieOptions.expires = new Date(Date.now() + ms);
|
|
955
977
|
}
|
|
956
978
|
ctx.cookies.set("strapi_admin_refresh", refreshToken, cookieOptions);
|
|
957
979
|
ctx.cookies.set("oidc_authenticated", "1", { ...cookieOptions, path: "/" });
|
|
@@ -1027,9 +1049,7 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
1027
1049
|
if (!settings) {
|
|
1028
1050
|
settings = {
|
|
1029
1051
|
useWhitelist: true,
|
|
1030
|
-
enforceOIDC: false
|
|
1031
|
-
showSSOButton: true,
|
|
1032
|
-
ssoButtonText: "Login via SSO"
|
|
1052
|
+
enforceOIDC: false
|
|
1033
1053
|
};
|
|
1034
1054
|
await getPluginStore().set({ key: "settings", value: settings });
|
|
1035
1055
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-oidc",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "A Strapi plugin that provides OpenID Connect (OIDC) authentication functionality for the Strapi Admin Panel.",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"displayName": "OIDC Plugin",
|
|
@@ -86,7 +86,6 @@
|
|
|
86
86
|
"msw": "^2.13.0",
|
|
87
87
|
"prettier": "^3.8.1",
|
|
88
88
|
"react": "^18.3.1",
|
|
89
|
-
"react-dom": "^18.3.1",
|
|
90
89
|
"react-router-dom": "^6.30.3",
|
|
91
90
|
"styled-components": "^6.3.12",
|
|
92
91
|
"supertest": "^7.2.2",
|