@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.
Files changed (195) hide show
  1. package/build/commands/clients_create.js +4 -4
  2. package/build/commands/configure.js +3 -2
  3. package/build/commands/doctor.js +8 -5
  4. package/build/commands/eject.js +1 -1
  5. package/build/commands/expire_scan.js +7 -5
  6. package/build/commands/import_users.js +1 -1
  7. package/build/commands/keys_rotate.js +7 -4
  8. package/build/host/views/account/apps.edge +5 -5
  9. package/build/host/views/account/login.edge +1 -1
  10. package/build/host/views/account/mfa.edge +7 -7
  11. package/build/host/views/account/orgs.edge +5 -5
  12. package/build/host/views/account/security.edge +10 -10
  13. package/build/host/views/account/tokens.edge +5 -5
  14. package/build/host/views/otp-unlock.edge +2 -2
  15. package/build/index.d.ts +7 -7
  16. package/build/index.js +5 -5
  17. package/build/providers/authkit_server_provider.d.ts +2 -2
  18. package/build/providers/authkit_server_provider.js +26 -10
  19. package/build/services/booted_app.d.ts +8 -0
  20. package/build/services/booted_app.js +27 -0
  21. package/build/services/main.d.ts +8 -1
  22. package/build/services/main.js +10 -2
  23. package/build/src/accounts/lucid_account_store.d.ts +3 -3
  24. package/build/src/accounts/lucid_account_store.js +6 -8
  25. package/build/src/accounts/lucid_store/core.js +1 -1
  26. package/build/src/accounts/lucid_store/mfa.js +1 -1
  27. package/build/src/accounts/lucid_store/organizations.js +2 -4
  28. package/build/src/accounts/lucid_store/password_hygiene.js +1 -4
  29. package/build/src/accounts/lucid_store/shared.d.ts +1 -1
  30. package/build/src/accounts/lucid_stores.d.ts +3 -3
  31. package/build/src/accounts/lucid_stores.js +2 -2
  32. package/build/src/adapters/database_adapter.js +3 -1
  33. package/build/src/adapters/factory.js +1 -1
  34. package/build/src/adapters/redis_adapter.js +2 -1
  35. package/build/src/commands/expire_scan_command.js +19 -5
  36. package/build/src/commands/settings_commands.js +22 -5
  37. package/build/src/define_config.d.ts +20 -20
  38. package/build/src/define_config.js +62 -67
  39. package/build/src/doctor/checks.js +45 -20
  40. package/build/src/events/dispatcher.d.ts +1 -1
  41. package/build/src/events/dispatcher.js +10 -10
  42. package/build/src/host/account_api/account_api_controller.js +95 -39
  43. package/build/src/host/account_deletion_ops.d.ts +4 -4
  44. package/build/src/host/account_deletion_ops.js +5 -5
  45. package/build/src/host/account_deletion_service.d.ts +2 -2
  46. package/build/src/host/account_deletion_service.js +2 -2
  47. package/build/src/host/account_export_service.d.ts +1 -1
  48. package/build/src/host/account_export_service.js +4 -6
  49. package/build/src/host/account_home.d.ts +0 -8
  50. package/build/src/host/account_home.js +6 -4
  51. package/build/src/host/account_login_url.d.ts +44 -0
  52. package/build/src/host/account_login_url.js +58 -0
  53. package/build/src/host/account_paths.d.ts +120 -0
  54. package/build/src/host/account_paths.js +161 -0
  55. package/build/src/host/admin_api/admin_orgs_service.d.ts +2 -2
  56. package/build/src/host/admin_api/admin_orgs_service.js +3 -2
  57. package/build/src/host/admin_api/admin_users_service.d.ts +12 -12
  58. package/build/src/host/admin_api/admin_users_service.js +20 -20
  59. package/build/src/host/admin_api/api_clients_controller.js +2 -2
  60. package/build/src/host/admin_api/api_misc_controller.js +2 -2
  61. package/build/src/host/admin_api/api_orgs_controller.js +3 -3
  62. package/build/src/host/admin_api/api_settings_controller.js +11 -5
  63. package/build/src/host/admin_api/api_users_controller.d.ts +2 -2
  64. package/build/src/host/admin_api/api_users_controller.js +37 -38
  65. package/build/src/host/admin_api/dto.d.ts +4 -4
  66. package/build/src/host/admin_clients_service.js +5 -4
  67. package/build/src/host/admin_console/admin_shell_controller.js +4 -2
  68. package/build/src/host/admin_console/console_audit_controller.js +1 -1
  69. package/build/src/host/admin_console/console_clients_controller.js +5 -3
  70. package/build/src/host/admin_console/console_impersonation_controller.js +1 -1
  71. package/build/src/host/admin_console/console_keys_controller.js +2 -4
  72. package/build/src/host/admin_console/console_orgs_controller.js +3 -3
  73. package/build/src/host/admin_console/console_roles_controller.js +30 -12
  74. package/build/src/host/admin_console/console_sessions_controller.js +3 -3
  75. package/build/src/host/admin_console/console_settings_controller.js +11 -5
  76. package/build/src/host/admin_console/console_users_controller.d.ts +2 -2
  77. package/build/src/host/admin_console/console_users_controller.js +46 -47
  78. package/build/src/host/admin_prefix.js +2 -2
  79. package/build/src/host/admin_sessions_service.d.ts +3 -1
  80. package/build/src/host/admin_sessions_service.js +36 -6
  81. package/build/src/host/adonis_auth_sync.d.ts +1 -1
  82. package/build/src/host/adonis_auth_user_provider.d.ts +1 -1
  83. package/build/src/host/app_key.js +1 -1
  84. package/build/src/host/avatar_storage.js +1 -3
  85. package/build/src/host/config_locks.js +1 -3
  86. package/build/src/host/console_session.d.ts +4 -0
  87. package/build/src/host/console_session.js +9 -2
  88. package/build/src/host/controllers/account_apps_controller.js +3 -2
  89. package/build/src/host/controllers/account_confirm_controller.js +2 -6
  90. package/build/src/host/controllers/account_mfa_controller.js +63 -12
  91. package/build/src/host/controllers/account_orgs_controller.js +53 -30
  92. package/build/src/host/controllers/account_security_controller.d.ts +2 -2
  93. package/build/src/host/controllers/account_security_controller.js +116 -116
  94. package/build/src/host/controllers/account_session_controller.js +7 -5
  95. package/build/src/host/controllers/account_tokens_controller.js +14 -2
  96. package/build/src/host/controllers/interaction_controller.js +59 -22
  97. package/build/src/host/controllers/pat_introspection_controller.js +10 -0
  98. package/build/src/host/controllers/registration_controller.js +28 -13
  99. package/build/src/host/default_mailer.js +11 -7
  100. package/build/src/host/durable/account_deletion_workflow.d.ts +2 -2
  101. package/build/src/host/durable/account_deletion_workflow.js +14 -14
  102. package/build/src/host/durable/account_export_workflow.d.ts +2 -2
  103. package/build/src/host/durable/account_export_workflow.js +12 -12
  104. package/build/src/host/durable/index.d.ts +5 -5
  105. package/build/src/host/durable/index.js +6 -6
  106. package/build/src/host/i18n.d.ts +1376 -1376
  107. package/build/src/host/i18n.js +1380 -1380
  108. package/build/src/host/impersonation.js +1 -7
  109. package/build/src/host/key_rotation_actions.d.ts +1 -1
  110. package/build/src/host/login_attempt.js +35 -6
  111. package/build/src/host/login_notify.js +1 -1
  112. package/build/src/host/middleware/account_auth.js +3 -1
  113. package/build/src/host/otp_lockout.js +1 -3
  114. package/build/src/host/rate_limit.js +1 -1
  115. package/build/src/host/register_auth_host.d.ts +96 -2
  116. package/build/src/host/register_auth_host.js +196 -91
  117. package/build/src/host/renderers/edge_renderer.js +19 -1
  118. package/build/src/host/renderers/inertia_renderer.d.ts +63 -0
  119. package/build/src/host/renderers/inertia_renderer.js +63 -0
  120. package/build/src/host/runtime_settings.js +1 -1
  121. package/build/src/host/runtime_toggles.d.ts +3 -3
  122. package/build/src/host/runtime_toggles.js +69 -24
  123. package/build/src/host/security_notice_service.d.ts +1 -1
  124. package/build/src/host/security_notice_service.js +1 -1
  125. package/build/src/host/session_context.js +1 -1
  126. package/build/src/host/sudo/index.d.ts +3 -3
  127. package/build/src/host/sudo/index.js +3 -3
  128. package/build/src/host/sudo/methods/magic_link.js +6 -5
  129. package/build/src/host/sudo/methods/passkey.js +7 -4
  130. package/build/src/host/sudo/methods/password.js +8 -3
  131. package/build/src/host/sudo/runtime.js +6 -13
  132. package/build/src/host/sudo_mode.js +3 -2
  133. package/build/src/host/ui-dist/assets/index-BQoTDiLV.js +137 -0
  134. package/build/src/host/ui-dist/index.html +1 -1
  135. package/build/src/keys/jwks_manager.js +1 -1
  136. package/build/src/keys/keystore.js +1 -1
  137. package/build/src/keys/keystore_manager.d.ts +2 -2
  138. package/build/src/keys/keystore_manager.js +2 -2
  139. package/build/src/keys/keystore_vault.js +8 -4
  140. package/build/src/mixins/with_audit_log.d.ts +1 -1
  141. package/build/src/mixins/with_auth_user.d.ts +1 -1
  142. package/build/src/mixins/with_auth_user.js +1 -1
  143. package/build/src/mixins/with_credentials.d.ts +1 -1
  144. package/build/src/mixins/with_mfa.d.ts +1 -1
  145. package/build/src/mixins/with_personal_access_token.d.ts +1 -1
  146. package/build/src/mixins/with_provider_identity.d.ts +1 -1
  147. package/build/src/mixins/with_webauthn_credential.d.ts +1 -1
  148. package/build/src/observability/diagnostics_bridge.js +2 -2
  149. package/build/src/observability/metrics_service.js +1 -1
  150. package/build/src/observability/telescope/data_providers.d.ts +1 -1
  151. package/build/src/observability/telescope/data_providers.js +29 -43
  152. package/build/src/observability/telescope/extension.d.ts +1 -1
  153. package/build/src/observability/telescope/extension.js +58 -58
  154. package/build/src/observability/telescope/index.d.ts +2 -2
  155. package/build/src/observability/telescope/index.js +2 -2
  156. package/build/src/observability/wire_provider_events.d.ts +1 -1
  157. package/build/src/observability/wire_provider_events.js +11 -11
  158. package/build/src/password/common_passwords.js +1 -1
  159. package/build/src/password/password_manager.d.ts +1 -1
  160. package/build/src/password/password_manager.js +4 -4
  161. package/build/src/pat/lucid_pat_store.js +2 -6
  162. package/build/src/pat/pat_tokens.js +1 -1
  163. package/build/src/provider/interaction_actions.js +1 -1
  164. package/build/src/provider/key_rotation_scheduler.js +3 -1
  165. package/build/src/provider/logout_sources.js +2 -8
  166. package/build/src/provider/oidc_service.d.ts +2 -2
  167. package/build/src/provider/oidc_service.js +22 -14
  168. package/build/src/provider/single_flight_lock.js +1 -3
  169. package/build/src/provider/token_exchange.d.ts +1 -1
  170. package/build/src/schema/ensure.js +3 -1
  171. package/build/stubs/ui/react/components/auth_shell.tsx +19 -19
  172. package/build/stubs/ui/react/pages/account/login.tsx +6 -7
  173. package/build/stubs/ui/react/pages/account/mfa.tsx +16 -15
  174. package/build/stubs/ui/react/pages/account/tokens.tsx +27 -17
  175. package/build/stubs/ui/react/pages/consent.tsx +12 -12
  176. package/build/stubs/ui/react/pages/forgot.tsx +7 -7
  177. package/build/stubs/ui/react/pages/login.tsx +22 -24
  178. package/build/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
  179. package/build/stubs/ui/react/pages/reset.tsx +10 -10
  180. package/build/stubs/ui/react/pages/signup.tsx +30 -16
  181. package/build/stubs/ui/react/pages/verify-email.tsx +6 -6
  182. package/package.json +1 -1
  183. package/stubs/main.ts +2 -2
  184. package/stubs/ui/react/components/auth_shell.tsx +19 -19
  185. package/stubs/ui/react/pages/account/login.tsx +6 -7
  186. package/stubs/ui/react/pages/account/mfa.tsx +16 -15
  187. package/stubs/ui/react/pages/account/tokens.tsx +27 -17
  188. package/stubs/ui/react/pages/consent.tsx +12 -12
  189. package/stubs/ui/react/pages/forgot.tsx +7 -7
  190. package/stubs/ui/react/pages/login.tsx +22 -24
  191. package/stubs/ui/react/pages/mfa-challenge.tsx +9 -10
  192. package/stubs/ui/react/pages/reset.tsx +10 -10
  193. package/stubs/ui/react/pages/signup.tsx +30 -16
  194. package/stubs/ui/react/pages/verify-email.tsx +6 -6
  195. package/build/src/host/ui-dist/assets/index-BmI_J87g.js +0 -137
@@ -1,9 +1,11 @@
1
1
  import '../augmentations.js';
2
2
  import { supportsOrganizations } from '../../accounts/account_store.js';
3
+ import { getAccountLoginUrl } from '../account_login_url.js';
4
+ import { accountPath } from '../account_paths.js';
5
+ import { ACTIVE_ORG_COOKIE, ACTIVE_ORG_COOKIE_TTL, encodeActiveOrgCookie, } from '../active_org_cookie.js';
3
6
  import { ACCOUNT_SESSION_KEY } from '../middleware/account_auth.js';
4
7
  import { resolveRuntimeSettings } from '../runtime_settings.js';
5
8
  import { isRoleInCatalog } from '../runtime_toggles.js';
6
- import { ACTIVE_ORG_COOKIE, ACTIVE_ORG_COOKIE_TTL, encodeActiveOrgCookie, } from '../active_org_cookie.js';
7
9
  /**
8
10
  * Console de conta — Organizations. Server-rendered, padrão dos outros controllers
9
11
  * de conta (account_tokens_controller, account_security_controller, etc.).
@@ -26,7 +28,7 @@ export default class AccountOrgsController {
26
28
  const accountId = session.get(ACCOUNT_SESSION_KEY);
27
29
  const account = await store.findById(accountId);
28
30
  if (!account)
29
- return response.redirect('/account/login');
31
+ return response.redirect(getAccountLoginUrl());
30
32
  const orgs = await store.listOrgsForAccount(accountId);
31
33
  const pendingInvitations = await store.listPendingInvitationsForEmail(account.email);
32
34
  // Enriquece convites com o nome da org
@@ -51,9 +53,7 @@ export default class AccountOrgsController {
51
53
  availableRoles: cfg.organizations.roles,
52
54
  messages,
53
55
  };
54
- return cfg.render
55
- ? cfg.render(ctx, 'account/orgs', props)
56
- : response.notFound();
56
+ return cfg.render ? cfg.render(ctx, 'account/orgs', props) : response.notFound();
57
57
  }
58
58
  /** POST /account/orgs — criar nova org (requer allowSelfCreate). */
59
59
  async store(ctx) {
@@ -68,7 +68,7 @@ export default class AccountOrgsController {
68
68
  const name = request.input('name', '').trim();
69
69
  const slug = request.input('slug', '').trim();
70
70
  if (!name || !slug)
71
- return response.redirect('/account/orgs');
71
+ return response.redirect(accountPath('orgs'));
72
72
  try {
73
73
  await store.createOrg({ name, slug, ownerAccountId: accountId });
74
74
  await cfg.audit?.record({ type: 'organization.created', accountId, metadata: { slug } });
@@ -76,7 +76,7 @@ export default class AccountOrgsController {
76
76
  catch {
77
77
  // slug duplicado ou outro erro — redireciona sem mensagem de erro específica
78
78
  }
79
- return response.redirect('/account/orgs');
79
+ return response.redirect(accountPath('orgs'));
80
80
  }
81
81
  /** POST /account/orgs/:id/activate — define org ativa (valida membership). */
82
82
  async activate(ctx) {
@@ -90,12 +90,16 @@ export default class AccountOrgsController {
90
90
  const orgId = params.id;
91
91
  const membership = await store.getOrgMembership(orgId, accountId);
92
92
  if (!membership)
93
- return response.redirect('/account/orgs');
93
+ return response.redirect(accountPath('orgs'));
94
94
  const org = await store.findOrgById(orgId);
95
95
  if (!org)
96
- return response.redirect('/account/orgs');
96
+ return response.redirect(accountPath('orgs'));
97
97
  // Grava cookie de org ativa
98
- const cookieValue = encodeActiveOrgCookie({ orgId, orgSlug: org.slug, orgRole: membership.role });
98
+ const cookieValue = encodeActiveOrgCookie({
99
+ orgId,
100
+ orgSlug: org.slug,
101
+ orgRole: membership.role,
102
+ });
99
103
  ctx.response.cookie(ACTIVE_ORG_COOKIE, cookieValue, {
100
104
  httpOnly: true,
101
105
  sameSite: 'lax',
@@ -103,8 +107,12 @@ export default class AccountOrgsController {
103
107
  secure: ctx.request.secure(),
104
108
  path: '/',
105
109
  });
106
- await cfg.audit?.record({ type: 'organization.switched', accountId, metadata: { orgId, orgSlug: org.slug } });
107
- return response.redirect('/account/orgs');
110
+ await cfg.audit?.record({
111
+ type: 'organization.switched',
112
+ accountId,
113
+ metadata: { orgId, orgSlug: org.slug },
114
+ });
115
+ return response.redirect(accountPath('orgs'));
108
116
  }
109
117
  /** POST /account/orgs/deactivate — remove org ativa. */
110
118
  async deactivate(ctx) {
@@ -114,7 +122,7 @@ export default class AccountOrgsController {
114
122
  const accountId = session.get(ACCOUNT_SESSION_KEY);
115
123
  ctx.response.clearCookie(ACTIVE_ORG_COOKIE, { path: '/' });
116
124
  await cfg.audit?.record({ type: 'organization.deactivated', accountId });
117
- return response.redirect('/account/orgs');
125
+ return response.redirect(accountPath('orgs'));
118
126
  }
119
127
  /** POST /account/orgs/:id/leave — sai da org (verifica last_owner). */
120
128
  async leave(ctx) {
@@ -127,9 +135,13 @@ export default class AccountOrgsController {
127
135
  return response.forbidden();
128
136
  const result = await store.removeOrgMember(params.id, accountId);
129
137
  if (result.ok) {
130
- await cfg.audit?.record({ type: 'organization.member_removed', accountId, metadata: { orgId: params.id, self: true } });
138
+ await cfg.audit?.record({
139
+ type: 'organization.member_removed',
140
+ accountId,
141
+ metadata: { orgId: params.id, self: true },
142
+ });
131
143
  }
132
- return response.redirect('/account/orgs');
144
+ return response.redirect(accountPath('orgs'));
133
145
  }
134
146
  /** POST /account/orgs/:id/invite — convida membro por e-mail. */
135
147
  async invite(ctx) {
@@ -148,7 +160,7 @@ export default class AccountOrgsController {
148
160
  const email = request.input('email', '').trim();
149
161
  const role = request.input('role', 'member').trim();
150
162
  if (!email)
151
- return response.redirect('/account/orgs');
163
+ return response.redirect(accountPath('orgs'));
152
164
  // H4: valida o role contra o catálogo efetivo de roles da org (runtime →
153
165
  // config → defaults). Role fora do catálogo é rejeitada (não cria convite).
154
166
  // Usa o helper PURO `isRoleInCatalog` (mesmo ponto de verdade do caminho admin).
@@ -159,7 +171,9 @@ export default class AccountOrgsController {
159
171
  invitationTtlHours: cfg.organizations.invitationTtlHours,
160
172
  }, params.id);
161
173
  if (!roleValid) {
162
- return response.unprocessableEntity({ error: { code: 'invalid_role', message: 'Role inválida.' } });
174
+ return response.unprocessableEntity({
175
+ error: { code: 'invalid_role', message: 'Role inválida.' },
176
+ });
163
177
  }
164
178
  // H4: no fluxo member-facing, só um OWNER pode conceder a role `owner`.
165
179
  // Um admin (não-owner) tentando convidar como `owner` é escalonamento.
@@ -176,7 +190,7 @@ export default class AccountOrgsController {
176
190
  // Dispara e-mail via mail hook (best-effort)
177
191
  if (cfg.mail?.onOrgInvitation) {
178
192
  const org = await store.findOrgById(params.id);
179
- const acceptUrl = `${ctx.request.protocol()}://${ctx.request.host()}/account/orgs/invitations/${token}/accept`;
193
+ const acceptUrl = `${ctx.request.protocol()}://${ctx.request.host()}${accountPath('orgs')}/invitations/${token}/accept`;
180
194
  try {
181
195
  await cfg.mail.onOrgInvitation({
182
196
  email,
@@ -197,7 +211,7 @@ export default class AccountOrgsController {
197
211
  accountId,
198
212
  metadata: { orgId: params.id, email, role },
199
213
  });
200
- return response.redirect('/account/orgs');
214
+ return response.redirect(accountPath('orgs'));
201
215
  }
202
216
  /** GET /account/orgs/invitations/:token/accept — mostra tela de aceite. */
203
217
  async showAcceptInvitation(ctx) {
@@ -210,9 +224,11 @@ export default class AccountOrgsController {
210
224
  return response.notFound();
211
225
  const accountId = session.get(ACCOUNT_SESSION_KEY);
212
226
  if (!accountId) {
213
- // Não logado: redireciona para login com return URL
214
- const returnTo = encodeURIComponent(`/account/orgs/invitations/${params.token}/accept`);
215
- return response.redirect(`/account/login?returnTo=${returnTo}`);
227
+ // Não logado: redireciona para login (configurável) com return URL
228
+ const loginUrl = getAccountLoginUrl();
229
+ const returnTo = encodeURIComponent(`${accountPath('orgs')}/invitations/${params.token}/accept`);
230
+ const sep = loginUrl.includes('?') ? '&' : '?';
231
+ return response.redirect(`${loginUrl}${sep}returnTo=${returnTo}`);
216
232
  }
217
233
  const tokenHash = createHash('sha256').update(params.token).digest('hex');
218
234
  const invitation = await store.findInvitationByTokenHash(tokenHash);
@@ -236,11 +252,11 @@ export default class AccountOrgsController {
236
252
  return response.notFound();
237
253
  const accountId = session.get(ACCOUNT_SESSION_KEY);
238
254
  if (!accountId)
239
- return response.redirect('/account/login');
255
+ return response.redirect(getAccountLoginUrl());
240
256
  const tokenHash = createHash('sha256').update(params.token).digest('hex');
241
257
  const invitation = await store.findInvitationByTokenHash(tokenHash);
242
258
  if (!invitation)
243
- return response.redirect('/account/orgs');
259
+ return response.redirect(accountPath('orgs'));
244
260
  const result = await store.acceptInvitation(invitation.id, accountId);
245
261
  if (result.ok) {
246
262
  await cfg.audit?.record({
@@ -249,7 +265,7 @@ export default class AccountOrgsController {
249
265
  metadata: { orgId: invitation.organizationId, invitationId: invitation.id },
250
266
  });
251
267
  }
252
- return response.redirect('/account/orgs');
268
+ return response.redirect(accountPath('orgs'));
253
269
  }
254
270
  /** POST /account/orgs/:id/members/:accountId/remove */
255
271
  async removeMember(ctx) {
@@ -261,7 +277,8 @@ export default class AccountOrgsController {
261
277
  if (!supportsOrganizations(store))
262
278
  return response.forbidden();
263
279
  const actorMembership = await store.getOrgMembership(params.id, actorId);
264
- if (!actorMembership || (actorMembership.role !== 'owner' && actorMembership.role !== 'admin')) {
280
+ if (!actorMembership ||
281
+ (actorMembership.role !== 'owner' && actorMembership.role !== 'admin')) {
265
282
  return response.forbidden();
266
283
  }
267
284
  const result = await store.removeOrgMember(params.id, params.accountId);
@@ -272,7 +289,7 @@ export default class AccountOrgsController {
272
289
  metadata: { orgId: params.id, targetAccountId: params.accountId },
273
290
  });
274
291
  }
275
- return response.redirect('/account/orgs');
292
+ return response.redirect(accountPath('orgs'));
276
293
  }
277
294
  /** POST /account/orgs/:id/invitations/:invId/revoke */
278
295
  async revokeInvitation(ctx) {
@@ -284,7 +301,8 @@ export default class AccountOrgsController {
284
301
  if (!supportsOrganizations(store))
285
302
  return response.forbidden();
286
303
  const actorMembership = await store.getOrgMembership(params.id, actorId);
287
- if (!actorMembership || (actorMembership.role !== 'owner' && actorMembership.role !== 'admin')) {
304
+ if (!actorMembership ||
305
+ (actorMembership.role !== 'owner' && actorMembership.role !== 'admin')) {
288
306
  return response.forbidden();
289
307
  }
290
308
  // Escopado por org (params.id já validado acima): impede IDOR cross-org.
@@ -294,7 +312,7 @@ export default class AccountOrgsController {
294
312
  actorId,
295
313
  metadata: { orgId: params.id, invitationId: params.invId },
296
314
  });
297
- return response.redirect('/account/orgs');
315
+ return response.redirect(accountPath('orgs'));
298
316
  }
299
317
  // ──────────────────────────────────────────────────────────────────────────
300
318
  // JSON endpoints — consumed by @adonis-agora/authkit-react hooks.
@@ -353,7 +371,12 @@ export default class AccountOrgsController {
353
371
  const members = canManage ? await store.listOrgMembers(params.id) : [];
354
372
  const enrichedMembers = await Promise.all(members.map(async (m) => {
355
373
  const account = await store.findById(m.accountId);
356
- return { accountId: m.accountId, email: account?.email ?? null, role: m.role, joinedAt: m.joinedAt };
374
+ return {
375
+ accountId: m.accountId,
376
+ email: account?.email ?? null,
377
+ role: m.role,
378
+ joinedAt: m.joinedAt,
379
+ };
357
380
  }));
358
381
  return {
359
382
  id: org.id,
@@ -1,5 +1,5 @@
1
- import "../augmentations.js";
2
- import type { HttpContext } from "@adonisjs/core/http";
1
+ import '../augmentations.js';
2
+ import type { HttpContext } from '@adonisjs/core/http';
3
3
  /**
4
4
  * Self-service de segurança da conta (console de conta): trocar a senha e o
5
5
  * e-mail. A troca de senha exige a senha ATUAL (verifyCredentials). A troca de