@adonis-agora/authkit-server 0.46.0 → 0.48.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/commands/clients_create.js +4 -4
- package/build/commands/configure.js +3 -2
- package/build/commands/doctor.js +8 -5
- package/build/commands/eject.js +1 -1
- package/build/commands/expire_scan.js +7 -5
- package/build/commands/import_users.js +1 -1
- package/build/commands/keys_rotate.js +7 -4
- package/build/host/views/account/apps.edge +5 -5
- package/build/host/views/account/login.edge +1 -1
- package/build/host/views/account/mfa.edge +7 -7
- package/build/host/views/account/orgs.edge +5 -5
- package/build/host/views/account/security.edge +10 -10
- package/build/host/views/account/tokens.edge +5 -5
- package/build/host/views/otp-unlock.edge +2 -2
- package/build/index.d.ts +7 -7
- package/build/index.js +5 -5
- package/build/providers/authkit_server_provider.d.ts +2 -2
- package/build/providers/authkit_server_provider.js +26 -10
- package/build/services/booted_app.d.ts +8 -0
- package/build/services/booted_app.js +27 -0
- package/build/services/main.d.ts +8 -1
- package/build/services/main.js +10 -2
- package/build/src/accounts/lucid_account_store.d.ts +3 -3
- package/build/src/accounts/lucid_account_store.js +6 -8
- package/build/src/accounts/lucid_store/core.js +1 -1
- package/build/src/accounts/lucid_store/mfa.js +1 -1
- package/build/src/accounts/lucid_store/organizations.js +2 -4
- package/build/src/accounts/lucid_store/password_hygiene.js +1 -4
- package/build/src/accounts/lucid_store/shared.d.ts +1 -1
- package/build/src/accounts/lucid_stores.d.ts +3 -3
- package/build/src/accounts/lucid_stores.js +2 -2
- package/build/src/adapters/database_adapter.js +3 -1
- package/build/src/adapters/factory.js +1 -1
- package/build/src/adapters/redis_adapter.js +2 -1
- package/build/src/commands/expire_scan_command.js +19 -5
- package/build/src/commands/settings_commands.js +22 -5
- package/build/src/define_config.d.ts +20 -20
- package/build/src/define_config.js +62 -67
- package/build/src/doctor/checks.js +45 -20
- package/build/src/events/dispatcher.d.ts +1 -1
- package/build/src/events/dispatcher.js +10 -10
- package/build/src/host/account_api/account_api_controller.js +95 -39
- package/build/src/host/account_deletion_ops.d.ts +4 -4
- package/build/src/host/account_deletion_ops.js +5 -5
- package/build/src/host/account_deletion_service.d.ts +2 -2
- package/build/src/host/account_deletion_service.js +2 -2
- package/build/src/host/account_export_service.d.ts +1 -1
- package/build/src/host/account_export_service.js +4 -6
- package/build/src/host/account_home.d.ts +0 -8
- package/build/src/host/account_home.js +6 -4
- package/build/src/host/account_login_url.d.ts +44 -0
- package/build/src/host/account_login_url.js +58 -0
- package/build/src/host/account_paths.d.ts +120 -0
- package/build/src/host/account_paths.js +161 -0
- package/build/src/host/admin_api/admin_orgs_service.d.ts +2 -2
- package/build/src/host/admin_api/admin_orgs_service.js +3 -2
- package/build/src/host/admin_api/admin_users_service.d.ts +12 -12
- package/build/src/host/admin_api/admin_users_service.js +20 -20
- package/build/src/host/admin_api/api_clients_controller.js +2 -2
- package/build/src/host/admin_api/api_misc_controller.js +2 -2
- package/build/src/host/admin_api/api_orgs_controller.js +3 -3
- package/build/src/host/admin_api/api_settings_controller.js +11 -5
- package/build/src/host/admin_api/api_users_controller.d.ts +2 -2
- package/build/src/host/admin_api/api_users_controller.js +37 -38
- package/build/src/host/admin_api/dto.d.ts +4 -4
- package/build/src/host/admin_clients_service.js +5 -4
- package/build/src/host/admin_console/admin_shell_controller.js +4 -2
- package/build/src/host/admin_console/console_audit_controller.js +1 -1
- package/build/src/host/admin_console/console_clients_controller.js +5 -3
- package/build/src/host/admin_console/console_impersonation_controller.js +1 -1
- package/build/src/host/admin_console/console_keys_controller.js +2 -4
- package/build/src/host/admin_console/console_orgs_controller.js +3 -3
- package/build/src/host/admin_console/console_roles_controller.js +30 -12
- package/build/src/host/admin_console/console_sessions_controller.js +3 -3
- package/build/src/host/admin_console/console_settings_controller.js +11 -5
- package/build/src/host/admin_console/console_users_controller.d.ts +2 -2
- package/build/src/host/admin_console/console_users_controller.js +46 -47
- package/build/src/host/admin_prefix.js +2 -2
- package/build/src/host/admin_sessions_service.d.ts +3 -1
- package/build/src/host/admin_sessions_service.js +36 -6
- package/build/src/host/adonis_auth_sync.d.ts +1 -1
- package/build/src/host/adonis_auth_user_provider.d.ts +1 -1
- package/build/src/host/app_key.js +1 -1
- package/build/src/host/avatar_storage.js +1 -3
- package/build/src/host/config_locks.js +1 -3
- package/build/src/host/console_session.d.ts +4 -0
- package/build/src/host/console_session.js +9 -2
- package/build/src/host/controllers/account_apps_controller.js +3 -2
- package/build/src/host/controllers/account_confirm_controller.js +2 -6
- package/build/src/host/controllers/account_mfa_controller.js +63 -12
- package/build/src/host/controllers/account_orgs_controller.js +53 -30
- package/build/src/host/controllers/account_security_controller.d.ts +2 -2
- package/build/src/host/controllers/account_security_controller.js +116 -116
- package/build/src/host/controllers/account_session_controller.js +7 -5
- package/build/src/host/controllers/account_tokens_controller.js +14 -2
- package/build/src/host/controllers/interaction_controller.js +59 -22
- package/build/src/host/controllers/pat_introspection_controller.js +10 -0
- package/build/src/host/controllers/registration_controller.js +28 -13
- package/build/src/host/default_mailer.js +11 -7
- package/build/src/host/durable/account_deletion_workflow.d.ts +2 -2
- package/build/src/host/durable/account_deletion_workflow.js +14 -14
- package/build/src/host/durable/account_export_workflow.d.ts +2 -2
- package/build/src/host/durable/account_export_workflow.js +12 -12
- package/build/src/host/durable/index.d.ts +5 -5
- package/build/src/host/durable/index.js +6 -6
- package/build/src/host/i18n.d.ts +1376 -1376
- package/build/src/host/i18n.js +1380 -1380
- package/build/src/host/impersonation.js +1 -7
- package/build/src/host/key_rotation_actions.d.ts +1 -1
- package/build/src/host/login_attempt.js +35 -6
- package/build/src/host/login_notify.js +1 -1
- package/build/src/host/middleware/account_auth.js +3 -1
- package/build/src/host/otp_lockout.js +1 -3
- package/build/src/host/rate_limit.js +1 -1
- package/build/src/host/register_auth_host.d.ts +96 -2
- package/build/src/host/register_auth_host.js +196 -91
- package/build/src/host/renderers/edge_renderer.js +19 -1
- package/build/src/host/renderers/inertia_renderer.d.ts +63 -0
- package/build/src/host/renderers/inertia_renderer.js +63 -0
- package/build/src/host/runtime_settings.js +1 -1
- package/build/src/host/runtime_toggles.d.ts +3 -3
- package/build/src/host/runtime_toggles.js +69 -24
- package/build/src/host/security_notice_service.d.ts +1 -1
- package/build/src/host/security_notice_service.js +1 -1
- package/build/src/host/session_context.js +1 -1
- package/build/src/host/sudo/index.d.ts +3 -3
- package/build/src/host/sudo/index.js +3 -3
- package/build/src/host/sudo/methods/magic_link.js +6 -5
- package/build/src/host/sudo/methods/passkey.js +7 -4
- package/build/src/host/sudo/methods/password.js +8 -3
- package/build/src/host/sudo/runtime.js +6 -13
- package/build/src/host/sudo_mode.js +3 -2
- package/build/src/host/ui-dist/assets/index-BQoTDiLV.js +137 -0
- package/build/src/host/ui-dist/index.html +1 -1
- package/build/src/keys/jwks_manager.js +1 -1
- package/build/src/keys/keystore.js +1 -1
- package/build/src/keys/keystore_manager.d.ts +2 -2
- package/build/src/keys/keystore_manager.js +2 -2
- package/build/src/keys/keystore_vault.js +8 -4
- package/build/src/mixins/with_audit_log.d.ts +1 -1
- package/build/src/mixins/with_auth_user.d.ts +1 -1
- package/build/src/mixins/with_auth_user.js +1 -1
- package/build/src/mixins/with_credentials.d.ts +1 -1
- package/build/src/mixins/with_mfa.d.ts +1 -1
- package/build/src/mixins/with_personal_access_token.d.ts +1 -1
- package/build/src/mixins/with_provider_identity.d.ts +1 -1
- package/build/src/mixins/with_webauthn_credential.d.ts +1 -1
- package/build/src/observability/diagnostics_bridge.js +2 -2
- package/build/src/observability/metrics_service.js +1 -1
- package/build/src/observability/telescope/data_providers.d.ts +1 -1
- package/build/src/observability/telescope/data_providers.js +29 -43
- package/build/src/observability/telescope/extension.d.ts +1 -1
- package/build/src/observability/telescope/extension.js +58 -58
- package/build/src/observability/telescope/index.d.ts +2 -2
- package/build/src/observability/telescope/index.js +2 -2
- package/build/src/observability/wire_provider_events.d.ts +1 -1
- package/build/src/observability/wire_provider_events.js +11 -11
- package/build/src/password/common_passwords.js +1 -1
- package/build/src/password/password_manager.d.ts +1 -1
- package/build/src/password/password_manager.js +4 -4
- package/build/src/pat/lucid_pat_store.js +2 -6
- package/build/src/pat/pat_tokens.js +1 -1
- package/build/src/provider/interaction_actions.js +1 -1
- package/build/src/provider/key_rotation_scheduler.js +3 -1
- package/build/src/provider/logout_sources.js +2 -8
- package/build/src/provider/oidc_service.d.ts +2 -2
- package/build/src/provider/oidc_service.js +22 -14
- package/build/src/provider/single_flight_lock.js +1 -3
- package/build/src/provider/token_exchange.d.ts +1 -1
- package/build/src/schema/ensure.js +3 -1
- package/build/stubs/ui/react/components/auth_shell.tsx +19 -19
- package/build/stubs/ui/react/pages/account/login.tsx +6 -7
- package/build/stubs/ui/react/pages/account/mfa.tsx +16 -15
- package/build/stubs/ui/react/pages/account/tokens.tsx +27 -17
- package/build/stubs/ui/react/pages/consent.tsx +12 -12
- package/build/stubs/ui/react/pages/forgot.tsx +7 -7
- package/build/stubs/ui/react/pages/login.tsx +22 -24
- package/build/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
- package/build/stubs/ui/react/pages/reset.tsx +10 -10
- package/build/stubs/ui/react/pages/signup.tsx +30 -16
- package/build/stubs/ui/react/pages/verify-email.tsx +6 -6
- package/package.json +1 -1
- package/stubs/main.ts +2 -2
- package/stubs/ui/react/components/auth_shell.tsx +19 -19
- package/stubs/ui/react/pages/account/login.tsx +6 -7
- package/stubs/ui/react/pages/account/mfa.tsx +16 -15
- package/stubs/ui/react/pages/account/tokens.tsx +27 -17
- package/stubs/ui/react/pages/consent.tsx +12 -12
- package/stubs/ui/react/pages/forgot.tsx +7 -7
- package/stubs/ui/react/pages/login.tsx +22 -24
- package/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
- package/stubs/ui/react/pages/reset.tsx +10 -10
- package/stubs/ui/react/pages/signup.tsx +30 -16
- package/stubs/ui/react/pages/verify-email.tsx +6 -6
- package/build/src/host/ui-dist/assets/index-BmI_J87g.js +0 -137
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { resolveRateLimit } from '../define_config.js';
|
|
2
|
-
import { createAuthThrottles } from './rate_limit.js';
|
|
3
|
-
import { ACCOUNT_SESSION_KEY } from './middleware/account_auth.js';
|
|
4
2
|
import { accountHome } from './account_home.js';
|
|
3
|
+
import { getAccountLoginUrl, setAccountLoginUrl } from './account_login_url.js';
|
|
4
|
+
import { accountPath, joinAccountPath, setAccountPaths, } from './account_paths.js';
|
|
5
5
|
import { resolveAccountRoles } from './account_roles.js';
|
|
6
6
|
import { adminApiGuard } from './admin_api/admin_api_guard.js';
|
|
7
|
-
import {
|
|
7
|
+
import { normalizeAdminApiPrefix, normalizeAdminPrefix, setAdminApiPrefix, setAdminPrefix, } from './admin_prefix.js';
|
|
8
|
+
import { getAuthHostConfig } from './auth_host_config.js';
|
|
9
|
+
import { ACCOUNT_SESSION_KEY } from './middleware/account_auth.js';
|
|
10
|
+
import { createAuthThrottles } from './rate_limit.js';
|
|
8
11
|
import { resolveRuntimeSettings } from './runtime_settings.js';
|
|
9
12
|
import { resolveEffectiveSessionPolicy } from './runtime_toggles.js';
|
|
10
|
-
import { getAuthHostConfig } from './auth_host_config.js';
|
|
11
|
-
import { completeSudo, fail, guardSudoRoutes, sudoContextFrom, setMountedSudoMethods, } from './sudo/runtime.js';
|
|
12
|
-
import { password as sudoPassword } from './sudo/methods/password.js';
|
|
13
13
|
import { passkey as sudoPasskey } from './sudo/methods/passkey.js';
|
|
14
|
+
import { password as sudoPassword } from './sudo/methods/password.js';
|
|
15
|
+
import { completeSudo, fail, guardSudoRoutes, setMountedSudoMethods, sudoContextFrom, } from './sudo/runtime.js';
|
|
14
16
|
/**
|
|
15
17
|
* Métodos de sudo montados quando o host não passa `sudoMethods` —
|
|
16
18
|
* comportamento histórico (senha + passkey).
|
|
@@ -68,16 +70,26 @@ async function checkAndRefreshIdle(ctx) {
|
|
|
68
70
|
* @internal
|
|
69
71
|
*/
|
|
70
72
|
function buildLoginRedirect(ctx, extra) {
|
|
73
|
+
// Destino configurável (`accountLoginUrl`): default `/account/login`, mas um
|
|
74
|
+
// host que desmontou a tela de login (`account: { login: false }`) aponta para
|
|
75
|
+
// a própria rota de login dele (ex.: `/login`). Ver `account_login_url.ts`.
|
|
76
|
+
const loginUrl = getAccountLoginUrl();
|
|
71
77
|
const url = ctx.request?.url?.() ?? '';
|
|
72
78
|
const qs = ctx.request?.parsedUrl?.search ?? '';
|
|
73
79
|
const dest = qs ? `${url}${qs}` : url;
|
|
74
80
|
// Só inclui return_to quando há um caminho real (não vazio, não é o próprio login).
|
|
75
|
-
if (dest && dest !== '/' && !dest.startsWith(
|
|
81
|
+
if (dest && dest !== '/' && !dest.startsWith(loginUrl)) {
|
|
76
82
|
const encoded = encodeURIComponent(dest);
|
|
77
|
-
const
|
|
83
|
+
const sep = loginUrl.includes('?') ? '&' : '?';
|
|
84
|
+
const base = extra
|
|
85
|
+
? `${loginUrl}${sep}${extra}&return_to=${encoded}`
|
|
86
|
+
: `${loginUrl}${sep}return_to=${encoded}`;
|
|
78
87
|
return base;
|
|
79
88
|
}
|
|
80
|
-
|
|
89
|
+
if (!extra)
|
|
90
|
+
return loginUrl;
|
|
91
|
+
const sep = loginUrl.includes('?') ? '&' : '?';
|
|
92
|
+
return `${loginUrl}${sep}${extra}`;
|
|
81
93
|
}
|
|
82
94
|
/**
|
|
83
95
|
* Guard inline do console de conta. Usamos uma closure (forma confiável do
|
|
@@ -100,9 +112,11 @@ const accountGuard = async (ctx, next) => {
|
|
|
100
112
|
* Guard do console admin (B6). Como o `accountGuard`, é uma closure inline (forma
|
|
101
113
|
* confiável do `.use()` num grupo). Exige:
|
|
102
114
|
* 0. `config.admin.enabled` ligado (senão → 404; ver nota de flag-drift abaixo);
|
|
103
|
-
* 1. sessão de conta ativa (senão → /account/login);
|
|
115
|
+
* 1. sessão de conta ativa (senão → `accountLoginUrl`, default /account/login);
|
|
104
116
|
* 2. a conta logada com pelo menos UMA das `config.admin.roles` nas roles globais
|
|
105
|
-
* (senão → /account/
|
|
117
|
+
* (senão → `accountHome(cfg)`, default /account/security — NÃO revela a
|
|
118
|
+
* existência do /admin, e cai numa tela que o host controla via `accountHome`;
|
|
119
|
+
* se a tela default estiver desmontada, aponte `config.accountHome` para uma montada).
|
|
106
120
|
* As roles permitidas são resolvidas em runtime do `authkit.server` (config lazy).
|
|
107
121
|
*/
|
|
108
122
|
export const adminGuard = async (ctx, next) => {
|
|
@@ -188,6 +202,38 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
188
202
|
const social = opts.social ?? hostCfg?.social;
|
|
189
203
|
const adminOpt = opts.admin ?? (hostCfg?.adminEnabled ? true : undefined);
|
|
190
204
|
const adminApiOpt = opts.adminApi ?? (hostCfg?.adminApiEnabled ? true : undefined);
|
|
205
|
+
// Prefixo/segmentos configuráveis do console de conta — persiste no singleton
|
|
206
|
+
// de processo ANTES de qualquer construção de rota/closure, para que o registro
|
|
207
|
+
// de rotas, os guards, os controllers, os e-mails e as views leiam o mesmo
|
|
208
|
+
// valor. Top-level de propósito (vale mesmo com `account: false`): as rotas de
|
|
209
|
+
// sudo e a JSON API respeitam o prefixo. Ausente → default `/account/*`
|
|
210
|
+
// (back-compat). Ver `account_paths.ts`.
|
|
211
|
+
if (opts.accountRoutes !== undefined) {
|
|
212
|
+
setAccountPaths(opts.accountRoutes);
|
|
213
|
+
}
|
|
214
|
+
// Destino do redirect de "faça login" — persiste no singleton de processo para
|
|
215
|
+
// que os guards (closures de tempo de registro), o middleware, os controllers e
|
|
216
|
+
// as views leiam o mesmo valor. Só quando a opção foi passada (senão deriva de
|
|
217
|
+
// `accountPath('login')` — back-compat).
|
|
218
|
+
if (opts.accountLoginUrl !== undefined) {
|
|
219
|
+
setAccountLoginUrl(opts.accountLoginUrl);
|
|
220
|
+
}
|
|
221
|
+
// Montagem por tela do console de conta. `undefined` → tudo montado;
|
|
222
|
+
// `false` → nada; objeto → cada flag ausente default `true`.
|
|
223
|
+
const accountOpt = opts.account;
|
|
224
|
+
const mountScreen = (key) => {
|
|
225
|
+
if (accountOpt === false)
|
|
226
|
+
return false;
|
|
227
|
+
if (accountOpt && typeof accountOpt === 'object')
|
|
228
|
+
return accountOpt[key] !== false;
|
|
229
|
+
return true;
|
|
230
|
+
};
|
|
231
|
+
const mountLogin = mountScreen('login');
|
|
232
|
+
const mountTokens = mountScreen('tokens');
|
|
233
|
+
const mountOrgs = mountScreen('orgs');
|
|
234
|
+
const mountSecurity = mountScreen('security');
|
|
235
|
+
const mountMfa = mountScreen('mfa');
|
|
236
|
+
const mountApps = mountScreen('apps');
|
|
191
237
|
// Throttles opt-in (anti-brute-force). `undefined` quando rate-limit desligado.
|
|
192
238
|
const resolvedRateLimit = opts.rateLimit !== undefined
|
|
193
239
|
? resolveRateLimit(opts.rateLimit)
|
|
@@ -230,7 +276,10 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
230
276
|
withLogin(router.post('/auth/interaction/:uid/login', [C.interaction, 'login']));
|
|
231
277
|
withLogin(router.post('/auth/interaction/:uid/mfa', [C.interaction, 'mfaVerify']));
|
|
232
278
|
// Troca de senha obrigatória quando a senha expirou (password expiration gate).
|
|
233
|
-
withLogin(router.post('/auth/interaction/:uid/password-expired', [
|
|
279
|
+
withLogin(router.post('/auth/interaction/:uid/password-expired', [
|
|
280
|
+
C.interaction,
|
|
281
|
+
'changeExpiredPassword',
|
|
282
|
+
]));
|
|
234
283
|
// Passkey como 2º fator alternativo no login (begin/finish; challenge na sessão).
|
|
235
284
|
router.post('/auth/interaction/:uid/passkey/options', [C.interaction, 'passkeyOptions']);
|
|
236
285
|
withLogin(router.post('/auth/interaction/:uid/passkey/verify', [C.interaction, 'passkeyVerify']));
|
|
@@ -257,54 +306,90 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
257
306
|
}
|
|
258
307
|
// PAT introspection (server-to-server).
|
|
259
308
|
withIntrospection(router.post('/authkit/pat/introspect', [C.patIntrospection, 'handle']));
|
|
309
|
+
// Paths do console de conta (configuráveis/localizáveis via `accountRoutes`).
|
|
310
|
+
// As TELAS vêm de `accountPath(key)` (prefixo + segmento configurável); os
|
|
311
|
+
// action-subpaths concatenados (`/password`, `/enroll`, ...) são FIXOS —
|
|
312
|
+
// endpoints de formulário invisíveis ao usuário. A JSON API segue o prefixo
|
|
313
|
+
// com o segmento `api` FIXO. Capturados uma vez aqui: `setAccountPaths` já
|
|
314
|
+
// rodou no topo e o singleton não muda mais neste processo.
|
|
315
|
+
const loginPath = accountPath('login');
|
|
316
|
+
const logoutPath = accountPath('logout');
|
|
317
|
+
const securityPath = accountPath('security');
|
|
318
|
+
const tokensPath = accountPath('tokens');
|
|
319
|
+
const appsPath = accountPath('apps');
|
|
320
|
+
const mfaPath = accountPath('mfa');
|
|
321
|
+
const confirmPath = accountPath('confirm');
|
|
322
|
+
const orgsPath = accountPath('orgs');
|
|
323
|
+
const emailConfirmPath = accountPath('emailConfirm');
|
|
324
|
+
const apiBase = joinAccountPath('api');
|
|
260
325
|
// Organizations — invitation accept (sem guard: controller lida com não-autenticado).
|
|
261
|
-
|
|
262
|
-
|
|
326
|
+
// Parte da tela `orgs`: desmontada junto (sem multi-tenancy, não há convite a aceitar).
|
|
327
|
+
if (mountOrgs) {
|
|
328
|
+
router.get(`${orgsPath}/invitations/:token/accept`, [C.accountOrgs, 'showAcceptInvitation']);
|
|
329
|
+
router.post(`${orgsPath}/invitations/:token/accept`, [C.accountOrgs, 'acceptInvitation']);
|
|
330
|
+
}
|
|
263
331
|
// Console de conta (login de sessão do IdP + gerência de PAT).
|
|
264
|
-
|
|
265
|
-
//
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
332
|
+
// Tela `login` desmontável: hosts passwordless delegam ao OIDC próprio e
|
|
333
|
+
// apontam `accountLoginUrl` para a rota de login deles.
|
|
334
|
+
if (mountLogin) {
|
|
335
|
+
router.get(loginPath, [C.accountSession, 'show']);
|
|
336
|
+
// L6: throttle por IP no login/logout do console de conta (anti-brute-force),
|
|
337
|
+
// alinhado com as demais rotas de credencial (interaction, forgot, reset).
|
|
338
|
+
withLogin(router.post(loginPath, [C.accountSession, 'login']));
|
|
339
|
+
withLogin(router.post(logoutPath, [C.accountSession, 'logout']));
|
|
340
|
+
}
|
|
269
341
|
// Confirmação de troca de e-mail (standalone, GET-only — consome o token do link;
|
|
270
|
-
// pode ser aberta em outro dispositivo, então NÃO exige sessão).
|
|
271
|
-
|
|
272
|
-
|
|
342
|
+
// pode ser aberta em outro dispositivo, então NÃO exige sessão). Parte da tela
|
|
343
|
+
// `security` (o terminal do fluxo de troca de e-mail).
|
|
344
|
+
if (mountSecurity) {
|
|
345
|
+
router.get(emailConfirmPath, [C.accountSecurity, 'confirmEmail']);
|
|
346
|
+
}
|
|
347
|
+
// Rotas de tokens protegidas por AccountAuthMiddleware (redireciona para a tela de login se não autenticado).
|
|
273
348
|
router
|
|
274
349
|
.group(() => {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
C.accountSecurity,
|
|
291
|
-
'
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
350
|
+
// Personal Access Tokens (tela `tokens`).
|
|
351
|
+
if (mountTokens) {
|
|
352
|
+
router.get(tokensPath, [C.accountTokens, 'index']);
|
|
353
|
+
router.post(tokensPath, [C.accountTokens, 'store']);
|
|
354
|
+
router.post(`${tokensPath}/:id/revoke`, [C.accountTokens, 'destroy']);
|
|
355
|
+
}
|
|
356
|
+
// Segurança da conta: trocar senha + solicitar troca de e-mail + perfil (tela `security`).
|
|
357
|
+
if (mountSecurity) {
|
|
358
|
+
router.get(securityPath, [C.accountSecurity, 'index']);
|
|
359
|
+
router.post(`${securityPath}/password`, [C.accountSecurity, 'changePassword']);
|
|
360
|
+
router.post(`${securityPath}/email`, [C.accountSecurity, 'changeEmail']);
|
|
361
|
+
router.post(`${securityPath}/email/cancel`, [C.accountSecurity, 'cancelEmailChange']);
|
|
362
|
+
router.post(`${securityPath}/profile`, [C.accountSecurity, 'updateProfile']);
|
|
363
|
+
// LGPD/GDPR: export de dados (portabilidade) + deleção self-service (danger zone).
|
|
364
|
+
// O export carrega o throttle de login (anti-abuso) quando o rate-limit existe.
|
|
365
|
+
withLogin(router.get(`${securityPath}/export`, [C.accountSecurity, 'exportData']));
|
|
366
|
+
router.post(`${securityPath}/delete`, [C.accountSecurity, 'deleteAccount']);
|
|
367
|
+
// Trusted devices: limpa o cookie de confiança DESTE navegador.
|
|
368
|
+
router.post(`${securityPath}/trusted-devices/revoke`, [
|
|
369
|
+
C.accountSecurity,
|
|
370
|
+
'revokeTrustedDevices',
|
|
371
|
+
]);
|
|
372
|
+
}
|
|
373
|
+
// Apps com acesso (consentimento): lista os grants da conta + revogação por client (tela `apps`).
|
|
374
|
+
if (mountApps) {
|
|
375
|
+
router.get(appsPath, [C.accountApps, 'index']);
|
|
376
|
+
router.post(`${appsPath}/:clientId/revoke`, [C.accountApps, 'revoke']);
|
|
377
|
+
}
|
|
378
|
+
// MFA — TOTP + passkeys (tela `mfa`).
|
|
379
|
+
if (mountMfa) {
|
|
380
|
+
// MFA / TOTP (enrollment, confirmação, disable).
|
|
381
|
+
router.get(mfaPath, [C.accountMfa, 'index']);
|
|
382
|
+
router.post(`${mfaPath}/enroll`, [C.accountMfa, 'enroll']);
|
|
383
|
+
router.post(`${mfaPath}/confirm`, [C.accountMfa, 'confirm']);
|
|
384
|
+
router.post(`${mfaPath}/disable`, [C.accountMfa, 'disable']);
|
|
385
|
+
// MFA / WebAuthn (passkeys): registro (begin/finish) + remoção.
|
|
386
|
+
router.post(`${mfaPath}/passkeys/options`, [C.accountMfa, 'passkeyRegisterOptions']);
|
|
387
|
+
router.post(`${mfaPath}/passkeys/verify`, [C.accountMfa, 'passkeyRegisterVerify']);
|
|
388
|
+
router.post(`${mfaPath}/passkeys/:id/remove`, [C.accountMfa, 'passkeyRemove']);
|
|
389
|
+
}
|
|
305
390
|
// Sudo mode (confirm identity): o GET lista os métodos; cada método
|
|
306
391
|
// registra suas próprias rotas de verificação (SPI `SudoMethod`).
|
|
307
|
-
router.get(
|
|
392
|
+
router.get(confirmPath, [C.accountConfirm, 'show']);
|
|
308
393
|
// Rotas próprias dos métodos de sudo — DENTRO do grupo com `accountGuard`.
|
|
309
394
|
// O guard não é só "tem sessão": ele roda `checkAndRefreshIdle`, que apaga
|
|
310
395
|
// a sessão vencida por idle e refresca `authkit_last_seen`. Fora do grupo,
|
|
@@ -342,50 +427,58 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
342
427
|
// configura `config.sudo.methods`: a tela oferece exatamente isto, e os
|
|
343
428
|
// handlers aceitam exatamente isto.
|
|
344
429
|
setMountedSudoMethods(sudoMethodsToMount);
|
|
345
|
-
// Organizations (multi-tenancy) —
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
430
|
+
// Organizations (multi-tenancy) — tela `orgs`. Montadas por default;
|
|
431
|
+
// controller retorna 404/403 sem tabelas (capability-probed).
|
|
432
|
+
if (mountOrgs) {
|
|
433
|
+
router.get(orgsPath, [C.accountOrgs, 'index']);
|
|
434
|
+
router.post(orgsPath, [C.accountOrgs, 'store']);
|
|
435
|
+
router.post(`${orgsPath}/deactivate`, [C.accountOrgs, 'deactivate']);
|
|
436
|
+
router.post(`${orgsPath}/:id/activate`, [C.accountOrgs, 'activate']);
|
|
437
|
+
router.post(`${orgsPath}/:id/leave`, [C.accountOrgs, 'leave']);
|
|
438
|
+
router.post(`${orgsPath}/:id/invite`, [C.accountOrgs, 'invite']);
|
|
439
|
+
router.post(`${orgsPath}/:id/members/:accountId/remove`, [C.accountOrgs, 'removeMember']);
|
|
440
|
+
router.post(`${orgsPath}/:id/invitations/:invId/revoke`, [
|
|
441
|
+
C.accountOrgs,
|
|
442
|
+
'revokeInvitation',
|
|
443
|
+
]);
|
|
444
|
+
// JSON endpoints for React hooks (authkit-react).
|
|
445
|
+
router.get(`${orgsPath}/json`, [C.accountOrgs, 'listJson']);
|
|
446
|
+
router.get(`${orgsPath}/invitations/json`, [C.accountOrgs, 'listInvitationsJson']);
|
|
447
|
+
router.get(`${orgsPath}/:id/json`, [C.accountOrgs, 'showJson']);
|
|
448
|
+
}
|
|
358
449
|
// ─── Account self-service JSON API (authkit-react TanStack hooks) ─────
|
|
359
450
|
// ⚠️ ORDER MATTERS: fixed-segment routes before parameterised ones.
|
|
360
451
|
// Registered INSIDE the accountGuard group → same session-auth protection.
|
|
361
452
|
// Mutating routes use CSRF (shield middleware on the host app).
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
router.
|
|
365
|
-
router.
|
|
453
|
+
// Segue o prefixo do console (`accountRoutes.prefix`); o segmento `api` é
|
|
454
|
+
// FIXO — é contrato de máquina (authkit-react), não path de humano.
|
|
455
|
+
router.get(`${apiBase}/me`, [C.accountApi, 'me']);
|
|
456
|
+
router.get(`${apiBase}/security`, [C.accountApi, 'securityOverview']);
|
|
457
|
+
router.patch(`${apiBase}/profile`, [C.accountApi, 'updateProfile']);
|
|
458
|
+
router.post(`${apiBase}/password`, [C.accountApi, 'changePassword']);
|
|
366
459
|
// Email-change: cancel BEFORE the generic post to avoid pattern collision.
|
|
367
|
-
router.post(
|
|
368
|
-
router.post(
|
|
460
|
+
router.post(`${apiBase}/email-change/cancel`, [C.accountApi, 'cancelEmailChange']);
|
|
461
|
+
router.post(`${apiBase}/email-change`, [C.accountApi, 'requestEmailChange']);
|
|
369
462
|
// Sessions: fixed routes BEFORE :id.
|
|
370
|
-
router.get(
|
|
371
|
-
router.post(
|
|
372
|
-
router.post(
|
|
373
|
-
router.delete(
|
|
463
|
+
router.get(`${apiBase}/sessions`, [C.accountApi, 'listSessions']);
|
|
464
|
+
router.post(`${apiBase}/sessions/revoke-others`, [C.accountApi, 'revokeOtherSessions']);
|
|
465
|
+
router.post(`${apiBase}/sessions/revoke-all`, [C.accountApi, 'revokeAllSessions']);
|
|
466
|
+
router.delete(`${apiBase}/sessions/:id`, [C.accountApi, 'revokeSession']);
|
|
374
467
|
// Apps (grants).
|
|
375
|
-
router.get(
|
|
376
|
-
router.delete(
|
|
468
|
+
router.get(`${apiBase}/apps`, [C.accountApi, 'listApps']);
|
|
469
|
+
router.delete(`${apiBase}/apps/:clientId`, [C.accountApi, 'revokeApp']);
|
|
377
470
|
// MFA + passkeys.
|
|
378
|
-
router.get(
|
|
379
|
-
router.get(
|
|
380
|
-
router.delete(
|
|
471
|
+
router.get(`${apiBase}/mfa`, [C.accountApi, 'mfaStatus']);
|
|
472
|
+
router.get(`${apiBase}/passkeys`, [C.accountApi, 'listPasskeys']);
|
|
473
|
+
router.delete(`${apiBase}/passkeys/:id`, [C.accountApi, 'removePasskey']);
|
|
381
474
|
// PATs.
|
|
382
|
-
router.get(
|
|
383
|
-
router.post(
|
|
384
|
-
router.delete(
|
|
475
|
+
router.get(`${apiBase}/tokens`, [C.accountApi, 'listTokens']);
|
|
476
|
+
router.post(`${apiBase}/tokens`, [C.accountApi, 'createToken']);
|
|
477
|
+
router.delete(`${apiBase}/tokens/:id`, [C.accountApi, 'revokeToken']);
|
|
385
478
|
// Orgs: invitations BEFORE :id (fixed segment before parameterised).
|
|
386
|
-
router.get(
|
|
387
|
-
router.get(
|
|
388
|
-
router.get(
|
|
479
|
+
router.get(`${apiBase}/orgs`, [C.accountApi, 'listOrgs']);
|
|
480
|
+
router.get(`${apiBase}/orgs/invitations`, [C.accountApi, 'listOrgInvitations']);
|
|
481
|
+
router.get(`${apiBase}/orgs/:id`, [C.accountApi, 'showOrg']);
|
|
389
482
|
})
|
|
390
483
|
.use([accountGuard]);
|
|
391
484
|
// Console admin (do config.admin.enabled ou opts). Protegido pelo adminGuard (sessão + role global).
|
|
@@ -422,13 +515,19 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
422
515
|
router.post(`${ap}/api/sessions/revoke-all`, [C.consoleSessions, 'revokeAll']);
|
|
423
516
|
// Sessões por usuário (drawer do user — ANTES do catch-all para não receber HTML).
|
|
424
517
|
router.get(`${ap}/api/users/:id/sessions`, [C.consoleSessions, 'userSessions']);
|
|
425
|
-
router.post(`${ap}/api/users/:id/revoke-sessions`, [
|
|
518
|
+
router.post(`${ap}/api/users/:id/revoke-sessions`, [
|
|
519
|
+
C.consoleSessions,
|
|
520
|
+
'userRevokeSessions',
|
|
521
|
+
]);
|
|
426
522
|
// Clients OIDC.
|
|
427
523
|
router.get(`${ap}/api/clients`, [C.consoleClients, 'index']);
|
|
428
524
|
router.post(`${ap}/api/clients`, [C.consoleClients, 'store']);
|
|
429
525
|
router.patch(`${ap}/api/clients/:id`, [C.consoleClients, 'update']);
|
|
430
526
|
router.delete(`${ap}/api/clients/:id`, [C.consoleClients, 'destroy']);
|
|
431
|
-
router.post(`${ap}/api/clients/:id/regenerate-secret`, [
|
|
527
|
+
router.post(`${ap}/api/clients/:id/regenerate-secret`, [
|
|
528
|
+
C.consoleClients,
|
|
529
|
+
'regenerateSecret',
|
|
530
|
+
]);
|
|
432
531
|
// Roles.
|
|
433
532
|
router.get(`${ap}/api/roles`, [C.consoleRoles, 'index']);
|
|
434
533
|
router.post(`${ap}/api/roles`, [C.consoleRoles, 'store']);
|
|
@@ -447,7 +546,10 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
447
546
|
router.delete(`${ap}/api/orgs/:id/members/:accountId`, [C.consoleOrgs, 'removeMember']);
|
|
448
547
|
// Convites.
|
|
449
548
|
router.post(`${ap}/api/orgs/:id/invitations`, [C.consoleOrgs, 'createInvitation']);
|
|
450
|
-
router.delete(`${ap}/api/orgs/:id/invitations/:invitationId`, [
|
|
549
|
+
router.delete(`${ap}/api/orgs/:id/invitations/:invitationId`, [
|
|
550
|
+
C.consoleOrgs,
|
|
551
|
+
'revokeInvitation',
|
|
552
|
+
]);
|
|
451
553
|
// Auditoria (capability-gated: 404 quando sink não suporta consulta).
|
|
452
554
|
router.get(`${ap}/api/audit`, [C.consoleAudit, 'index']);
|
|
453
555
|
// Settings.
|
|
@@ -515,7 +617,10 @@ export function registerAuthHost(router, opts = {}) {
|
|
|
515
617
|
withApiThrottle(router.delete('/organizations/:id/members/:accountId', [C.apiOrgs, 'removeMember']));
|
|
516
618
|
withApiThrottle(router.patch('/organizations/:id/members/:accountId', [C.apiOrgs, 'updateMemberRole']));
|
|
517
619
|
withApiThrottle(router.post('/organizations/:id/invitations', [C.apiOrgs, 'createInvitation']));
|
|
518
|
-
withApiThrottle(router.delete('/organizations/:id/invitations/:invitationId', [
|
|
620
|
+
withApiThrottle(router.delete('/organizations/:id/invitations/:invitationId', [
|
|
621
|
+
C.apiOrgs,
|
|
622
|
+
'revokeInvitation',
|
|
623
|
+
]));
|
|
519
624
|
// Auditoria + métricas + verificação de token.
|
|
520
625
|
withApiThrottle(router.get('/audit', [C.apiMisc, 'audit']));
|
|
521
626
|
withApiThrottle(router.get('/stats', [C.apiMisc, 'stats']));
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getAccountLoginUrl } from '../account_login_url.js';
|
|
2
|
+
import { accountPathsMap } from '../account_paths.js';
|
|
1
3
|
import { DEFAULT_MESSAGES, translate } from '../i18n.js';
|
|
2
4
|
/**
|
|
3
5
|
* Resolve o catálogo de mensagens ativo a partir do `authkit.server` (config
|
|
@@ -28,7 +30,23 @@ async function resolveMessagesFromCtx(ctx) {
|
|
|
28
30
|
export async function renderEdgeView(ctx, view, props) {
|
|
29
31
|
const messages = await resolveMessagesFromCtx(ctx);
|
|
30
32
|
const t = (key, params) => translate(messages, key, params);
|
|
31
|
-
|
|
33
|
+
// `loginUrl` como prop global: as views que linkam "faça login" (ex.: `otp-unlock`)
|
|
34
|
+
// usam o destino configurável (`accountLoginUrl`) em vez do `/account/login` fixo,
|
|
35
|
+
// que pode estar desmontado. Props explícitas ainda têm precedência (spread depois).
|
|
36
|
+
const loginUrl = getAccountLoginUrl();
|
|
37
|
+
// `accountPaths` como prop global: os `<form action>`/`fetch()` das views do
|
|
38
|
+
// console de conta (security, mfa, tokens, apps, orgs, ...) derivam o path de
|
|
39
|
+
// cada tela daqui, respeitando o prefixo/segmentos configurados via
|
|
40
|
+
// `accountRoutes` — sem cada view conhecer o prefixo. Os action-subpaths
|
|
41
|
+
// fixos (`/password`, `/passkeys/verify`, ...) são concatenados na própria view.
|
|
42
|
+
const accountPaths = accountPathsMap();
|
|
43
|
+
return ctx.view.render(`authkit::${view}`, {
|
|
44
|
+
loginUrl,
|
|
45
|
+
accountPaths,
|
|
46
|
+
...props,
|
|
47
|
+
t,
|
|
48
|
+
messages,
|
|
49
|
+
});
|
|
32
50
|
}
|
|
33
51
|
/** Renderer do seam para hosts Edge. As views são donas-da-lib (disco `authkit::`). */
|
|
34
52
|
export function edgeRenderer() {
|
|
@@ -66,5 +66,68 @@ export type AuthkitScreen = 'login' | 'signup' | 'consent' | 'forgot' | 'reset'
|
|
|
66
66
|
* | `returnTo` | `string \| null` | Caminho interno de destino pós-login (já validado pelo servidor — só caminhos internos). Quando presente, o formulário deve incluir `<input type="hidden" name="return_to" value={returnTo} />`. O servidor revalida o valor no POST; hosts com tela custom precisam propagar esse hidden input. |
|
|
67
67
|
* | `error` | `string \| undefined` | Mensagem de erro de autenticação localizada (credenciais inválidas, conta bloqueada, etc.). |
|
|
68
68
|
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
69
|
+
*
|
|
70
|
+
* ### Props da tela `account/security`
|
|
71
|
+
*
|
|
72
|
+
* | Prop | Tipo | Descrição |
|
|
73
|
+
* |-------------------------|---------------------|-----------|
|
|
74
|
+
* | `csrfToken` | `string` | Token CSRF para os formulários da tela. |
|
|
75
|
+
* | `supported` | `boolean` | `false` quando o store não suporta o self-service de segurança (troca de senha/e-mail) — a tela deve degradar. |
|
|
76
|
+
* | `profileSupported` | `boolean` | `true` quando o store suporta editar nome/avatar (`updateProfile`). |
|
|
77
|
+
* | `avatarUploadSupported` | `boolean` | `true` quando algum backend (drive OU media) pode armazenar o upload de avatar. |
|
|
78
|
+
* | `email` | `string` | E-mail atual da conta (`''` se ausente). |
|
|
79
|
+
* | `name` | `string` | Nome atual da conta (`''` se ausente). |
|
|
80
|
+
* | `avatarUrl` | `string` | URL do avatar atual (`''` se ausente). |
|
|
81
|
+
* | `passwordChanged` | `string \| null` | Flash de sucesso da troca de senha (mensagem localizada) ou `null`. |
|
|
82
|
+
* | `emailChangeRequested` | `string \| null` | Flash: link de confirmação de troca de e-mail enviado (ou cancelamento) ou `null`. |
|
|
83
|
+
* | `emailChanged` | `string \| null` | Flash: troca de e-mail concluída ou `null`. |
|
|
84
|
+
* | `profileUpdated` | `string \| null` | Flash: perfil atualizado ou `null`. |
|
|
85
|
+
* | `error` | `string \| null` | Flash de erro de segurança (senha inválida, e-mail em uso, política violada) ou `null`. |
|
|
86
|
+
* | `trustedDevicesEnabled` | `boolean` | `true` quando o recurso de dispositivos confiáveis está ligado. |
|
|
87
|
+
* | `trustedDevicesRevoked` | `string \| null` | Flash: confiança deste navegador revogada ou `null`. |
|
|
88
|
+
* | `sessionsSupported` | `boolean` | `true` quando o adapter OIDC enumera as sessões ativas da conta. |
|
|
89
|
+
* | `sessions` | `Array<{ loginTs: string; browser: string; os: string; ip: string; location: string }>` | Sessões ativas da própria conta (vazio quando não suportado). `loginTs` é ISO ou `''`. |
|
|
90
|
+
* | `exportSupported` | `boolean` | Sempre `true` — export de dados (portabilidade/LGPD) disponível para a conta logada. |
|
|
91
|
+
* | `deletionSupported` | `boolean` | `true` quando o store suporta hard delete (danger zone). |
|
|
92
|
+
* | `deleteError` | `string \| null` | Flash de erro da confirmação de deleção ou `null`. |
|
|
93
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
94
|
+
*
|
|
95
|
+
* ### Props da tela `account/mfa`
|
|
96
|
+
*
|
|
97
|
+
* As props variam por action: `index` manda o estado base; `enroll` acrescenta
|
|
98
|
+
* `enrolling`/`secret`/`qrDataUrl` (passo do QR); `confirm` com código inválido
|
|
99
|
+
* reenvia `enrolling: true` + `error` (sem regenerar o segredo).
|
|
100
|
+
*
|
|
101
|
+
* | Prop | Tipo | Descrição |
|
|
102
|
+
* |---------------------|---------------------|-----------|
|
|
103
|
+
* | `csrfToken` | `string` | Token CSRF para os formulários de enroll/confirm/disable e passkeys. |
|
|
104
|
+
* | `enabled` | `boolean` | `true` quando o TOTP já está confirmado (habilitado) para a conta. |
|
|
105
|
+
* | `recoveryCodes` | `string[] \| null` | Códigos de recuperação recém-gerados (exibidos UMA vez após enroll/confirm) ou `null`. |
|
|
106
|
+
* | `passkeysSupported` | `boolean` | `true` quando o store persiste credenciais WebAuthn (passkeys). |
|
|
107
|
+
* | `passkeys` | `Array<{ id: string; label?: string; createdAt: string }>` | Passkeys cadastradas (vazio quando não suportado). `id` é base64url; `createdAt` é ISO. Presente em `index`. |
|
|
108
|
+
* | `enrolling` | `boolean \| undefined` | `true` no passo de enrollment (após `POST /mfa/enroll` e na reexibição do `confirm` com código inválido) — a tela mostra o QR/segredo e o campo de código. Ausente em `index`. |
|
|
109
|
+
* | `secret` | `string \| null \| undefined` | Segredo TOTP em texto (base32) para entrada manual, exibido no passo de enroll. `null` na reexibição do `confirm` (o segredo pendente NÃO é regenerado). Ausente em `index`. |
|
|
110
|
+
* | `qrDataUrl` | `string \| null \| undefined` | QR code do `otpauth://` como data-URL (`<img src>`), no passo de enroll. `null` na reexibição do `confirm`. Ausente em `index`. |
|
|
111
|
+
* | `error` | `string \| undefined` | Mensagem de erro localizada (ex.: código TOTP inválido no `confirm`). Ausente quando não há erro. |
|
|
112
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
113
|
+
*
|
|
114
|
+
* ### Props da tela `account/confirm` (sudo — confirmar identidade)
|
|
115
|
+
*
|
|
116
|
+
* | Prop | Tipo | Descrição |
|
|
117
|
+
* |---------------|---------------------|-----------|
|
|
118
|
+
* | `csrfToken` | `string` | Token CSRF para o POST de cada método. |
|
|
119
|
+
* | `returnTo` | `string \| null` | Caminho interno de destino após confirmar (validado pelo servidor) ou `null`. |
|
|
120
|
+
* | `error` | `string \| null` | Flash de erro da última tentativa de confirmação ou `null`. |
|
|
121
|
+
* | `notice` | `string \| null` | Flash informativo (ex.: "link de confirmação enviado") ou `null`. |
|
|
122
|
+
* | `methods` | `Array<{ id: string; labelKey: string; kind: 'form' \| 'action' \| 'redirect' \| 'webauthn'; endpoint: string; fields?: Array<{ name: string; type: 'password' \| 'text'; labelKey: string }> }>` | Métodos de sudo disponíveis para a conta. A tela renderiza por `kind`; `endpoint` é o POST de verificação (`webauthn` pede options em `${endpoint}/options`). |
|
|
123
|
+
* | `preferredId` | `string \| null` | `id` do último método usado (destaque na UI) ou `null`. |
|
|
124
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
125
|
+
*
|
|
126
|
+
* ### Props da tela `account/email-confirmed` (terminal do link de troca de e-mail)
|
|
127
|
+
*
|
|
128
|
+
* | Prop | Tipo | Descrição |
|
|
129
|
+
* |------------|----------------|-----------|
|
|
130
|
+
* | `ok` | `boolean` | `true` quando o token era válido e o novo e-mail foi aplicado; `false` para token inválido/expirado ou store sem suporte. A tela mostra sucesso ou falha conforme o valor. |
|
|
131
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
69
132
|
*/
|
|
70
133
|
export declare function inertiaRenderer(opts: InertiaRendererOptions): (ctx: HttpContext, view: string, props: Record<string, unknown>) => Promise<any>;
|
|
@@ -37,6 +37,69 @@ async function resolveMessagesFromCtx(ctx) {
|
|
|
37
37
|
* | `returnTo` | `string \| null` | Caminho interno de destino pós-login (já validado pelo servidor — só caminhos internos). Quando presente, o formulário deve incluir `<input type="hidden" name="return_to" value={returnTo} />`. O servidor revalida o valor no POST; hosts com tela custom precisam propagar esse hidden input. |
|
|
38
38
|
* | `error` | `string \| undefined` | Mensagem de erro de autenticação localizada (credenciais inválidas, conta bloqueada, etc.). |
|
|
39
39
|
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
40
|
+
*
|
|
41
|
+
* ### Props da tela `account/security`
|
|
42
|
+
*
|
|
43
|
+
* | Prop | Tipo | Descrição |
|
|
44
|
+
* |-------------------------|---------------------|-----------|
|
|
45
|
+
* | `csrfToken` | `string` | Token CSRF para os formulários da tela. |
|
|
46
|
+
* | `supported` | `boolean` | `false` quando o store não suporta o self-service de segurança (troca de senha/e-mail) — a tela deve degradar. |
|
|
47
|
+
* | `profileSupported` | `boolean` | `true` quando o store suporta editar nome/avatar (`updateProfile`). |
|
|
48
|
+
* | `avatarUploadSupported` | `boolean` | `true` quando algum backend (drive OU media) pode armazenar o upload de avatar. |
|
|
49
|
+
* | `email` | `string` | E-mail atual da conta (`''` se ausente). |
|
|
50
|
+
* | `name` | `string` | Nome atual da conta (`''` se ausente). |
|
|
51
|
+
* | `avatarUrl` | `string` | URL do avatar atual (`''` se ausente). |
|
|
52
|
+
* | `passwordChanged` | `string \| null` | Flash de sucesso da troca de senha (mensagem localizada) ou `null`. |
|
|
53
|
+
* | `emailChangeRequested` | `string \| null` | Flash: link de confirmação de troca de e-mail enviado (ou cancelamento) ou `null`. |
|
|
54
|
+
* | `emailChanged` | `string \| null` | Flash: troca de e-mail concluída ou `null`. |
|
|
55
|
+
* | `profileUpdated` | `string \| null` | Flash: perfil atualizado ou `null`. |
|
|
56
|
+
* | `error` | `string \| null` | Flash de erro de segurança (senha inválida, e-mail em uso, política violada) ou `null`. |
|
|
57
|
+
* | `trustedDevicesEnabled` | `boolean` | `true` quando o recurso de dispositivos confiáveis está ligado. |
|
|
58
|
+
* | `trustedDevicesRevoked` | `string \| null` | Flash: confiança deste navegador revogada ou `null`. |
|
|
59
|
+
* | `sessionsSupported` | `boolean` | `true` quando o adapter OIDC enumera as sessões ativas da conta. |
|
|
60
|
+
* | `sessions` | `Array<{ loginTs: string; browser: string; os: string; ip: string; location: string }>` | Sessões ativas da própria conta (vazio quando não suportado). `loginTs` é ISO ou `''`. |
|
|
61
|
+
* | `exportSupported` | `boolean` | Sempre `true` — export de dados (portabilidade/LGPD) disponível para a conta logada. |
|
|
62
|
+
* | `deletionSupported` | `boolean` | `true` quando o store suporta hard delete (danger zone). |
|
|
63
|
+
* | `deleteError` | `string \| null` | Flash de erro da confirmação de deleção ou `null`. |
|
|
64
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
65
|
+
*
|
|
66
|
+
* ### Props da tela `account/mfa`
|
|
67
|
+
*
|
|
68
|
+
* As props variam por action: `index` manda o estado base; `enroll` acrescenta
|
|
69
|
+
* `enrolling`/`secret`/`qrDataUrl` (passo do QR); `confirm` com código inválido
|
|
70
|
+
* reenvia `enrolling: true` + `error` (sem regenerar o segredo).
|
|
71
|
+
*
|
|
72
|
+
* | Prop | Tipo | Descrição |
|
|
73
|
+
* |---------------------|---------------------|-----------|
|
|
74
|
+
* | `csrfToken` | `string` | Token CSRF para os formulários de enroll/confirm/disable e passkeys. |
|
|
75
|
+
* | `enabled` | `boolean` | `true` quando o TOTP já está confirmado (habilitado) para a conta. |
|
|
76
|
+
* | `recoveryCodes` | `string[] \| null` | Códigos de recuperação recém-gerados (exibidos UMA vez após enroll/confirm) ou `null`. |
|
|
77
|
+
* | `passkeysSupported` | `boolean` | `true` quando o store persiste credenciais WebAuthn (passkeys). |
|
|
78
|
+
* | `passkeys` | `Array<{ id: string; label?: string; createdAt: string }>` | Passkeys cadastradas (vazio quando não suportado). `id` é base64url; `createdAt` é ISO. Presente em `index`. |
|
|
79
|
+
* | `enrolling` | `boolean \| undefined` | `true` no passo de enrollment (após `POST /mfa/enroll` e na reexibição do `confirm` com código inválido) — a tela mostra o QR/segredo e o campo de código. Ausente em `index`. |
|
|
80
|
+
* | `secret` | `string \| null \| undefined` | Segredo TOTP em texto (base32) para entrada manual, exibido no passo de enroll. `null` na reexibição do `confirm` (o segredo pendente NÃO é regenerado). Ausente em `index`. |
|
|
81
|
+
* | `qrDataUrl` | `string \| null \| undefined` | QR code do `otpauth://` como data-URL (`<img src>`), no passo de enroll. `null` na reexibição do `confirm`. Ausente em `index`. |
|
|
82
|
+
* | `error` | `string \| undefined` | Mensagem de erro localizada (ex.: código TOTP inválido no `confirm`). Ausente quando não há erro. |
|
|
83
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
84
|
+
*
|
|
85
|
+
* ### Props da tela `account/confirm` (sudo — confirmar identidade)
|
|
86
|
+
*
|
|
87
|
+
* | Prop | Tipo | Descrição |
|
|
88
|
+
* |---------------|---------------------|-----------|
|
|
89
|
+
* | `csrfToken` | `string` | Token CSRF para o POST de cada método. |
|
|
90
|
+
* | `returnTo` | `string \| null` | Caminho interno de destino após confirmar (validado pelo servidor) ou `null`. |
|
|
91
|
+
* | `error` | `string \| null` | Flash de erro da última tentativa de confirmação ou `null`. |
|
|
92
|
+
* | `notice` | `string \| null` | Flash informativo (ex.: "link de confirmação enviado") ou `null`. |
|
|
93
|
+
* | `methods` | `Array<{ id: string; labelKey: string; kind: 'form' \| 'action' \| 'redirect' \| 'webauthn'; endpoint: string; fields?: Array<{ name: string; type: 'password' \| 'text'; labelKey: string }> }>` | Métodos de sudo disponíveis para a conta. A tela renderiza por `kind`; `endpoint` é o POST de verificação (`webauthn` pede options em `${endpoint}/options`). |
|
|
94
|
+
* | `preferredId` | `string \| null` | `id` do último método usado (destaque na UI) ou `null`. |
|
|
95
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
96
|
+
*
|
|
97
|
+
* ### Props da tela `account/email-confirmed` (terminal do link de troca de e-mail)
|
|
98
|
+
*
|
|
99
|
+
* | Prop | Tipo | Descrição |
|
|
100
|
+
* |------------|----------------|-----------|
|
|
101
|
+
* | `ok` | `boolean` | `true` quando o token era válido e o novo e-mail foi aplicado; `false` para token inválido/expirado ou store sem suporte. A tela mostra sucesso ou falha conforme o valor. |
|
|
102
|
+
* | `messages` | `AuthMessages` | Catálogo de mensagens i18n. |
|
|
40
103
|
*/
|
|
41
104
|
export function inertiaRenderer(opts) {
|
|
42
105
|
const allowed = opts.views ? new Set(opts.views) : null;
|
|
@@ -65,7 +65,7 @@ export interface RegistrationSetting {
|
|
|
65
65
|
* FAIL-SAFE: `getSetting` nunca lança (contrato do RuntimeSettings). Se
|
|
66
66
|
* retornar null, usamos configDefault.
|
|
67
67
|
*/
|
|
68
|
-
export declare function resolveEffectiveRegistration(configDefault: boolean
|
|
68
|
+
export declare function resolveEffectiveRegistration(configDefault: boolean, settings: SettingsCapability): Promise<boolean>;
|
|
69
69
|
/**
|
|
70
70
|
* Shape da setting `require_verified_email` em `auth_settings`.
|
|
71
71
|
*
|
|
@@ -96,14 +96,14 @@ export interface ResolvedRequireVerifiedEmail {
|
|
|
96
96
|
* - setting presente → sobrescreve.
|
|
97
97
|
* - setting ausente/inválido/erro → usa configDefault.
|
|
98
98
|
*/
|
|
99
|
-
export declare function resolveEffectiveRequireVerifiedEmail(configDefault: boolean
|
|
99
|
+
export declare function resolveEffectiveRequireVerifiedEmail(configDefault: boolean, settings: SettingsCapability): Promise<boolean>;
|
|
100
100
|
/**
|
|
101
101
|
* Resolve o valor efetivo COMPLETO de `require_verified_email` incluindo
|
|
102
102
|
* `graceDays`. Usado pelo gate de login para implementar a janela de graça.
|
|
103
103
|
*
|
|
104
104
|
* FAIL-SAFE: qualquer erro → `{ enabled: configDefault, graceDays: 0 }`.
|
|
105
105
|
*/
|
|
106
|
-
export declare function resolveEffectiveRequireVerifiedEmailFull(configDefault: boolean
|
|
106
|
+
export declare function resolveEffectiveRequireVerifiedEmailFull(configDefault: boolean, settings: SettingsCapability): Promise<ResolvedRequireVerifiedEmail>;
|
|
107
107
|
/**
|
|
108
108
|
* Shape da setting `maintenance_mode` em `auth_settings`.
|
|
109
109
|
*
|