@adonis-agora/authkit-server 0.55.2 → 0.56.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.
@@ -8,13 +8,15 @@ export interface AccountDeleteWorkflowInput {
8
8
  actor: DeletionActor;
9
9
  }
10
10
  /**
11
- * Forma mínima do `ctx` durável que o corpo usa (um `ctx.step` checkpointado e
12
- * idempotente). Tipada estruturalmente para NÃO acoplar o build do authkit ao
13
- * pacote `@adonis-agora/durable` (peer OPCIONAL): o app passa o `engine.register`
14
- * real e o ctx satisfaz esta interface em runtime.
11
+ * Forma mínima do `ctx` durável que o corpo usa (um `ctx.localStep` checkpointado
12
+ * e idempotente executado IN-PROCESS, nunca dispatchado a um worker remoto;
13
+ * distinto do `ctx.step` do engine, que é SEMPRE dispatchado a um handler
14
+ * registrado por nome). Tipada estruturalmente para NÃO acoplar o build do
15
+ * authkit ao pacote `@adonis-agora/durable` (peer OPCIONAL): o app passa o
16
+ * `engine.register` real e o ctx satisfaz esta interface em runtime.
15
17
  */
16
18
  export interface DurableStepCtx {
17
- step<T>(name: string, fn: (...args: any[]) => Promise<T>, options?: unknown): Promise<T>;
19
+ localStep<T>(name: string, fn: (...args: any[]) => Promise<T>, options?: unknown): Promise<T>;
18
20
  }
19
21
  /** A assinatura do corpo do workflow (compatível com `engine.register`). */
20
22
  export type WorkflowBody = (ctx: DurableStepCtx, input: AccountDeleteWorkflowInput) => Promise<unknown>;
@@ -35,9 +37,9 @@ export interface AccountDeletionWorkflowDeps {
35
37
  * ```
36
38
  *
37
39
  * O corpo é FORWARD-ONLY (sem compensação — nunca des-deleta): cada etapa do
38
- * cascade é um `ctx.step` checkpointado, com retry por-etapa e resumabilidade. A
40
+ * cascade é um `ctx.localStep` checkpointado, com retry por-etapa e resumabilidade. A
39
41
  * linha da conta é a ÚLTIMA etapa. Todos os efeitos colaterais ficam DENTRO de
40
- * `ctx.step` (corpo determinístico: nada de Date.now()/random no corpo). A
42
+ * `ctx.localStep` (corpo determinístico: nada de Date.now()/random no corpo). A
41
43
  * idempotência por `accountId` é feita pelo run-id no enqueue (ver
42
44
  * `enqueueAccountDeletion`).
43
45
  */
@@ -30,9 +30,9 @@ function emptyResult() {
30
30
  * ```
31
31
  *
32
32
  * O corpo é FORWARD-ONLY (sem compensação — nunca des-deleta): cada etapa do
33
- * cascade é um `ctx.step` checkpointado, com retry por-etapa e resumabilidade. A
33
+ * cascade é um `ctx.localStep` checkpointado, com retry por-etapa e resumabilidade. A
34
34
  * linha da conta é a ÚLTIMA etapa. Todos os efeitos colaterais ficam DENTRO de
35
- * `ctx.step` (corpo determinístico: nada de Date.now()/random no corpo). A
35
+ * `ctx.localStep` (corpo determinístico: nada de Date.now()/random no corpo). A
36
36
  * idempotência por `accountId` é feita pelo run-id no enqueue (ver
37
37
  * `enqueueAccountDeletion`).
38
38
  */
@@ -42,7 +42,7 @@ export function defineAccountDeletionWorkflow(deps) {
42
42
  // Snapshot da conta ANTES de destruir (e-mail + avatar) — capturado num step
43
43
  // para ser determinístico no replay. Se a conta não existe (ou já foi
44
44
  // deletada num run anterior), encerra como no-op.
45
- const snapshot = await ctx.step('snapshot', async () => {
45
+ const snapshot = await ctx.localStep('snapshot', async () => {
46
46
  const cfg = (await deps.oidc()).config;
47
47
  return snapshotAccount(cfg, accountId);
48
48
  });
@@ -50,36 +50,36 @@ export function defineAccountDeletionWorkflow(deps) {
50
50
  return emptyResult();
51
51
  const result = emptyResult();
52
52
  // 1) Audit `account.deleted` ANTES de qualquer destruição.
53
- await ctx.step('audit.deleted', async () => {
53
+ await ctx.localStep('audit.deleted', async () => {
54
54
  const cfg = (await deps.oidc()).config;
55
55
  await auditDeleted(cfg, snapshot, actor);
56
56
  });
57
57
  // 2) Sessões + grants (cascateia os tokens do oidc-provider).
58
- const revoke = await ctx.step('revoke.sessions', async () => revokeSessions(await deps.oidc(), accountId));
58
+ const revoke = await ctx.localStep('revoke.sessions', async () => revokeSessions(await deps.oidc(), accountId));
59
59
  result.sessions = revoke.sessions;
60
60
  result.grants = revoke.grants;
61
61
  result.accessTokens = revoke.accessTokens;
62
62
  result.refreshTokens = revoke.refreshTokens;
63
63
  // 3) Personal Access Tokens.
64
- result.pats = (await ctx.step('revoke.pats', async () => revokePats((await deps.oidc()).config, accountId))).pats;
64
+ result.pats = (await ctx.localStep('revoke.pats', async () => revokePats((await deps.oidc()).config, accountId))).pats;
65
65
  // 4) Passkeys / credenciais WebAuthn.
66
- result.passkeys = (await ctx.step('remove.passkeys', async () => removePasskeys((await deps.oidc()).config, accountId))).passkeys;
66
+ result.passkeys = (await ctx.localStep('remove.passkeys', async () => removePasskeys((await deps.oidc()).config, accountId))).passkeys;
67
67
  // 5) MFA / TOTP.
68
- await ctx.step('disable.mfa', async () => {
68
+ await ctx.localStep('disable.mfa', async () => {
69
69
  await disableMfa((await deps.oidc()).config, accountId);
70
70
  });
71
71
  // 6) Identidades de provider linkadas.
72
- result.providerIdentities = (await ctx.step('unlink.providers', async () => unlinkProviders((await deps.oidc()).config, accountId))).providerIdentities;
72
+ result.providerIdentities = (await ctx.localStep('unlink.providers', async () => unlinkProviders((await deps.oidc()).config, accountId))).providerIdentities;
73
73
  // 6b) Organizations.
74
- const orgResult = await ctx.step('remove.orgs', async () => removeFromOrgs((await deps.oidc()).config, accountId));
74
+ const orgResult = await ctx.localStep('remove.orgs', async () => removeFromOrgs((await deps.oidc()).config, accountId));
75
75
  result.orgMemberships = orgResult.orgMemberships;
76
76
  result.orgInvitations = orgResult.orgInvitations;
77
77
  // 7) Avatar no drive.
78
- result.avatarDeleted = (await ctx.step('delete.avatar', async () => deleteAccountAvatar((await deps.oidc()).config, accountId, snapshot.avatarUrl))).avatarDeleted;
78
+ result.avatarDeleted = (await ctx.localStep('delete.avatar', async () => deleteAccountAvatar((await deps.oidc()).config, accountId, snapshot.avatarUrl))).avatarDeleted;
79
79
  // 8) Anonimiza o histórico de audit.
80
- result.auditAnonymized = (await ctx.step('anonymize.audit', async () => anonymizeAudit((await deps.oidc()).config, accountId))).auditAnonymized;
80
+ result.auditAnonymized = (await ctx.localStep('anonymize.audit', async () => anonymizeAudit((await deps.oidc()).config, accountId))).auditAnonymized;
81
81
  // 9) Deleta a linha da conta (ÚLTIMA etapa, forward-only).
82
- result.ok = (await ctx.step('delete.account', async () => deleteAccountRow((await deps.oidc()).config, accountId))).ok;
82
+ result.ok = (await ctx.localStep('delete.account', async () => deleteAccountRow((await deps.oidc()).config, accountId))).ok;
83
83
  return result;
84
84
  };
85
85
  return { name: ACCOUNT_DELETE_WORKFLOW, version: '1', body };
@@ -50,7 +50,7 @@ export interface AccountExportWorkflowDeps {
50
50
  /**
51
51
  * Define a REGISTRAÇÃO do workflow durável `authkit.account.export`.
52
52
  *
53
- * Etapas (todas efeitos colaterais dentro de `ctx.step`, corpo determinístico):
53
+ * Etapas (todas efeitos colaterais dentro de `ctx.localStep`, corpo determinístico):
54
54
  * 1. `collect` — reúne o payload (reusa {@link AccountExportService.collect});
55
55
  * 2. `audit` — registra `account.exported`;
56
56
  * 3. `persist` — serializa + grava o artefato no drive;
@@ -45,7 +45,7 @@ const noopDeliver = async () => { };
45
45
  /**
46
46
  * Define a REGISTRAÇÃO do workflow durável `authkit.account.export`.
47
47
  *
48
- * Etapas (todas efeitos colaterais dentro de `ctx.step`, corpo determinístico):
48
+ * Etapas (todas efeitos colaterais dentro de `ctx.localStep`, corpo determinístico):
49
49
  * 1. `collect` — reúne o payload (reusa {@link AccountExportService.collect});
50
50
  * 2. `audit` — registra `account.exported`;
51
51
  * 3. `persist` — serializa + grava o artefato no drive;
@@ -61,14 +61,14 @@ export function defineAccountExportWorkflow(deps) {
61
61
  const { accountId } = input;
62
62
  const runId = ctx.runId ?? accountId;
63
63
  // 1) Coleta o payload (reusa a coleta inline do AccountExportService).
64
- const payload = await ctx.step('collect', async () => {
64
+ const payload = await ctx.localStep('collect', async () => {
65
65
  const oidc = await deps.oidc();
66
66
  return new AccountExportService(oidc).collect(accountId);
67
67
  });
68
68
  if (!payload)
69
69
  return { ok: false, artifactKey: null, bytes: 0 };
70
70
  // 2) Audita o export (account.exported).
71
- await ctx.step('audit', async () => {
71
+ await ctx.localStep('audit', async () => {
72
72
  const cfg = (await deps.oidc()).config;
73
73
  await cfg.audit?.record({
74
74
  type: 'account.exported',
@@ -78,12 +78,12 @@ export function defineAccountExportWorkflow(deps) {
78
78
  });
79
79
  // 3) Serializa + persiste o artefato.
80
80
  const json = JSON.stringify(payload, null, 2);
81
- const artifactKey = await ctx.step('persist', async () => {
81
+ const artifactKey = await ctx.localStep('persist', async () => {
82
82
  const oidc = await deps.oidc();
83
83
  return persist({ accountId, runId, json, oidc });
84
84
  });
85
85
  // 4) Entrega ao titular (signal + e-mail, pluggable).
86
- await ctx.step('deliver', async () => {
86
+ await ctx.localStep('deliver', async () => {
87
87
  const oidc = await deps.oidc();
88
88
  await deliver({ accountId, runId, artifactKey, oidc });
89
89
  });