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.
- package/README.md +93 -44
- package/dist/admin/{index-D1ypRUlq.mjs → index-8hB6LKml.mjs} +15 -2
- package/dist/admin/{index-CFmg9Kxl.mjs → index-BTTGSnuQ.mjs} +142 -9
- package/dist/admin/{index-Cse9ex24.js → index-CZDixCh4.js} +15 -2
- package/dist/admin/{index-BqyGGX8X.js → index-QZkv75Xp.js} +138 -5
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +184 -126
- package/dist/server/index.mjs +184 -126
- package/package.json +11 -4
package/dist/server/index.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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
|
+
"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
|
-
"
|
|
32
|
-
"
|
|
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",
|