@adonis-agora/authkit-server 0.55.0 → 0.55.1

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.
@@ -128,6 +128,11 @@ export class OidcService {
128
128
  findAccount: config.findAccount,
129
129
  globalRolesClaim: config.globalRolesClaim,
130
130
  resolveTokenRoles: config.resolveTokenRoles,
131
+ // Allowlist de roles que autorizam impersonation — a MESMA de
132
+ // `config.admin.roles` usada pelos guards do console (default
133
+ // `['ADMIN']`). Permite que um host use papel próprio (ex.: `admin`
134
+ // minúsculo num store de roles próprio) sem alterar `globalRoles`.
135
+ adminRoles: config.admin.roles,
131
136
  // Resource indicators (RFC 8707) suportados: o `audience` default + cada
132
137
  // resource declarado. Usado para validar `audience`/`resource` no pedido de
133
138
  // token-exchange — alvos fora desta lista são rejeitados (invalid_target).
@@ -14,6 +14,11 @@ export interface TokenExchangeDeps {
14
14
  * `target.globalRoles ?? []` (unchanged behavior). Mirrors the mint-time hook used
15
15
  * by the authorization-code flow so impersonated tokens source roles from the same
16
16
  * authority (e.g. @adonis-agora/authz) or custom store.
17
+ *
18
+ * The SAME hook also gates the ACTOR (the admin trying to impersonate): its roles
19
+ * are resolved through it too, so an app that keeps roles in its own table
20
+ * (e.g. via `@adonis-agora/authz`) can impersonate without storing roles in the
21
+ * authkit `globalRoles` column. When omitted, falls back to `actor.globalRoles`.
17
22
  */
18
23
  resolveTokenRoles?: (account: AuthAccount, context: {
19
24
  clientId?: string;
@@ -23,6 +28,14 @@ export interface TokenExchangeDeps {
23
28
  orgRole: string;
24
29
  } | null;
25
30
  }) => string[] | Promise<string[]>;
31
+ /**
32
+ * Allowlist de roles que autorizam a impersonation. Default: `['ADMIN']`.
33
+ * Aceita o papel EXATO (ex.: `'admin'` minúsculo) do app — resolve contra a
34
+ * MESMA fonte de roles do `resolveTokenRoles`/`globalRoles`, não a um papel
35
+ * hardcoded. Mantém `adminRole` como alias singular para back-compat.
36
+ */
37
+ adminRoles?: string[];
38
+ /** @deprecated Use `adminRoles` (allowlist). Mantido como alias singular. */
26
39
  adminRole?: string;
27
40
  /**
28
41
  * Resource indicators (RFC 8707) suportados pelo provider. Quando o pedido traz
@@ -16,7 +16,7 @@ function intersectScopes(requested, allowed) {
16
16
  return out.join(' ');
17
17
  }
18
18
  export function registerTokenExchange(provider, deps) {
19
- const adminRole = deps.adminRole ?? 'ADMIN';
19
+ const adminRoles = deps.adminRoles ?? (deps.adminRole ? [deps.adminRole] : ['ADMIN']);
20
20
  const supportedResources = new Set(deps.supportedResources ?? []);
21
21
  const handler = async (ctx) => {
22
22
  const { params, client } = ctx.oidc;
@@ -36,7 +36,22 @@ export function registerTokenExchange(provider, deps) {
36
36
  throw new errors.InvalidGrant('subject_token was not issued to this client');
37
37
  }
38
38
  const actor = await deps.findAccount(subjectAt.accountId);
39
- if (!actor || !(actor.globalRoles ?? []).includes(adminRole)) {
39
+ if (!actor) {
40
+ throw new errors.InvalidGrant('actor not permitted to impersonate');
41
+ }
42
+ // Resolve as roles do ATOR pela MESMA fonte do claim (resolveTokenRoles
43
+ // quando o host configura — ex.: roles em tabela própria via
44
+ // `@adonis-agora/authz`), com fallback pro `globalRoles` do store. Sem isso
45
+ // um host que não grava roles na coluna `globalRoles` do authkit nunca
46
+ // conseguiria impersonar (o gate bateria sempre em `[]`). Mesmo padrão do
47
+ // console (`resolveAccountRoles` em `host/account_roles.ts`).
48
+ const actorRoles = deps.resolveTokenRoles
49
+ ? await deps.resolveTokenRoles(actor, {
50
+ clientId: client?.clientId,
51
+ activeOrg: null,
52
+ })
53
+ : (actor.globalRoles ?? []);
54
+ if (!actorRoles.some((r) => adminRoles.includes(r))) {
40
55
  throw new errors.InvalidGrant('actor not permitted to impersonate');
41
56
  }
42
57
  const targetId = params.requested_subject;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/authkit-server",
3
- "version": "0.55.0",
3
+ "version": "0.55.1",
4
4
  "description": "AdonisJS OIDC/OAuth2 provider (Identity Provider) toolkit: ejectable auth server with sessions, rate-limiting, MFA/TOTP, audit log, federated logout and OpenTelemetry metrics.",
5
5
  "license": "MIT",
6
6
  "author": "dudousxd",