@adonis-agora/authkit-server 0.73.0 → 0.74.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.
Files changed (35) hide show
  1. package/README.md +4 -0
  2. package/build/commands/clients_create.d.ts +2 -0
  3. package/build/commands/clients_create.js +41 -13
  4. package/build/commands/commands.json +7 -0
  5. package/build/index.d.ts +6 -0
  6. package/build/index.js +7 -0
  7. package/build/src/commands/import_clients.js +2 -0
  8. package/build/src/host/access_token_verifier.d.ts +100 -0
  9. package/build/src/host/access_token_verifier.js +240 -0
  10. package/build/src/host/admin_api/api_clients_controller.d.ts +4 -1
  11. package/build/src/host/admin_api/api_clients_controller.js +25 -2
  12. package/build/src/host/admin_api/dto.d.ts +1 -0
  13. package/build/src/host/admin_api/dto.js +1 -0
  14. package/build/src/host/admin_clients_service.d.ts +9 -0
  15. package/build/src/host/admin_clients_service.js +21 -0
  16. package/build/src/host/admin_console/console_clients_controller.d.ts +3 -1
  17. package/build/src/host/admin_console/console_clients_controller.js +25 -2
  18. package/build/src/host/admin_validators.d.ts +11 -1
  19. package/build/src/host/admin_validators.js +36 -8
  20. package/build/src/host/bearer_account.d.ts +9 -0
  21. package/build/src/host/bearer_account.js +28 -0
  22. package/build/src/host/client_metadata.d.ts +51 -0
  23. package/build/src/host/client_metadata.js +98 -0
  24. package/build/src/host/console_session.d.ts +14 -3
  25. package/build/src/host/console_session.js +21 -9
  26. package/build/src/host/oidc_bearer_guard.d.ts +113 -0
  27. package/build/src/host/oidc_bearer_guard.js +223 -0
  28. package/build/src/host/oidc_rp_guard.d.ts +3 -1
  29. package/build/src/host/oidc_rp_guard.js +6 -2
  30. package/build/src/host/ui-dist/assets/{index-Dct63ai-.js → index-CIqtoNcO.js} +1 -1
  31. package/build/src/host/ui-dist/index.html +1 -1
  32. package/build/src/provider/build_provider.js +42 -17
  33. package/build/src/provider/oidc_service.d.ts +8 -0
  34. package/build/src/provider/oidc_service.js +11 -1
  35. package/package.json +3 -3
@@ -1,6 +1,7 @@
1
1
  import * as oidc from 'oidc-provider';
2
2
  import { pickModelAdapterClass } from '../adapters/factory.js';
3
3
  import { normalizeActiveOrg, readActiveOrgFromKoaCtx } from '../host/active_org_cookie.js';
4
+ import { assertClientMetadata } from '../host/client_metadata.js';
4
5
  import { createDeviceSources } from './device_sources.js';
5
6
  import { createLogoutSources } from './logout_sources.js';
6
7
  import { registrationPolicyMiddleware } from './registration_policy.js';
@@ -123,23 +124,39 @@ export function buildProvider(config, options, sessionTtlHolder, tokenTtlHolder)
123
124
  // `pickModelAdapterClass`, usada também pelos serviços que instanciam
124
125
  // adapter na mão. Sem `session.adapter`, as duas classes são a mesma.
125
126
  adapter: ((name) => new (pickModelAdapterClass(name, config.AdapterClass, config.SessionAdapterClass))(name)),
126
- clients: config.clients.map((c) => ({
127
- client_id: c.clientId,
128
- client_secret: c.clientSecret,
129
- redirect_uris: c.redirectUris,
130
- post_logout_redirect_uris: c.postLogoutRedirectUris ?? [],
131
- grant_types: c.grants ?? ['authorization_code', 'refresh_token'],
132
- response_types: (c.grants ?? ['authorization_code']).includes('authorization_code')
133
- ? ['code']
134
- : [],
135
- token_endpoint_auth_method: c.tokenEndpointAuthMethod ?? (c.clientSecret ? 'client_secret_basic' : 'none'),
136
- // OIDC Back-Channel Logout: só envia as chaves quando o client as declara,
137
- // p/ não forçar metadata vazio em clients que não usam o recurso.
138
- ...(c.backchannelLogoutUri ? { backchannel_logout_uri: c.backchannelLogoutUri } : {}),
139
- ...(c.backchannelLogoutSessionRequired !== undefined
140
- ? { backchannel_logout_session_required: c.backchannelLogoutSessionRequired }
141
- : {}),
142
- })),
127
+ clients: config.clients.map((c) => {
128
+ const grants = c.grants ?? ['authorization_code', 'refresh_token'];
129
+ const tokenEndpointAuthMethod = c.tokenEndpointAuthMethod ?? (c.clientSecret ? 'client_secret_basic' : 'none');
130
+ // Clients do `defineConfig` passam pela MESMA validação do admin/CLI/import:
131
+ // um nativo com secret (ou redirect inválido pro tipo) falha no boot, não em runtime.
132
+ assertClientMetadata({
133
+ applicationType: c.applicationType ?? 'web',
134
+ tokenEndpointAuthMethod,
135
+ grantTypes: grants,
136
+ redirectUris: c.redirectUris,
137
+ postLogoutRedirectUris: c.postLogoutRedirectUris ?? [],
138
+ });
139
+ return {
140
+ client_id: c.clientId,
141
+ client_secret: c.clientSecret,
142
+ redirect_uris: c.redirectUris,
143
+ post_logout_redirect_uris: c.postLogoutRedirectUris ?? [],
144
+ grant_types: grants,
145
+ response_types: (c.grants ?? ['authorization_code']).includes('authorization_code')
146
+ ? ['code']
147
+ : [],
148
+ token_endpoint_auth_method: tokenEndpointAuthMethod,
149
+ // App nativo (RFC 8252): libera redirect de esquema privado/loopback. Sem a
150
+ // chave, o oidc-provider assume `web` — o comportamento de sempre.
151
+ ...(c.applicationType === 'native' ? { application_type: 'native' } : {}),
152
+ // OIDC Back-Channel Logout: só envia as chaves quando o client as declara,
153
+ // p/ não forçar metadata vazio em clients que não usam o recurso.
154
+ ...(c.backchannelLogoutUri ? { backchannel_logout_uri: c.backchannelLogoutUri } : {}),
155
+ ...(c.backchannelLogoutSessionRequired !== undefined
156
+ ? { backchannel_logout_session_required: c.backchannelLogoutSessionRequired }
157
+ : {}),
158
+ };
159
+ }),
143
160
  findAccount: options.findAccount,
144
161
  // Grant REAPROVEITADO (consent já lembrado): o org capturado no primeiro
145
162
  // consent ficaria VELHO se o usuário trocasse de org no console e voltasse a
@@ -220,6 +237,14 @@ export function buildProvider(config, options, sessionTtlHolder, tokenTtlHolder)
220
237
  // sobreviva ao authorize e fique disponivel em interactionDetails().params.audience.
221
238
  extraParams: ['audience'],
222
239
  pkce: { methods: ['S256'], required: () => true },
240
+ // Rotação SEMPRE: todo uso do refresh token emite um novo e invalida o
241
+ // anterior (reuso de um RT já rotacionado revoga o grant inteiro — detecção de
242
+ // replay do oidc-provider). Vale igual para clients públicos (SPA, app nativo
243
+ // RFC 8252), para os quais a rotação é a defesa exigida pelo OAuth 2.0 Security
244
+ // BCP, já que o RT não é amarrado a um secret. O `issueRefreshToken` fica no
245
+ // default do provider: emite RT quando o client tem o grant `refresh_token` e o
246
+ // escopo `offline_access` foi concedido (o que exige `prompt=consent` no
247
+ // authorize — OIDC Core §11), sem distinção entre client público e confidencial.
223
248
  rotateRefreshToken: true,
224
249
  features: {
225
250
  devInteractions: { enabled: false },
@@ -9,6 +9,14 @@ export declare class OidcService {
9
9
  get provider(): ReturnType<typeof buildProvider>;
10
10
  get callback(): (req: any, res: any) => void;
11
11
  get interactions(): InteractionActions;
12
+ /**
13
+ * JWKS PÚBLICO do keystore em uso pelo provider ATUAL (o mesmo que o `jwks_uri`
14
+ * serve). Troca junto com o provider num `reloadKeys`/rotação — quem verifica JWT
15
+ * in-process (ex.: `oidcBearerGuard`) lê daqui a cada verificação.
16
+ */
17
+ get publicJwks(): {
18
+ keys: Record<string, any>[];
19
+ };
12
20
  /** Pathname do issuer sem barra final (ex.: `/oidc`). Vazio quando montado na raiz. */
13
21
  readonly mountPath: string;
14
22
  readonly recorder: MetricsRecorder;
@@ -4,7 +4,7 @@ import Koa from 'koa';
4
4
  import mount from 'koa-mount';
5
5
  import { normalizeActiveOrg, readActiveOrgFromKoaCtx, verifyActiveOrgMembership, } from '../host/active_org_cookie.js';
6
6
  import { isFirstPartyClient } from '../host/branding.js';
7
- import { listKeyInfos, signingKeyAgeDays } from '../keys/keystore.js';
7
+ import { listKeyInfos, signingKeyAgeDays, toPublicJwks, } from '../keys/keystore.js';
8
8
  import { wireProviderEvents } from '../observability/wire_provider_events.js';
9
9
  import { buildProvider } from './build_provider.js';
10
10
  import { createInteractionActions } from './interaction_actions.js';
@@ -13,6 +13,7 @@ export class OidcService {
13
13
  #provider;
14
14
  #callback;
15
15
  #interactions;
16
+ #publicJwks;
16
17
  #appKey;
17
18
  get provider() {
18
19
  return this.#provider;
@@ -23,6 +24,14 @@ export class OidcService {
23
24
  get interactions() {
24
25
  return this.#interactions;
25
26
  }
27
+ /**
28
+ * JWKS PÚBLICO do keystore em uso pelo provider ATUAL (o mesmo que o `jwks_uri`
29
+ * serve). Troca junto com o provider num `reloadKeys`/rotação — quem verifica JWT
30
+ * in-process (ex.: `oidcBearerGuard`) lê daqui a cada verificação.
31
+ */
32
+ get publicJwks() {
33
+ return this.#publicJwks;
34
+ }
26
35
  /** Pathname do issuer sem barra final (ex.: `/oidc`). Vazio quando montado na raiz. */
27
36
  mountPath;
28
37
  recorder;
@@ -205,6 +214,7 @@ export class OidcService {
205
214
  this.#provider = provider;
206
215
  this.#callback = callback;
207
216
  this.#interactions = interactions;
217
+ this.#publicJwks = toPublicJwks(jwks);
208
218
  }
209
219
  /**
210
220
  * Recarrega as chaves de assinatura AO VIVO: relê o keystore do cofre e reconstrói
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/authkit-server",
3
- "version": "0.73.0",
3
+ "version": "0.74.0",
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",
@@ -102,7 +102,7 @@
102
102
  }
103
103
  },
104
104
  "dependencies": {
105
- "@adonis-agora/authkit-core": "0.8.0",
105
+ "@adonis-agora/authkit-core": "0.9.0",
106
106
  "@simplewebauthn/browser": "14.0.0",
107
107
  "@simplewebauthn/server": "14.0.2",
108
108
  "jose": "6.2.12",
@@ -113,7 +113,7 @@
113
113
  "qrcode": "1.5.4"
114
114
  },
115
115
  "devDependencies": {
116
- "@adonis-agora/authkit-react": "0.22.0",
116
+ "@adonis-agora/authkit-react": "0.23.0",
117
117
  "@adonis-agora/durable": "0.40.0",
118
118
  "@adonis-agora/telescope": "0.21.1",
119
119
  "@adonisjs/ally": "6.3.0",