@adonis-agora/authkit-server 1.0.0-rc.1 → 1.0.0-rc.11
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/CHANGELOG.md +107 -0
- package/README.md +4 -5
- package/build/commands/agora_doctor.d.ts +22 -0
- package/build/commands/agora_doctor.js +109 -0
- package/build/commands/clients_create.d.ts +4 -0
- package/build/commands/clients_create.js +97 -0
- package/build/commands/commands.json +78 -0
- package/build/commands/doctor.js +8 -74
- package/build/host/views/account/apps.edge +1 -5
- package/build/host/views/account/extension.edge +77 -0
- package/build/host/views/account/mfa.edge +2 -0
- package/build/host/views/account/partials/extension_actions.edge +14 -0
- package/build/host/views/account/partials/extension_block.edge +197 -0
- package/build/host/views/account/partials/extension_value.edge +8 -0
- package/build/host/views/account/partials/nav.edge +14 -0
- package/build/host/views/account/security.edge +1 -5
- package/build/host/views/account/tokens.edge +2 -2
- package/build/host/views/agents/consent.edge +11 -2
- package/build/host/views/agents/done.edge +1 -1
- package/build/host/views/partials/styles.edge +1 -1
- package/build/index.d.ts +12 -12
- package/build/index.js +7 -9
- package/build/providers/authkit_server_provider.js +29 -8
- package/build/src/account/extension.d.ts +10 -0
- package/build/src/account/extension.js +9 -0
- package/build/src/account/http.d.ts +77 -0
- package/build/src/account/http.js +381 -0
- package/build/src/account/mount.d.ts +40 -0
- package/build/src/account/mount.js +171 -0
- package/build/src/account/registry.d.ts +41 -0
- package/build/src/account/registry.js +81 -0
- package/build/src/account/remote.d.ts +72 -0
- package/build/src/account/remote.js +406 -0
- package/build/src/account/runtime.d.ts +289 -0
- package/build/src/account/runtime.js +641 -0
- package/build/src/accounts/account_store.d.ts +13 -7
- package/build/src/accounts/lucid_account_store.d.ts +3 -3
- package/build/src/accounts/lucid_account_store.js +42 -17
- package/build/src/accounts/lucid_store/mfa.js +3 -3
- package/build/src/accounts/lucid_store/organization_models.d.ts +14 -3
- package/build/src/accounts/lucid_store/organization_models.js +31 -3
- package/build/src/accounts/lucid_store/organizations.d.ts +2 -2
- package/build/src/accounts/lucid_store/organizations.js +40 -31
- package/build/src/accounts/lucid_store/shared.d.ts +11 -3
- package/build/src/accounts/lucid_store/shared.js +7 -5
- package/build/src/accounts/lucid_store/webauthn.js +1 -1
- package/build/src/adapters/factory.d.ts +13 -2
- package/build/src/adapters/factory.js +2 -2
- package/build/src/agents/config.d.ts +9 -13
- package/build/src/agents/config.js +17 -11
- package/build/src/agents/delegation_service.js +3 -3
- package/build/src/agents/delegation_store.d.ts +3 -2
- package/build/src/agents/delegation_store.js +6 -5
- package/build/src/agents/extension.d.ts +261 -0
- package/build/src/agents/extension.js +40 -0
- package/build/src/agents/middleware.js +1 -1
- package/build/src/agents/protocol.d.ts +4 -4
- package/build/src/agents/registry_store.d.ts +3 -2
- package/build/src/agents/registry_store.js +1 -1
- package/build/src/agents/runtime.d.ts +26 -7
- package/build/src/agents/runtime.js +110 -75
- package/build/src/audit/audit_sink.d.ts +1 -1
- package/build/src/audit/audit_sink.js +10 -1
- package/build/src/commands/expire_scan_command.js +1 -1
- package/build/src/commands/settings_commands.js +2 -2
- package/build/src/console_switcher.d.ts +132 -0
- package/build/src/console_switcher.js +206 -0
- package/build/src/define_config.d.ts +38 -13
- package/build/src/define_config.js +32 -10
- package/build/src/dev_tools/contract.d.ts +72 -0
- package/build/src/dev_tools/contract.js +10 -0
- package/build/src/dev_tools/gate.d.ts +17 -0
- package/build/src/dev_tools/gate.js +69 -0
- package/build/src/dev_tools/register.d.ts +11 -0
- package/build/src/dev_tools/register.js +25 -0
- package/build/src/dev_tools/tools.d.ts +24 -0
- package/build/src/dev_tools/tools.js +384 -0
- package/build/src/doctor/agora_checks.d.ts +15 -0
- package/build/src/doctor/agora_checks.js +150 -0
- package/build/src/doctor/agora_doctor.d.ts +115 -0
- package/build/src/doctor/agora_doctor.js +692 -0
- package/build/src/doctor/checks.js +2 -2
- package/build/src/doctor/doctor_input.d.ts +27 -0
- package/build/src/doctor/doctor_input.js +86 -0
- package/build/src/doctor/index.d.ts +5 -0
- package/build/src/doctor/index.js +4 -0
- package/build/src/host/access_token_verifier.js +7 -0
- package/build/src/host/account_api/account_api_controller.js +8 -6
- package/build/src/host/account_session_sign_in.d.ts +12 -0
- package/build/src/host/account_session_sign_in.js +19 -0
- package/build/src/host/admin_api/admin_users_service.d.ts +5 -2
- package/build/src/host/admin_api/api_clients_controller.d.ts +37 -0
- package/build/src/host/admin_api/api_clients_controller.js +31 -1
- package/build/src/host/admin_api/dto.d.ts +3 -1
- package/build/src/host/admin_api/dto.js +2 -0
- package/build/src/host/admin_authorize.d.ts +8 -0
- package/build/src/host/admin_authorize.js +25 -0
- package/build/src/host/admin_clients_service.d.ts +20 -0
- package/build/src/host/admin_clients_service.js +55 -0
- package/build/src/host/admin_console/admin_console_entry.d.ts +14 -0
- package/build/src/host/admin_console/admin_console_entry.js +80 -0
- package/build/src/host/admin_console/admin_shell_controller.js +8 -0
- package/build/src/host/admin_console/console_clients_controller.d.ts +41 -0
- package/build/src/host/admin_console/console_clients_controller.js +34 -1
- package/build/src/host/admin_console/console_personal_agents_controller.d.ts +1 -6
- package/build/src/host/admin_console/console_personal_agents_controller.js +50 -30
- package/build/src/host/admin_console/console_switcher_controller.d.ts +11 -0
- package/build/src/host/admin_console/console_switcher_controller.js +23 -0
- package/build/src/host/admin_sessions_service.js +8 -5
- package/build/src/host/admin_validators.d.ts +29 -0
- package/build/src/host/admin_validators.js +30 -0
- package/build/src/host/auth_host_config.d.ts +9 -2
- package/build/src/host/controllers/account_apps_controller.js +15 -11
- package/build/src/host/csrf.d.ts +3 -3
- package/build/src/host/csrf.js +3 -13
- package/build/src/host/default_mailer.d.ts +11 -6
- package/build/src/host/default_mailer.js +16 -12
- package/build/src/host/i18n.d.ts +41 -14
- package/build/src/host/i18n.js +55 -13
- package/build/src/host/rate_limit.d.ts +8 -0
- package/build/src/host/rate_limit.js +9 -0
- package/build/src/host/register_auth_host.d.ts +14 -0
- package/build/src/host/register_auth_host.js +167 -106
- package/build/src/host/renderers/edge_renderer.js +5 -0
- package/build/src/host/renderers/inertia_renderer.js +7 -1
- package/build/src/host/runtime_settings.d.ts +6 -6
- package/build/src/host/runtime_settings.js +4 -3
- package/build/src/host/screen_props.d.ts +39 -8
- package/build/src/host/ui-dist/assets/index-Dq3dJVBv.js +67 -0
- package/build/src/host/ui-dist/assets/{index-DTSmD4RU.css → index-WNIyCEPA.css} +1 -1
- package/build/src/host/ui-dist/index.html +2 -2
- package/build/src/provider/build_provider.js +37 -6
- package/build/src/provider/oidc_service.d.ts +1 -1
- package/build/src/provider/oidc_service.js +1 -1
- package/build/src/schema/ensure.d.ts +24 -1
- package/build/src/schema/ensure.js +44 -154
- package/build/src/schema/tables_location.d.ts +27 -0
- package/build/src/schema/tables_location.js +22 -0
- package/build/src/service_tenants/client_metadata.d.ts +39 -0
- package/build/src/service_tenants/client_metadata.js +80 -0
- package/build/src/service_tenants/config.d.ts +44 -0
- package/build/src/service_tenants/config.js +44 -0
- package/build/src/service_tenants/provider_hooks.d.ts +52 -0
- package/build/src/service_tenants/provider_hooks.js +124 -0
- package/build/src/service_tenants/tenant_verifier.d.ts +73 -0
- package/build/src/service_tenants/tenant_verifier.js +104 -0
- package/build/src/tenancy/tenant_labels.d.ts +30 -0
- package/build/src/tenancy/tenant_labels.js +64 -0
- package/build/types.d.ts +3 -1
- package/package.json +9 -6
- package/build/src/agents/poppy/client_registry.d.ts +0 -50
- package/build/src/agents/poppy/client_registry.js +0 -260
- package/build/src/agents/poppy/config.d.ts +0 -396
- package/build/src/agents/poppy/config.js +0 -228
- package/build/src/agents/poppy/dpop.d.ts +0 -61
- package/build/src/agents/poppy/dpop.js +0 -158
- package/build/src/agents/poppy/email_code_sign_in.d.ts +0 -27
- package/build/src/agents/poppy/email_code_sign_in.js +0 -140
- package/build/src/agents/poppy/errors.d.ts +0 -25
- package/build/src/agents/poppy/errors.js +0 -25
- package/build/src/agents/poppy/replay.d.ts +0 -25
- package/build/src/agents/poppy/replay.js +0 -106
- package/build/src/agents/poppy/resource.d.ts +0 -100
- package/build/src/agents/poppy/resource.js +0 -129
- package/build/src/agents/poppy/safe_fetch.d.ts +0 -48
- package/build/src/agents/poppy/safe_fetch.js +0 -262
- package/build/src/agents/poppy/service.d.ts +0 -293
- package/build/src/agents/poppy/service.js +0 -1458
- package/build/src/agents/poppy/session_jwt.d.ts +0 -30
- package/build/src/agents/poppy/session_jwt.js +0 -133
- package/build/src/agents/poppy/store.d.ts +0 -106
- package/build/src/agents/poppy/store.js +0 -261
- package/build/src/agents/poppy/web_session.d.ts +0 -39
- package/build/src/agents/poppy/web_session.js +0 -122
- package/build/src/host/controllers/poppy_consent_controller.d.ts +0 -19
- package/build/src/host/controllers/poppy_consent_controller.js +0 -199
- package/build/src/host/controllers/poppy_controller.d.ts +0 -33
- package/build/src/host/controllers/poppy_controller.js +0 -219
- package/build/src/host/poppy_session_key.d.ts +0 -9
- package/build/src/host/poppy_session_key.js +0 -9
- package/build/src/host/ui-dist/assets/index-D0EIeyKK.js +0 -67
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { PasswordManager } from '../password/password_manager.js';
|
|
2
|
+
import { authkitTablesClient, BIND_TABLES_LOCATION, } from '../schema/tables_location.js';
|
|
2
3
|
import { buildCore } from './lucid_store/core.js';
|
|
3
4
|
import { buildLoginMethods, supportsLoginMethodsColumn } from './lucid_store/login_methods.js';
|
|
4
5
|
import { buildMfa } from './lucid_store/mfa.js';
|
|
5
|
-
import { defaultOrganizationModels } from './lucid_store/organization_models.js';
|
|
6
|
+
import { defaultOrganizationModels, organizationModelsOn, } from './lucid_store/organization_models.js';
|
|
6
7
|
import { buildOrganizations } from './lucid_store/organizations.js';
|
|
7
8
|
import { buildPasswordExpiration, buildPasswordHistory } from './lucid_store/password_hygiene.js';
|
|
8
9
|
import { buildProviderIdentity } from './lucid_store/provider_identity.js';
|
|
@@ -162,11 +163,23 @@ export function lucidAccountStore(Model, options = {}) {
|
|
|
162
163
|
// opt-out explícito é `false`. O trio explícito segue como escape hatch.
|
|
163
164
|
const orgModelsOption = options.organizationModels;
|
|
164
165
|
const usesDefaultOrgModels = orgModelsOption === undefined || orgModelsOption === true;
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
const explicitOrgModels = orgModelsOption === false || usesDefaultOrgModels ? undefined : orgModelsOption;
|
|
167
|
+
/**
|
|
168
|
+
* Onde vivem as tabelas do AuthKit (`schema.connection`). O `defineConfig` informa
|
|
169
|
+
* via {@link BIND_TABLES_LOCATION} — o store é construído antes de o config existir.
|
|
170
|
+
* `null` = ainda não informado (store usado fora do `defineConfig`): as tabelas
|
|
171
|
+
* lib-owned seguem a conexão do model e os models de org default, a primária.
|
|
172
|
+
*/
|
|
173
|
+
let tablesLocation = null;
|
|
174
|
+
const tablesClient = () => {
|
|
175
|
+
const db = Model.$adapter?.db;
|
|
176
|
+
if (!tablesLocation || !db)
|
|
177
|
+
return Model.query().client;
|
|
178
|
+
return authkitTablesClient(db, tablesLocation);
|
|
179
|
+
};
|
|
180
|
+
const orgModels = () => explicitOrgModels ??
|
|
181
|
+
(tablesLocation ? organizationModelsOn(tablesLocation.connection) : defaultOrganizationModels);
|
|
182
|
+
const OrgModels = orgModelsOption === false ? undefined : orgModels;
|
|
170
183
|
// RP do WebAuthn: usado nas cerimônias. Default do rpName cai no mfaIssuer.
|
|
171
184
|
const webauthn = options.webauthn ?? {
|
|
172
185
|
rpName: mfaIssuer,
|
|
@@ -190,6 +203,7 @@ export function lucidAccountStore(Model, options = {}) {
|
|
|
190
203
|
audit: options.audit,
|
|
191
204
|
emailVerificationTtlHours: emailTokens.verificationTtlHours,
|
|
192
205
|
emailChangeTtlHours: emailTokens.changeTtlHours,
|
|
206
|
+
tablesClient,
|
|
193
207
|
// Encripta o segredo antes de persistir (no-op sem encrypter).
|
|
194
208
|
sealSecret: (secret) => (encrypter ? encrypter.encrypt(secret) : secret),
|
|
195
209
|
// Decripta o segredo armazenado; retorna null em falha/adulteração (no-op sem encrypter).
|
|
@@ -264,9 +278,15 @@ export function lucidAccountStore(Model, options = {}) {
|
|
|
264
278
|
// NÃO faz parte do contrato AccountStore.
|
|
265
279
|
__organizationModelsSource: usesDefaultOrgModels ? 'default' : 'explicit',
|
|
266
280
|
...buildOrganizations({
|
|
267
|
-
OrgModel
|
|
268
|
-
|
|
269
|
-
|
|
281
|
+
get OrgModel() {
|
|
282
|
+
return OrgModels().OrgModel;
|
|
283
|
+
},
|
|
284
|
+
get MemberModel() {
|
|
285
|
+
return OrgModels().MemberModel;
|
|
286
|
+
},
|
|
287
|
+
get InvitationModel() {
|
|
288
|
+
return OrgModels().InvitationModel;
|
|
289
|
+
},
|
|
270
290
|
findAccountEmail: async (accountId) => {
|
|
271
291
|
const row = await Model.find(accountId);
|
|
272
292
|
return row?.email ?? null;
|
|
@@ -292,11 +312,10 @@ export function lucidAccountStore(Model, options = {}) {
|
|
|
292
312
|
}
|
|
293
313
|
},
|
|
294
314
|
/**
|
|
295
|
-
* Nome da conexão Lucid
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
* Undefined quando o model usa a conexão default
|
|
299
|
-
* NÃO faz parte do contrato AccountStore.
|
|
315
|
+
* Nome da conexão Lucid do MODEL da conta (deriva de `Model.connection`) — onde
|
|
316
|
+
* vive a tabela da conta (e a coluna `login_methods`). As tabelas do authkit
|
|
317
|
+
* NÃO seguem esta conexão: elas usam `schema.connection`.
|
|
318
|
+
* Undefined quando o model usa a conexão default.
|
|
300
319
|
*/
|
|
301
320
|
connectionName: Model.connection ?? undefined,
|
|
302
321
|
/**
|
|
@@ -318,10 +337,16 @@ export function lucidAccountStore(Model, options = {}) {
|
|
|
318
337
|
__model: Model,
|
|
319
338
|
};
|
|
320
339
|
// Histórico de senhas: tabela lib-owned `auth_password_history`, pela conexão
|
|
321
|
-
// do
|
|
340
|
+
// das tabelas do authkit (resolvida a cada uso, como no MFA).
|
|
322
341
|
Object.assign(store, buildPasswordHistory(ctx, {
|
|
323
|
-
query: () =>
|
|
324
|
-
table: (name) =>
|
|
342
|
+
query: () => tablesClient().query(),
|
|
343
|
+
table: (name) => tablesClient().table(name),
|
|
325
344
|
}));
|
|
345
|
+
// Não-enumerável: o `defineConfig` informa `schema.connection` por aqui.
|
|
346
|
+
Object.defineProperty(store, BIND_TABLES_LOCATION, {
|
|
347
|
+
value: (location) => {
|
|
348
|
+
tablesLocation = { connection: location.connection };
|
|
349
|
+
},
|
|
350
|
+
});
|
|
326
351
|
return store;
|
|
327
352
|
}
|
|
@@ -8,8 +8,8 @@ import { buildMfaStateRepo, generateRecoveryCode, hashesEqual, sha256, } from '.
|
|
|
8
8
|
* {@link ensureAuthkitSchema}), keyed por `account_id`. O host NÃO precisa migrar
|
|
9
9
|
* nada e o model não declara colunas de MFA.
|
|
10
10
|
*
|
|
11
|
-
* Acesso ao banco
|
|
12
|
-
*
|
|
11
|
+
* Acesso ao banco pela conexão das tabelas do authkit (`schema.connection`), a
|
|
12
|
+
* mesma em que o `autoManage` cria `auth_mfa`. O `email` (para o keyuri/QR) continua vindo do
|
|
13
13
|
* model principal — só o ESTADO de MFA migrou para `auth_mfa`.
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
@@ -19,7 +19,7 @@ import { buildMfaStateRepo, generateRecoveryCode, hashesEqual, sha256, } from '.
|
|
|
19
19
|
const TOTP_PERIOD = 30;
|
|
20
20
|
export function buildMfa(ctx) {
|
|
21
21
|
const { Model, mfaIssuer, recoveryCodeCount, sealSecret, openSecret } = ctx;
|
|
22
|
-
const repo = buildMfaStateRepo(Model);
|
|
22
|
+
const repo = buildMfaStateRepo(Model, ctx.tablesClient);
|
|
23
23
|
return {
|
|
24
24
|
async getMfaState(accountId) {
|
|
25
25
|
const state = await repo.read(accountId);
|
|
@@ -10,10 +10,11 @@ import type { DateTime } from 'luxon';
|
|
|
10
10
|
* pelo `autoManage` sem que o model escrito à mão no host saiba dela, e o
|
|
11
11
|
* sintoma aparece longe da causa.
|
|
12
12
|
*
|
|
13
|
-
* Use com `organizationModels: true` em {@link lucidAccountStore}.
|
|
13
|
+
* Use com `organizationModels: true` em {@link lucidAccountStore}. Eles seguem a
|
|
14
|
+
* conexão das tabelas do authkit (`schema.connection` do `defineConfig`, como
|
|
15
|
+
* todas as tabelas lib-owned — ver {@link organizationModelsOn}). O caminho
|
|
14
16
|
* explícito (`{ OrgModel, MemberModel, InvitationModel }`) continua valendo como
|
|
15
|
-
* escape hatch
|
|
16
|
-
* próprios (`static connection = 'auth'`), que estes defaults não declaram.
|
|
17
|
+
* escape hatch; aí a conexão é a que os models do host declaram.
|
|
17
18
|
*
|
|
18
19
|
* Não crie migration para estas tabelas: elas são criadas/atualizadas pelo
|
|
19
20
|
* `schema.autoManage` do authkit.
|
|
@@ -65,3 +66,13 @@ export declare const defaultOrganizationModels: {
|
|
|
65
66
|
readonly MemberModel: typeof AuthOrganizationMember;
|
|
66
67
|
readonly InvitationModel: typeof AuthOrganizationInvitation;
|
|
67
68
|
};
|
|
69
|
+
export type OrganizationModels = {
|
|
70
|
+
OrgModel: any;
|
|
71
|
+
MemberModel: any;
|
|
72
|
+
InvitationModel: any;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Os models default numa conexão Lucid nomeada (subclasses com `static connection`),
|
|
76
|
+
* memoizados por conexão. `undefined` → os próprios defaults (conexão primária).
|
|
77
|
+
*/
|
|
78
|
+
export declare function organizationModelsOn(connection: string | undefined): OrganizationModels;
|
|
@@ -15,10 +15,11 @@ import { BaseModel, column } from '@adonisjs/lucid/orm';
|
|
|
15
15
|
* pelo `autoManage` sem que o model escrito à mão no host saiba dela, e o
|
|
16
16
|
* sintoma aparece longe da causa.
|
|
17
17
|
*
|
|
18
|
-
* Use com `organizationModels: true` em {@link lucidAccountStore}.
|
|
18
|
+
* Use com `organizationModels: true` em {@link lucidAccountStore}. Eles seguem a
|
|
19
|
+
* conexão das tabelas do authkit (`schema.connection` do `defineConfig`, como
|
|
20
|
+
* todas as tabelas lib-owned — ver {@link organizationModelsOn}). O caminho
|
|
19
21
|
* explícito (`{ OrgModel, MemberModel, InvitationModel }`) continua valendo como
|
|
20
|
-
* escape hatch
|
|
21
|
-
* próprios (`static connection = 'auth'`), que estes defaults não declaram.
|
|
22
|
+
* escape hatch; aí a conexão é a que os models do host declaram.
|
|
22
23
|
*
|
|
23
24
|
* Não crie migration para estas tabelas: elas são criadas/atualizadas pelo
|
|
24
25
|
* `schema.autoManage` do authkit.
|
|
@@ -111,3 +112,30 @@ export const defaultOrganizationModels = {
|
|
|
111
112
|
MemberModel: AuthOrganizationMember,
|
|
112
113
|
InvitationModel: AuthOrganizationInvitation,
|
|
113
114
|
};
|
|
115
|
+
const modelsByConnection = new Map();
|
|
116
|
+
/**
|
|
117
|
+
* Os models default numa conexão Lucid nomeada (subclasses com `static connection`),
|
|
118
|
+
* memoizados por conexão. `undefined` → os próprios defaults (conexão primária).
|
|
119
|
+
*/
|
|
120
|
+
export function organizationModelsOn(connection) {
|
|
121
|
+
if (!connection)
|
|
122
|
+
return defaultOrganizationModels;
|
|
123
|
+
let models = modelsByConnection.get(connection);
|
|
124
|
+
if (!models) {
|
|
125
|
+
class OrgModel extends AuthOrganization {
|
|
126
|
+
static table = 'auth_organizations';
|
|
127
|
+
static connection = connection;
|
|
128
|
+
}
|
|
129
|
+
class MemberModel extends AuthOrganizationMember {
|
|
130
|
+
static table = 'auth_organization_members';
|
|
131
|
+
static connection = connection;
|
|
132
|
+
}
|
|
133
|
+
class InvitationModel extends AuthOrganizationInvitation {
|
|
134
|
+
static table = 'auth_organization_invitations';
|
|
135
|
+
static connection = connection;
|
|
136
|
+
}
|
|
137
|
+
models = { OrgModel, MemberModel, InvitationModel };
|
|
138
|
+
modelsByConnection.set(connection, models);
|
|
139
|
+
}
|
|
140
|
+
return models;
|
|
141
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { OrganizationsCapability } from '../account_store.js';
|
|
2
2
|
/**
|
|
3
|
-
* Contexto mínimo para o builder de organizations.
|
|
4
|
-
* (
|
|
3
|
+
* Contexto mínimo para o builder de organizations. Os três models são lidos a cada
|
|
4
|
+
* uso (podem ser getters — ver `lucidAccountStore`).
|
|
5
5
|
*/
|
|
6
6
|
export interface OrgStoreContext {
|
|
7
7
|
OrgModel: any;
|
|
@@ -59,7 +59,10 @@ async function countOwners(MemberModel, orgId) {
|
|
|
59
59
|
return Number(result[0]?.$extras?.total ?? 0);
|
|
60
60
|
}
|
|
61
61
|
export function buildOrganizations(ctx) {
|
|
62
|
-
|
|
62
|
+
// Os models são lidos do ctx a CADA uso (não desestruturados): o `lucidAccountStore`
|
|
63
|
+
// troca os models default pelos da conexão das tabelas do authkit quando o
|
|
64
|
+
// `defineConfig` informa o `schema.connection`, depois de construir o store.
|
|
65
|
+
const { findAccountEmail, listAccountIdsInAdminOrder } = ctx;
|
|
63
66
|
return {
|
|
64
67
|
...(listAccountIdsInAdminOrder
|
|
65
68
|
? {
|
|
@@ -73,7 +76,7 @@ export function buildOrganizations(ctx) {
|
|
|
73
76
|
* (like `listOrgMembers(orgId).length`).
|
|
74
77
|
*/
|
|
75
78
|
async listAllOrgsWithMemberCount() {
|
|
76
|
-
const memberships = await MemberModel.query();
|
|
79
|
+
const memberships = await ctx.MemberModel.query();
|
|
77
80
|
if (memberships.length === 0)
|
|
78
81
|
return [];
|
|
79
82
|
const byAccount = new Map();
|
|
@@ -90,7 +93,7 @@ export function buildOrganizations(ctx) {
|
|
|
90
93
|
}
|
|
91
94
|
const accountIds = await listAccountIdsInAdminOrder([...byAccount.keys()]);
|
|
92
95
|
const orgs = new Map();
|
|
93
|
-
for (const org of await findManyChunked(OrgModel, [...memberCount.keys()])) {
|
|
96
|
+
for (const org of await findManyChunked(ctx.OrgModel, [...memberCount.keys()])) {
|
|
94
97
|
orgs.set(String(org.id), org);
|
|
95
98
|
}
|
|
96
99
|
const result = [];
|
|
@@ -117,7 +120,7 @@ export function buildOrganizations(ctx) {
|
|
|
117
120
|
: {}),
|
|
118
121
|
async createOrg(input) {
|
|
119
122
|
const { randomUUID } = await import('node:crypto');
|
|
120
|
-
const org = await OrgModel.create({
|
|
123
|
+
const org = await ctx.OrgModel.create({
|
|
121
124
|
id: randomUUID(),
|
|
122
125
|
name: input.name,
|
|
123
126
|
slug: input.slug,
|
|
@@ -125,7 +128,7 @@ export function buildOrganizations(ctx) {
|
|
|
125
128
|
metadata: input.metadata ?? null,
|
|
126
129
|
});
|
|
127
130
|
// Cria a membership do owner automaticamente
|
|
128
|
-
await MemberModel.create({
|
|
131
|
+
await ctx.MemberModel.create({
|
|
129
132
|
id: randomUUID(),
|
|
130
133
|
organizationId: org.id,
|
|
131
134
|
accountId: input.ownerAccountId,
|
|
@@ -134,22 +137,28 @@ export function buildOrganizations(ctx) {
|
|
|
134
137
|
return toOrgSummary(org);
|
|
135
138
|
},
|
|
136
139
|
async findOrgById(orgId) {
|
|
137
|
-
const row = await OrgModel.find(orgId);
|
|
140
|
+
const row = await ctx.OrgModel.find(orgId);
|
|
138
141
|
return row ? toOrgSummary(row) : null;
|
|
139
142
|
},
|
|
143
|
+
async findOrgsByIds(orgIds) {
|
|
144
|
+
const ids = [...new Set(orgIds)];
|
|
145
|
+
if (ids.length === 0)
|
|
146
|
+
return [];
|
|
147
|
+
return (await findManyChunked(ctx.OrgModel, ids)).map(toOrgSummary);
|
|
148
|
+
},
|
|
140
149
|
async findOrgBySlug(slug) {
|
|
141
|
-
const row = await OrgModel.query().where('slug', slug).first();
|
|
150
|
+
const row = await ctx.OrgModel.query().where('slug', slug).first();
|
|
142
151
|
return row ? toOrgSummary(row) : null;
|
|
143
152
|
},
|
|
144
153
|
async listOrgsForAccount(accountId) {
|
|
145
|
-
const memberships = await MemberModel.query().where('account_id', accountId);
|
|
154
|
+
const memberships = await ctx.MemberModel.query().where('account_id', accountId);
|
|
146
155
|
if (memberships.length === 0)
|
|
147
156
|
return [];
|
|
148
157
|
// One query for every org (by primary key, like `find`), instead of one per
|
|
149
158
|
// membership. The result keeps the memberships' order.
|
|
150
159
|
const ids = [...new Set(memberships.map((m) => m.organizationId))];
|
|
151
160
|
const orgs = new Map();
|
|
152
|
-
for (const org of await OrgModel.findMany(ids))
|
|
161
|
+
for (const org of await ctx.OrgModel.findMany(ids))
|
|
153
162
|
orgs.set(String(org.id), org);
|
|
154
163
|
const result = [];
|
|
155
164
|
for (const m of memberships) {
|
|
@@ -160,7 +169,7 @@ export function buildOrganizations(ctx) {
|
|
|
160
169
|
return result;
|
|
161
170
|
},
|
|
162
171
|
async updateOrg(orgId, patch) {
|
|
163
|
-
const row = await OrgModel.find(orgId);
|
|
172
|
+
const row = await ctx.OrgModel.find(orgId);
|
|
164
173
|
if (!row)
|
|
165
174
|
return null;
|
|
166
175
|
if (patch.name !== undefined)
|
|
@@ -173,16 +182,16 @@ export function buildOrganizations(ctx) {
|
|
|
173
182
|
return toOrgSummary(row);
|
|
174
183
|
},
|
|
175
184
|
async deleteOrg(orgId) {
|
|
176
|
-
const row = await OrgModel.find(orgId);
|
|
185
|
+
const row = await ctx.OrgModel.find(orgId);
|
|
177
186
|
if (!row)
|
|
178
187
|
return false;
|
|
179
|
-
await MemberModel.query().where('organization_id', orgId).delete();
|
|
180
|
-
await InvitationModel.query().where('organization_id', orgId).delete();
|
|
188
|
+
await ctx.MemberModel.query().where('organization_id', orgId).delete();
|
|
189
|
+
await ctx.InvitationModel.query().where('organization_id', orgId).delete();
|
|
181
190
|
await row.delete();
|
|
182
191
|
return true;
|
|
183
192
|
},
|
|
184
193
|
async listOrgMembers(orgId) {
|
|
185
|
-
const rows = await MemberModel.query().where('organization_id', orgId);
|
|
194
|
+
const rows = await ctx.MemberModel.query().where('organization_id', orgId);
|
|
186
195
|
return rows.map((r) => ({
|
|
187
196
|
accountId: r.accountId,
|
|
188
197
|
email: null, // o caller enriquece com findById se necessário
|
|
@@ -193,7 +202,7 @@ export function buildOrganizations(ctx) {
|
|
|
193
202
|
async addOrgMember(orgId, accountId, role) {
|
|
194
203
|
const { randomUUID } = await import('node:crypto');
|
|
195
204
|
// Upsert: se já existe, atualiza a role
|
|
196
|
-
const existing = await MemberModel.query()
|
|
205
|
+
const existing = await ctx.MemberModel.query()
|
|
197
206
|
.where('organization_id', orgId)
|
|
198
207
|
.where('account_id', accountId)
|
|
199
208
|
.first();
|
|
@@ -202,11 +211,11 @@ export function buildOrganizations(ctx) {
|
|
|
202
211
|
await existing.save();
|
|
203
212
|
}
|
|
204
213
|
else {
|
|
205
|
-
await MemberModel.create({ id: randomUUID(), organizationId: orgId, accountId, role });
|
|
214
|
+
await ctx.MemberModel.create({ id: randomUUID(), organizationId: orgId, accountId, role });
|
|
206
215
|
}
|
|
207
216
|
},
|
|
208
217
|
async removeOrgMember(orgId, accountId) {
|
|
209
|
-
const row = await MemberModel.query()
|
|
218
|
+
const row = await ctx.MemberModel.query()
|
|
210
219
|
.where('organization_id', orgId)
|
|
211
220
|
.where('account_id', accountId)
|
|
212
221
|
.first();
|
|
@@ -214,7 +223,7 @@ export function buildOrganizations(ctx) {
|
|
|
214
223
|
return { ok: false, reason: 'not_found' };
|
|
215
224
|
// Invariante: org deve ter sempre >= 1 owner
|
|
216
225
|
if (row.role === 'owner') {
|
|
217
|
-
const ownerCount = await countOwners(MemberModel, orgId);
|
|
226
|
+
const ownerCount = await countOwners(ctx.MemberModel, orgId);
|
|
218
227
|
if (ownerCount <= 1)
|
|
219
228
|
return { ok: false, reason: 'last_owner' };
|
|
220
229
|
}
|
|
@@ -222,7 +231,7 @@ export function buildOrganizations(ctx) {
|
|
|
222
231
|
return { ok: true };
|
|
223
232
|
},
|
|
224
233
|
async updateOrgMemberRole(orgId, accountId, newRole) {
|
|
225
|
-
const row = await MemberModel.query()
|
|
234
|
+
const row = await ctx.MemberModel.query()
|
|
226
235
|
.where('organization_id', orgId)
|
|
227
236
|
.where('account_id', accountId)
|
|
228
237
|
.first();
|
|
@@ -230,7 +239,7 @@ export function buildOrganizations(ctx) {
|
|
|
230
239
|
return { ok: false, reason: 'not_found' };
|
|
231
240
|
// Invariante: não rebaixa o último owner
|
|
232
241
|
if (row.role === 'owner' && newRole !== 'owner') {
|
|
233
|
-
const ownerCount = await countOwners(MemberModel, orgId);
|
|
242
|
+
const ownerCount = await countOwners(ctx.MemberModel, orgId);
|
|
234
243
|
if (ownerCount <= 1)
|
|
235
244
|
return { ok: false, reason: 'last_owner' };
|
|
236
245
|
}
|
|
@@ -239,7 +248,7 @@ export function buildOrganizations(ctx) {
|
|
|
239
248
|
return { ok: true };
|
|
240
249
|
},
|
|
241
250
|
async getOrgMembership(orgId, accountId) {
|
|
242
|
-
const row = await MemberModel.query()
|
|
251
|
+
const row = await ctx.MemberModel.query()
|
|
243
252
|
.where('organization_id', orgId)
|
|
244
253
|
.where('account_id', accountId)
|
|
245
254
|
.first();
|
|
@@ -250,7 +259,7 @@ export function buildOrganizations(ctx) {
|
|
|
250
259
|
const token = randomBytes(32).toString('hex');
|
|
251
260
|
const tokenHash = createHash('sha256').update(token).digest('hex');
|
|
252
261
|
const expiresAt = DateTime.now().plus({ hours: input.ttlHours });
|
|
253
|
-
const inv = await InvitationModel.create({
|
|
262
|
+
const inv = await ctx.InvitationModel.create({
|
|
254
263
|
id: randomUUID(),
|
|
255
264
|
organizationId: input.organizationId,
|
|
256
265
|
email: input.email,
|
|
@@ -263,21 +272,21 @@ export function buildOrganizations(ctx) {
|
|
|
263
272
|
return { invitation: toOrgInvitation(inv), token };
|
|
264
273
|
},
|
|
265
274
|
async findInvitationByTokenHash(tokenHash) {
|
|
266
|
-
const row = await InvitationModel.query().where('token_hash', tokenHash).first();
|
|
275
|
+
const row = await ctx.InvitationModel.query().where('token_hash', tokenHash).first();
|
|
267
276
|
return row ? toOrgInvitation(row) : null;
|
|
268
277
|
},
|
|
269
278
|
async listPendingInvitationsForOrg(orgId) {
|
|
270
|
-
const rows = await InvitationModel.query()
|
|
279
|
+
const rows = await ctx.InvitationModel.query()
|
|
271
280
|
.where('organization_id', orgId)
|
|
272
281
|
.whereNull('accepted_at');
|
|
273
282
|
return rows.map(toOrgInvitation);
|
|
274
283
|
},
|
|
275
284
|
async listPendingInvitationsForEmail(email) {
|
|
276
|
-
const rows = await InvitationModel.query().where('email', email).whereNull('accepted_at');
|
|
285
|
+
const rows = await ctx.InvitationModel.query().where('email', email).whereNull('accepted_at');
|
|
277
286
|
return rows.map(toOrgInvitation);
|
|
278
287
|
},
|
|
279
288
|
async acceptInvitation(invitationId, accountId) {
|
|
280
|
-
const inv = await InvitationModel.find(invitationId);
|
|
289
|
+
const inv = await ctx.InvitationModel.find(invitationId);
|
|
281
290
|
if (!inv)
|
|
282
291
|
return { ok: false, reason: 'not_found' };
|
|
283
292
|
// Verifica expiração (expiresAt pode ser DateTime Luxon, Date, ou string do SQLite)
|
|
@@ -305,7 +314,7 @@ export function buildOrganizations(ctx) {
|
|
|
305
314
|
return { ok: false, reason: 'email_mismatch' };
|
|
306
315
|
}
|
|
307
316
|
// Verifica se já é membro
|
|
308
|
-
const existing = await MemberModel.query()
|
|
317
|
+
const existing = await ctx.MemberModel.query()
|
|
309
318
|
.where('organization_id', inv.organizationId)
|
|
310
319
|
.where('account_id', accountId)
|
|
311
320
|
.first();
|
|
@@ -317,7 +326,7 @@ export function buildOrganizations(ctx) {
|
|
|
317
326
|
}
|
|
318
327
|
// Cria membership + marca accepted_at
|
|
319
328
|
const { randomUUID } = await import('node:crypto');
|
|
320
|
-
await MemberModel.create({
|
|
329
|
+
await ctx.MemberModel.create({
|
|
321
330
|
id: randomUUID(),
|
|
322
331
|
organizationId: inv.organizationId,
|
|
323
332
|
accountId,
|
|
@@ -331,7 +340,7 @@ export function buildOrganizations(ctx) {
|
|
|
331
340
|
// Escopado por org: exige que o convite pertença à org informada antes de
|
|
332
341
|
// deletar. Sem esse filtro, um owner/admin de qualquer org revogaria
|
|
333
342
|
// convites de outra org sabendo apenas o invitationId (IDOR cross-org).
|
|
334
|
-
const inv = await InvitationModel.query()
|
|
343
|
+
const inv = await ctx.InvitationModel.query()
|
|
335
344
|
.where('id', invitationId)
|
|
336
345
|
.where('organization_id', organizationId)
|
|
337
346
|
.first();
|
|
@@ -342,7 +351,7 @@ export function buildOrganizations(ctx) {
|
|
|
342
351
|
},
|
|
343
352
|
async removeAccountFromAllOrgs(accountId) {
|
|
344
353
|
// Memberships: remove todas, mesmo se for único owner (LGPD não pode bloquear)
|
|
345
|
-
const memberships = await MemberModel.query().where('account_id', accountId);
|
|
354
|
+
const memberships = await ctx.MemberModel.query().where('account_id', accountId);
|
|
346
355
|
for (const m of memberships) {
|
|
347
356
|
await m.delete();
|
|
348
357
|
}
|
|
@@ -350,7 +359,7 @@ export function buildOrganizations(ctx) {
|
|
|
350
359
|
const email = await findAccountEmail(accountId);
|
|
351
360
|
let invCount = 0;
|
|
352
361
|
if (email) {
|
|
353
|
-
const invitations = await InvitationModel.query()
|
|
362
|
+
const invitations = await ctx.InvitationModel.query()
|
|
354
363
|
.where('email', email)
|
|
355
364
|
.whereNull('accepted_at');
|
|
356
365
|
for (const inv of invitations) {
|
|
@@ -78,6 +78,12 @@ export interface LucidStoreContext {
|
|
|
78
78
|
* recovery da conta. Ver nota de `emailVerificationTtlHours`.
|
|
79
79
|
*/
|
|
80
80
|
emailChangeTtlHours?: number;
|
|
81
|
+
/**
|
|
82
|
+
* Query client for AuthKit's own tables (`auth_mfa`, `auth_password_history`):
|
|
83
|
+
* `schema.connection` of `defineConfig`, NOT the account model's connection. Absent
|
|
84
|
+
* → the model's connection (a store used without `defineConfig`).
|
|
85
|
+
*/
|
|
86
|
+
tablesClient?: () => any;
|
|
81
87
|
}
|
|
82
88
|
export declare const sha256: (value: string) => string;
|
|
83
89
|
/** Recovery code legível: 10 chars hex em duas metades (ex.: a1b2c-3d4e5). */
|
|
@@ -105,15 +111,17 @@ export interface MfaStatePatch {
|
|
|
105
111
|
}
|
|
106
112
|
/**
|
|
107
113
|
* Repositório do estado de MFA na tabela LIB-OWNED `auth_mfa`, keyed por
|
|
108
|
-
* `account_id`. Acessa o banco pela
|
|
109
|
-
*
|
|
114
|
+
* `account_id`. Acessa o banco pela conexão das tabelas do authkit
|
|
115
|
+
* (`schema.connection`, via `tablesClient`), a mesma em que o `autoManage` cria a
|
|
116
|
+
* tabela — sem exigir migration no host. Sem `tablesClient` (store fora do
|
|
117
|
+
* `defineConfig`), cai na conexão do model.
|
|
110
118
|
*
|
|
111
119
|
* O `upsert` é portável (sqlite + pg sem UPSERT nativo): tenta UPDATE pela PK;
|
|
112
120
|
* se não afetou nenhuma linha, faz INSERT. `recovery_codes` é serializado como
|
|
113
121
|
* JSON (string) na escrita e desserializado na leitura (aceita tanto string —
|
|
114
122
|
* sqlite/text — quanto array já parseado — pg jsonb).
|
|
115
123
|
*/
|
|
116
|
-
export declare function buildMfaStateRepo(Model: any): {
|
|
124
|
+
export declare function buildMfaStateRepo(Model: any, tablesClient?: () => any): {
|
|
117
125
|
/** Lê o estado de MFA da conta; null se não há linha em `auth_mfa`. */
|
|
118
126
|
read(accountId: string): Promise<MfaState | null>;
|
|
119
127
|
/**
|
|
@@ -39,19 +39,21 @@ export function hashesEqual(a, b) {
|
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Repositório do estado de MFA na tabela LIB-OWNED `auth_mfa`, keyed por
|
|
42
|
-
* `account_id`. Acessa o banco pela
|
|
43
|
-
*
|
|
42
|
+
* `account_id`. Acessa o banco pela conexão das tabelas do authkit
|
|
43
|
+
* (`schema.connection`, via `tablesClient`), a mesma em que o `autoManage` cria a
|
|
44
|
+
* tabela — sem exigir migration no host. Sem `tablesClient` (store fora do
|
|
45
|
+
* `defineConfig`), cai na conexão do model.
|
|
44
46
|
*
|
|
45
47
|
* O `upsert` é portável (sqlite + pg sem UPSERT nativo): tenta UPDATE pela PK;
|
|
46
48
|
* se não afetou nenhuma linha, faz INSERT. `recovery_codes` é serializado como
|
|
47
49
|
* JSON (string) na escrita e desserializado na leitura (aceita tanto string —
|
|
48
50
|
* sqlite/text — quanto array já parseado — pg jsonb).
|
|
49
51
|
*/
|
|
50
|
-
export function buildMfaStateRepo(Model) {
|
|
52
|
+
export function buildMfaStateRepo(Model, tablesClient) {
|
|
51
53
|
const TABLE = 'auth_mfa';
|
|
52
|
-
/** QueryClient
|
|
54
|
+
/** QueryClient das tabelas do authkit (equivale ao `db` do password_history). */
|
|
53
55
|
function client() {
|
|
54
|
-
return Model.query().client;
|
|
56
|
+
return tablesClient ? tablesClient() : Model.query().client;
|
|
55
57
|
}
|
|
56
58
|
/** Normaliza `recovery_codes` vindo do banco (json string OU array já parseado). */
|
|
57
59
|
function parseRecoveryCodes(raw) {
|
|
@@ -8,7 +8,7 @@ export function buildWebauthn(ctx, Credential, webauthn, ceremonies) {
|
|
|
8
8
|
const { Model } = ctx;
|
|
9
9
|
// Estado de MFA é LIB-OWNED (tabela `auth_mfa`): registrar uma passkey habilita
|
|
10
10
|
// o MFA gravando `mfa_enabled_at` em `auth_mfa`, não numa coluna do model.
|
|
11
|
-
const mfaState = buildMfaStateRepo(Model);
|
|
11
|
+
const mfaState = buildMfaStateRepo(Model, ctx.tablesClient);
|
|
12
12
|
return {
|
|
13
13
|
async generatePasskeyRegistrationOptions(accountId) {
|
|
14
14
|
const row = await Model.find(accountId);
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { ApplicationService } from '@adonisjs/core/types';
|
|
2
2
|
import type { OidcAdapter } from './adapter_contract.js';
|
|
3
3
|
export type OidcAdapterClass = new (name: string) => OidcAdapter;
|
|
4
|
+
/** What `defineConfig` hands every adapter factory. */
|
|
5
|
+
export interface AdapterResolveContext {
|
|
6
|
+
/**
|
|
7
|
+
* `schema.connection` of `defineConfig`: the Lucid connection AuthKit's tables live
|
|
8
|
+
* on. A database adapter without its own `connection` uses it.
|
|
9
|
+
*/
|
|
10
|
+
connection?: string;
|
|
11
|
+
}
|
|
4
12
|
export interface AdapterFactory {
|
|
5
|
-
resolver(app: ApplicationService): Promise<OidcAdapterClass>;
|
|
13
|
+
resolver(app: ApplicationService, context?: AdapterResolveContext): Promise<OidcAdapterClass>;
|
|
6
14
|
}
|
|
7
15
|
/**
|
|
8
16
|
* Modelos do oidc-provider de vida curta, amarrados ao ciclo da sessão de
|
|
@@ -35,7 +43,10 @@ export interface RedisAdapterConfig {
|
|
|
35
43
|
prefix?: string;
|
|
36
44
|
}
|
|
37
45
|
export interface DatabaseAdapterConfig {
|
|
38
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Nome da conexão Lucid. Default: `schema.connection` do `defineConfig` (a conexão
|
|
48
|
+
* de todas as tabelas do authkit), e sem ela a primária.
|
|
49
|
+
*/
|
|
39
50
|
connection?: string;
|
|
40
51
|
}
|
|
41
52
|
export declare const adapters: {
|
|
@@ -67,9 +67,9 @@ export const adapters = {
|
|
|
67
67
|
*/
|
|
68
68
|
database(config = {}) {
|
|
69
69
|
return {
|
|
70
|
-
async resolver(app) {
|
|
70
|
+
async resolver(app, context) {
|
|
71
71
|
const db = await app.container.make('lucid.db');
|
|
72
|
-
const connection = config.connection;
|
|
72
|
+
const connection = config.connection ?? context?.connection;
|
|
73
73
|
const conn = connection ? db.connection(connection) : db;
|
|
74
74
|
return class extends DatabaseAdapter {
|
|
75
75
|
constructor(name) {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* recibos) não depende de protocolo; o formato do fio vem do adapter em
|
|
13
13
|
* `protocol` (default: PACT — https://openpactprotocol.org). Ver `protocol.ts`.
|
|
14
14
|
*/
|
|
15
|
-
import { type
|
|
15
|
+
import { type PersonalAgentExtension, type ResolvedPersonalAgentExtension } from './extension.js';
|
|
16
16
|
import { type BuiltinProtocolId, type PersonalAgentProtocol } from './protocol.js';
|
|
17
17
|
/** Registro de um personal agent conhecido (PACT §3.1). */
|
|
18
18
|
export interface PersonalAgentRegistration {
|
|
@@ -58,8 +58,8 @@ export interface PersonalAgentsConfigInput {
|
|
|
58
58
|
/**
|
|
59
59
|
* Valor que os personal agents põem no `aud` do JWT deles (PACT). Opaco e
|
|
60
60
|
* atribuído por ESTE app no registro do agente — um valor por app, não
|
|
61
|
-
* derivado de URL. Liga o PACT; obrigatório, a não ser num app
|
|
62
|
-
*
|
|
61
|
+
* derivado de URL. Liga o PACT; obrigatório, a não ser num app que só usa
|
|
62
|
+
* `extensions` (sem `audience`).
|
|
63
63
|
*/
|
|
64
64
|
audience?: string;
|
|
65
65
|
/**
|
|
@@ -79,14 +79,10 @@ export interface PersonalAgentsConfigInput {
|
|
|
79
79
|
/** Prefixo das rotas (`{prefix}/oauth/*`, `{prefix}/consent`). Default: `/agents`. */
|
|
80
80
|
prefix?: string;
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* `poppy/config.ts`.
|
|
85
|
-
*
|
|
86
|
-
* @experimental Poppy (Personal Agent Protocol) Draft 0.3 — acompanha a spec em desenvolvimento e PODE MUDAR
|
|
87
|
-
* de forma incompatível fora de majors enquanto ela for draft.
|
|
82
|
+
* Outros protocolos de personal agents, de pacotes à parte, ao lado do PACT
|
|
83
|
+
* (ex.: `poppy()` de `@adonis-agora/authkit-poppy`). Ver {@link PersonalAgentExtension}.
|
|
88
84
|
*/
|
|
89
|
-
|
|
85
|
+
extensions?: PersonalAgentExtension[];
|
|
90
86
|
}
|
|
91
87
|
export interface ResolvedPersonalAgentDelegationConfig {
|
|
92
88
|
interfaceUrl: string;
|
|
@@ -108,11 +104,11 @@ export interface ResolvedPersonalAgentsConfig {
|
|
|
108
104
|
open: boolean;
|
|
109
105
|
delegation?: ResolvedPersonalAgentDelegationConfig;
|
|
110
106
|
prefix: string;
|
|
111
|
-
/**
|
|
112
|
-
|
|
107
|
+
/** `extensions` resolvidas, na ordem do config. */
|
|
108
|
+
extensions: ResolvedPersonalAgentExtension[];
|
|
113
109
|
}
|
|
114
110
|
export declare function normalizePersonalAgentsPrefix(prefix: string | undefined): string;
|
|
115
|
-
export declare function resolvePersonalAgentsConfig(input: PersonalAgentsConfigInput | undefined): ResolvedPersonalAgentsConfig | undefined;
|
|
111
|
+
export declare function resolvePersonalAgentsConfig(input: PersonalAgentsConfigInput | undefined, issuer?: string): ResolvedPersonalAgentsConfig | undefined;
|
|
116
112
|
/** `"a b c"` → `['a','b','c']` sem duplicatas, na ordem. */
|
|
117
113
|
export declare function parseScope(value: string | null | undefined): string[];
|
|
118
114
|
export declare function formatScope(scopes: Iterable<string>): string;
|