strapi-plugin-oidc 1.0.0 → 1.0.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/edmogeor/strapi-plugin-oidc/main/assets/icon.png" width="140" alt="OIDC Plugin for Strapi Logo"/>
3
- <h1>OIDC Plugin for Strapi</h1>
2
+ <img src="https://raw.githubusercontent.com/edmogeor/strapi-plugin-oidc/main/assets/icon.png" width="140" alt="OIDC Login for Strapi Logo"/>
3
+ <h1>OIDC Login for Strapi</h1>
4
4
  <p>
5
5
  <a href="https://github.com/edmogeor/strapi-plugin-oidc/actions/workflows/test.yml">
6
6
  <img src="https://github.com/edmogeor/strapi-plugin-oidc/actions/workflows/test.yml/badge.svg" alt="Tests">
@@ -8,7 +8,7 @@
8
8
  </p>
9
9
  </div>
10
10
 
11
- A Strapi plugin that provides OpenID Connect (OIDC) authentication functionality for the Strapi Admin Panel.
11
+ A Strapi plugin that provides OpenID Connect (OIDC) authentication functionality for the Strapi Admin Panel.
12
12
 
13
13
  This plugin allows your administrators to log in to the Strapi administration interface using external OIDC identity providers such as Zitadel, Keycloak, Auth0, AWS Cognito, and others.
14
14
 
@@ -43,22 +43,22 @@ module.exports = ({ env }) => ({
43
43
  OIDC_CLIENT_SECRET: '[Client Secret from OpenID Provider]',
44
44
 
45
45
  OIDC_SCOPES: 'openid profile email', // Standard OIDC scopes
46
-
46
+
47
47
  // API Endpoints required for OIDC provider
48
48
  OIDC_AUTHORIZATION_ENDPOINT: '[Authorization Endpoint]',
49
49
  OIDC_TOKEN_ENDPOINT: '[Token Endpoint]',
50
50
  OIDC_USER_INFO_ENDPOINT: '[User Info Endpoint]',
51
51
  OIDC_USER_INFO_ENDPOINT_WITH_AUTH_HEADER: false,
52
- OIDC_GRANT_TYPE: 'authorization_code',
53
-
52
+ OIDC_GRANT_TYPE: 'authorization_code',
53
+
54
54
  // Customizable user field mapping for user creation
55
55
  OIDC_FAMILY_NAME_FIELD: 'family_name',
56
56
  OIDC_GIVEN_NAME_FIELD: 'given_name',
57
-
57
+
58
58
  // Redirect to OIDC provider's logout page when users log out of Strapi
59
- OIDC_LOGOUT_URL: '[OIDC Provider Logout URL]'
60
- }
61
- }
59
+ OIDC_LOGOUT_URL: '[OIDC Provider Logout URL]',
60
+ },
61
+ },
62
62
  // ...
63
63
  });
64
64
  ```
@@ -71,13 +71,14 @@ Once the plugin is installed and configured, you can manage the OIDC settings fr
71
71
 
72
72
  - **Whitelist Management**: Restrict login to specific users by adding their email addresses to the whitelist. You can also whitelist entire email domains (e.g., `*@company.com`). If the whitelist is empty, any user who successfully authenticates via your OIDC provider will be able to log in and an account will be automatically created for them.
73
73
  - **Default Role Assignment**: Select the default Strapi admin role that will be assigned to newly created users when they log in for the first time via OIDC.
74
- - **Enforce OIDC Login**: When enabled, the default Strapi email and password login form will be disabled, forcing all administrators to log in using your OIDC provider. *(Note: This option is automatically disabled and grayed out if your whitelist is empty to prevent accidentally locking everyone out of the admin panel).*
74
+ - **Enforce OIDC Login**: When enabled, the default Strapi email and password login form will be disabled, forcing all administrators to log in using your OIDC provider. _(Note: This option is automatically disabled and grayed out if your whitelist is empty to prevent accidentally locking everyone out of the admin panel)._
75
75
 
76
76
  ## Credits & Changes
77
77
 
78
78
  This plugin is a hard fork of the original [`strapi-plugin-sso`](https://github.com/yasudacloud/strapi-plugin-sso) created by **yasudacloud**. Huge thanks to them for creating the foundation of this plugin!
79
79
 
80
80
  ### Changes made to the original codebase:
81
+
81
82
  - Removed alternative SSO methods to simplify the plugin.
82
83
  - Redesigned the Whitelist and Role management UI (switched to native Strapi cards, added pagination, etc.).
83
84
  - Added an OIDC logout redirect URL.
@@ -85,4 +86,4 @@ This plugin is a hard fork of the original [`strapi-plugin-sso`](https://github.
85
86
  - Migrated the testing framework to Vitest and added comprehensive test coverage for controllers and services.
86
87
  - Cleaned up dead code and unused dependencies to improve maintainability.
87
88
  - Upgraded to use newer versions of Node.js.
88
- - Added misc. quality of life improvements and bug fixes.
89
+ - Added misc. quality of life improvements and bug fixes.
@@ -75,6 +75,8 @@ function destroy() {
75
75
  const config = {
76
76
  default: {
77
77
  REMEMBER_ME: false,
78
+ REMEMBER_ME_DURATION: 30 * 24 * 60 * 60 * 1e3,
79
+ // 30 days in milliseconds
78
80
  OIDC_REDIRECT_URI: "http://localhost:1337/strapi-plugin-oidc/oidc/callback",
79
81
  OIDC_CLIENT_ID: "",
80
82
  OIDC_CLIENT_SECRET: "",
@@ -546,10 +548,13 @@ function oauthService({ strapi: strapi2 }) {
546
548
  ENTRY_CREATE = webhookStore.allowedEvents.get("ENTRY_CREATE");
547
549
  }
548
550
  const modelDef = strapi2.getModel("admin::user");
549
- const sanitizedEntity = await strapiUtils__default.default.sanitize.sanitizers.defaultSanitizeOutput({
550
- schema: modelDef,
551
- getModel: (uid2) => strapi2.getModel(uid2)
552
- }, user);
551
+ const sanitizedEntity = await strapiUtils__default.default.sanitize.sanitizers.defaultSanitizeOutput(
552
+ {
553
+ schema: modelDef,
554
+ getModel: (uid2) => strapi2.getModel(uid2)
555
+ },
556
+ user
557
+ );
553
558
  eventHub.emit(ENTRY_CREATE, {
554
559
  model: modelDef.modelName,
555
560
  entry: sanitizedEntity
@@ -606,19 +611,39 @@ function oauthService({ strapi: strapi2 }) {
606
611
  async generateToken(user, ctx) {
607
612
  const sessionManager = strapi2.sessionManager;
608
613
  if (!sessionManager) {
609
- throw new Error("sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later.");
614
+ throw new Error(
615
+ "sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later."
616
+ );
610
617
  }
611
618
  const userId = String(user.id);
612
619
  const deviceId = node_crypto.randomUUID();
613
620
  const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
614
621
  const REMEMBER_ME = config2["REMEMBER_ME"];
615
622
  const rememberMe = !!REMEMBER_ME;
616
- const { token: refreshToken } = await sessionManager(
617
- "admin"
618
- ).generateRefreshToken(userId, deviceId, {
619
- type: rememberMe ? "refresh" : "session"
620
- });
621
- const cookieOptions = {};
623
+ const { token: refreshToken } = await sessionManager("admin").generateRefreshToken(
624
+ userId,
625
+ deviceId,
626
+ {
627
+ type: rememberMe ? "refresh" : "session"
628
+ }
629
+ );
630
+ const isProduction = strapi2.config.get("environment") === "production";
631
+ const domain = strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain");
632
+ const path = strapi2.config.get("admin.auth.cookie.path", "/admin");
633
+ const sameSite = strapi2.config.get("admin.auth.cookie.sameSite", "lax");
634
+ const cookieOptions = {
635
+ httpOnly: true,
636
+ secure: isProduction,
637
+ overwrite: true,
638
+ domain,
639
+ path,
640
+ sameSite
641
+ };
642
+ if (rememberMe) {
643
+ const REMEMBER_ME_DURATION = config2["REMEMBER_ME_DURATION"] || 30 * 24 * 60 * 60 * 1e3;
644
+ cookieOptions.maxAge = REMEMBER_ME_DURATION;
645
+ cookieOptions.expires = new Date(Date.now() + REMEMBER_ME_DURATION);
646
+ }
622
647
  ctx.cookies.set("strapi_admin_refresh", refreshToken, cookieOptions);
623
648
  const accessResult = await sessionManager("admin").generateAccessToken(refreshToken);
624
649
  if ("error" in accessResult) {
@@ -68,6 +68,8 @@ function destroy() {
68
68
  const config = {
69
69
  default: {
70
70
  REMEMBER_ME: false,
71
+ REMEMBER_ME_DURATION: 30 * 24 * 60 * 60 * 1e3,
72
+ // 30 days in milliseconds
71
73
  OIDC_REDIRECT_URI: "http://localhost:1337/strapi-plugin-oidc/oidc/callback",
72
74
  OIDC_CLIENT_ID: "",
73
75
  OIDC_CLIENT_SECRET: "",
@@ -539,10 +541,13 @@ function oauthService({ strapi: strapi2 }) {
539
541
  ENTRY_CREATE = webhookStore.allowedEvents.get("ENTRY_CREATE");
540
542
  }
541
543
  const modelDef = strapi2.getModel("admin::user");
542
- const sanitizedEntity = await strapiUtils.sanitize.sanitizers.defaultSanitizeOutput({
543
- schema: modelDef,
544
- getModel: (uid2) => strapi2.getModel(uid2)
545
- }, user);
544
+ const sanitizedEntity = await strapiUtils.sanitize.sanitizers.defaultSanitizeOutput(
545
+ {
546
+ schema: modelDef,
547
+ getModel: (uid2) => strapi2.getModel(uid2)
548
+ },
549
+ user
550
+ );
546
551
  eventHub.emit(ENTRY_CREATE, {
547
552
  model: modelDef.modelName,
548
553
  entry: sanitizedEntity
@@ -599,19 +604,39 @@ function oauthService({ strapi: strapi2 }) {
599
604
  async generateToken(user, ctx) {
600
605
  const sessionManager = strapi2.sessionManager;
601
606
  if (!sessionManager) {
602
- throw new Error("sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later.");
607
+ throw new Error(
608
+ "sessionManager is not supported. Please upgrade to Strapi v5.24.1 or later."
609
+ );
603
610
  }
604
611
  const userId = String(user.id);
605
612
  const deviceId = randomUUID();
606
613
  const config2 = strapi2.config.get("plugin::strapi-plugin-oidc");
607
614
  const REMEMBER_ME = config2["REMEMBER_ME"];
608
615
  const rememberMe = !!REMEMBER_ME;
609
- const { token: refreshToken } = await sessionManager(
610
- "admin"
611
- ).generateRefreshToken(userId, deviceId, {
612
- type: rememberMe ? "refresh" : "session"
613
- });
614
- const cookieOptions = {};
616
+ const { token: refreshToken } = await sessionManager("admin").generateRefreshToken(
617
+ userId,
618
+ deviceId,
619
+ {
620
+ type: rememberMe ? "refresh" : "session"
621
+ }
622
+ );
623
+ const isProduction = strapi2.config.get("environment") === "production";
624
+ const domain = strapi2.config.get("admin.auth.cookie.domain") || strapi2.config.get("admin.auth.domain");
625
+ const path = strapi2.config.get("admin.auth.cookie.path", "/admin");
626
+ const sameSite = strapi2.config.get("admin.auth.cookie.sameSite", "lax");
627
+ const cookieOptions = {
628
+ httpOnly: true,
629
+ secure: isProduction,
630
+ overwrite: true,
631
+ domain,
632
+ path,
633
+ sameSite
634
+ };
635
+ if (rememberMe) {
636
+ const REMEMBER_ME_DURATION = config2["REMEMBER_ME_DURATION"] || 30 * 24 * 60 * 60 * 1e3;
637
+ cookieOptions.maxAge = REMEMBER_ME_DURATION;
638
+ cookieOptions.expires = new Date(Date.now() + REMEMBER_ME_DURATION);
639
+ }
615
640
  ctx.cookies.set("strapi_admin_refresh", refreshToken, cookieOptions);
616
641
  const accessResult = await sessionManager("admin").generateAccessToken(refreshToken);
617
642
  if ("error" in accessResult) {
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "strapi-plugin-oidc",
3
- "version": "1.0.0",
4
- "description": "OIDC plugin for Strapi!",
3
+ "version": "1.0.3",
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",
7
7
  "name": "strapi-plugin-oidc",
8
- "description": "Provides OIDC middleware for Strapi instances",
8
+ "description": "A Strapi plugin that provides OpenID Connect (OIDC) authentication functionality for the Strapi Admin Panel.",
9
9
  "kind": "plugin"
10
10
  },
11
11
  "scripts": {
@@ -1,23 +0,0 @@
1
- const en = {
2
- "page.title": "Default role setting at first login",
3
- "page.notes": "This will not be reflected for already registered users.",
4
- "page.save": "Save",
5
- "page.save.success": "Updated settings",
6
- "page.save.error": "Update failed.",
7
- "page.cancel": "Cancel",
8
- "page.ok": "OK",
9
- "tab.roles": "Roles",
10
- "tab.whitelist": "Whitelist",
11
- "tab.whitelist.error.unique": "Already registered email address.",
12
- "tab.whitelist.enabled": "Whitelist is currently enabled.",
13
- "tab.whitelist.disabled": "Whitelist is currently disabled.",
14
- "tab.whitelist.description": "Only the following email addresses are allowed to authenticate with SSO.",
15
- "tab.whitelist.table.no": "No",
16
- "tab.whitelist.table.email": "Email",
17
- "tab.whitelist.table.created": "Created At",
18
- "tab.whitelist.delete.title": "Confirmation",
19
- "tab.whitelist.delete.description": "Are you sure you want to delete this?"
20
- };
21
- export {
22
- en as default
23
- };
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const en = {
4
- "page.title": "Default role setting at first login",
5
- "page.notes": "This will not be reflected for already registered users.",
6
- "page.save": "Save",
7
- "page.save.success": "Updated settings",
8
- "page.save.error": "Update failed.",
9
- "page.cancel": "Cancel",
10
- "page.ok": "OK",
11
- "tab.roles": "Roles",
12
- "tab.whitelist": "Whitelist",
13
- "tab.whitelist.error.unique": "Already registered email address.",
14
- "tab.whitelist.enabled": "Whitelist is currently enabled.",
15
- "tab.whitelist.disabled": "Whitelist is currently disabled.",
16
- "tab.whitelist.description": "Only the following email addresses are allowed to authenticate with SSO.",
17
- "tab.whitelist.table.no": "No",
18
- "tab.whitelist.table.email": "Email",
19
- "tab.whitelist.table.created": "Created At",
20
- "tab.whitelist.delete.title": "Confirmation",
21
- "tab.whitelist.delete.description": "Are you sure you want to delete this?"
22
- };
23
- exports.default = en;
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const fr = {};
4
- exports.default = fr;
@@ -1,4 +0,0 @@
1
- const fr = {};
2
- export {
3
- fr as default
4
- };