@adonis-agora/authkit-server 0.89.0 → 0.90.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/build/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export { appKeyEncrypter, lucidAccountStore } from './src/accounts/lucid_account
10
10
  export { AuthOrganization, AuthOrganizationInvitation, AuthOrganizationMember, defaultOrganizationModels, } from './src/accounts/lucid_store/organization_models.js';
11
11
  export type { LucidStoresModels, LucidStoresOptions, LucidStoresResult, } from './src/accounts/lucid_stores.js';
12
12
  export { lucidStores } from './src/accounts/lucid_stores.js';
13
+ export { type LinkProviderIdentityResult, ProviderIdentities, ProviderIdentitiesUnsupportedError, } from './src/accounts/provider_identities.js';
13
14
  export type { PersonalAgentIdentity } from './src/agents/agent_identity.js';
14
15
  export { PersonalAgentVerifier } from './src/agents/agent_identity.js';
15
16
  export type { PersonalAgentDelegationConfigInput, PersonalAgentRegistration, PersonalAgentResolver, PersonalAgentsConfigInput, ResolvedPersonalAgentsConfig, } from './src/agents/config.js';
package/build/index.js CHANGED
@@ -7,6 +7,7 @@ export { supportsAccountDeletion, supportsAccountEmailRewrite, supportsAccountIm
7
7
  export { appKeyEncrypter, lucidAccountStore } from './src/accounts/lucid_account_store.js';
8
8
  export { AuthOrganization, AuthOrganizationInvitation, AuthOrganizationMember, defaultOrganizationModels, } from './src/accounts/lucid_store/organization_models.js';
9
9
  export { lucidStores } from './src/accounts/lucid_stores.js';
10
+ export { ProviderIdentities, ProviderIdentitiesUnsupportedError, } from './src/accounts/provider_identities.js';
10
11
  export { PersonalAgentVerifier } from './src/agents/agent_identity.js';
11
12
  export { personalAgentAuth, personalAgentOf, personalAgentReceipt, personalAgentSecurity, personalAgentStepUp, } from './src/agents/middleware.js';
12
13
  export { accessTokenHash, hmacNonceSource, verifyDpopProof, } from './src/agents/poppy/dpop.js';
@@ -0,0 +1,43 @@
1
+ import { type AccountStore, type AuthAccount, type LinkProviderIdentityInput, type ProviderIdentitySummary } from './account_store.js';
2
+ /** O account store não tem account linking (o host não passou `providerIdentityModel`). */
3
+ export declare class ProviderIdentitiesUnsupportedError extends Error {
4
+ constructor();
5
+ }
6
+ /** Resultado de {@link ProviderIdentities.link}. */
7
+ export interface LinkProviderIdentityResult {
8
+ /**
9
+ * Conta a que a identidade estava ligada antes; `null` se era nova. Diferente do
10
+ * `accountId` pedido = a identidade MUDOU de conta (o "Entrar com <provider>" passa
11
+ * a abrir a conta nova).
12
+ */
13
+ previousAccountId: string | null;
14
+ }
15
+ /**
16
+ * Identidades de provider (Google, GitHub, …) das contas: a MESMA ligação que o
17
+ * "Entrar com <provider>" consulta antes de cair no e-mail. Exposto como
18
+ * `authkit.identities` (`@adonis-agora/authkit-server/services/main`) para o host
19
+ * ligar uma conta a um provider fora do login social — ex.: quando a pessoa conecta
20
+ * o Google numa tela de integrações — sem tocar na tabela nem no account store cru.
21
+ *
22
+ * Store sem a capacidade: `supported` é `false` e os demais métodos lançam
23
+ * {@link ProviderIdentitiesUnsupportedError}. Nada falha em silêncio.
24
+ */
25
+ export declare class ProviderIdentities {
26
+ #private;
27
+ constructor(getStore: () => AccountStore);
28
+ /** O account store tem account linking por provider. */
29
+ get supported(): boolean;
30
+ /** A conta ligada a `(provider, providerUserId)`; `null` se ninguém. */
31
+ find(provider: string, providerUserId: string): Promise<AuthAccount | null>;
32
+ /**
33
+ * Liga a identidade à conta. Idempotente na chave `(provider, providerUserId)`: se
34
+ * ela já estava em OUTRA conta, MUDA para esta (e `previousAccountId` diz de onde).
35
+ * Só chame depois de provar que a pessoa é dona da identidade (OAuth concluído)
36
+ * E da conta (sessão nela).
37
+ */
38
+ link(input: LinkProviderIdentityInput): Promise<LinkProviderIdentityResult>;
39
+ /** As identidades da conta, sem tokens. */
40
+ list(accountId: string): Promise<ProviderIdentitySummary[]>;
41
+ /** Remove todas as identidades da conta; devolve quantas. */
42
+ unlinkAll(accountId: string): Promise<number>;
43
+ }
@@ -0,0 +1,58 @@
1
+ import { supportsProviderIdentity, } from './account_store.js';
2
+ /** O account store não tem account linking (o host não passou `providerIdentityModel`). */
3
+ export class ProviderIdentitiesUnsupportedError extends Error {
4
+ constructor() {
5
+ super('[authkit] o accountStore não suporta identidades de provider — passe `providerIdentityModel` ao lucidAccountStore');
6
+ this.name = 'ProviderIdentitiesUnsupportedError';
7
+ }
8
+ }
9
+ /**
10
+ * Identidades de provider (Google, GitHub, …) das contas: a MESMA ligação que o
11
+ * "Entrar com <provider>" consulta antes de cair no e-mail. Exposto como
12
+ * `authkit.identities` (`@adonis-agora/authkit-server/services/main`) para o host
13
+ * ligar uma conta a um provider fora do login social — ex.: quando a pessoa conecta
14
+ * o Google numa tela de integrações — sem tocar na tabela nem no account store cru.
15
+ *
16
+ * Store sem a capacidade: `supported` é `false` e os demais métodos lançam
17
+ * {@link ProviderIdentitiesUnsupportedError}. Nada falha em silêncio.
18
+ */
19
+ export class ProviderIdentities {
20
+ #getStore;
21
+ constructor(getStore) {
22
+ this.#getStore = getStore;
23
+ }
24
+ /** O account store tem account linking por provider. */
25
+ get supported() {
26
+ return supportsProviderIdentity(this.#getStore());
27
+ }
28
+ #store() {
29
+ const store = this.#getStore();
30
+ if (!supportsProviderIdentity(store))
31
+ throw new ProviderIdentitiesUnsupportedError();
32
+ return store;
33
+ }
34
+ /** A conta ligada a `(provider, providerUserId)`; `null` se ninguém. */
35
+ find(provider, providerUserId) {
36
+ return this.#store().findByProviderIdentity(provider, providerUserId);
37
+ }
38
+ /**
39
+ * Liga a identidade à conta. Idempotente na chave `(provider, providerUserId)`: se
40
+ * ela já estava em OUTRA conta, MUDA para esta (e `previousAccountId` diz de onde).
41
+ * Só chame depois de provar que a pessoa é dona da identidade (OAuth concluído)
42
+ * E da conta (sessão nela).
43
+ */
44
+ async link(input) {
45
+ const store = this.#store();
46
+ const previous = await store.findByProviderIdentity(input.provider, input.providerUserId);
47
+ await store.linkProviderIdentity(input);
48
+ return { previousAccountId: previous?.id ?? null };
49
+ }
50
+ /** As identidades da conta, sem tokens. */
51
+ list(accountId) {
52
+ return this.#store().listProviderIdentities(accountId);
53
+ }
54
+ /** Remove todas as identidades da conta; devolve quantas. */
55
+ unlinkAll(accountId) {
56
+ return this.#store().unlinkAllProviderIdentities(accountId);
57
+ }
58
+ }
@@ -1,4 +1,5 @@
1
1
  import { type MetricsRecorder } from '@adonis-agora/authkit-core';
2
+ import { ProviderIdentities } from '../accounts/provider_identities.js';
2
3
  import type { ResolvedServerConfig } from '../define_config.js';
3
4
  import { type ManagedKeyInfo } from '../keys/keystore.js';
4
5
  import type { KeystoreManager } from '../keys/keystore_manager.js';
@@ -38,6 +39,12 @@ export declare class OidcService {
38
39
  /** Holder mutável dos TTLs de access/id/refresh tokens (lido sincronamente pelo oidc-provider). */
39
40
  readonly tokenTtlHolder: TokenTtlHolder;
40
41
  get config(): ResolvedServerConfig;
42
+ /**
43
+ * Identidades de provider das contas — a ligação que o "Entrar com <provider>" usa.
44
+ * Para o host ligar uma conta a um provider fora do login social sem tocar no
45
+ * account store cru. Ver {@link ProviderIdentities}.
46
+ */
47
+ get identities(): ProviderIdentities;
41
48
  /** @internal Loader de JWKS do cofre (usado por reloadKeys). */
42
49
  get jwksLoader(): (() => Promise<{
43
50
  keys: Record<string, any>[];
@@ -2,6 +2,7 @@ import { createHmac, timingSafeEqual } from 'node:crypto';
2
2
  import { NoopRecorder } from '@adonis-agora/authkit-core';
3
3
  import Koa from 'koa';
4
4
  import mount from 'koa-mount';
5
+ import { ProviderIdentities } from '../accounts/provider_identities.js';
5
6
  import { normalizeActiveOrg, readActiveOrgFromKoaCtx, verifyActiveOrgMembership, } from '../host/active_org_cookie.js';
6
7
  import { isFirstPartyClient } from '../host/branding.js';
7
8
  import { listKeyInfos, signingKeyAgeDays, toPublicJwks, } from '../keys/keystore.js';
@@ -66,6 +67,16 @@ export class OidcService {
66
67
  get config() {
67
68
  return this.#config;
68
69
  }
70
+ #identities;
71
+ /**
72
+ * Identidades de provider das contas — a ligação que o "Entrar com <provider>" usa.
73
+ * Para o host ligar uma conta a um provider fora do login social sem tocar no
74
+ * account store cru. Ver {@link ProviderIdentities}.
75
+ */
76
+ get identities() {
77
+ this.#identities ??= new ProviderIdentities(() => this.#config.accountStore);
78
+ return this.#identities;
79
+ }
69
80
  /** @internal Loader de JWKS do cofre (usado por reloadKeys). */
70
81
  get jwksLoader() {
71
82
  return this.#deps.jwksLoader;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/authkit-server",
3
- "version": "0.89.0",
3
+ "version": "0.90.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",