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.
@@ -49,11 +49,15 @@ const en = {
49
49
  "roles.placeholder": "Select default role(s)",
50
50
  "whitelist.title": "Whitelist",
51
51
  "whitelist.error.unique": "Already registered email address.",
52
- "whitelist.enabled": "Whitelist is currently enabled.",
53
- "whitelist.disabled": "Whitelist is currently disabled.",
54
52
  "whitelist.description": "Restrict OIDC authentication to specific email addresses and optionally assign them custom role(s).",
55
53
  "whitelist.user_exists": "User already exists, matching existing role(s)",
56
54
  "whitelist.users_exists": "Users already exist, matching existing role(s)",
55
+ "alert.title.success": "Success",
56
+ "alert.title.error": "Error",
57
+ "alert.title.info": "Info",
58
+ "pagination.previous": "Go to previous page",
59
+ "pagination.page": "Go to page {page}",
60
+ "pagination.next": "Go to next page",
57
61
  "whitelist.table.no": "No.",
58
62
  "whitelist.table.email": "Email",
59
63
  "whitelist.table.created": "Created At",
@@ -65,7 +69,6 @@ const en = {
65
69
  "whitelist.email.placeholder": "Email address",
66
70
  "whitelist.roles.placeholder": "Select specific role(s)",
67
71
  "whitelist.table.roles": "Role(s)",
68
- "whitelist.table.roles.default": "Default",
69
72
  "whitelist.table.empty": "No email addresses",
70
73
  "whitelist.delete.label": "Delete",
71
74
  "page.title.oidc": "OIDC",
@@ -73,15 +76,20 @@ const en = {
73
76
  "enforce.toggle.enabled": "Enabled",
74
77
  "enforce.toggle.disabled": "Disabled",
75
78
  "enforce.warning": "Make sure OIDC is setup correctly before saving changes, you won't be able to login normally.",
79
+ "enforce.config.info": "Enforcement is controlled by the OIDC_ENFORCE config variable and cannot be changed here.",
76
80
  "login.settings.title": "Login Settings",
77
- "login.sso": "Login via SSO",
78
- "login.sso.show": "Add button for OIDC on login screen",
79
- "login.sso.button.text.label": "Login button text"
81
+ "login.sso": "Login via SSO"
80
82
  };
81
- const en$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
82
- __proto__: null,
83
- default: en
84
- }, Symbol.toStringTag, { value: "Module" }));
83
+ function getTrad(id) {
84
+ const pluginIdWithId = `${pluginId}.${id}`;
85
+ return {
86
+ id: pluginIdWithId,
87
+ defaultMessage: en[id] || pluginIdWithId
88
+ };
89
+ }
90
+ function t(id) {
91
+ return en[id];
92
+ }
85
93
  const name = pluginPkg.strapi.displayName;
86
94
  const index = {
87
95
  register(app) {
@@ -101,7 +109,7 @@ const index = {
101
109
  defaultMessage: "Configuration"
102
110
  },
103
111
  Component: async () => {
104
- return await import("./index-BD7cK7Hf.mjs");
112
+ return await import("./index-CFmg9Kxl.mjs");
105
113
  },
106
114
  permissions: [{ action: "plugin::strapi-plugin-oidc.read", subject: null }]
107
115
  }
@@ -113,50 +121,11 @@ const index = {
113
121
  });
114
122
  },
115
123
  bootstrap() {
116
- let isLogoutInProgress = false;
117
- let historyPatched = false;
118
- const ENFORCE_CACHE_KEY = "strapi_oidc_enforced";
124
+ const defaultButtonText = t("login.sso");
119
125
  const isAuthRoute = (path) => /\/auth\/(login|register|forgot-password|reset-password)/.test(path);
120
- const patchHistory = () => {
121
- if (historyPatched) return;
122
- historyPatched = true;
123
- const interceptHistory = (originalMethod) => {
124
- return function(...args) {
125
- const url = args[2];
126
- if (url && typeof url === "string") {
127
- const urlWithoutQuery = url.split("?")[0].split("#")[0];
128
- if (isAuthRoute(urlWithoutQuery)) {
129
- if (isLogoutInProgress) {
130
- return;
131
- }
132
- if (sessionStorage.getItem("oidc_logout")) {
133
- sessionStorage.removeItem("oidc_logout");
134
- return originalMethod.apply(window.history, args);
135
- }
136
- document.documentElement.style.visibility = "hidden";
137
- window.location.href = "/strapi-plugin-oidc/oidc";
138
- return;
139
- }
140
- }
141
- return originalMethod.apply(window.history, args);
142
- };
143
- };
144
- window.history.pushState = interceptHistory(window.history.pushState);
145
- window.history.replaceState = interceptHistory(window.history.replaceState);
146
- if (isAuthRoute(window.location.pathname)) {
147
- if (sessionStorage.getItem("oidc_logout")) {
148
- sessionStorage.removeItem("oidc_logout");
149
- document.documentElement.style.visibility = "";
150
- } else {
151
- document.documentElement.style.visibility = "hidden";
152
- window.location.replace("/strapi-plugin-oidc/oidc");
153
- }
154
- }
155
- };
156
126
  let ssoButtonInjected = false;
157
- let ssoObserver = null;
158
- let ssoButtonText = en["login.sso"];
159
- const injectSSOButton = () => {
127
+ let loginObserver = null;
128
+ const injectSSOButton = (buttonText) => {
160
129
  if (ssoButtonInjected) return;
161
130
  if (!isAuthRoute(window.location.pathname)) return;
162
131
  if (document.getElementById("strapi-oidc-sso-btn")) return;
@@ -166,74 +135,75 @@ const index = {
166
135
  btn.id = "strapi-oidc-sso-btn";
167
136
  btn.type = "button";
168
137
  btn.className = submitButton.className;
169
- btn.style.marginTop = "8px";
170
138
  btn.onclick = () => {
171
139
  window.location.href = "/strapi-plugin-oidc/oidc";
172
140
  };
173
141
  const innerSpan = submitButton.querySelector("span");
174
142
  const span = document.createElement("span");
175
143
  if (innerSpan) span.className = innerSpan.className;
176
- span.textContent = ssoButtonText;
144
+ span.style.display = "inline-flex";
145
+ span.style.alignItems = "center";
146
+ span.style.gap = "8px";
147
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
148
+ svg.setAttribute("width", "16");
149
+ svg.setAttribute("height", "16");
150
+ svg.setAttribute("viewBox", "0 0 24 24");
151
+ svg.setAttribute("fill", "none");
152
+ svg.setAttribute("stroke", "currentColor");
153
+ svg.setAttribute("stroke-width", "2");
154
+ svg.setAttribute("stroke-linecap", "round");
155
+ svg.setAttribute("stroke-linejoin", "round");
156
+ svg.setAttribute("aria-hidden", "true");
157
+ svg.innerHTML = '<path d="M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z"/><circle cx="16.5" cy="7.5" r=".5" fill="currentColor"/>';
158
+ span.appendChild(svg);
159
+ span.appendChild(document.createTextNode(buttonText));
177
160
  btn.appendChild(span);
178
161
  submitButton.parentNode.insertBefore(btn, submitButton.nextSibling);
179
162
  ssoButtonInjected = true;
180
163
  };
181
- const startSSOButtonObserver = () => {
182
- if (ssoObserver) return;
183
- injectSSOButton();
184
- ssoObserver = new MutationObserver(() => {
185
- if (isAuthRoute(window.location.pathname)) injectSSOButton();
164
+ const removeEnforcedElements = () => {
165
+ [
166
+ 'form > div > div:has(input[name="email"])',
167
+ 'form > div > div:has(input[name="password"])',
168
+ 'form > div > div:has(button[role="checkbox"])',
169
+ 'form > div > button[type="submit"]:not(#strapi-oidc-sso-btn)'
170
+ ].forEach((selector) => {
171
+ document.querySelectorAll(selector).forEach((el) => el.remove());
172
+ });
173
+ document.querySelectorAll('a[href*="forgot-password"]').forEach((el) => {
174
+ (el.closest("div")?.parentElement ?? el).remove();
186
175
  });
187
- ssoObserver.observe(document.body, { childList: true, subtree: true });
188
176
  };
189
- const stopSSOButtonObserver = () => {
190
- ssoObserver?.disconnect();
191
- ssoObserver = null;
192
- document.getElementById("strapi-oidc-sso-btn")?.remove();
193
- ssoButtonInjected = false;
177
+ const startLoginObserver = (buttonText, enforced) => {
178
+ if (loginObserver) return;
179
+ const tick = () => {
180
+ if (!isAuthRoute(window.location.pathname)) return;
181
+ injectSSOButton(buttonText);
182
+ if (enforced) removeEnforcedElements();
183
+ };
184
+ tick();
185
+ loginObserver = new MutationObserver(tick);
186
+ loginObserver.observe(document.body, { childList: true, subtree: true });
194
187
  };
195
- if (!localStorage.getItem("jwtToken") && !sessionStorage.getItem("oidc_logout")) {
196
- document.documentElement.style.visibility = "hidden";
197
- }
198
- if (localStorage.getItem(ENFORCE_CACHE_KEY) === "1") {
199
- patchHistory();
200
- }
201
- if (isAuthRoute(window.location.pathname)) {
202
- document.documentElement.style.visibility = "hidden";
203
- }
204
- const checkEnforceOIDC = async () => {
188
+ const applySettings = async () => {
205
189
  try {
206
190
  const response = await window.fetch("/strapi-plugin-oidc/settings/public");
207
191
  if (response.ok) {
208
192
  const data = await response.json();
209
- if (data.enforceOIDC) {
210
- localStorage.setItem(ENFORCE_CACHE_KEY, "1");
211
- stopSSOButtonObserver();
212
- patchHistory();
213
- } else {
214
- localStorage.removeItem(ENFORCE_CACHE_KEY);
215
- document.documentElement.style.visibility = "";
216
- if (data.showSSOButton !== false) {
217
- ssoButtonText = data.ssoButtonText || en["login.sso"];
218
- startSSOButtonObserver();
219
- } else {
220
- stopSSOButtonObserver();
221
- }
222
- }
193
+ startLoginObserver(data.ssoButtonText || defaultButtonText, !!data.enforceOIDC);
194
+ } else {
195
+ startLoginObserver(defaultButtonText, false);
223
196
  }
224
197
  } catch (error) {
225
- document.documentElement.style.visibility = "";
226
- console.error("Failed to check OIDC enforcement setting:", error);
198
+ startLoginObserver(defaultButtonText, false);
199
+ console.error("Failed to fetch OIDC settings:", error);
227
200
  }
228
201
  };
229
- checkEnforceOIDC();
202
+ applySettings();
230
203
  const originalFetch = window.fetch;
231
204
  window.fetch = async (...args) => {
232
205
  const url = typeof args[0] === "string" ? args[0] : args[0].url;
233
206
  const isLogout = url && url.endsWith("/admin/logout") && args[1]?.method?.toUpperCase() === "POST";
234
- if (isLogout) {
235
- isLogoutInProgress = true;
236
- }
237
207
  const response = await originalFetch(...args);
238
208
  if (isLogout && response.ok) {
239
209
  window.localStorage.removeItem("jwtToken");
@@ -242,43 +212,32 @@ const index = {
242
212
  window.sessionStorage.removeItem("isLoggedIn");
243
213
  document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
244
214
  document.cookie = "jwtToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/admin";
245
- sessionStorage.setItem("oidc_logout", "1");
246
215
  window.location.href = "/strapi-plugin-oidc/logout";
247
216
  return new Promise(() => {
248
217
  });
249
- } else if (isLogout) {
250
- isLogoutInProgress = false;
251
218
  }
252
219
  return response;
253
220
  };
254
221
  },
255
222
  async registerTrads({ locales }) {
223
+ const transformKeys = (data) => Object.fromEntries(
224
+ Object.entries(data).map(([key, value]) => [
225
+ key.startsWith("global.") ? key : getTranslation(key),
226
+ value
227
+ ])
228
+ );
256
229
  const importedTrads = await Promise.all(
257
230
  locales.map((locale) => {
258
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => en$1) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
259
- const newData = Object.fromEntries(
260
- Object.entries(data).map(([key, value]) => [
261
- key.startsWith("global.") ? key : getTranslation(key),
262
- value
263
- ])
264
- );
265
- return {
266
- data: newData,
267
- locale
268
- };
269
- }).catch(() => {
270
- return {
271
- data: {},
272
- locale
273
- };
274
- });
231
+ if (locale === "en") {
232
+ return Promise.resolve({ data: transformKeys(en), locale });
233
+ }
234
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({}), `./translations/locales/${locale}.json`, 4).then(({ default: data }) => ({ data: transformKeys(data), locale })).catch(() => ({ data: {}, locale }));
275
235
  })
276
236
  );
277
- return Promise.resolve(importedTrads);
237
+ return importedTrads;
278
238
  }
279
239
  };
280
240
  export {
281
- en as e,
282
- index as i,
283
- pluginId as p
241
+ getTrad as g,
242
+ index as i
284
243
  };
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const index = require("./index-Cxj6lwW7.js");
3
+ const index = require("./index-Cse9ex24.js");
4
4
  exports.default = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "./index-B2dKk7YS.mjs";
1
+ import { i } from "./index-D1ypRUlq.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
@@ -10,22 +10,19 @@ 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
- };
13
+ function getEnforceOIDCConfig(strapi2) {
14
+ const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
15
+ const val = config2.OIDC_ENFORCE;
16
+ if (val === null || val === void 0) return null;
17
+ if (typeof val === "boolean") return val;
18
+ if (val === "true") return true;
19
+ if (val === "false") return false;
20
+ return null;
24
21
  }
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, path: "/" });
22
+ function resolveEnforceOIDC(strapi2, dbValue) {
23
+ const configValue = getEnforceOIDCConfig(strapi2);
24
+ if (configValue !== null) return configValue;
25
+ return dbValue ?? false;
29
26
  }
30
27
  async function bootstrap({ strapi: strapi2 }) {
31
28
  const enforceOidcMiddleware = async (ctx, next) => {
@@ -38,13 +35,12 @@ async function bootstrap({ strapi: strapi2 }) {
38
35
  ];
39
36
  const isPostAuth = authRoutes.includes(ctx.request.path) && ctx.request.method === "POST";
40
37
  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]+$/);
42
- const isGetAdminHtml = ctx.request.method === "GET" && ctx.request.path.startsWith(adminUrl) && isHtmlRequest;
43
- if (isPostAuth || isTokenRefresh || isGetAdminHtml) {
38
+ if (isPostAuth || isTokenRefresh) {
44
39
  try {
45
40
  const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
46
41
  const settings = await whitelistService2.getSettings();
47
- if (settings?.enforceOIDC) {
42
+ const enforceOIDC = resolveEnforceOIDC(strapi2, settings?.enforceOIDC);
43
+ if (enforceOIDC) {
48
44
  if (isPostAuth) {
49
45
  ctx.status = 403;
50
46
  ctx.body = {
@@ -72,18 +68,6 @@ async function bootstrap({ strapi: strapi2 }) {
72
68
  };
73
69
  return;
74
70
  }
75
- if (isGetAdminHtml) {
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
- }
82
- if (!hasRefreshCookie) {
83
- ctx.redirect("/strapi-plugin-oidc/oidc");
84
- return;
85
- }
86
- }
87
71
  }
88
72
  } catch (err) {
89
73
  strapi2.log.error("Error checking OIDC enforcement in middleware:", err);
@@ -111,6 +95,21 @@ async function bootstrap({ strapi: strapi2 }) {
111
95
  }
112
96
  ];
113
97
  await strapi2.admin.services.permission.actionProvider.registerMany(actions);
98
+ const enforceOIDCConfig = getEnforceOIDCConfig(strapi2);
99
+ if (enforceOIDCConfig !== null) {
100
+ try {
101
+ const whitelistService2 = strapi2.plugin("strapi-plugin-oidc").service("whitelist");
102
+ const settings = await whitelistService2.getSettings();
103
+ if (settings.enforceOIDC !== enforceOIDCConfig) {
104
+ await whitelistService2.setSettings({ ...settings, enforceOIDC: enforceOIDCConfig });
105
+ strapi2.log.info(
106
+ `[strapi-plugin-oidc] OIDC_ENFORCE=${enforceOIDCConfig} written to database settings`
107
+ );
108
+ }
109
+ } catch (err) {
110
+ strapi2.log.error("[strapi-plugin-oidc] Failed to sync OIDC_ENFORCE to database:", err);
111
+ }
112
+ }
114
113
  try {
115
114
  const oidcRoleCount = await strapi2.query("plugin::strapi-plugin-oidc.roles").count({
116
115
  where: { oauth_type: "4" }
@@ -158,8 +157,6 @@ function destroy() {
158
157
  const config = {
159
158
  default: {
160
159
  REMEMBER_ME: false,
161
- REMEMBER_ME_DAYS: 30,
162
- // 30 days
163
160
  OIDC_REDIRECT_URI: "http://localhost:1337/strapi-plugin-oidc/oidc/callback",
164
161
  OIDC_CLIENT_ID: "",
165
162
  OIDC_CLIENT_SECRET: "",
@@ -171,7 +168,10 @@ const config = {
171
168
  OIDC_GRANT_TYPE: "authorization_code",
172
169
  OIDC_FAMILY_NAME_FIELD: "family_name",
173
170
  OIDC_GIVEN_NAME_FIELD: "given_name",
174
- OIDC_LOGOUT_URL: ""
171
+ OIDC_LOGOUT_URL: "",
172
+ OIDC_SSO_BUTTON_TEXT: "Login via SSO",
173
+ OIDC_ENFORCE: null
174
+ // null = use DB setting; true/false = override DB (useful for lockout recovery)
175
175
  },
176
176
  validator() {
177
177
  }
@@ -206,6 +206,23 @@ const contentTypes = {
206
206
  roles,
207
207
  whitelists
208
208
  };
209
+ function getExpiredCookieOptions(strapi2, ctx) {
210
+ const isProduction = strapi2.config.get("environment") === "production";
211
+ return {
212
+ httpOnly: true,
213
+ secure: isProduction && ctx.request.secure,
214
+ path: strapi2.config.get("admin.auth.cookie.path", "/admin"),
215
+ domain: strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain"),
216
+ sameSite: strapi2.config.get("admin.auth.cookie.sameSite", "lax"),
217
+ maxAge: 0,
218
+ expires: /* @__PURE__ */ new Date(0)
219
+ };
220
+ }
221
+ function clearAuthCookies(strapi2, ctx) {
222
+ const options2 = getExpiredCookieOptions(strapi2, ctx);
223
+ ctx.cookies.set("strapi_admin_refresh", "", options2);
224
+ ctx.cookies.set("oidc_authenticated", "", { ...options2, path: "/" });
225
+ }
209
226
  function configValidation() {
210
227
  const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
211
228
  const requiredKeys = [
@@ -345,6 +362,8 @@ async function oidcSignInCallback(ctx) {
345
362
  }
346
363
  const oidcState = ctx.cookies.get("oidc_state");
347
364
  const codeVerifier = ctx.cookies.get("oidc_code_verifier");
365
+ ctx.cookies.set("oidc_state", null);
366
+ ctx.cookies.set("oidc_code_verifier", null);
348
367
  if (!ctx.query.state || ctx.query.state !== oidcState) {
349
368
  return ctx.send(oauthService2.renderSignUpError("Invalid state"));
350
369
  }
@@ -425,14 +444,13 @@ async function info(ctx) {
425
444
  const whitelistUsers = await whitelistService2.getUsers();
426
445
  ctx.body = {
427
446
  useWhitelist: settings.useWhitelist,
428
- enforceOIDC: settings.enforceOIDC || false,
429
- showSSOButton: settings.showSSOButton !== false,
430
- ssoButtonText: settings.ssoButtonText || "Login via SSO",
447
+ enforceOIDC: resolveEnforceOIDC(strapi, settings.enforceOIDC),
448
+ enforceOIDCConfig: getEnforceOIDCConfig(strapi),
431
449
  whitelistUsers
432
450
  };
433
451
  }
434
452
  async function updateSettings(ctx) {
435
- let { useWhitelist, enforceOIDC, showSSOButton, ssoButtonText } = ctx.request.body;
453
+ let { useWhitelist, enforceOIDC } = ctx.request.body;
436
454
  const whitelistService2 = strapi.plugin("strapi-plugin-oidc").service("whitelist");
437
455
  if (useWhitelist && enforceOIDC) {
438
456
  const users = await whitelistService2.getUsers();
@@ -440,16 +458,16 @@ async function updateSettings(ctx) {
440
458
  enforceOIDC = false;
441
459
  }
442
460
  }
443
- await whitelistService2.setSettings({ useWhitelist, enforceOIDC, showSSOButton, ssoButtonText });
444
- ctx.body = { useWhitelist, enforceOIDC, showSSOButton, ssoButtonText };
461
+ await whitelistService2.setSettings({ useWhitelist, enforceOIDC });
462
+ ctx.body = { useWhitelist, enforceOIDC };
445
463
  }
446
464
  async function publicSettings(ctx) {
447
465
  const whitelistService2 = strapi.plugin("strapi-plugin-oidc").service("whitelist");
448
466
  const settings = await whitelistService2.getSettings();
467
+ const config2 = strapi.config.get("plugin::strapi-plugin-oidc");
449
468
  ctx.body = {
450
- enforceOIDC: settings.enforceOIDC || false,
451
- showSSOButton: settings.showSSOButton !== false,
452
- ssoButtonText: settings.ssoButtonText || "Login via SSO"
469
+ enforceOIDC: resolveEnforceOIDC(strapi, settings.enforceOIDC),
470
+ ssoButtonText: config2.OIDC_SSO_BUTTON_TEXT
453
471
  };
454
472
  }
455
473
  async function register(ctx) {
@@ -934,13 +952,11 @@ function oauthService({ strapi: strapi2 }) {
934
952
  const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
935
953
  const REMEMBER_ME = config2["REMEMBER_ME"];
936
954
  const rememberMe = !!REMEMBER_ME;
937
- const { token: refreshToken } = await sessionManager("admin").generateRefreshToken(
938
- userId,
939
- deviceId,
940
- {
941
- type: rememberMe ? "refresh" : "session"
942
- }
943
- );
955
+ const { token: refreshToken, absoluteExpiresAt } = await sessionManager(
956
+ "admin"
957
+ ).generateRefreshToken(userId, deviceId, {
958
+ type: rememberMe ? "refresh" : "session"
959
+ });
944
960
  const isProduction = strapi2.config.get("environment") === "production";
945
961
  const domain = strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain");
946
962
  const path = strapi2.config.get("admin.auth.cookie.path", "/admin");
@@ -954,10 +970,16 @@ function oauthService({ strapi: strapi2 }) {
954
970
  sameSite
955
971
  };
956
972
  if (rememberMe) {
957
- const REMEMBER_ME_DAYS = config2["REMEMBER_ME_DAYS"] || 30;
958
- const durationInMs = REMEMBER_ME_DAYS * 24 * 60 * 60 * 1e3;
959
- cookieOptions.maxAge = durationInMs;
960
- cookieOptions.expires = new Date(Date.now() + durationInMs);
973
+ const idleLifespanSec = strapi2.config.get(
974
+ "admin.auth.sessions.idleRefreshTokenLifespan",
975
+ 1209600
976
+ // 14 days Strapi default
977
+ );
978
+ const idleMs = idleLifespanSec * 1e3;
979
+ const absoluteMs = new Date(absoluteExpiresAt).getTime() - Date.now();
980
+ const ms = Math.min(idleMs, absoluteMs);
981
+ cookieOptions.maxAge = ms;
982
+ cookieOptions.expires = new Date(Date.now() + ms);
961
983
  }
962
984
  ctx.cookies.set("strapi_admin_refresh", refreshToken, cookieOptions);
963
985
  ctx.cookies.set("oidc_authenticated", "1", { ...cookieOptions, path: "/" });
@@ -1033,9 +1055,7 @@ function whitelistService({ strapi: strapi2 }) {
1033
1055
  if (!settings) {
1034
1056
  settings = {
1035
1057
  useWhitelist: true,
1036
- enforceOIDC: false,
1037
- showSSOButton: true,
1038
- ssoButtonText: "Login via SSO"
1058
+ enforceOIDC: false
1039
1059
  };
1040
1060
  await getPluginStore().set({ key: "settings", value: settings });
1041
1061
  }