strapi-plugin-oidc 1.6.3 → 1.6.5
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-f3cmU_tE.js → index-C2BnnDzh.js} +8 -8
- package/dist/admin/{index-P9HriRms.mjs → index-DgUClS5s.mjs} +8 -8
- package/dist/admin/{index-DmJadA2p.mjs → index-HQ2uuypE.mjs} +81 -110
- package/dist/admin/{index-DTOcUHZi.js → index-pWwCtdNu.js} +81 -110
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +131 -183
- package/dist/server/index.mjs +131 -183
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -30,52 +30,45 @@ function getRetentionDays() {
|
|
|
30
30
|
function isAuditLogEnabled() {
|
|
31
31
|
return getRetentionDays() !== 0;
|
|
32
32
|
}
|
|
33
|
+
const AUTH_ROUTES = ["login", "register", "register-admin", "forgot-password", "reset-password"];
|
|
33
34
|
async function bootstrap({ strapi: strapi2 }) {
|
|
34
35
|
const adminUrl = strapi2.config.get("admin.url", "/admin");
|
|
35
|
-
const authRoutes = [
|
|
36
|
-
`${adminUrl}/login`,
|
|
37
|
-
`${adminUrl}/register`,
|
|
38
|
-
`${adminUrl}/register-admin`,
|
|
39
|
-
`${adminUrl}/forgot-password`,
|
|
40
|
-
`${adminUrl}/reset-password`
|
|
41
|
-
];
|
|
42
36
|
const tokenRefreshPath = `${adminUrl}/token/refresh`;
|
|
43
37
|
const enforceOidcMiddleware = async (ctx, next) => {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
38
|
+
const path = ctx.request.path;
|
|
39
|
+
const isPost = ctx.request.method === "POST";
|
|
40
|
+
const isAuthRoute = AUTH_ROUTES.some((r) => path.includes(r));
|
|
41
|
+
const isTokenRefresh = path === tokenRefreshPath;
|
|
42
|
+
if (isAuthRoute && isPost || isTokenRefresh) {
|
|
47
43
|
try {
|
|
48
44
|
const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
|
|
49
45
|
const settings = await whitelistService2.getSettings();
|
|
50
46
|
const enforceOIDC = resolveEnforceOIDC(strapi2, settings?.enforceOIDC);
|
|
51
|
-
if (enforceOIDC) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
};
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
47
|
+
if (enforceOIDC && isAuthRoute && isPost) {
|
|
48
|
+
ctx.status = 403;
|
|
49
|
+
ctx.body = {
|
|
50
|
+
data: null,
|
|
51
|
+
error: {
|
|
52
|
+
status: 403,
|
|
53
|
+
name: "ForbiddenError",
|
|
54
|
+
message: "Local login is disabled. Please use OIDC.",
|
|
55
|
+
details: {}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (enforceOIDC && isTokenRefresh && !ctx.cookies.get("oidc_authenticated")) {
|
|
61
|
+
ctx.status = 401;
|
|
62
|
+
ctx.body = {
|
|
63
|
+
data: null,
|
|
64
|
+
error: {
|
|
65
|
+
status: 401,
|
|
66
|
+
name: "UnauthorizedError",
|
|
67
|
+
message: "Session was not created via OIDC. Please log in again.",
|
|
68
|
+
details: {}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
return;
|
|
79
72
|
}
|
|
80
73
|
} catch (err) {
|
|
81
74
|
strapi2.log.error("Error checking OIDC enforcement in middleware:", err);
|
|
@@ -89,18 +82,8 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
89
82
|
strapi2.server.use(enforceOidcMiddleware);
|
|
90
83
|
}
|
|
91
84
|
const actions = [
|
|
92
|
-
{
|
|
93
|
-
|
|
94
|
-
displayName: "Read",
|
|
95
|
-
uid: "read",
|
|
96
|
-
pluginName: "strapi-plugin-oidc"
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
section: "plugins",
|
|
100
|
-
displayName: "Update",
|
|
101
|
-
uid: "update",
|
|
102
|
-
pluginName: "strapi-plugin-oidc"
|
|
103
|
-
}
|
|
85
|
+
{ section: "plugins", displayName: "Read", uid: "read", pluginName: "strapi-plugin-oidc" },
|
|
86
|
+
{ section: "plugins", displayName: "Update", uid: "update", pluginName: "strapi-plugin-oidc" }
|
|
104
87
|
];
|
|
105
88
|
await strapi2.admin.services.permission.actionProvider.registerMany(actions);
|
|
106
89
|
const enforceOIDCConfig = getEnforceOIDCConfig(strapi2);
|
|
@@ -119,17 +102,12 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
119
102
|
}
|
|
120
103
|
}
|
|
121
104
|
try {
|
|
122
|
-
const oidcRoleCount = await strapi2.query("plugin::strapi-plugin-oidc.roles").count({
|
|
123
|
-
where: { oauth_type: "4" }
|
|
124
|
-
});
|
|
105
|
+
const oidcRoleCount = await strapi2.query("plugin::strapi-plugin-oidc.roles").count({ where: { oauth_type: "4" } });
|
|
125
106
|
if (oidcRoleCount === 0) {
|
|
126
107
|
const defaultRole = await strapi2.query("admin::role").findOne({ where: { code: "strapi-editor" } }) ?? await strapi2.query("admin::role").findOne({});
|
|
127
108
|
if (defaultRole) {
|
|
128
109
|
await strapi2.query("plugin::strapi-plugin-oidc.roles").create({
|
|
129
|
-
data: {
|
|
130
|
-
oauth_type: "4",
|
|
131
|
-
roles: [defaultRole.id.toString()]
|
|
132
|
-
}
|
|
110
|
+
data: { oauth_type: "4", roles: [String(defaultRole.id)] }
|
|
133
111
|
});
|
|
134
112
|
}
|
|
135
113
|
}
|
|
@@ -147,7 +125,6 @@ async function bootstrap({ strapi: strapi2 }) {
|
|
|
147
125
|
}
|
|
148
126
|
},
|
|
149
127
|
options: { rule: "0 0 * * *" }
|
|
150
|
-
// daily at midnight
|
|
151
128
|
}
|
|
152
129
|
});
|
|
153
130
|
}
|
|
@@ -249,24 +226,37 @@ const errorCodes = {
|
|
|
249
226
|
USER_CREATION_FAILED: "USER_CREATION_FAILED",
|
|
250
227
|
WHITELIST_CHECK_FAILED: "WHITELIST_CHECK_FAILED"
|
|
251
228
|
};
|
|
229
|
+
const ERROR_DETAIL_TEMPLATES = {
|
|
230
|
+
token_exchange_failed: "Token exchange failed with HTTP status {status}",
|
|
231
|
+
userinfo_fetch_failed: "UserInfo endpoint returned HTTP {status}",
|
|
232
|
+
role_update_failed: "Role update failed for user {userId}: {error}",
|
|
233
|
+
user_creation_failed: "User creation failed for {email}: {error}",
|
|
234
|
+
id_token_parse_failed: "ID token parse failed: {error}",
|
|
235
|
+
sign_in_unknown: "Unknown sign-in error: {error}",
|
|
236
|
+
invalid_email: "Invalid email address received from OIDC provider",
|
|
237
|
+
whitelist_not_present: "Email not present in whitelist",
|
|
238
|
+
session_manager_unsupported: "sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later.",
|
|
239
|
+
missing_config: "Missing required config keys: {keys}"
|
|
240
|
+
};
|
|
241
|
+
function interpolate$1(template, params) {
|
|
242
|
+
if (!params) return template;
|
|
243
|
+
return template.replace(/\{(\w+)\}/g, (_, key) => String(params[key] ?? `{${key}}`));
|
|
244
|
+
}
|
|
252
245
|
function getErrorDetail(key, params) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
case "userinfo_fetch_failed":
|
|
257
|
-
return `UserInfo endpoint returned HTTP ${params?.status ?? "unknown"}`;
|
|
258
|
-
case "role_update_failed":
|
|
259
|
-
return `Role update failed for user ${params?.userId}: ${params?.error ?? "unknown"}`;
|
|
260
|
-
case "user_creation_failed":
|
|
261
|
-
return `User creation failed for ${params?.email}: ${params?.error ?? "unknown"}`;
|
|
262
|
-
case "id_token_parse_failed":
|
|
263
|
-
return `ID token parse failed: ${params?.error ?? "unknown"}`;
|
|
264
|
-
case "sign_in_unknown":
|
|
265
|
-
return `Unknown sign-in error: ${params?.error ?? "unknown"}`;
|
|
266
|
-
default:
|
|
267
|
-
return void 0;
|
|
268
|
-
}
|
|
246
|
+
const template = ERROR_DETAIL_TEMPLATES[key];
|
|
247
|
+
if (!template) return void 0;
|
|
248
|
+
return interpolate$1(template, params);
|
|
269
249
|
}
|
|
250
|
+
const errorMessages = {
|
|
251
|
+
TOKEN_EXCHANGE_FAILED: "Token exchange failed",
|
|
252
|
+
USERINFO_FETCH_FAILED: "Failed to fetch user info",
|
|
253
|
+
ID_TOKEN_PARSE_FAILED: "Failed to parse ID token",
|
|
254
|
+
NONCE_MISMATCH: "Nonce mismatch",
|
|
255
|
+
INVALID_EMAIL: "Invalid email address received from OIDC provider",
|
|
256
|
+
WHITELIST_NOT_PRESENT: "Not present in whitelist",
|
|
257
|
+
SESSION_MANAGER_UNSUPPORTED: "sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later.",
|
|
258
|
+
MISSING_CONFIG: (keys) => `Missing required config keys: ${keys}`
|
|
259
|
+
};
|
|
270
260
|
const en = {
|
|
271
261
|
"global.plugins.strapi-plugin-oidc": "OIDC Plugin",
|
|
272
262
|
"page.title": "Configure OIDC default role(s) and access controls.",
|
|
@@ -297,8 +287,6 @@ const en = {
|
|
|
297
287
|
"whitelist.toggle.enabled": "Enabled",
|
|
298
288
|
"whitelist.toggle.disabled": "Disabled",
|
|
299
289
|
"whitelist.email.placeholder": "Email address",
|
|
300
|
-
"whitelist.roles.placeholder": "Select specific role(s)",
|
|
301
|
-
"whitelist.table.roles": "Role(s)",
|
|
302
290
|
"whitelist.table.empty": "No email addresses",
|
|
303
291
|
"whitelist.delete.label": "Delete",
|
|
304
292
|
"page.title.oidc": "OIDC",
|
|
@@ -322,7 +310,6 @@ const en = {
|
|
|
322
310
|
"unsaved.description": "You have unsaved changes that will be lost if you leave. Do you want to continue?",
|
|
323
311
|
"unsaved.confirm": "Leave",
|
|
324
312
|
"unsaved.cancel": "Stay",
|
|
325
|
-
"whitelist.table.roles.default": "(Default)",
|
|
326
313
|
"auditlog.title": "Audit Logs",
|
|
327
314
|
"auditlog.export": "Download",
|
|
328
315
|
"auditlog.table.timestamp": "Timestamp",
|
|
@@ -331,6 +318,7 @@ const en = {
|
|
|
331
318
|
"auditlog.table.ip": "IP",
|
|
332
319
|
"auditlog.table.details": "Details",
|
|
333
320
|
"auditlog.table.empty": "No audit log entries",
|
|
321
|
+
"auditlog.loading": "Loading…",
|
|
334
322
|
"auditlog.clear": "Clear Logs",
|
|
335
323
|
"auditlog.clear.title": "Clear All Logs",
|
|
336
324
|
"auditlog.clear.description": "This will permanently delete all {count, plural, one {# audit log entry} other {# audit log entries}}. This action cannot be undone.",
|
|
@@ -349,7 +337,9 @@ const en = {
|
|
|
349
337
|
"auditlog.action.whitelist_rejected": "The user's email address is not on the whitelist. Access was denied.",
|
|
350
338
|
"user.missing_code": "Authorisation code was not received from the OIDC provider.",
|
|
351
339
|
"user.invalid_state": "State parameter mismatch. Please restart the login flow.",
|
|
352
|
-
"user.signInError": "Authentication failed. Please try again."
|
|
340
|
+
"user.signInError": "Authentication failed. Please try again.",
|
|
341
|
+
"settings.section": "OIDC",
|
|
342
|
+
"settings.configuration": "Configuration"
|
|
353
343
|
};
|
|
354
344
|
const userFacingMessages = {
|
|
355
345
|
get missing_code() {
|
|
@@ -376,12 +366,11 @@ const REQUIRED_CONFIG_KEYS = [
|
|
|
376
366
|
];
|
|
377
367
|
function configValidation() {
|
|
378
368
|
const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
|
|
379
|
-
|
|
369
|
+
const missing = REQUIRED_CONFIG_KEYS.filter((key) => !config2[key]);
|
|
370
|
+
if (missing.length === 0) {
|
|
380
371
|
return config2;
|
|
381
372
|
}
|
|
382
|
-
throw new Error(
|
|
383
|
-
`The following configuration keys are required: ${REQUIRED_CONFIG_KEYS.join(", ")}`
|
|
384
|
-
);
|
|
373
|
+
throw new Error(errorMessages.MISSING_CONFIG(missing.join(", ")));
|
|
385
374
|
}
|
|
386
375
|
async function oidcSignIn(ctx) {
|
|
387
376
|
const { OIDC_CLIENT_ID, OIDC_REDIRECT_URI, OIDC_SCOPE, OIDC_AUTHORIZATION_ENDPOINT } = configValidation();
|
|
@@ -422,7 +411,7 @@ async function exchangeTokenAndFetchUserInfo(config2, params, expectedNonce) {
|
|
|
422
411
|
}
|
|
423
412
|
});
|
|
424
413
|
if (!response.ok) {
|
|
425
|
-
throw new Error(
|
|
414
|
+
throw new Error(errorMessages.TOKEN_EXCHANGE_FAILED);
|
|
426
415
|
}
|
|
427
416
|
const tokenData = await response.json();
|
|
428
417
|
if (tokenData.id_token) {
|
|
@@ -430,18 +419,18 @@ async function exchangeTokenAndFetchUserInfo(config2, params, expectedNonce) {
|
|
|
430
419
|
const payloadB64 = tokenData.id_token.split(".")[1];
|
|
431
420
|
const idTokenPayload = JSON.parse(Buffer.from(payloadB64, "base64url").toString("utf8"));
|
|
432
421
|
if (idTokenPayload.nonce !== expectedNonce) {
|
|
433
|
-
throw new Error(
|
|
422
|
+
throw new Error(errorMessages.NONCE_MISMATCH);
|
|
434
423
|
}
|
|
435
424
|
} catch (e) {
|
|
436
425
|
if (e.message === "Nonce mismatch") throw e;
|
|
437
|
-
throw new Error(
|
|
426
|
+
throw new Error(errorMessages.ID_TOKEN_PARSE_FAILED);
|
|
438
427
|
}
|
|
439
428
|
}
|
|
440
429
|
const userResponse = await fetch(config2.OIDC_USERINFO_ENDPOINT, {
|
|
441
430
|
headers: { Authorization: `Bearer ${tokenData.access_token}` }
|
|
442
431
|
});
|
|
443
432
|
if (!userResponse.ok) {
|
|
444
|
-
throw new Error(
|
|
433
|
+
throw new Error(errorMessages.USERINFO_FETCH_FAILED);
|
|
445
434
|
}
|
|
446
435
|
const userInfo = await userResponse.json();
|
|
447
436
|
return { userInfo, accessToken: tokenData.access_token };
|
|
@@ -489,7 +478,11 @@ async function registerNewUser(oauthService2, email, userResponseData, config2,
|
|
|
489
478
|
return activateUser;
|
|
490
479
|
}
|
|
491
480
|
function rolesChanged(current, next) {
|
|
492
|
-
|
|
481
|
+
if (current.size !== next.size) return true;
|
|
482
|
+
for (const id of next) {
|
|
483
|
+
if (!current.has(id)) return true;
|
|
484
|
+
}
|
|
485
|
+
return false;
|
|
493
486
|
}
|
|
494
487
|
async function updateUserRoles(user, currentRoleIds, newRoleIds) {
|
|
495
488
|
try {
|
|
@@ -516,7 +509,7 @@ async function handleUserAuthentication(userService, oauthService2, roleService2
|
|
|
516
509
|
const rawEmail = String(userResponseData.email ?? "");
|
|
517
510
|
const email = rawEmail.toLowerCase();
|
|
518
511
|
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
519
|
-
throw new Error(
|
|
512
|
+
throw new Error(errorMessages.INVALID_EMAIL);
|
|
520
513
|
}
|
|
521
514
|
await whitelistService2.checkWhitelistForEmail(email);
|
|
522
515
|
const allRoles = await strapi.db.query("admin::role").findMany();
|
|
@@ -546,52 +539,39 @@ async function handleUserAuthentication(userService, oauthService2, roleService2
|
|
|
546
539
|
return { activateUser: user, jwtToken, userCreated, rolesUpdated, resolvedRoleNames };
|
|
547
540
|
}
|
|
548
541
|
function classifyOidcError(msg, userInfo) {
|
|
549
|
-
|
|
550
|
-
{
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
},
|
|
583
|
-
{
|
|
584
|
-
test: (m) => m === "User creation failed" || m.includes("createUser"),
|
|
585
|
-
result: {
|
|
586
|
-
action: "login_failure",
|
|
587
|
-
code: errorCodes.USER_CREATION_FAILED,
|
|
588
|
-
key: "user_creation_failed",
|
|
589
|
-
params: userInfo?.email ? { email: userInfo.email, error: msg } : void 0
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
];
|
|
593
|
-
for (const { test, result } of errorMap) {
|
|
594
|
-
if (test(msg)) return result;
|
|
542
|
+
if (msg.includes("whitelist")) {
|
|
543
|
+
return {
|
|
544
|
+
action: "whitelist_rejected",
|
|
545
|
+
code: errorCodes.WHITELIST_CHECK_FAILED,
|
|
546
|
+
key: "whitelist_rejected"
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
if (msg === "Nonce mismatch")
|
|
550
|
+
return { action: "nonce_mismatch", code: errorCodes.NONCE_MISMATCH };
|
|
551
|
+
if (msg === "Token exchange failed")
|
|
552
|
+
return { action: "token_exchange_failed", code: errorCodes.TOKEN_EXCHANGE_FAILED };
|
|
553
|
+
if (msg === "Failed to fetch user info") {
|
|
554
|
+
return {
|
|
555
|
+
action: "login_failure",
|
|
556
|
+
code: errorCodes.USERINFO_FETCH_FAILED,
|
|
557
|
+
key: "userinfo_fetch_failed"
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
if (msg === "Failed to parse ID token") {
|
|
561
|
+
return {
|
|
562
|
+
action: "login_failure",
|
|
563
|
+
code: errorCodes.ID_TOKEN_PARSE_FAILED,
|
|
564
|
+
key: "id_token_parse_failed",
|
|
565
|
+
params: { error: msg }
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
if (msg === "User creation failed" || msg.includes("createUser")) {
|
|
569
|
+
return {
|
|
570
|
+
action: "login_failure",
|
|
571
|
+
code: errorCodes.USER_CREATION_FAILED,
|
|
572
|
+
key: "user_creation_failed",
|
|
573
|
+
params: userInfo?.email ? { email: userInfo.email, error: msg } : void 0
|
|
574
|
+
};
|
|
595
575
|
}
|
|
596
576
|
return {
|
|
597
577
|
action: "login_failure",
|
|
@@ -824,13 +804,9 @@ async function register(ctx) {
|
|
|
824
804
|
const whitelistService2 = getWhitelistService();
|
|
825
805
|
let matchedExistingUsersCount = 0;
|
|
826
806
|
for (const singleEmail of emailList) {
|
|
827
|
-
const existingUser = await strapi.query("admin::user").findOne({
|
|
828
|
-
where: { email: singleEmail }
|
|
829
|
-
});
|
|
807
|
+
const existingUser = await strapi.query("admin::user").findOne({ where: { email: singleEmail } });
|
|
830
808
|
if (existingUser) matchedExistingUsersCount++;
|
|
831
|
-
const alreadyWhitelisted = await strapi.query("plugin::strapi-plugin-oidc.whitelists").findOne({
|
|
832
|
-
where: { email: singleEmail }
|
|
833
|
-
});
|
|
809
|
+
const alreadyWhitelisted = await strapi.query("plugin::strapi-plugin-oidc.whitelists").findOne({ where: { email: singleEmail } });
|
|
834
810
|
if (!alreadyWhitelisted) {
|
|
835
811
|
await whitelistService2.registerUser(singleEmail);
|
|
836
812
|
}
|
|
@@ -972,9 +948,7 @@ function rateLimitMiddleware(ctx, next) {
|
|
|
972
948
|
const key = getRateLimitKey(ctx);
|
|
973
949
|
const now = Date.now();
|
|
974
950
|
const windowStart = now - RATE_LIMIT_WINDOW;
|
|
975
|
-
const requestStamps = (rateLimitMap.get(key)
|
|
976
|
-
(timestamp) => timestamp > windowStart
|
|
977
|
-
);
|
|
951
|
+
const requestStamps = (rateLimitMap.get(key) ?? []).filter((ts) => ts > windowStart);
|
|
978
952
|
if (requestStamps.length >= MAX_REQUESTS) {
|
|
979
953
|
ctx.status = 429;
|
|
980
954
|
ctx.body = "Too Many Requests";
|
|
@@ -1281,9 +1255,7 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
1281
1255
|
const userService = strapi2.service("admin::user");
|
|
1282
1256
|
if (/[A-Z]/.test(email)) {
|
|
1283
1257
|
const dbUser = await userService.findOneByEmail(email.toLocaleLowerCase());
|
|
1284
|
-
if (dbUser)
|
|
1285
|
-
return dbUser;
|
|
1286
|
-
}
|
|
1258
|
+
if (dbUser) return dbUser;
|
|
1287
1259
|
}
|
|
1288
1260
|
const createdUser = await userService.create({
|
|
1289
1261
|
firstname: firstname || "unset",
|
|
@@ -1299,7 +1271,6 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
1299
1271
|
lastname: lastname || "user",
|
|
1300
1272
|
password: generator.generate({
|
|
1301
1273
|
length: 43,
|
|
1302
|
-
// 256 bits (https://en.wikipedia.org/wiki/Password_strength#Random_passwords)
|
|
1303
1274
|
numbers: true,
|
|
1304
1275
|
lowercase: true,
|
|
1305
1276
|
uppercase: true,
|
|
@@ -1310,14 +1281,10 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
1310
1281
|
});
|
|
1311
1282
|
},
|
|
1312
1283
|
addGmailAlias(baseEmail, baseAlias) {
|
|
1313
|
-
if (!baseAlias)
|
|
1314
|
-
return baseEmail;
|
|
1315
|
-
}
|
|
1284
|
+
if (!baseAlias) return baseEmail;
|
|
1316
1285
|
const alias = baseAlias.replace(/\+/g, "");
|
|
1317
|
-
const
|
|
1318
|
-
|
|
1319
|
-
const domain = baseEmail.substring(beforePosition);
|
|
1320
|
-
return `${origin}+${alias}${domain}`;
|
|
1286
|
+
const atIndex = baseEmail.indexOf("@");
|
|
1287
|
+
return `${baseEmail.slice(0, atIndex)}+${alias}${baseEmail.slice(atIndex)}`;
|
|
1321
1288
|
},
|
|
1322
1289
|
localeFindByHeader(headers) {
|
|
1323
1290
|
return headers["accept-language"]?.includes("ja") ? "ja" : "en";
|
|
@@ -1398,9 +1365,7 @@ function oauthService({ strapi: strapi2 }) {
|
|
|
1398
1365
|
async generateToken(user, ctx) {
|
|
1399
1366
|
const sessionManager = strapi2.sessionManager;
|
|
1400
1367
|
if (!sessionManager) {
|
|
1401
|
-
throw new Error(
|
|
1402
|
-
"sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later."
|
|
1403
|
-
);
|
|
1368
|
+
throw new Error(errorMessages.SESSION_MANAGER_UNSUPPORTED);
|
|
1404
1369
|
}
|
|
1405
1370
|
const userId = String(user.id);
|
|
1406
1371
|
const deviceId = randomUUID();
|
|
@@ -1490,15 +1455,11 @@ function roleService({ strapi: strapi2 }) {
|
|
|
1490
1455
|
}
|
|
1491
1456
|
};
|
|
1492
1457
|
}
|
|
1458
|
+
const SETTINGS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
1493
1459
|
function whitelistService({ strapi: strapi2 }) {
|
|
1494
|
-
const getPluginStore = () => strapi2.store({
|
|
1495
|
-
environment: "",
|
|
1496
|
-
type: "plugin",
|
|
1497
|
-
name: "strapi-plugin-oidc"
|
|
1498
|
-
});
|
|
1499
|
-
const getWhitelistQuery = () => strapi2.query("plugin::strapi-plugin-oidc.whitelists");
|
|
1500
1460
|
let settingsCache = null;
|
|
1501
|
-
const
|
|
1461
|
+
const getPluginStore = () => strapi2.store({ environment: "", type: "plugin", name: "strapi-plugin-oidc" });
|
|
1462
|
+
const getWhitelistQuery = () => strapi2.query("plugin::strapi-plugin-oidc.whitelists");
|
|
1502
1463
|
return {
|
|
1503
1464
|
async getSettings() {
|
|
1504
1465
|
const now = Date.now();
|
|
@@ -1507,10 +1468,7 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
1507
1468
|
}
|
|
1508
1469
|
let settings = await getPluginStore().get({ key: "settings" });
|
|
1509
1470
|
if (!settings) {
|
|
1510
|
-
settings = {
|
|
1511
|
-
useWhitelist: true,
|
|
1512
|
-
enforceOIDC: false
|
|
1513
|
-
};
|
|
1471
|
+
settings = { useWhitelist: true, enforceOIDC: false };
|
|
1514
1472
|
await getPluginStore().set({ key: "settings", value: settings });
|
|
1515
1473
|
}
|
|
1516
1474
|
settingsCache = { value: settings, ts: now };
|
|
@@ -1524,26 +1482,18 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
1524
1482
|
return getWhitelistQuery().findMany();
|
|
1525
1483
|
},
|
|
1526
1484
|
async registerUser(email) {
|
|
1527
|
-
await getWhitelistQuery().create({
|
|
1528
|
-
data: { email }
|
|
1529
|
-
});
|
|
1485
|
+
await getWhitelistQuery().create({ data: { email } });
|
|
1530
1486
|
},
|
|
1531
1487
|
async removeUser(email) {
|
|
1532
|
-
await getWhitelistQuery().deleteMany({
|
|
1533
|
-
where: { email }
|
|
1534
|
-
});
|
|
1488
|
+
await getWhitelistQuery().deleteMany({ where: { email } });
|
|
1535
1489
|
},
|
|
1536
1490
|
async checkWhitelistForEmail(email) {
|
|
1537
1491
|
const settings = await this.getSettings();
|
|
1538
|
-
if (!settings.useWhitelist)
|
|
1539
|
-
return null;
|
|
1540
|
-
}
|
|
1492
|
+
if (!settings.useWhitelist) return null;
|
|
1541
1493
|
const result = await getWhitelistQuery().findOne({
|
|
1542
1494
|
where: { email }
|
|
1543
1495
|
});
|
|
1544
|
-
if (!result)
|
|
1545
|
-
throw new Error("Not present in whitelist");
|
|
1546
|
-
}
|
|
1496
|
+
if (!result) throw new Error(errorMessages.WHITELIST_NOT_PRESENT);
|
|
1547
1497
|
return result;
|
|
1548
1498
|
}
|
|
1549
1499
|
};
|
|
@@ -1604,9 +1554,7 @@ function auditLogService({ strapi: strapi2 }) {
|
|
|
1604
1554
|
},
|
|
1605
1555
|
async cleanup(retentionDays) {
|
|
1606
1556
|
const cutoff = new Date(Date.now() - retentionDays * 864e5);
|
|
1607
|
-
await strapi2.db.query("plugin::strapi-plugin-oidc.audit-log").deleteMany({
|
|
1608
|
-
where: { createdAt: { $lt: cutoff } }
|
|
1609
|
-
});
|
|
1557
|
+
await strapi2.db.query("plugin::strapi-plugin-oidc.audit-log").deleteMany({ where: { createdAt: { $lt: cutoff } } });
|
|
1610
1558
|
}
|
|
1611
1559
|
};
|
|
1612
1560
|
}
|
package/package.json
CHANGED