strapi-plugin-oidc 1.6.1 → 1.6.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.
- package/README.md +6 -1
- package/dist/server/index.js +38 -28
- package/dist/server/index.mjs +38 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -121,7 +121,12 @@ Role names are the **display names** shown in **Settings → Roles** (e.g. `"Edi
|
|
|
121
121
|
1. **User's OIDC groups match `OIDC_GROUP_ROLE_MAP`** → use the mapped Strapi roles
|
|
122
122
|
2. **No group match or no mapping configured** → use the default OIDC roles
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
### Role updates on subsequent logins
|
|
125
|
+
|
|
126
|
+
- **New users** — OIDC roles are always assigned on first login.
|
|
127
|
+
- **Existing users with manually unchanged roles** — If a user's current roles still match the roles assigned by OIDC on their previous login (i.e., an administrator has not manually changed their roles), their roles are updated to reflect the current group mapping. This ensures that when the group-to-role mapping changes, returning users pick up the new roles automatically.
|
|
128
|
+
- **Existing users with manually changed roles** — If an administrator has manually assigned the user different roles since their last OIDC login, the user's roles are left unchanged. OIDC will not overwrite a manual role assignment.
|
|
129
|
+
- **Mapping removed or user's groups don't map** — If the `OIDC_GROUP_ROLE_MAP` is removed, a user's groups no longer match any mapping, or there are no default OIDC roles configured, the user keeps their last known roles.
|
|
125
130
|
|
|
126
131
|
## Whitelist API
|
|
127
132
|
|
package/dist/server/index.js
CHANGED
|
@@ -494,6 +494,30 @@ async function registerNewUser(oauthService2, email, userResponseData, config2,
|
|
|
494
494
|
await oauthService2.triggerWebHook(activateUser);
|
|
495
495
|
return activateUser;
|
|
496
496
|
}
|
|
497
|
+
function rolesChanged(current, next) {
|
|
498
|
+
return current.size !== next.size || [...next].some((id) => !current.has(id));
|
|
499
|
+
}
|
|
500
|
+
async function updateUserRoles(user, currentRoleIds, newRoleIds) {
|
|
501
|
+
try {
|
|
502
|
+
strapi.log.info(
|
|
503
|
+
`[OIDC] Roles updated for user ${user.id}: [${[...currentRoleIds].join(",")}] -> [${newRoleIds.join(",")}]`
|
|
504
|
+
);
|
|
505
|
+
await strapi.db.query("admin::user").update({
|
|
506
|
+
where: { id: user.id },
|
|
507
|
+
data: { roles: newRoleIds }
|
|
508
|
+
});
|
|
509
|
+
} catch (updateErr) {
|
|
510
|
+
strapi.log.error({
|
|
511
|
+
code: errorCodes.ROLE_UPDATE_FAILED,
|
|
512
|
+
userId: user.id,
|
|
513
|
+
detail: getErrorDetail("role_update_failed", {
|
|
514
|
+
userId: user.id,
|
|
515
|
+
error: updateErr.message
|
|
516
|
+
})
|
|
517
|
+
});
|
|
518
|
+
throw updateErr;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
497
521
|
async function handleUserAuthentication(userService, oauthService2, roleService2, whitelistService2, userResponseData, config2, ctx) {
|
|
498
522
|
const rawEmail = String(userResponseData.email ?? "");
|
|
499
523
|
const email = rawEmail.toLowerCase();
|
|
@@ -506,40 +530,26 @@ async function handleUserAuthentication(userService, oauthService2, roleService2
|
|
|
506
530
|
const resolvedRoleNames = allRoles.filter((r) => roles2.includes(String(r.id))).map((r) => r.name);
|
|
507
531
|
let userCreated = false;
|
|
508
532
|
let rolesUpdated = false;
|
|
509
|
-
let
|
|
510
|
-
if (!
|
|
511
|
-
|
|
533
|
+
let user = await userService.findOneByEmail(email, ["roles"]);
|
|
534
|
+
if (!user) {
|
|
535
|
+
user = await registerNewUser(oauthService2, email, userResponseData, config2, ctx, roles2);
|
|
512
536
|
userCreated = true;
|
|
537
|
+
rolesUpdated = true;
|
|
513
538
|
} else if (roles2.length > 0) {
|
|
514
|
-
const
|
|
539
|
+
const defaultRoleIds = new Set(user.roles.map((r) => String(r.id)));
|
|
540
|
+
const currentRoleIds = new Set(user.roles.map((r) => String(r.id)));
|
|
515
541
|
const newRoleIds = new Set(roles2);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
`[OIDC] Roles updated for user ${activateUser.id}: [${[...currentRoleIds].join(",")}] -> [${roles2.join(",")}]`
|
|
521
|
-
);
|
|
522
|
-
await strapi.db.query("admin::user").update({
|
|
523
|
-
where: { id: activateUser.id },
|
|
524
|
-
data: { roles: roles2 }
|
|
525
|
-
});
|
|
542
|
+
if (rolesChanged(currentRoleIds, newRoleIds)) {
|
|
543
|
+
const isOnDefaultRoles = currentRoleIds.size === defaultRoleIds.size && [...currentRoleIds].every((id) => defaultRoleIds.has(id));
|
|
544
|
+
if (isOnDefaultRoles) {
|
|
545
|
+
await updateUserRoles(user, currentRoleIds, roles2);
|
|
526
546
|
rolesUpdated = true;
|
|
527
|
-
} catch (updateErr) {
|
|
528
|
-
strapi.log.error({
|
|
529
|
-
code: errorCodes.ROLE_UPDATE_FAILED,
|
|
530
|
-
userId: activateUser.id,
|
|
531
|
-
detail: getErrorDetail("role_update_failed", {
|
|
532
|
-
userId: activateUser.id,
|
|
533
|
-
error: updateErr.message
|
|
534
|
-
})
|
|
535
|
-
});
|
|
536
|
-
throw updateErr;
|
|
537
547
|
}
|
|
538
548
|
}
|
|
539
549
|
}
|
|
540
|
-
const jwtToken = await oauthService2.generateToken(
|
|
541
|
-
oauthService2.triggerSignInSuccess(
|
|
542
|
-
return { activateUser, jwtToken, userCreated, rolesUpdated, resolvedRoleNames };
|
|
550
|
+
const jwtToken = await oauthService2.generateToken(user, ctx);
|
|
551
|
+
oauthService2.triggerSignInSuccess(user);
|
|
552
|
+
return { activateUser: user, jwtToken, userCreated, rolesUpdated, resolvedRoleNames };
|
|
543
553
|
}
|
|
544
554
|
function classifyOidcError(msg, userInfo) {
|
|
545
555
|
const errorMap = [
|
|
@@ -1525,7 +1535,7 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
1525
1535
|
});
|
|
1526
1536
|
},
|
|
1527
1537
|
async removeUser(email) {
|
|
1528
|
-
await
|
|
1538
|
+
await getWhitelistQuery().deleteMany({
|
|
1529
1539
|
where: { email }
|
|
1530
1540
|
});
|
|
1531
1541
|
},
|
package/dist/server/index.mjs
CHANGED
|
@@ -488,6 +488,30 @@ async function registerNewUser(oauthService2, email, userResponseData, config2,
|
|
|
488
488
|
await oauthService2.triggerWebHook(activateUser);
|
|
489
489
|
return activateUser;
|
|
490
490
|
}
|
|
491
|
+
function rolesChanged(current, next) {
|
|
492
|
+
return current.size !== next.size || [...next].some((id) => !current.has(id));
|
|
493
|
+
}
|
|
494
|
+
async function updateUserRoles(user, currentRoleIds, newRoleIds) {
|
|
495
|
+
try {
|
|
496
|
+
strapi.log.info(
|
|
497
|
+
`[OIDC] Roles updated for user ${user.id}: [${[...currentRoleIds].join(",")}] -> [${newRoleIds.join(",")}]`
|
|
498
|
+
);
|
|
499
|
+
await strapi.db.query("admin::user").update({
|
|
500
|
+
where: { id: user.id },
|
|
501
|
+
data: { roles: newRoleIds }
|
|
502
|
+
});
|
|
503
|
+
} catch (updateErr) {
|
|
504
|
+
strapi.log.error({
|
|
505
|
+
code: errorCodes.ROLE_UPDATE_FAILED,
|
|
506
|
+
userId: user.id,
|
|
507
|
+
detail: getErrorDetail("role_update_failed", {
|
|
508
|
+
userId: user.id,
|
|
509
|
+
error: updateErr.message
|
|
510
|
+
})
|
|
511
|
+
});
|
|
512
|
+
throw updateErr;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
491
515
|
async function handleUserAuthentication(userService, oauthService2, roleService2, whitelistService2, userResponseData, config2, ctx) {
|
|
492
516
|
const rawEmail = String(userResponseData.email ?? "");
|
|
493
517
|
const email = rawEmail.toLowerCase();
|
|
@@ -500,40 +524,26 @@ async function handleUserAuthentication(userService, oauthService2, roleService2
|
|
|
500
524
|
const resolvedRoleNames = allRoles.filter((r) => roles2.includes(String(r.id))).map((r) => r.name);
|
|
501
525
|
let userCreated = false;
|
|
502
526
|
let rolesUpdated = false;
|
|
503
|
-
let
|
|
504
|
-
if (!
|
|
505
|
-
|
|
527
|
+
let user = await userService.findOneByEmail(email, ["roles"]);
|
|
528
|
+
if (!user) {
|
|
529
|
+
user = await registerNewUser(oauthService2, email, userResponseData, config2, ctx, roles2);
|
|
506
530
|
userCreated = true;
|
|
531
|
+
rolesUpdated = true;
|
|
507
532
|
} else if (roles2.length > 0) {
|
|
508
|
-
const
|
|
533
|
+
const defaultRoleIds = new Set(user.roles.map((r) => String(r.id)));
|
|
534
|
+
const currentRoleIds = new Set(user.roles.map((r) => String(r.id)));
|
|
509
535
|
const newRoleIds = new Set(roles2);
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
`[OIDC] Roles updated for user ${activateUser.id}: [${[...currentRoleIds].join(",")}] -> [${roles2.join(",")}]`
|
|
515
|
-
);
|
|
516
|
-
await strapi.db.query("admin::user").update({
|
|
517
|
-
where: { id: activateUser.id },
|
|
518
|
-
data: { roles: roles2 }
|
|
519
|
-
});
|
|
536
|
+
if (rolesChanged(currentRoleIds, newRoleIds)) {
|
|
537
|
+
const isOnDefaultRoles = currentRoleIds.size === defaultRoleIds.size && [...currentRoleIds].every((id) => defaultRoleIds.has(id));
|
|
538
|
+
if (isOnDefaultRoles) {
|
|
539
|
+
await updateUserRoles(user, currentRoleIds, roles2);
|
|
520
540
|
rolesUpdated = true;
|
|
521
|
-
} catch (updateErr) {
|
|
522
|
-
strapi.log.error({
|
|
523
|
-
code: errorCodes.ROLE_UPDATE_FAILED,
|
|
524
|
-
userId: activateUser.id,
|
|
525
|
-
detail: getErrorDetail("role_update_failed", {
|
|
526
|
-
userId: activateUser.id,
|
|
527
|
-
error: updateErr.message
|
|
528
|
-
})
|
|
529
|
-
});
|
|
530
|
-
throw updateErr;
|
|
531
541
|
}
|
|
532
542
|
}
|
|
533
543
|
}
|
|
534
|
-
const jwtToken = await oauthService2.generateToken(
|
|
535
|
-
oauthService2.triggerSignInSuccess(
|
|
536
|
-
return { activateUser, jwtToken, userCreated, rolesUpdated, resolvedRoleNames };
|
|
544
|
+
const jwtToken = await oauthService2.generateToken(user, ctx);
|
|
545
|
+
oauthService2.triggerSignInSuccess(user);
|
|
546
|
+
return { activateUser: user, jwtToken, userCreated, rolesUpdated, resolvedRoleNames };
|
|
537
547
|
}
|
|
538
548
|
function classifyOidcError(msg, userInfo) {
|
|
539
549
|
const errorMap = [
|
|
@@ -1519,7 +1529,7 @@ function whitelistService({ strapi: strapi2 }) {
|
|
|
1519
1529
|
});
|
|
1520
1530
|
},
|
|
1521
1531
|
async removeUser(email) {
|
|
1522
|
-
await
|
|
1532
|
+
await getWhitelistQuery().deleteMany({
|
|
1523
1533
|
where: { email }
|
|
1524
1534
|
});
|
|
1525
1535
|
},
|
package/package.json
CHANGED