strapi-plugin-oidc 1.3.1 → 1.4.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.
@@ -89,6 +89,21 @@ async function bootstrap({ strapi: strapi2 }) {
89
89
  }
90
90
  ];
91
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
+ }
92
107
  try {
93
108
  const oidcRoleCount = await strapi2.query("plugin::strapi-plugin-oidc.roles").count({
94
109
  where: { oauth_type: "4" }
@@ -485,6 +500,48 @@ async function removeEmail(ctx) {
485
500
  await whitelistService2.removeUser(id);
486
501
  ctx.body = {};
487
502
  }
503
+ async function deleteAll(ctx) {
504
+ await strapi.db.query("plugin::strapi-plugin-oidc.whitelists").deleteMany({});
505
+ ctx.body = {};
506
+ }
507
+ async function importUsers(ctx) {
508
+ const { users } = ctx.request.body;
509
+ if (!Array.isArray(users)) {
510
+ ctx.status = 400;
511
+ ctx.body = { error: "Expected { users: [{email, roles}] }" };
512
+ return;
513
+ }
514
+ const allRoles = await strapi.query("admin::role").findMany({});
515
+ const roleNameToId = new Map(allRoles.map((r) => [r.name, String(r.id)]));
516
+ const resolveRole = (nameOrId) => roleNameToId.get(nameOrId) ?? nameOrId;
517
+ const normalized = users.filter((u) => u?.email).map((u) => ({
518
+ email: String(u.email).trim().toLowerCase(),
519
+ roles: (Array.isArray(u.roles) ? u.roles : []).map(resolveRole)
520
+ }));
521
+ const seen = /* @__PURE__ */ new Set();
522
+ const deduped = normalized.filter((u) => {
523
+ if (seen.has(u.email)) return false;
524
+ seen.add(u.email);
525
+ return true;
526
+ });
527
+ const strapiUsers = await strapi.query("admin::user").findMany({
528
+ where: { email: { $in: deduped.map((u) => u.email) } },
529
+ populate: ["roles"]
530
+ });
531
+ const strapiUserMap = new Map(strapiUsers.map((u) => [u.email, u]));
532
+ const whitelistService2 = strapi.plugin("strapi-plugin-oidc").service("whitelist");
533
+ const existing = await whitelistService2.getUsers();
534
+ const existingEmails = new Set(existing.map((u) => u.email));
535
+ let importedCount = 0;
536
+ for (const user of deduped) {
537
+ if (existingEmails.has(user.email)) continue;
538
+ const strapiUser = strapiUserMap.get(user.email);
539
+ const finalRoles = strapiUser?.roles?.length ? strapiUser.roles.map((r) => String(r.id)) : user.roles;
540
+ await whitelistService2.registerUser(user.email, finalRoles);
541
+ importedCount++;
542
+ }
543
+ ctx.body = { importedCount };
544
+ }
488
545
  async function syncUsers(ctx) {
489
546
  let { users } = ctx.request.body;
490
547
  users = users.map((u) => ({ ...u, email: String(u.email).toLowerCase() }));
@@ -526,7 +583,9 @@ const whitelist = {
526
583
  publicSettings,
527
584
  register,
528
585
  removeEmail,
529
- syncUsers
586
+ deleteAll,
587
+ syncUsers,
588
+ importUsers
530
589
  };
531
590
  const controllers = {
532
591
  oidc,
@@ -550,134 +609,133 @@ const rateLimitMiddleware = async (ctx, next) => {
550
609
  rateLimitMap.set(ip, requestStamps);
551
610
  await next();
552
611
  };
553
- const routes = [
554
- {
555
- method: "GET",
556
- path: "/oidc-roles",
557
- handler: "role.find",
558
- config: {
559
- policies: [
560
- "admin::isAuthenticatedAdmin",
561
- { name: "admin::hasPermissions", config: { actions: ["plugin::strapi-plugin-oidc.read"] } }
562
- ]
563
- }
564
- },
565
- {
566
- method: "PUT",
567
- path: "/oidc-roles",
568
- handler: "role.update",
569
- config: {
570
- policies: [
571
- "admin::isAuthenticatedAdmin",
572
- {
573
- name: "admin::hasPermissions",
574
- config: { actions: ["plugin::strapi-plugin-oidc.update"] }
575
- }
576
- ]
577
- }
578
- },
579
- {
580
- method: "GET",
581
- path: "/oidc",
582
- handler: "oidc.oidcSignIn",
583
- config: {
584
- auth: false,
585
- middlewares: [rateLimitMiddleware]
586
- }
587
- },
588
- {
589
- method: "GET",
590
- path: "/oidc/callback",
591
- handler: "oidc.oidcSignInCallback",
592
- config: {
593
- auth: false,
594
- middlewares: [rateLimitMiddleware]
595
- }
596
- },
597
- {
598
- method: "GET",
599
- path: "/logout",
600
- handler: "oidc.logout",
601
- config: {
602
- auth: false
603
- }
604
- },
605
- {
606
- method: "GET",
607
- path: "/whitelist",
608
- handler: "whitelist.info",
609
- config: {
610
- policies: [
611
- "admin::isAuthenticatedAdmin",
612
- { name: "admin::hasPermissions", config: { actions: ["plugin::strapi-plugin-oidc.read"] } }
613
- ]
614
- }
615
- },
616
- {
617
- method: "PUT",
618
- path: "/whitelist/settings",
619
- handler: "whitelist.updateSettings",
620
- config: {
621
- policies: [
622
- "admin::isAuthenticatedAdmin",
623
- {
624
- name: "admin::hasPermissions",
625
- config: { actions: ["plugin::strapi-plugin-oidc.update"] }
626
- }
627
- ]
628
- }
629
- },
630
- {
631
- method: "GET",
632
- path: "/settings/public",
633
- handler: "whitelist.publicSettings",
634
- config: {
635
- auth: false
636
- }
637
- },
638
- {
639
- method: "PUT",
640
- path: "/whitelist/sync",
641
- handler: "whitelist.syncUsers",
642
- config: {
643
- policies: [
644
- "admin::isAuthenticatedAdmin",
645
- {
646
- name: "admin::hasPermissions",
647
- config: { actions: ["plugin::strapi-plugin-oidc.update"] }
648
- }
649
- ]
650
- }
651
- },
652
- {
653
- method: "POST",
654
- path: "/whitelist",
655
- handler: "whitelist.register",
656
- config: {
657
- policies: [
658
- "admin::isAuthenticatedAdmin",
659
- {
660
- name: "admin::hasPermissions",
661
- config: { actions: ["plugin::strapi-plugin-oidc.update"] }
662
- }
663
- ]
612
+ const adminPolicies = (action) => ({
613
+ policies: [
614
+ "admin::isAuthenticatedAdmin",
615
+ {
616
+ name: "admin::hasPermissions",
617
+ config: { actions: [`plugin::strapi-plugin-oidc.${action}`] }
664
618
  }
619
+ ]
620
+ });
621
+ const routes = {
622
+ admin: {
623
+ type: "admin",
624
+ routes: [
625
+ {
626
+ method: "GET",
627
+ path: "/oidc-roles",
628
+ handler: "role.find",
629
+ config: adminPolicies("read")
630
+ },
631
+ {
632
+ method: "PUT",
633
+ path: "/oidc-roles",
634
+ handler: "role.update",
635
+ config: adminPolicies("update")
636
+ },
637
+ {
638
+ method: "GET",
639
+ path: "/oidc",
640
+ handler: "oidc.oidcSignIn",
641
+ config: { auth: false, middlewares: [rateLimitMiddleware] }
642
+ },
643
+ {
644
+ method: "GET",
645
+ path: "/oidc/callback",
646
+ handler: "oidc.oidcSignInCallback",
647
+ config: { auth: false, middlewares: [rateLimitMiddleware] }
648
+ },
649
+ {
650
+ method: "GET",
651
+ path: "/logout",
652
+ handler: "oidc.logout",
653
+ config: { auth: false }
654
+ },
655
+ {
656
+ method: "GET",
657
+ path: "/whitelist",
658
+ handler: "whitelist.info",
659
+ config: adminPolicies("read")
660
+ },
661
+ {
662
+ method: "PUT",
663
+ path: "/whitelist/settings",
664
+ handler: "whitelist.updateSettings",
665
+ config: adminPolicies("update")
666
+ },
667
+ {
668
+ method: "GET",
669
+ path: "/settings/public",
670
+ handler: "whitelist.publicSettings",
671
+ config: { auth: false }
672
+ },
673
+ {
674
+ method: "PUT",
675
+ path: "/whitelist/sync",
676
+ handler: "whitelist.syncUsers",
677
+ config: adminPolicies("update")
678
+ },
679
+ {
680
+ method: "POST",
681
+ path: "/whitelist/import",
682
+ handler: "whitelist.importUsers",
683
+ config: adminPolicies("update")
684
+ },
685
+ {
686
+ method: "POST",
687
+ path: "/whitelist",
688
+ handler: "whitelist.register",
689
+ config: adminPolicies("update")
690
+ },
691
+ {
692
+ method: "DELETE",
693
+ path: "/whitelist/:id",
694
+ handler: "whitelist.removeEmail",
695
+ config: adminPolicies("update")
696
+ },
697
+ {
698
+ method: "DELETE",
699
+ path: "/whitelist",
700
+ handler: "whitelist.deleteAll",
701
+ config: adminPolicies("update")
702
+ }
703
+ ]
665
704
  },
666
- {
667
- method: "DELETE",
668
- path: "/whitelist/:id",
669
- handler: "whitelist.removeEmail",
670
- config: {
671
- policies: [
672
- "admin::isAuthenticatedAdmin",
673
- {
674
- name: "admin::hasPermissions",
675
- config: { actions: ["plugin::strapi-plugin-oidc.update"] }
676
- }
677
- ]
678
- }
705
+ // API-token-authenticated routes for programmatic whitelist management.
706
+ // Accessible at /strapi-plugin-oidc/... using a Strapi API token
707
+ // (full-access or custom) in the Authorization: Bearer <token> header.
708
+ "content-api": {
709
+ type: "content-api",
710
+ routes: [
711
+ {
712
+ method: "GET",
713
+ path: "/whitelist",
714
+ handler: "whitelist.info"
715
+ },
716
+ {
717
+ method: "POST",
718
+ path: "/whitelist",
719
+ handler: "whitelist.register"
720
+ },
721
+ {
722
+ method: "POST",
723
+ path: "/whitelist/import",
724
+ handler: "whitelist.importUsers"
725
+ },
726
+ {
727
+ method: "DELETE",
728
+ path: "/whitelist/:id",
729
+ handler: "whitelist.removeEmail"
730
+ },
731
+ {
732
+ method: "DELETE",
733
+ path: "/whitelist",
734
+ handler: "whitelist.deleteAll"
735
+ }
736
+ ]
679
737
  }
680
- ];
738
+ };
681
739
  const policies = {};
682
740
  function renderHtmlTemplate(title, content) {
683
741
  return `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-oidc",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
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",
@@ -26,10 +26,17 @@
26
26
  },
27
27
  "keywords": [
28
28
  "strapi",
29
- "plugin",
29
+ "strapi-plugin",
30
+ "oidc",
30
31
  "oauth",
31
- "OIDC",
32
- "Zitadel"
32
+ "sso",
33
+ "authentication",
34
+ "keycloak",
35
+ "auth0",
36
+ "okta",
37
+ "azure-ad",
38
+ "authentik",
39
+ "authelia"
33
40
  ],
34
41
  "peerDependencies": {
35
42
  "@strapi/strapi": "^5.24.1",