@nxgt/janus 0.22.1 → 0.23.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 (54) hide show
  1. package/README.md +96 -16
  2. package/dist/auth/config/janus-config.d.ts +2 -0
  3. package/dist/auth/config/janus-config.d.ts.map +1 -1
  4. package/dist/auth/config/resolved-config.d.ts +1 -0
  5. package/dist/auth/config/resolved-config.d.ts.map +1 -1
  6. package/dist/auth/config/warn-throttle-window.d.ts.map +1 -1
  7. package/dist/auth/email-flows/change-email-token.d.ts +42 -0
  8. package/dist/auth/email-flows/change-email-token.d.ts.map +1 -0
  9. package/dist/auth/email-flows/change-email.d.ts +11 -0
  10. package/dist/auth/email-flows/change-email.d.ts.map +1 -0
  11. package/dist/auth/email-flows/flows.d.ts +5 -5
  12. package/dist/auth/email-flows/flows.d.ts.map +1 -1
  13. package/dist/auth/events.d.ts +3 -2
  14. package/dist/auth/events.d.ts.map +1 -1
  15. package/dist/auth/index.d.ts +1 -1
  16. package/dist/auth/index.d.ts.map +1 -1
  17. package/dist/auth/mail-requests.d.ts +6 -3
  18. package/dist/auth/mail-requests.d.ts.map +1 -1
  19. package/dist/auth/one-time/issue.d.ts +7 -1
  20. package/dist/auth/one-time/issue.d.ts.map +1 -1
  21. package/dist/auth/port/types/tokens.d.ts +10 -4
  22. package/dist/auth/port/types/tokens.d.ts.map +1 -1
  23. package/dist/auth/types/change-email.d.ts +51 -0
  24. package/dist/auth/types/change-email.d.ts.map +1 -0
  25. package/dist/auth/types/index.d.ts +1 -0
  26. package/dist/auth/types/index.d.ts.map +1 -1
  27. package/dist/auth/types/janus.d.ts +2 -1
  28. package/dist/auth/types/janus.d.ts.map +1 -1
  29. package/dist/auth/types/user-type.d.ts +3 -1
  30. package/dist/auth/types/user-type.d.ts.map +1 -1
  31. package/dist/auth/users/any-type-api.d.ts +2 -2
  32. package/dist/auth/users/any-type-api.d.ts.map +1 -1
  33. package/dist/auth/users/update.d.ts +2 -1
  34. package/dist/auth/users/update.d.ts.map +1 -1
  35. package/dist/conformance/cases/tokens/change-email.d.ts +8 -0
  36. package/dist/conformance/cases/tokens/change-email.d.ts.map +1 -0
  37. package/dist/conformance/cases/tokens/index.d.ts.map +1 -1
  38. package/dist/conformance/cases/tokens/kinds.d.ts.map +1 -1
  39. package/dist/conformance/index.js +92 -57
  40. package/dist/conformance/index.js.map +6 -5
  41. package/dist/errors/janus-error/codes.d.ts +7 -3
  42. package/dist/errors/janus-error/codes.d.ts.map +1 -1
  43. package/dist/index.js +134 -31
  44. package/dist/index.js.map +13 -11
  45. package/docs/README.md +1 -1
  46. package/docs/guide/adapters.md +13 -7
  47. package/docs/guide/email-flows.md +90 -10
  48. package/docs/guide/errors.md +3 -3
  49. package/docs/guide/events.md +5 -4
  50. package/docs/guide/users.md +10 -8
  51. package/docs/guide/vocabulary.md +3 -3
  52. package/docs/roadmap.md +13 -10
  53. package/docs/troubleshooting.md +32 -12
  54. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"janus.d.ts","sourceRoot":"","sources":["../../../src/auth/types/janus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"janus.d.ts","sourceRoot":"","sources":["../../../src/auth/types/janus.ts"],"names":[],"mappings":"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"}
@@ -47,7 +47,9 @@ export interface UserTypeApi<U, In> {
47
47
  /**
48
48
  * Changes some fields and keeps the others: the patch is merged over the
49
49
  * stored fields, then **the whole result is validated**. Changing the e-mail
50
- * sets `emailVerified` back to `false`.
50
+ * sets `emailVerified` back to `false` and spends the user's pending
51
+ * `changeEmail` links. To move a user to a new address the new address
52
+ * proved, use `changeEmail`.
51
53
  */
52
54
  update(user: UserRef, patch: Partial<In>, options?: WriteOptions): Promise<U>;
53
55
  /** Activates or deactivates. An inactive user's sessions stop authenticating. */
@@ -1 +1 @@
1
- {"version":3,"file":"user-type.d.ts","sourceRoot":"","sources":["../../../src/auth/types/user-type.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEpD,oCAAoC;AACpC,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,EAAE;IACjC;;;;;;;OAOG;IACH,MAAM,CACL,KAAK,EAAE,EAAE,GAAG;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GACnE,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd,qGAAqG;IACrG,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAE/C,6CAA6C;IAC7C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE5B,iHAAiH;IACjH,IAAI,CAAC,IAAI,CAAC,EAAE;QACX,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3B;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9E,iFAAiF;IACjF,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9E;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC"}
1
+ {"version":3,"file":"user-type.d.ts","sourceRoot":"","sources":["../../../src/auth/types/user-type.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEpD,oCAAoC;AACpC,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,EAAE;IACjC;;;;;;;OAOG;IACH,MAAM,CACL,KAAK,EAAE,EAAE,GAAG;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GACnE,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd,qGAAqG;IACrG,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAE/C,6CAA6C;IAC7C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE5B,iHAAiH;IACjH,IAAI,CAAC,IAAI,CAAC,EAAE;QACX,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3B;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9E,iFAAiF;IACjF,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9E;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC"}
@@ -1,6 +1,6 @@
1
1
  import type { AnyUser } from '../context';
2
- import type { FindByEmailApi, MagicLinkApi, PasswordApi, ProvenSignInApi, ResetPasswordApi, SecondFactorApi, SignInCodeApi, SignInResult, StepUpApi, StepUpByApp, StepUpByEmail, UserTypeApi, VerifyEmailApi } from '../types';
2
+ import type { ChangeEmailApi, FindByEmailApi, MagicLinkApi, PasswordApi, ProvenSignInApi, ResetPasswordApi, SecondFactorApi, SignInCodeApi, SignInResult, StepUpApi, StepUpByApp, StepUpByEmail, UserTypeApi, VerifyEmailApi } from '../types';
3
3
  import type { Input } from './flow-types';
4
4
  /** Everything one user type answers. Which flows it has is decided by its types; all are built. */
5
- export type AnyTypeApi = UserTypeApi<AnyUser, Input> & PasswordApi<AnyUser, Input, string, SignInResult<AnyUser>> & SecondFactorApi<AnyUser> & ProvenSignInApi<AnyUser, SignInResult<AnyUser>> & SignInCodeApi<AnyUser, SignInResult<AnyUser>> & MagicLinkApi<AnyUser, SignInResult<AnyUser>> & StepUpApi<AnyUser, StepUpByEmail<AnyUser> | StepUpByApp<AnyUser>> & VerifyEmailApi<AnyUser> & FindByEmailApi<AnyUser> & ResetPasswordApi<AnyUser>;
5
+ export type AnyTypeApi = UserTypeApi<AnyUser, Input> & PasswordApi<AnyUser, Input, string, SignInResult<AnyUser>> & SecondFactorApi<AnyUser> & ProvenSignInApi<AnyUser, SignInResult<AnyUser>> & SignInCodeApi<AnyUser, SignInResult<AnyUser>> & MagicLinkApi<AnyUser, SignInResult<AnyUser>> & StepUpApi<AnyUser, StepUpByEmail<AnyUser> | StepUpByApp<AnyUser>> & VerifyEmailApi<AnyUser> & ChangeEmailApi<AnyUser> & FindByEmailApi<AnyUser> & ResetPasswordApi<AnyUser>;
6
6
  //# sourceMappingURL=any-type-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"any-type-api.d.ts","sourceRoot":"","sources":["../../../src/auth/users/any-type-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,aAAa,EACb,WAAW,EACX,cAAc,EACd,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,mGAAmG;AACnG,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,GACnD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC1D,eAAe,CAAC,OAAO,CAAC,GACxB,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC/C,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC7C,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC5C,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GACjE,cAAc,CAAC,OAAO,CAAC,GACvB,cAAc,CAAC,OAAO,CAAC,GACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"any-type-api.d.ts","sourceRoot":"","sources":["../../../src/auth/users/any-type-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EACX,cAAc,EACd,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,SAAS,EACT,WAAW,EACX,aAAa,EACb,WAAW,EACX,cAAc,EACd,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,mGAAmG;AACnG,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,GACnD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC1D,eAAe,CAAC,OAAO,CAAC,GACxB,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC/C,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC7C,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,GAC5C,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GACjE,cAAc,CAAC,OAAO,CAAC,GACvB,cAAc,CAAC,OAAO,CAAC,GACvB,cAAc,CAAC,OAAO,CAAC,GACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC"}
@@ -6,7 +6,8 @@ import type { Input } from './flow-types';
6
6
  /**
7
7
  * `update`: the patch written over the stored fields, then — when it changed
8
8
  * the e-mail — `user.emailChanged`, carrying the address the write replaced,
9
- * which nothing keeps once it landed.
9
+ * which nothing keeps once it landed, and the user's pending `changeEmail`
10
+ * links spent.
10
11
  */
11
12
  export declare function update(context: Context, type: ResolvedType, user: UserRef, patch: Input, options: WriteOptions | undefined, where: string): Promise<UserRecord>;
12
13
  //# sourceMappingURL=update.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/auth/users/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,YAAY,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;GAIG;AACH,wBAAsB,MAAM,CAC3B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CA0BrB"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/auth/users/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,YAAY,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;GAKG;AACH,wBAAsB,MAAM,CAC3B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAqCrB"}
@@ -0,0 +1,8 @@
1
+ import type { ConformanceCase } from '../../types';
2
+ /**
3
+ * A change of e-mail's token kept apart from a verification's: the two can
4
+ * sit in the store for one user and one address, and neither is counted,
5
+ * spent or answered as the other.
6
+ */
7
+ export declare const tokenChangeEmailCases: readonly ConformanceCase[];
8
+ //# sourceMappingURL=change-email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"change-email.d.ts","sourceRoot":"","sources":["../../../../src/conformance/cases/tokens/change-email.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,eAAe,EAyD3D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/conformance/cases/tokens/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAQnD,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAE,SAAS,eAAe,EAOrD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/conformance/cases/tokens/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AASnD,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAE,SAAS,eAAe,EAQrD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../../../src/conformance/cases/tokens/kinds.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAmBnD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,eAAe,EAkGpD,CAAC"}
1
+ {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../../../../src/conformance/cases/tokens/kinds.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAoBnD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,eAAe,EAkGpD,CAAC"}
@@ -494,12 +494,45 @@ var tokenAttemptCases = [
494
494
  }
495
495
  ];
496
496
 
497
- // src/conformance/cases/tokens/deletion.ts
497
+ // src/conformance/cases/tokens/change-email.ts
498
498
  var group8 = "tokens";
499
+ var tokenChangeEmailCases = [
500
+ {
501
+ id: "tokens.changeEmailKind",
502
+ group: group8,
503
+ name: "keeps an e-mail change apart from a verification, and keeps the address it replaces in codeHash",
504
+ async run({ stores }) {
505
+ const userId = mintId2();
506
+ const address = "new@example.test";
507
+ const change = tokenRecord({
508
+ userId,
509
+ address,
510
+ kind: "changeEmail",
511
+ codeHash: "f".repeat(64)
512
+ });
513
+ const verification = tokenRecord({
514
+ userId,
515
+ address,
516
+ kind: "verifyEmail"
517
+ });
518
+ await stores.tokens.insertToken(change);
519
+ await stores.tokens.insertToken(verification);
520
+ const now = at("2026-02-01T00:00:00.000Z");
521
+ isNull(await stores.tokens.consumeToken(verification.tokenHash, "changeEmail", now), "consumeToken for a verifyEmail token redeemed as changeEmail");
522
+ isNull(await stores.tokens.consumeToken(change.tokenHash, "verifyEmail", now), "consumeToken for a changeEmail token redeemed as verifyEmail");
523
+ isNull(await stores.tokens.countAttempt(change.tokenHash, "verifyEmail"), "countAttempt for a changeEmail token counted as verifyEmail");
524
+ equal(await stores.tokens.spendUserTokens(userId, "changeEmail", now), 1, "spendUserTokens of changeEmail: the change only");
525
+ equal(await stores.tokens.consumeToken(verification.tokenHash, "verifyEmail", now), verification, "spendUserTokens of changeEmail should not touch a verification, nor anything else have counted it");
526
+ }
527
+ }
528
+ ];
529
+
530
+ // src/conformance/cases/tokens/deletion.ts
531
+ var group9 = "tokens";
499
532
  var tokenDeletionCases = [
500
533
  {
501
534
  id: "tokens.deleteUser",
502
- group: group8,
535
+ group: group9,
503
536
  name: "deletes every token of one user, spent or not, of either kind, and counts them",
504
537
  async run({ stores }) {
505
538
  const userId = mintId2();
@@ -524,11 +557,11 @@ var tokenDeletionCases = [
524
557
  ];
525
558
 
526
559
  // src/conformance/cases/tokens/inserts.ts
527
- var group9 = "tokens";
560
+ var group10 = "tokens";
528
561
  var tokenInsertCases = [
529
562
  {
530
563
  id: "tokens.challenge",
531
- group: group9,
564
+ group: group10,
532
565
  name: "keeps a second-factor challenge, whose address is '' — nothing was sent for it",
533
566
  async run({ stores }) {
534
567
  const record = tokenRecord({ kind: "secondFactor", address: "" });
@@ -539,7 +572,7 @@ var tokenInsertCases = [
539
572
  },
540
573
  {
541
574
  id: "tokens.lapsed",
542
- group: group9,
575
+ group: group10,
543
576
  name: "spends a lapsed token all the same: expiry is compared by the core, after the call",
544
577
  async run({ stores }) {
545
578
  const record = tokenRecord({ expiresAt: at("2020-01-01T00:00:00.000Z") });
@@ -554,7 +587,7 @@ var tokenInsertCases = [
554
587
  },
555
588
  {
556
589
  id: "tokens.idempotentInsert",
557
- group: group9,
590
+ group: group10,
558
591
  name: "is idempotent under retry: inserting an existing token hash writes nothing",
559
592
  async run({ stores }) {
560
593
  const record = tokenRecord();
@@ -569,19 +602,20 @@ var tokenInsertCases = [
569
602
  ];
570
603
 
571
604
  // src/conformance/cases/tokens/kinds.ts
572
- var group10 = "tokens";
605
+ var group11 = "tokens";
573
606
  var KINDS = Object.keys({
574
607
  verifyEmail: true,
575
608
  resetPassword: true,
576
609
  secondFactor: true,
577
610
  signInCode: true,
578
611
  magicLink: true,
579
- stepUp: true
612
+ stepUp: true,
613
+ changeEmail: true
580
614
  });
581
615
  var tokenKindCases = [
582
616
  {
583
617
  id: "tokens.everyKind",
584
- group: group10,
618
+ group: group11,
585
619
  name: "stores, counts and spends a token of every kind the port names",
586
620
  async run({ stores }) {
587
621
  const now = at("2026-02-01T00:00:00.000Z");
@@ -595,7 +629,7 @@ var tokenKindCases = [
595
629
  },
596
630
  {
597
631
  id: "tokens.stepUpKind",
598
- group: group10,
632
+ group: group11,
599
633
  name: "keeps a step-up apart from a sign-in code: neither is counted, spent nor answered as the other",
600
634
  async run({ stores }) {
601
635
  const userId = mintId2();
@@ -612,7 +646,7 @@ var tokenKindCases = [
612
646
  },
613
647
  {
614
648
  id: "tokens.magicLinkKind",
615
- group: group10,
649
+ group: group11,
616
650
  name: "keeps a sign-in link apart from a sign-in code: neither is counted, spent nor answered as the other",
617
651
  async run({ stores }) {
618
652
  const userId = mintId2();
@@ -634,11 +668,11 @@ var tokenKindCases = [
634
668
  ];
635
669
 
636
670
  // src/conformance/cases/tokens/redemption.ts
637
- var group11 = "tokens";
671
+ var group12 = "tokens";
638
672
  var tokenRedemptionCases = [
639
673
  {
640
674
  id: "tokens.consume",
641
- group: group11,
675
+ group: group12,
642
676
  name: "answers the token as it was before the call: spentAt null means this call spent it",
643
677
  async run({ stores }) {
644
678
  const record = tokenRecord();
@@ -650,7 +684,7 @@ var tokenRedemptionCases = [
650
684
  },
651
685
  {
652
686
  id: "tokens.concurrency",
653
- group: group11,
687
+ group: group12,
654
688
  name: "lets exactly one of twenty concurrent redemptions spend a token — one conditional write, never a read then a write",
655
689
  async run({ stores }) {
656
690
  const record = tokenRecord();
@@ -662,7 +696,7 @@ var tokenRedemptionCases = [
662
696
  },
663
697
  {
664
698
  id: "tokens.kind",
665
- group: group11,
699
+ group: group12,
666
700
  name: "does not know, and does not spend, a token of the other kind",
667
701
  async run({ stores }) {
668
702
  const record = tokenRecord({ kind: "verifyEmail" });
@@ -676,11 +710,11 @@ var tokenRedemptionCases = [
676
710
  ];
677
711
 
678
712
  // src/conformance/cases/tokens/spending.ts
679
- var group12 = "tokens";
713
+ var group13 = "tokens";
680
714
  var tokenSpendingCases = [
681
715
  {
682
716
  id: "tokens.spendUserTokens",
683
- group: group12,
717
+ group: group13,
684
718
  name: "spends every unspent token of one user and one kind, and counts them, leaving the rest as they were",
685
719
  async run({ stores }) {
686
720
  const userId = mintId2();
@@ -711,7 +745,7 @@ var tokenSpendingCases = [
711
745
  },
712
746
  {
713
747
  id: "tokens.spendUserTokensExcept",
714
- group: group12,
748
+ group: group13,
715
749
  name: "spares the token named by except, and spends the rest",
716
750
  async run({ stores }) {
717
751
  const userId = mintId2();
@@ -733,7 +767,7 @@ var tokenSpendingCases = [
733
767
  },
734
768
  {
735
769
  id: "tokens.spendUserTokensRace",
736
- group: group12,
770
+ group: group13,
737
771
  name: "spends a token once, when spending a user's tokens races a redemption",
738
772
  async run({ stores }) {
739
773
  const now = at("2026-02-01T00:00:00.000Z");
@@ -757,15 +791,16 @@ var tokenStoreCases = [
757
791
  ...tokenSpendingCases,
758
792
  ...tokenInsertCases,
759
793
  ...tokenKindCases,
794
+ ...tokenChangeEmailCases,
760
795
  ...tokenDeletionCases
761
796
  ];
762
797
  // src/conformance/cases/users/batch.ts
763
- var group13 = "users";
798
+ var group14 = "users";
764
799
  var byId = (a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
765
800
  var userBatchCases = [
766
801
  {
767
802
  id: "users.findUsers",
768
- group: group13,
803
+ group: group14,
769
804
  name: "findUsers answers each stored user once, byte for byte and whatever its type, and leaves out an id nobody holds",
770
805
  needs: "findUsers",
771
806
  async run({ stores }) {
@@ -788,7 +823,7 @@ var userBatchCases = [
788
823
  },
789
824
  {
790
825
  id: "users.findUsersNone",
791
- group: group13,
826
+ group: group14,
792
827
  name: "findUsers answers an empty list, not null, when no id is held",
793
828
  needs: "findUsers",
794
829
  async run({ stores }) {
@@ -799,11 +834,11 @@ var userBatchCases = [
799
834
  ];
800
835
 
801
836
  // src/conformance/cases/users/deletion.ts
802
- var group14 = "users";
837
+ var group15 = "users";
803
838
  var userDeletionCases = [
804
839
  {
805
840
  id: "users.delete",
806
- group: group14,
841
+ group: group15,
807
842
  name: "deletes a user and frees their logins, answers false for nobody, and touches no other user",
808
843
  async run({ stores }) {
809
844
  const record = userRecord();
@@ -823,11 +858,11 @@ var userDeletionCases = [
823
858
  ];
824
859
 
825
860
  // src/conformance/cases/users/inserts.ts
826
- var group15 = "users";
861
+ var group16 = "users";
827
862
  var userInsertCases = [
828
863
  {
829
864
  id: "users.idempotentInsert",
830
- group: group15,
865
+ group: group16,
831
866
  name: "is idempotent under retry: inserting an existing id answers the stored record and writes nothing",
832
867
  async run({ stores }) {
833
868
  const record = userRecord();
@@ -842,7 +877,7 @@ var userInsertCases = [
842
877
  },
843
878
  {
844
879
  id: "users.uniqueness",
845
- group: group15,
880
+ group: group16,
846
881
  name: "lets exactly one of twenty concurrent inserts hold a login: uniqueness is a constraint, not a read",
847
882
  async run({ stores }) {
848
883
  const records = Array.from({ length: 20 }, () => userRecord({ logins: ["contested@example.test"] }));
@@ -867,11 +902,11 @@ var userInsertCases = [
867
902
  ];
868
903
 
869
904
  // src/conformance/cases/users/listing.ts
870
- var group16 = "users";
905
+ var group17 = "users";
871
906
  var userListingCases = [
872
907
  {
873
908
  id: "users.pagination",
874
- group: group16,
909
+ group: group17,
875
910
  name: "pages 25 users of one type by 10 in ascending id order, with no gap, no repeat and no other type, and ends on a null cursor",
876
911
  async run({ stores }) {
877
912
  const records = Array.from({ length: 25 }, () => userRecord());
@@ -972,11 +1007,11 @@ async function nullClearsCodes(stores, id) {
972
1007
  }
973
1008
 
974
1009
  // src/conformance/cases/users/patches.ts
975
- var group17 = "users";
1010
+ var group18 = "users";
976
1011
  var userPatchCases = [
977
1012
  {
978
1013
  id: "users.omission",
979
- group: group17,
1014
+ group: group18,
980
1015
  name: "omission — the Kratos PUT trap: an update leaves every field it does not name exactly as it was",
981
1016
  async run({ stores }) {
982
1017
  const record = userRecord({
@@ -1001,7 +1036,7 @@ var userPatchCases = [
1001
1036
  },
1002
1037
  {
1003
1038
  id: "users.passwordSlot",
1004
- group: group17,
1039
+ group: group18,
1005
1040
  name: "keeps a password the patch does not name, and removes one the patch names null",
1006
1041
  async run({ stores }) {
1007
1042
  const record = userRecord();
@@ -1015,7 +1050,7 @@ var userPatchCases = [
1015
1050
  secondFactorSlotCase,
1016
1051
  {
1017
1052
  id: "users.loginsMove",
1018
- group: group17,
1053
+ group: group18,
1019
1054
  name: "moves logins on update: the old one is free, the new one found, one held elsewhere refused",
1020
1055
  async run({ stores }) {
1021
1056
  const record = userRecord();
@@ -1036,11 +1071,11 @@ var userPatchCases = [
1036
1071
  ];
1037
1072
 
1038
1073
  // src/conformance/cases/users/reads.ts
1039
- var group18 = "users";
1074
+ var group19 = "users";
1040
1075
  var userReadCases = [
1041
1076
  {
1042
1077
  id: "users.roundTrip",
1043
- group: group18,
1078
+ group: group19,
1044
1079
  name: 'round-trips a record byte for byte: nested fields, a 1 that stays a number, a "1" that stays a string',
1045
1080
  async run({ stores }) {
1046
1081
  const record = userRecord({
@@ -1064,7 +1099,7 @@ var userReadCases = [
1064
1099
  },
1065
1100
  {
1066
1101
  id: "users.edgeCharacters",
1067
- group: group18,
1102
+ group: group19,
1068
1103
  name: "round-trips every character the core lets through: control characters, U+FFFF and a surrogate pair",
1069
1104
  async run({ stores }) {
1070
1105
  const edge = "a\x01\x1F￿ \uD83D\uDE00 z";
@@ -1079,7 +1114,7 @@ var userReadCases = [
1079
1114
  },
1080
1115
  {
1081
1116
  id: "users.absence",
1082
- group: group18,
1117
+ group: group19,
1083
1118
  name: "answers null for an absence, never undefined, and an empty page for an empty store",
1084
1119
  async run({ stores }) {
1085
1120
  isNull(await stores.users.findUser(mintId2()), "findUser for an unknown id");
@@ -1089,7 +1124,7 @@ var userReadCases = [
1089
1124
  },
1090
1125
  {
1091
1126
  id: "users.loginBytes",
1092
- group: group18,
1127
+ group: group19,
1093
1128
  name: "compares logins as bytes, within one type: no case folding, no trimming, no collation",
1094
1129
  async run({ stores }) {
1095
1130
  const upper = userRecord({ logins: ["Ada@Example.test"] });
@@ -1106,11 +1141,11 @@ var userReadCases = [
1106
1141
  ];
1107
1142
 
1108
1143
  // src/conformance/cases/users/versions.ts
1109
- var group19 = "users";
1144
+ var group20 = "users";
1110
1145
  var userVersionCases = [
1111
1146
  {
1112
1147
  id: "users.versionIncrements",
1113
- group: group19,
1148
+ group: group20,
1114
1149
  name: "applies an update at the expected version, and answers the record written with its version one higher",
1115
1150
  async run({ stores }) {
1116
1151
  const record = userRecord();
@@ -1128,7 +1163,7 @@ var userVersionCases = [
1128
1163
  },
1129
1164
  {
1130
1165
  id: "users.versionConflict",
1131
- group: group19,
1166
+ group: group20,
1132
1167
  name: "refuses a stale version with both versions, and leaves the record identical byte for byte",
1133
1168
  async run({ stores }) {
1134
1169
  const record = userRecord();
@@ -1149,7 +1184,7 @@ var userVersionCases = [
1149
1184
  },
1150
1185
  {
1151
1186
  id: "users.unknownUpdate",
1152
- group: group19,
1187
+ group: group20,
1153
1188
  name: "refuses an update to an unknown id with NotFoundError, told apart from a version conflict",
1154
1189
  async run({ stores }) {
1155
1190
  const error = await rejects(stores.users.updateUser(mintId2(), { updatedAt: at("2026-02-01T00:00:00.000Z") }, 0), "updateUser on an unknown id should reject");
@@ -1309,11 +1344,11 @@ var tuple = (object, relation, subject) => ({ object, relation, subject });
1309
1344
  var sorted = (subjects) => subjects.map(formatSubject2).sort();
1310
1345
 
1311
1346
  // src/conformance/relations/cases/deletion.ts
1312
- var group20 = "relations";
1347
+ var group21 = "relations";
1313
1348
  var relationDeletionCases = [
1314
1349
  {
1315
1350
  id: "relations.deleteEntity",
1316
- group: group20,
1351
+ group: group21,
1317
1352
  name: "deletes every tuple naming an entity — as object, as subject, as a set’s entity — and counts them",
1318
1353
  async run({ store }) {
1319
1354
  const team = entity("team");
@@ -1340,11 +1375,11 @@ var relationDeletionCases = [
1340
1375
  ];
1341
1376
 
1342
1377
  // src/conformance/relations/cases/reads.ts
1343
- var group21 = "relations";
1378
+ var group22 = "relations";
1344
1379
  var relationReadCases = [
1345
1380
  {
1346
1381
  id: "relations.roundTrip",
1347
- group: group21,
1382
+ group: group22,
1348
1383
  name: "holds exactly the tuples written, byte for byte: staff:u1 is not patient:u1, and a set is not its entity",
1349
1384
  async run({ store }) {
1350
1385
  const record = entity("record", "R:1 — ÿ");
@@ -1360,7 +1395,7 @@ var relationReadCases = [
1360
1395
  },
1361
1396
  {
1362
1397
  id: "relations.edgeCharacters",
1363
- group: group21,
1398
+ group: group22,
1364
1399
  name: "round-trips every character the core lets through in an id: control characters, U+FFFF and a surrogate pair",
1365
1400
  async run({ store }) {
1366
1401
  const edge = "a\x01\x1F￿ \uD83D\uDE00 z";
@@ -1383,7 +1418,7 @@ var relationReadCases = [
1383
1418
  },
1384
1419
  {
1385
1420
  id: "relations.undefinedRelation",
1386
- group: group21,
1421
+ group: group22,
1387
1422
  name: "reads a subject whose relation is undefined as its entity, not as a set",
1388
1423
  async run({ store }) {
1389
1424
  const record = entity("record");
@@ -1413,7 +1448,7 @@ var relationReadCases = [
1413
1448
  },
1414
1449
  {
1415
1450
  id: "relations.absence",
1416
- group: group21,
1451
+ group: group22,
1417
1452
  name: "answers false, [], an empty page and 0 for an empty store — never null or undefined",
1418
1453
  async run({ store }) {
1419
1454
  const record = entity("record");
@@ -1434,11 +1469,11 @@ var relationReadCases = [
1434
1469
  ];
1435
1470
 
1436
1471
  // src/conformance/relations/cases/traversal.ts
1437
- var group22 = "relations";
1472
+ var group23 = "relations";
1438
1473
  var relationTraversalCases = [
1439
1474
  {
1440
1475
  id: "relations.oneHop",
1441
- group: group22,
1476
+ group: group23,
1442
1477
  name: "answers one hop: the subject sets and the entities holding one relation on one object, and nothing else",
1443
1478
  async run({ store }) {
1444
1479
  const record = entity("record");
@@ -1462,7 +1497,7 @@ var relationTraversalCases = [
1462
1497
  },
1463
1498
  {
1464
1499
  id: "relations.objects",
1465
- group: group22,
1500
+ group: group23,
1466
1501
  name: "pages 25 objects by 10 in ascending id order, for one type, relation and exact subject, and ends on a null cursor",
1467
1502
  async run({ store }) {
1468
1503
  const staff = entity("staff");
@@ -1509,11 +1544,11 @@ var relationTraversalCases = [
1509
1544
  ];
1510
1545
 
1511
1546
  // src/conformance/relations/cases/writes.ts
1512
- var group23 = "relations";
1547
+ var group24 = "relations";
1513
1548
  var relationWriteCases = [
1514
1549
  {
1515
1550
  id: "relations.idempotentWrite",
1516
- group: group23,
1551
+ group: group24,
1517
1552
  name: "is idempotent under retry: adding a stored tuple and removing an absent one write nothing",
1518
1553
  async run({ store }) {
1519
1554
  const record = entity("record");
@@ -1526,7 +1561,7 @@ var relationWriteCases = [
1526
1561
  },
1527
1562
  {
1528
1563
  id: "relations.uniqueness",
1529
- group: group23,
1564
+ group: group24,
1530
1565
  name: "keeps one tuple when twenty concurrent writes add it: uniqueness is a constraint, not a read",
1531
1566
  async run({ store }) {
1532
1567
  const record = entity("record");
@@ -1537,7 +1572,7 @@ var relationWriteCases = [
1537
1572
  },
1538
1573
  {
1539
1574
  id: "relations.removeThenAdd",
1540
- group: group23,
1575
+ group: group24,
1541
1576
  name: "applies one write’s removals and additions together",
1542
1577
  async run({ store }) {
1543
1578
  const record = entity("record");
@@ -1672,5 +1707,5 @@ export {
1672
1707
  userStoreCases
1673
1708
  };
1674
1709
 
1675
- //# debugId=E36CAD1FA03131AF64756E2164756E21
1710
+ //# debugId=A279A4865433665964756E2164756E21
1676
1711
  //# sourceMappingURL=index.js.map