@warlock.js/auth 5.31.0 → 5.32.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 (159) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/esm/commands/auth-cleanup-command.d.mts +1 -2
  3. package/esm/commands/auth-cleanup-command.d.mts.map +1 -1
  4. package/esm/commands/auth-purge-never-expiring-command.d.mts +1 -2
  5. package/esm/commands/auth-purge-never-expiring-command.d.mts.map +1 -1
  6. package/esm/commands/jwt-secret-generator-command.d.mts +1 -2
  7. package/esm/commands/jwt-secret-generator-command.d.mts.map +1 -1
  8. package/esm/contracts/auth-contract.d.mts +1 -3
  9. package/esm/contracts/auth-contract.d.mts.map +1 -1
  10. package/esm/contracts/index.d.mts +2 -1
  11. package/esm/contracts/providers.d.mts +82 -50
  12. package/esm/contracts/providers.d.mts.map +1 -1
  13. package/esm/contracts/request-locals.d.mts +2 -3
  14. package/esm/contracts/request-locals.d.mts.map +1 -1
  15. package/esm/contracts/types.d.mts +59 -43
  16. package/esm/contracts/types.d.mts.map +1 -1
  17. package/esm/errors/auth-provider-sdk-missing.error.d.mts +1 -3
  18. package/esm/errors/auth-provider-sdk-missing.error.d.mts.map +1 -1
  19. package/esm/errors/email-not-verified.error.d.mts +1 -3
  20. package/esm/errors/email-not-verified.error.d.mts.map +1 -1
  21. package/esm/errors/index.d.mts +2 -1
  22. package/esm/errors/index.mjs +1 -1
  23. package/esm/errors/invalid-one-time-token.error.d.mts +1 -3
  24. package/esm/errors/invalid-one-time-token.error.d.mts.map +1 -1
  25. package/esm/errors/invalid-passkey.error.d.mts +1 -3
  26. package/esm/errors/invalid-passkey.error.d.mts.map +1 -1
  27. package/esm/errors/invalid-provider-callback.error.d.mts +1 -3
  28. package/esm/errors/invalid-provider-callback.error.d.mts.map +1 -1
  29. package/esm/errors/notifications-unavailable.error.d.mts +1 -3
  30. package/esm/errors/notifications-unavailable.error.d.mts.map +1 -1
  31. package/esm/errors/provider-email-not-verified.error.d.mts +1 -3
  32. package/esm/errors/provider-email-not-verified.error.d.mts.map +1 -1
  33. package/esm/index.d.mts +8 -0
  34. package/esm/localization/auth-default-translations.d.mts +1 -3
  35. package/esm/localization/auth-default-translations.d.mts.map +1 -1
  36. package/esm/localization/auth-translations.type.d.mts +11 -7
  37. package/esm/localization/auth-translations.type.d.mts.map +1 -1
  38. package/esm/localization/index.mjs +1 -1
  39. package/esm/localization/register-auth-translations.d.mts +1 -2
  40. package/esm/localization/register-auth-translations.d.mts.map +1 -1
  41. package/esm/middleware/auth.middleware.d.mts +10 -10
  42. package/esm/middleware/auth.middleware.d.mts.map +1 -1
  43. package/esm/middleware/csrf-origin-check.d.mts +4 -6
  44. package/esm/middleware/csrf-origin-check.d.mts.map +1 -1
  45. package/esm/middleware/csrf-origin-check.mjs +1 -1
  46. package/esm/middleware/csrf-origin-check.mjs.map +1 -1
  47. package/esm/middleware/index.d.mts +2 -1
  48. package/esm/middleware/index.mjs +1 -1
  49. package/esm/middleware/login-throttle.middleware.d.mts +4 -6
  50. package/esm/middleware/login-throttle.middleware.d.mts.map +1 -1
  51. package/esm/middleware/one-time-token-throttle.middleware.d.mts +2 -4
  52. package/esm/middleware/one-time-token-throttle.middleware.d.mts.map +1 -1
  53. package/esm/middleware/otp-throttle.middleware.d.mts +2 -4
  54. package/esm/middleware/otp-throttle.middleware.d.mts.map +1 -1
  55. package/esm/middleware/require-verified-email.middleware.d.mts +1 -3
  56. package/esm/middleware/require-verified-email.middleware.d.mts.map +1 -1
  57. package/esm/models/access-token/access-token.model.d.mts +6 -6
  58. package/esm/models/access-token/access-token.model.d.mts.map +1 -1
  59. package/esm/models/access-token/index.d.mts +2 -1
  60. package/esm/models/access-token/index.mjs +1 -1
  61. package/esm/models/auth-token-family/auth-token-family.model.d.mts +2 -4
  62. package/esm/models/auth-token-family/auth-token-family.model.d.mts.map +1 -1
  63. package/esm/models/auth-token-family/index.d.mts +2 -1
  64. package/esm/models/auth-token-family/index.mjs +1 -1
  65. package/esm/models/auth.model.d.mts +1 -3
  66. package/esm/models/auth.model.d.mts.map +1 -1
  67. package/esm/models/index.d.mts +8 -2
  68. package/esm/models/index.d.mts.map +1 -1
  69. package/esm/models/index.mjs +1 -1
  70. package/esm/models/one-time-token/index.d.mts +2 -1
  71. package/esm/models/one-time-token/index.mjs +1 -1
  72. package/esm/models/one-time-token/one-time-token.model.d.mts +3 -5
  73. package/esm/models/one-time-token/one-time-token.model.d.mts.map +1 -1
  74. package/esm/models/passkey-credential/index.d.mts +2 -1
  75. package/esm/models/passkey-credential/index.mjs +1 -1
  76. package/esm/models/passkey-credential/passkey-credential.model.d.mts +2 -4
  77. package/esm/models/passkey-credential/passkey-credential.model.d.mts.map +1 -1
  78. package/esm/models/provider-account/index.d.mts +2 -1
  79. package/esm/models/provider-account/index.mjs +1 -1
  80. package/esm/models/provider-account/provider-account.model.d.mts +2 -4
  81. package/esm/models/provider-account/provider-account.model.d.mts.map +1 -1
  82. package/esm/models/refresh-token/index.d.mts +2 -1
  83. package/esm/models/refresh-token/index.mjs +1 -1
  84. package/esm/models/refresh-token/refresh-token.model.d.mts +7 -7
  85. package/esm/models/refresh-token/refresh-token.model.d.mts.map +1 -1
  86. package/esm/otp/index.d.mts +2 -1
  87. package/esm/otp/index.mjs +1 -1
  88. package/esm/otp/otp.d.mts +2 -4
  89. package/esm/otp/otp.d.mts.map +1 -1
  90. package/esm/otp/otp.mjs +2 -1
  91. package/esm/otp/otp.mjs.map +1 -1
  92. package/esm/passkeys/index.d.mts +2 -1
  93. package/esm/passkeys/index.mjs +1 -1
  94. package/esm/passkeys/passkey-authentication.d.mts +2 -4
  95. package/esm/passkeys/passkey-authentication.d.mts.map +1 -1
  96. package/esm/passkeys/passkey-authentication.mjs +2 -1
  97. package/esm/passkeys/passkey-authentication.mjs.map +1 -1
  98. package/esm/passkeys/passkey-registration.d.mts +3 -4
  99. package/esm/passkeys/passkey-registration.d.mts.map +1 -1
  100. package/esm/passkeys/simplewebauthn.d.mts +2 -3
  101. package/esm/passkeys/simplewebauthn.d.mts.map +1 -1
  102. package/esm/passkeys/simplewebauthn.mjs +1 -1
  103. package/esm/providers/apple-provider.d.mts +5 -9
  104. package/esm/providers/apple-provider.d.mts.map +1 -1
  105. package/esm/providers/discord-provider.d.mts +2 -7
  106. package/esm/providers/discord-provider.d.mts.map +1 -1
  107. package/esm/providers/facebook-provider.d.mts +2 -7
  108. package/esm/providers/facebook-provider.d.mts.map +1 -1
  109. package/esm/providers/github-provider.d.mts +2 -7
  110. package/esm/providers/github-provider.d.mts.map +1 -1
  111. package/esm/providers/google-provider.d.mts +5 -10
  112. package/esm/providers/google-provider.d.mts.map +1 -1
  113. package/esm/providers/index.d.mts +2 -1
  114. package/esm/providers/index.mjs +1 -1
  115. package/esm/providers/linkedin-provider.d.mts +3 -8
  116. package/esm/providers/linkedin-provider.d.mts.map +1 -1
  117. package/esm/providers/provider-login.d.mts +3 -5
  118. package/esm/providers/provider-login.d.mts.map +1 -1
  119. package/esm/providers/provider-login.mjs +3 -2
  120. package/esm/providers/provider-login.mjs.map +1 -1
  121. package/esm/providers/provider-state-cookie.mjs +3 -2
  122. package/esm/providers/provider-state-cookie.mjs.map +1 -1
  123. package/esm/providers/x-provider.d.mts +2 -7
  124. package/esm/providers/x-provider.d.mts.map +1 -1
  125. package/esm/services/auth-events.d.mts +5 -6
  126. package/esm/services/auth-events.d.mts.map +1 -1
  127. package/esm/services/auth.service.d.mts +10 -9
  128. package/esm/services/auth.service.d.mts.map +1 -1
  129. package/esm/services/current-user.d.mts +1 -3
  130. package/esm/services/current-user.d.mts.map +1 -1
  131. package/esm/services/email-verification.d.mts +3 -5
  132. package/esm/services/email-verification.d.mts.map +1 -1
  133. package/esm/services/generate-jwt-secret.d.mts +1 -2
  134. package/esm/services/generate-jwt-secret.d.mts.map +1 -1
  135. package/esm/services/index.d.mts +2 -1
  136. package/esm/services/index.mjs +1 -1
  137. package/esm/services/jwt.d.mts +8 -29
  138. package/esm/services/jwt.d.mts.map +1 -1
  139. package/esm/services/jwt.mjs +2 -2
  140. package/esm/services/jwt.mjs.map +1 -1
  141. package/esm/services/one-time-tokens.d.mts +6 -6
  142. package/esm/services/one-time-tokens.d.mts.map +1 -1
  143. package/esm/services/password-reset.d.mts +2 -4
  144. package/esm/services/password-reset.d.mts.map +1 -1
  145. package/esm/services/resolve-request-user.d.mts +19 -14
  146. package/esm/services/resolve-request-user.d.mts.map +1 -1
  147. package/esm/services/token-family-operation.mjs +1 -1
  148. package/esm/session/index.d.mts +2 -1
  149. package/esm/session/index.mjs +1 -1
  150. package/esm/session/page-session.d.mts +26 -18
  151. package/esm/session/page-session.d.mts.map +1 -1
  152. package/esm/utils/auth-error-codes.d.mts +11 -22
  153. package/esm/utils/auth-error-codes.d.mts.map +1 -1
  154. package/esm/utils/index.mjs +1 -1
  155. package/esm/utils/safe-equal.d.mts +1 -2
  156. package/esm/utils/safe-equal.d.mts.map +1 -1
  157. package/esm/utils/token-expiry.d.mts +3 -4
  158. package/esm/utils/token-expiry.d.mts.map +1 -1
  159. package/package.json +8 -8
@@ -1,3 +1,3 @@
1
1
  import { RefreshToken, refreshTokenSchema } from "./refresh-token.model.mjs";
2
2
 
3
- export { };
3
+ export { RefreshToken, refreshTokenSchema };
@@ -1,7 +1,6 @@
1
1
  import { Auth } from "../auth.model.mjs";
2
2
  import { DeviceInfo } from "../../contracts/types.mjs";
3
3
  import { Model } from "@warlock.js/cascade";
4
-
5
4
  //#region ../../packages/auth/src/models/refresh-token/refresh-token.model.d.ts
6
5
  /**
7
6
  * Seal schema for the persisted refresh-token record. Exported so an override
@@ -15,7 +14,7 @@ import { Model } from "@warlock.js/cascade";
15
14
  * });
16
15
  * }
17
16
  */
18
- declare const refreshTokenSchema: import("@warlock.js/seal").ObjectValidator<{
17
+ export declare const refreshTokenSchema: import("@warlock.js/seal").ObjectValidator<{
19
18
  token: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
20
19
  user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
21
20
  user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
@@ -26,7 +25,8 @@ declare const refreshTokenSchema: import("@warlock.js/seal").ObjectValidator<{
26
25
  };
27
26
  revoked_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date> & {
28
27
  isOptional: true;
29
- }; /** The successor pair a bounded concurrent renewal may reuse. */
28
+ };
29
+ /** The successor pair a bounded concurrent renewal may reuse. */
30
30
  successor_access_token_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
31
31
  isOptional: true;
32
32
  };
@@ -42,7 +42,7 @@ declare const refreshTokenSchema: import("@warlock.js/seal").ObjectValidator<{
42
42
  /**
43
43
  * Extra attributes captured when a refresh token is issued.
44
44
  */
45
- type RefreshTokenIssueOptions = {
45
+ export type RefreshTokenIssueOptions = {
46
46
  familyId: string;
47
47
  expiresAt: string;
48
48
  deviceInfo?: DeviceInfo;
@@ -57,7 +57,7 @@ type RefreshTokenIssueOptions = {
57
57
  * structurally impossible and lets an override rename or add columns by
58
58
  * extending this class and registering it under `config.auth.refreshToken.model`.
59
59
  */
60
- declare class RefreshToken extends Model {
60
+ export declare class RefreshToken extends Model {
61
61
  static table: string;
62
62
  static schema: import("@warlock.js/seal").ObjectValidator<{
63
63
  token: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
@@ -70,7 +70,8 @@ declare class RefreshToken extends Model {
70
70
  };
71
71
  revoked_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date> & {
72
72
  isOptional: true;
73
- }; /** The successor pair a bounded concurrent renewal may reuse. */
73
+ };
74
+ /** The successor pair a bounded concurrent renewal may reuse. */
74
75
  successor_access_token_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
75
76
  isOptional: true;
76
77
  };
@@ -208,5 +209,4 @@ declare class RefreshToken extends Model {
208
209
  static purgeNeverExpiring(): Promise<RefreshToken[]>;
209
210
  }
210
211
  //#endregion
211
- export { RefreshToken, RefreshTokenIssueOptions, refreshTokenSchema };
212
212
  //# sourceMappingURL=refresh-token.model.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"refresh-token.model.d.mts","names":[],"sources":["../../../../../../../../../packages/auth/src/models/refresh-token/refresh-token.model.ts"],"mappings":";;;;;;;AAkBA;;;;;;;;;;cAAa,kBAAA,6BAAkB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiBnB,wBAAA;EACV,QAAA;EACA,SAAA;EACA,UAAA,GAAa,UAAU;AAAA;;;;;;;;;;;cAaZ,YAAA,SAAqB,KAAA;EAAA,OAClB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;OAjBpB;;;;;;;;;;;;;;;;;;;SAyBc,MAAA;EAsF0C;;;;;;EAAA,OA9E1C,cAAA;EA0GwC;EAAA,IAvG3C,QAAA;EA4GmC;;;;;;;;;;EAAA,IA9FnC,SAAA;EAoImC;;;;EAAA,IAxHnC,YAAA;EA2KiC;EAAA,IAtKjC,SAAA;EAsLsC;EAAA,IAjLtC,OAAA;EAgMuC;;;EAzLrC,MAAA,IAAU,OAAA;EAjEc;;;;;;;EA4ExB,cAAA,IAAkB,OAAA;;;;EAclB,UAAA,IAAc,OAAA;;;;SAOb,KAAA,CAAM,IAAA,EAAM,IAAA,EAAM,KAAA,UAAe,OAAA,EAAS,wBAAA,GAAwB,OAAA,CAAA,YAAA;;;;SAoBlE,WAAA,CAAY,KAAA,WAAgB,OAAA,CAAQ,YAAA;;;;;SAQpC,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,KAAA,WAAgB,OAAA,CAAQ,YAAA;;SAKhD,YAAA,CAAa,QAAA,WAAmB,OAAA,CAAQ,YAAA;;;;;SAQxC,eAAA,CAAgB,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,YAAA;;;;SAOrC,aAAA,CAAc,IAAA,EAAM,IAAA,EAAM,KAAA,WAAa,OAAA;;;;SAOvC,SAAA,CAAU,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,YAAA;;;;;;;;;SAgBzB,YAAA,CAAa,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,YAAA;;;;;SAgBlC,YAAA,CAAa,QAAA,WAAmB,OAAA,CAAQ,YAAA;EApJjD;;;;;EAAA,OAmKS,UAAA,CAAW,IAAA,EAAM,IAAA,EAAM,GAAA,WAAc,OAAA;EA3H5C;;;;;EAAA,OA+IO,YAAA,IAAgB,OAAA,CAAQ,YAAA;EA1HxB;;;;;;EAAA,OA0IA,iBAAA,IAAqB,OAAA,CAAQ,YAAA;EAtHvB;;;;;;;;;EAAA,OAqIN,kBAAA,IAAsB,OAAA,CAAQ,YAAA;AAAA"}
1
+ {"version":3,"file":"refresh-token.model.d.mts","names":[],"sources":["../../../../../../../../../packages/auth/src/models/refresh-token/refresh-token.model.ts"],"mappings":";;;;;;;;;;;;;;;;qBAkBa,+CAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAiBnB;EACV;EACA;EACA,aAAa;;;;;;;;;;;;qBAaF,qBAAqB;SAClB;SAEA,mCAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAQN;;;;;;;SAQA;;MAGH;;;;;;;;;;;MAcA;;;;;MAYA;;MAKA;;MAKA;;;;EAOE,UAAU;;;;;;;;EAWV,kBAAkB;;;;EAclB,cAAc;;;;SAOb,MAAM,MAAM,MAAM,eAAe,SAAS,2BAAwB,QAAA;;;;SAoBlE,YAAY,gBAAgB,QAAQ;;;;;SAQpC,YAAY,MAAM,MAAM,gBAAgB,QAAQ;;SAKhD,aAAa,mBAAmB,QAAQ;;;;;SAQxC,gBAAgB,MAAM,OAAO,QAAQ;;;;SAOrC,cAAc,MAAM,MAAM,gBAAa;;;;SAOvC,UAAU,MAAM,OAAO,QAAQ;;;;;;;;;SAgBzB,aAAa,MAAM,OAAO,QAAQ;;;;;SAgBlC,aAAa,mBAAmB,QAAQ;;;;;;SAexC,WAAW,MAAM,MAAM,cAAc;;;;;;SAoBrC,gBAAgB,QAAQ;;;;;;;SAgBxB,qBAAqB,QAAQ;;;;;;;;;;SAe7B,sBAAsB,QAAQ"}
@@ -1 +1,2 @@
1
- import { requestOtp, verifyOtp } from "./otp.mjs";
1
+ import { requestOtp, verifyOtp } from "./otp.mjs";
2
+ export { requestOtp, verifyOtp };
package/esm/otp/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  import { requestOtp, verifyOtp } from "./otp.mjs";
2
2
 
3
- export { };
3
+ export { requestOtp, verifyOtp };
package/esm/otp/otp.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Auth } from "../models/auth.model.mjs";
2
2
  import { DeviceInfo, LoginResult } from "../contracts/types.mjs";
3
3
  import { ChildModel } from "@warlock.js/cascade";
4
-
5
4
  //#region ../../packages/auth/src/otp/otp.d.ts
6
5
  /**
7
6
  * Send a 6-digit login code to the account whose `auth.otp.phoneField`
@@ -17,7 +16,7 @@ import { ChildModel } from "@warlock.js/cascade";
17
16
  * @throws AuthProviderSdkMissingError when `@warlock.js/notifications` is not
18
17
  * installed and no `auth.otp.send` is configured.
19
18
  */
20
- declare function requestOtp<T extends Auth>(Model: ChildModel<T>, phone: string, options?: {
19
+ export declare function requestOtp<T extends Auth>(Model: ChildModel<T>, phone: string, options?: {
21
20
  channel?: string;
22
21
  }): Promise<void>;
23
22
  /**
@@ -32,7 +31,6 @@ declare function requestOtp<T extends Auth>(Model: ChildModel<T>, phone: string,
32
31
  * @throws InvalidOneTimeTokenError (400, EC008) — the same for an unknown
33
32
  * phone, a wrong, expired, used or exhausted code.
34
33
  */
35
- declare function verifyOtp<T extends Auth>(Model: ChildModel<T>, phone: string, code: string, deviceInfo?: DeviceInfo): Promise<LoginResult<T>>;
34
+ export declare function verifyOtp<T extends Auth>(Model: ChildModel<T>, phone: string, code: string, deviceInfo?: DeviceInfo): Promise<LoginResult<T>>;
36
35
  //#endregion
37
- export { requestOtp, verifyOtp };
38
36
  //# sourceMappingURL=otp.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"otp.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/otp/otp.ts"],"mappings":";;;;;;;AAuFA;;;;;;;;;;;;iBAAsB,UAAA,WAAqB,IAAA,EACzC,KAAA,EAAO,UAAA,CAAW,CAAA,GAClB,KAAA,UACA,OAAA;EAAW,OAAA;AAAA,IACV,OAAA;;;;;AAAO;AAkCV;;;;;;;iBAAsB,SAAA,WAAoB,IAAA,EACxC,KAAA,EAAO,UAAA,CAAW,CAAA,GAClB,KAAA,UACA,IAAA,UACA,UAAA,GAAa,UAAA,GACZ,OAAA,CAAQ,WAAA,CAAY,CAAA"}
1
+ {"version":3,"file":"otp.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/otp/otp.ts"],"mappings":";;;;;;;;;;;;;;;;;;wBAuFsB,WAAW,UAAU,MACzC,OAAO,WAAW,IAClB,eACA;EAAW;IACV;;;;;;;;;;;;;wBAkCmB,UAAU,UAAU,MACxC,OAAO,WAAW,IAClB,eACA,cACA,aAAa,aACZ,QAAQ,YAAY"}
package/esm/otp/otp.mjs CHANGED
@@ -19,7 +19,8 @@ function invalidCode() {
19
19
  * value unique.
20
20
  */
21
21
  function macCode(user, salt, code) {
22
- return createHmac("sha256", createHmac("sha256", authConfig.accessToken.secret()).update("@warlock.js/auth:otp").digest()).update(`${salt}:${user.userType}:${user.id}:${code}`).digest("base64url");
22
+ const key = createHmac("sha256", authConfig.accessToken.secret()).update("@warlock.js/auth:otp").digest();
23
+ return createHmac("sha256", key).update(`${salt}:${user.userType}:${user.id}:${code}`).digest("base64url");
23
24
  }
24
25
  /** Stored form: `<salt>.<mac>` — 16 + 1 + 43 chars, inside the 64-char `token_hash` column. */
25
26
  function storedCodeHash(user, code) {
@@ -1 +1 @@
1
- {"version":3,"file":"otp.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/otp/otp.ts"],"sourcesContent":["import type { ChildModel } from \"@warlock.js/cascade\";\nimport { createHmac, randomBytes, randomInt } from \"node:crypto\";\nimport type { OtpMessage, OtpSender } from \"../contracts/providers\";\nimport type { DeviceInfo, LoginResult } from \"../contracts/types\";\nimport { InvalidOneTimeTokenError } from \"../errors/invalid-one-time-token.error\";\nimport type { Auth } from \"../models/auth.model\";\nimport { authConfig } from \"../services/auth-config\";\nimport { authService } from \"../services/auth.service\";\nimport { oneTimeTokenModel } from \"../services/one-time-tokens\";\nimport { loadOptionalPeer } from \"../services/optional-peer\";\nimport { safeEqual } from \"../utils/safe-equal\";\n\n/** The slice of `@warlock.js/notifications` OTP delivery uses (an optional peer). */\ntype NotifyModule = {\n notify: {\n channel: (name: string) => { send: (to: string, payload: unknown) => Promise<unknown> };\n };\n};\n\nconst CODE_PATTERN = /^\\d{6}$/;\n\n/** One error for every rejection: unknown phone, no code, wrong, expired, used, over the cap. */\nfunction invalidCode(): InvalidOneTimeTokenError {\n return new InvalidOneTimeTokenError(\"Invalid or expired code.\");\n}\n\n/**\n * Keyed hash of a code. A plain SHA-256 of a 6-digit code is reversed by\n * trying all million values, so the MAC key (derived from the access-token\n * secret) is what keeps a leaked table useless. `salt` makes each stored\n * value unique.\n */\nfunction macCode(user: Auth, salt: string, code: string): string {\n const key = createHmac(\"sha256\", authConfig.accessToken.secret())\n .update(\"@warlock.js/auth:otp\")\n .digest();\n\n return createHmac(\"sha256\", key)\n .update(`${salt}:${user.userType}:${user.id}:${code}`)\n .digest(\"base64url\");\n}\n\n/** Stored form: `<salt>.<mac>` — 16 + 1 + 43 chars, inside the 64-char `token_hash` column. */\nfunction storedCodeHash(user: Auth, code: string): string {\n const salt = randomBytes(12).toString(\"base64url\");\n\n return `${salt}.${macCode(user, salt, code)}`;\n}\n\nfunction codeMatches(user: Auth, stored: string, code: string): boolean {\n const [salt, mac] = stored.split(\".\");\n\n return !!salt && !!mac && safeEqual(mac, macCode(user, salt, code));\n}\n\n/**\n * Resolve how a code is sent: `auth.otp.send`, else the app's notifications\n * channel. Resolved BEFORE the user lookup, so a missing notifications package\n * fails identically for known and unknown phones.\n */\nasync function resolveDelivery(channel: string): Promise<OtpSender> {\n const custom = authConfig.otp.send();\n\n if (custom) return custom;\n\n const { notify } = await loadOptionalPeer<NotifyModule>(\n \"@warlock.js/notifications\",\n \"notifications\",\n );\n\n return (phone, message, channelName) => notify.channel(channelName).send(phone, message);\n}\n\n/**\n * Send a 6-digit login code to the account whose `auth.otp.phoneField`\n * (default `phone`) equals `phone`, through the notifications channel named by\n * `options.channel` / `auth.otp.channel` (default `\"sms\"`). Auth ships no\n * SMS/WhatsApp driver — the app registers that channel.\n *\n * The code is stored only as a keyed hash in `one_time_tokens` (purpose\n * `otp`), expires after `auth.otp.expiresIn` (default 5m), and replaces any\n * earlier unused code. **Anti-enumeration:** an unknown phone resolves the same\n * way and sends nothing. Throttle the route with `otpRequestThrottleMiddleware()`.\n *\n * @throws AuthProviderSdkMissingError when `@warlock.js/notifications` is not\n * installed and no `auth.otp.send` is configured.\n */\nexport async function requestOtp<T extends Auth>(\n Model: ChildModel<T>,\n phone: string,\n options: { channel?: string } = {},\n): Promise<void> {\n const channel = options.channel ?? authConfig.otp.channel();\n const deliver = await resolveDelivery(channel);\n\n if (typeof phone !== \"string\" || phone.length === 0) return;\n\n const user = (await Model.first({ [authConfig.otp.phoneField()]: phone })) as T | null;\n\n if (!user) return;\n\n const code = String(randomInt(0, 1_000_000)).padStart(6, \"0\");\n const expiresAt = new Date(Date.now() + authConfig.otp.expiresInMs());\n const TokenModel = oneTimeTokenModel();\n\n await TokenModel.invalidateActiveFor(user, \"otp\");\n await TokenModel.issue(user, \"otp\", storedCodeHash(user, code), expiresAt);\n\n const message: OtpMessage = { body: authConfig.otp.message(code), code, expiresAt };\n\n await deliver(phone, message, channel);\n}\n\n/**\n * Verify a phone login code and log the user in through\n * `authService.completeLogin` — the same outcome as password login.\n *\n * Each check first counts an attempt atomically; once `auth.otp.maxAttempts`\n * (default 5) have been counted the code is invalidated, so it is compared at\n * most that many times even under concurrent guesses. A correct code is\n * consumed single-use. Throttle the route with `otpVerifyThrottleMiddleware()`.\n *\n * @throws InvalidOneTimeTokenError (400, EC008) — the same for an unknown\n * phone, a wrong, expired, used or exhausted code.\n */\nexport async function verifyOtp<T extends Auth>(\n Model: ChildModel<T>,\n phone: string,\n code: string,\n deviceInfo?: DeviceInfo,\n): Promise<LoginResult<T>> {\n if (typeof phone !== \"string\" || phone.length === 0) throw invalidCode();\n if (typeof code !== \"string\" || !CODE_PATTERN.test(code)) throw invalidCode();\n\n const user = (await Model.first({ [authConfig.otp.phoneField()]: phone })) as T | null;\n\n if (!user) throw invalidCode();\n\n const row = await oneTimeTokenModel().findActiveFor(user, \"otp\");\n\n if (!row || row.isConsumed || row.isExpired) throw invalidCode();\n\n if (!(await row.recordAttempt(authConfig.otp.maxAttempts()))) {\n await row.consumeIfActive();\n\n throw invalidCode();\n }\n\n if (!codeMatches(user, String(row.get(\"token_hash\") ?? \"\"), code)) throw invalidCode();\n\n if (!(await row.consumeIfActive())) throw invalidCode();\n\n return authService.completeLogin(user, deviceInfo);\n}\n"],"mappings":";;;;;;;;;AAmBA,MAAM,eAAe;;AAGrB,SAAS,cAAwC;CAC/C,OAAO,IAAI,yBAAyB,0BAA0B;AAChE;;;;;;;AAQA,SAAS,QAAQ,MAAY,MAAc,MAAsB;CAK/D,OAAO,WAAW,UAJN,WAAW,UAAU,WAAW,YAAY,OAAO,CAAC,CAAC,CAC9D,OAAO,sBAAsB,CAAC,CAC9B,OAE2B,CAAC,CAAC,CAC7B,OAAO,GAAG,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,GAAG,GAAG,MAAM,CAAC,CACrD,OAAO,WAAW;AACvB;;AAGA,SAAS,eAAe,MAAY,MAAsB;CACxD,MAAM,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,WAAW;CAEjD,OAAO,GAAG,KAAK,GAAG,QAAQ,MAAM,MAAM,IAAI;AAC5C;AAEA,SAAS,YAAY,MAAY,QAAgB,MAAuB;CACtE,MAAM,CAAC,MAAM,OAAO,OAAO,MAAM,GAAG;CAEpC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,UAAU,KAAK,QAAQ,MAAM,MAAM,IAAI,CAAC;AACpE;;;;;;AAOA,eAAe,gBAAgB,SAAqC;CAClE,MAAM,SAAS,WAAW,IAAI,KAAK;CAEnC,IAAI,QAAQ,OAAO;CAEnB,MAAM,EAAE,WAAW,MAAM,iBACvB,6BACA,eACF;CAEA,QAAQ,OAAO,SAAS,gBAAgB,OAAO,QAAQ,WAAW,CAAC,CAAC,KAAK,OAAO,OAAO;AACzF;;;;;;;;;;;;;;;AAgBA,eAAsB,WACpB,OACA,OACA,UAAgC,CAAC,GAClB;CACf,MAAM,UAAU,QAAQ,WAAW,WAAW,IAAI,QAAQ;CAC1D,MAAM,UAAU,MAAM,gBAAgB,OAAO;CAE7C,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;CAErD,MAAM,OAAQ,MAAM,MAAM,MAAM,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,CAAC;CAExE,IAAI,CAAC,MAAM;CAEX,MAAM,OAAO,OAAO,UAAU,GAAG,GAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CAC5D,MAAM,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,WAAW,IAAI,YAAY,CAAC;CACpE,MAAM,aAAa,kBAAkB;CAErC,MAAM,WAAW,oBAAoB,MAAM,KAAK;CAChD,MAAM,WAAW,MAAM,MAAM,OAAO,eAAe,MAAM,IAAI,GAAG,SAAS;CAIzE,MAAM,QAAQ,OAAO;EAFS,MAAM,WAAW,IAAI,QAAQ,IAAI;EAAG;EAAM;CAE7C,GAAG,OAAO;AACvC;;;;;;;;;;;;;AAcA,eAAsB,UACpB,OACA,OACA,MACA,YACyB;CACzB,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG,MAAM,YAAY;CACvE,IAAI,OAAO,SAAS,YAAY,CAAC,aAAa,KAAK,IAAI,GAAG,MAAM,YAAY;CAE5E,MAAM,OAAQ,MAAM,MAAM,MAAM,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,CAAC;CAExE,IAAI,CAAC,MAAM,MAAM,YAAY;CAE7B,MAAM,MAAM,MAAM,kBAAkB,CAAC,CAAC,cAAc,MAAM,KAAK;CAE/D,IAAI,CAAC,OAAO,IAAI,cAAc,IAAI,WAAW,MAAM,YAAY;CAE/D,IAAI,CAAE,MAAM,IAAI,cAAc,WAAW,IAAI,YAAY,CAAC,GAAI;EAC5D,MAAM,IAAI,gBAAgB;EAE1B,MAAM,YAAY;CACpB;CAEA,IAAI,CAAC,YAAY,MAAM,OAAO,IAAI,IAAI,YAAY,KAAK,EAAE,GAAG,IAAI,GAAG,MAAM,YAAY;CAErF,IAAI,CAAE,MAAM,IAAI,gBAAgB,GAAI,MAAM,YAAY;CAEtD,OAAO,YAAY,cAAc,MAAM,UAAU;AACnD"}
1
+ {"version":3,"file":"otp.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/otp/otp.ts"],"sourcesContent":["import type { ChildModel } from \"@warlock.js/cascade\";\nimport { createHmac, randomBytes, randomInt } from \"node:crypto\";\nimport type { OtpMessage, OtpSender } from \"../contracts/providers\";\nimport type { DeviceInfo, LoginResult } from \"../contracts/types\";\nimport { InvalidOneTimeTokenError } from \"../errors/invalid-one-time-token.error\";\nimport type { Auth } from \"../models/auth.model\";\nimport { authConfig } from \"../services/auth-config\";\nimport { authService } from \"../services/auth.service\";\nimport { oneTimeTokenModel } from \"../services/one-time-tokens\";\nimport { loadOptionalPeer } from \"../services/optional-peer\";\nimport { safeEqual } from \"../utils/safe-equal\";\n\n/** The slice of `@warlock.js/notifications` OTP delivery uses (an optional peer). */\ntype NotifyModule = {\n notify: {\n channel: (name: string) => { send: (to: string, payload: unknown) => Promise<unknown> };\n };\n};\n\nconst CODE_PATTERN = /^\\d{6}$/;\n\n/** One error for every rejection: unknown phone, no code, wrong, expired, used, over the cap. */\nfunction invalidCode(): InvalidOneTimeTokenError {\n return new InvalidOneTimeTokenError(\"Invalid or expired code.\");\n}\n\n/**\n * Keyed hash of a code. A plain SHA-256 of a 6-digit code is reversed by\n * trying all million values, so the MAC key (derived from the access-token\n * secret) is what keeps a leaked table useless. `salt` makes each stored\n * value unique.\n */\nfunction macCode(user: Auth, salt: string, code: string): string {\n const key = createHmac(\"sha256\", authConfig.accessToken.secret())\n .update(\"@warlock.js/auth:otp\")\n .digest();\n\n return createHmac(\"sha256\", key)\n .update(`${salt}:${user.userType}:${user.id}:${code}`)\n .digest(\"base64url\");\n}\n\n/** Stored form: `<salt>.<mac>` — 16 + 1 + 43 chars, inside the 64-char `token_hash` column. */\nfunction storedCodeHash(user: Auth, code: string): string {\n const salt = randomBytes(12).toString(\"base64url\");\n\n return `${salt}.${macCode(user, salt, code)}`;\n}\n\nfunction codeMatches(user: Auth, stored: string, code: string): boolean {\n const [salt, mac] = stored.split(\".\");\n\n return !!salt && !!mac && safeEqual(mac, macCode(user, salt, code));\n}\n\n/**\n * Resolve how a code is sent: `auth.otp.send`, else the app's notifications\n * channel. Resolved BEFORE the user lookup, so a missing notifications package\n * fails identically for known and unknown phones.\n */\nasync function resolveDelivery(channel: string): Promise<OtpSender> {\n const custom = authConfig.otp.send();\n\n if (custom) return custom;\n\n const { notify } = await loadOptionalPeer<NotifyModule>(\n \"@warlock.js/notifications\",\n \"notifications\",\n );\n\n return (phone, message, channelName) => notify.channel(channelName).send(phone, message);\n}\n\n/**\n * Send a 6-digit login code to the account whose `auth.otp.phoneField`\n * (default `phone`) equals `phone`, through the notifications channel named by\n * `options.channel` / `auth.otp.channel` (default `\"sms\"`). Auth ships no\n * SMS/WhatsApp driver — the app registers that channel.\n *\n * The code is stored only as a keyed hash in `one_time_tokens` (purpose\n * `otp`), expires after `auth.otp.expiresIn` (default 5m), and replaces any\n * earlier unused code. **Anti-enumeration:** an unknown phone resolves the same\n * way and sends nothing. Throttle the route with `otpRequestThrottleMiddleware()`.\n *\n * @throws AuthProviderSdkMissingError when `@warlock.js/notifications` is not\n * installed and no `auth.otp.send` is configured.\n */\nexport async function requestOtp<T extends Auth>(\n Model: ChildModel<T>,\n phone: string,\n options: { channel?: string } = {},\n): Promise<void> {\n const channel = options.channel ?? authConfig.otp.channel();\n const deliver = await resolveDelivery(channel);\n\n if (typeof phone !== \"string\" || phone.length === 0) return;\n\n const user = (await Model.first({ [authConfig.otp.phoneField()]: phone })) as T | null;\n\n if (!user) return;\n\n const code = String(randomInt(0, 1_000_000)).padStart(6, \"0\");\n const expiresAt = new Date(Date.now() + authConfig.otp.expiresInMs());\n const TokenModel = oneTimeTokenModel();\n\n await TokenModel.invalidateActiveFor(user, \"otp\");\n await TokenModel.issue(user, \"otp\", storedCodeHash(user, code), expiresAt);\n\n const message: OtpMessage = { body: authConfig.otp.message(code), code, expiresAt };\n\n await deliver(phone, message, channel);\n}\n\n/**\n * Verify a phone login code and log the user in through\n * `authService.completeLogin` — the same outcome as password login.\n *\n * Each check first counts an attempt atomically; once `auth.otp.maxAttempts`\n * (default 5) have been counted the code is invalidated, so it is compared at\n * most that many times even under concurrent guesses. A correct code is\n * consumed single-use. Throttle the route with `otpVerifyThrottleMiddleware()`.\n *\n * @throws InvalidOneTimeTokenError (400, EC008) — the same for an unknown\n * phone, a wrong, expired, used or exhausted code.\n */\nexport async function verifyOtp<T extends Auth>(\n Model: ChildModel<T>,\n phone: string,\n code: string,\n deviceInfo?: DeviceInfo,\n): Promise<LoginResult<T>> {\n if (typeof phone !== \"string\" || phone.length === 0) throw invalidCode();\n if (typeof code !== \"string\" || !CODE_PATTERN.test(code)) throw invalidCode();\n\n const user = (await Model.first({ [authConfig.otp.phoneField()]: phone })) as T | null;\n\n if (!user) throw invalidCode();\n\n const row = await oneTimeTokenModel().findActiveFor(user, \"otp\");\n\n if (!row || row.isConsumed || row.isExpired) throw invalidCode();\n\n if (!(await row.recordAttempt(authConfig.otp.maxAttempts()))) {\n await row.consumeIfActive();\n\n throw invalidCode();\n }\n\n if (!codeMatches(user, String(row.get(\"token_hash\") ?? \"\"), code)) throw invalidCode();\n\n if (!(await row.consumeIfActive())) throw invalidCode();\n\n return authService.completeLogin(user, deviceInfo);\n}\n"],"mappings":";;;;;;;;;AAmBA,MAAM,eAAe;;AAGrB,SAAS,cAAwC;CAC/C,OAAO,IAAI,yBAAyB,0BAA0B;AAChE;;;;;;;AAQA,SAAS,QAAQ,MAAY,MAAc,MAAsB;CAC/D,MAAM,MAAM,WAAW,UAAU,WAAW,YAAY,OAAO,CAAC,CAAC,CAC9D,OAAO,sBAAsB,CAAC,CAC9B,OAAO;CAEV,OAAO,WAAW,UAAU,GAAG,CAAC,CAC7B,OAAO,GAAG,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,GAAG,GAAG,MAAM,CAAC,CACrD,OAAO,WAAW;AACvB;;AAGA,SAAS,eAAe,MAAY,MAAsB;CACxD,MAAM,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,WAAW;CAEjD,OAAO,GAAG,KAAK,GAAG,QAAQ,MAAM,MAAM,IAAI;AAC5C;AAEA,SAAS,YAAY,MAAY,QAAgB,MAAuB;CACtE,MAAM,CAAC,MAAM,OAAO,OAAO,MAAM,GAAG;CAEpC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,UAAU,KAAK,QAAQ,MAAM,MAAM,IAAI,CAAC;AACpE;;;;;;AAOA,eAAe,gBAAgB,SAAqC;CAClE,MAAM,SAAS,WAAW,IAAI,KAAK;CAEnC,IAAI,QAAQ,OAAO;CAEnB,MAAM,EAAE,WAAW,MAAM,iBACvB,6BACA,eACF;CAEA,QAAQ,OAAO,SAAS,gBAAgB,OAAO,QAAQ,WAAW,CAAC,CAAC,KAAK,OAAO,OAAO;AACzF;;;;;;;;;;;;;;;AAgBA,eAAsB,WACpB,OACA,OACA,UAAgC,CAAC,GAClB;CACf,MAAM,UAAU,QAAQ,WAAW,WAAW,IAAI,QAAQ;CAC1D,MAAM,UAAU,MAAM,gBAAgB,OAAO;CAE7C,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;CAErD,MAAM,OAAQ,MAAM,MAAM,MAAM,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,CAAC;CAExE,IAAI,CAAC,MAAM;CAEX,MAAM,OAAO,OAAO,UAAU,GAAG,GAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CAC5D,MAAM,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,WAAW,IAAI,YAAY,CAAC;CACpE,MAAM,aAAa,kBAAkB;CAErC,MAAM,WAAW,oBAAoB,MAAM,KAAK;CAChD,MAAM,WAAW,MAAM,MAAM,OAAO,eAAe,MAAM,IAAI,GAAG,SAAS;CAIzE,MAAM,QAAQ,OAAO;EAFS,MAAM,WAAW,IAAI,QAAQ,IAAI;EAAG;EAAM;CAE7C,GAAG,OAAO;AACvC;;;;;;;;;;;;;AAcA,eAAsB,UACpB,OACA,OACA,MACA,YACyB;CACzB,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG,MAAM,YAAY;CACvE,IAAI,OAAO,SAAS,YAAY,CAAC,aAAa,KAAK,IAAI,GAAG,MAAM,YAAY;CAE5E,MAAM,OAAQ,MAAM,MAAM,MAAM,GAAG,WAAW,IAAI,WAAW,IAAI,MAAM,CAAC;CAExE,IAAI,CAAC,MAAM,MAAM,YAAY;CAE7B,MAAM,MAAM,MAAM,kBAAkB,CAAC,CAAC,cAAc,MAAM,KAAK;CAE/D,IAAI,CAAC,OAAO,IAAI,cAAc,IAAI,WAAW,MAAM,YAAY;CAE/D,IAAI,CAAE,MAAM,IAAI,cAAc,WAAW,IAAI,YAAY,CAAC,GAAI;EAC5D,MAAM,IAAI,gBAAgB;EAE1B,MAAM,YAAY;CACpB;CAEA,IAAI,CAAC,YAAY,MAAM,OAAO,IAAI,IAAI,YAAY,KAAK,EAAE,GAAG,IAAI,GAAG,MAAM,YAAY;CAErF,IAAI,CAAE,MAAM,IAAI,gBAAgB,GAAI,MAAM,YAAY;CAEtD,OAAO,YAAY,cAAc,MAAM,UAAU;AACnD"}
@@ -1,3 +1,4 @@
1
1
  import { PasskeyOptionsJSON, PasskeyResponseJSON } from "./simplewebauthn.mjs";
2
2
  import { generatePasskeyAuthenticationOptions, verifyPasskeyAuthentication } from "./passkey-authentication.mjs";
3
- import { generatePasskeyRegistrationOptions, verifyPasskeyRegistration } from "./passkey-registration.mjs";
3
+ import { generatePasskeyRegistrationOptions, verifyPasskeyRegistration } from "./passkey-registration.mjs";
4
+ export { type PasskeyOptionsJSON, type PasskeyResponseJSON, generatePasskeyAuthenticationOptions, generatePasskeyRegistrationOptions, verifyPasskeyAuthentication, verifyPasskeyRegistration };
@@ -1,4 +1,4 @@
1
1
  import { generatePasskeyAuthenticationOptions, verifyPasskeyAuthentication } from "./passkey-authentication.mjs";
2
2
  import { generatePasskeyRegistrationOptions, verifyPasskeyRegistration } from "./passkey-registration.mjs";
3
3
 
4
- export { };
4
+ export { generatePasskeyAuthenticationOptions, generatePasskeyRegistrationOptions, verifyPasskeyAuthentication, verifyPasskeyRegistration };
@@ -2,7 +2,6 @@ import { Auth } from "../models/auth.model.mjs";
2
2
  import { DeviceInfo, LoginResult } from "../contracts/types.mjs";
3
3
  import { PasskeyOptionsJSON, PasskeyResponseJSON } from "./simplewebauthn.mjs";
4
4
  import { Request } from "@warlock.js/core";
5
-
6
5
  //#region ../../packages/auth/src/passkeys/passkey-authentication.d.ts
7
6
  /**
8
7
  * Authentication options for a passkey login. No user is identified yet
@@ -13,7 +12,7 @@ import { Request } from "@warlock.js/core";
13
12
  * // POST /auth/passkeys/login/options
14
13
  * response.success(await generatePasskeyAuthenticationOptions());
15
14
  */
16
- declare function generatePasskeyAuthenticationOptions(): Promise<PasskeyOptionsJSON>;
15
+ export declare function generatePasskeyAuthenticationOptions(): Promise<PasskeyOptionsJSON>;
17
16
  /**
18
17
  * Verify a passkey assertion and log its owner in through
19
18
  * `authService.completeLogin` — the same outcome as password login.
@@ -27,7 +26,6 @@ declare function generatePasskeyAuthenticationOptions(): Promise<PasskeyOptionsJ
27
26
  *
28
27
  * @throws InvalidPasskeyError (400, EC011) on any rejection.
29
28
  */
30
- declare function verifyPasskeyAuthentication(request: Request, credential: PasskeyResponseJSON, deviceInfo?: DeviceInfo): Promise<LoginResult<Auth>>;
29
+ export declare function verifyPasskeyAuthentication(request: Request, credential: PasskeyResponseJSON, deviceInfo?: DeviceInfo): Promise<LoginResult<Auth>>;
31
30
  //#endregion
32
- export { generatePasskeyAuthenticationOptions, verifyPasskeyAuthentication };
33
31
  //# sourceMappingURL=passkey-authentication.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passkey-authentication.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/passkey-authentication.ts"],"mappings":";;;;;;;;AAiDA;;;;AAAwF;AA0BxF;;iBA1BsB,oCAAA,IAAwC,OAAO,CAAC,kBAAA;;;;;;;;;;;;;;iBA0BhD,2BAAA,CACpB,OAAA,EAAS,OAAA,EACT,UAAA,EAAY,mBAAA,EACZ,UAAA,GAAa,UAAA,GACZ,OAAA,CAAQ,WAAA,CAAY,IAAA"}
1
+ {"version":3,"file":"passkey-authentication.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/passkey-authentication.ts"],"mappings":";;;;;;;;;;;;;;wBAiDsB,wCAAwC,QAAQ;;;;;;;;;;;;;;wBA0BhD,4BACpB,SAAS,SACT,YAAY,qBACZ,aAAa,aACZ,QAAQ,YAAY"}
@@ -75,7 +75,8 @@ async function verifyPasskeyAuthentication(request, credential, deviceInfo) {
75
75
  requireUserVerification: false
76
76
  });
77
77
  } catch (error) {
78
- throw new InvalidPasskeyError(counterRegressed(stored.counter, presentedCounter(credential)) ? "counter-regression" : "authentication-verification-failed", error);
78
+ const reason = counterRegressed(stored.counter, presentedCounter(credential)) ? "counter-regression" : "authentication-verification-failed";
79
+ throw new InvalidPasskeyError(reason, error);
79
80
  }
80
81
  if (!verification.verified) throw new InvalidPasskeyError("authentication-not-verified");
81
82
  const previous = stored.counter;
@@ -1 +1 @@
1
- {"version":3,"file":"passkey-authentication.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/passkey-authentication.ts"],"sourcesContent":["import type { ChildModel } from \"@warlock.js/cascade\";\nimport { config, type Request } from \"@warlock.js/core\";\nimport type { DeviceInfo, LoginResult } from \"../contracts/types\";\nimport { InvalidPasskeyError } from \"../errors/invalid-passkey.error\";\nimport type { Auth } from \"../models/auth.model\";\nimport { PasskeyCredential } from \"../models/passkey-credential\";\nimport { authConfig } from \"../services/auth-config\";\nimport { authService } from \"../services/auth.service\";\nimport {\n assertPasskeyOrigin,\n storePasskeyChallenge,\n takePasskeyChallenge,\n} from \"./passkey-challenges\";\nimport {\n loadSimpleWebAuthn,\n type PasskeyOptionsJSON,\n type PasskeyResponseJSON,\n} from \"./simplewebauthn\";\n\n/** A counter that did not advance past the stored one (when either is non-zero): a cloned authenticator. */\nfunction counterRegressed(stored: number, presented: number | undefined): boolean {\n if (presented === undefined) return false;\n\n return (stored > 0 || presented > 0) && !(presented > stored);\n}\n\n/**\n * The signature counter an assertion CLAIMS (bytes 33–36 of authenticatorData).\n * Unverified — only used to label a rejection the SDK already made.\n */\nfunction presentedCounter(credential: PasskeyResponseJSON): number | undefined {\n const encoded = credential.response.authenticatorData;\n\n if (typeof encoded !== \"string\") return undefined;\n\n const authData = Buffer.from(encoded, \"base64url\");\n\n return authData.length >= 37 ? authData.readUInt32BE(33) : undefined;\n}\n\n/**\n * Authentication options for a passkey login. No user is identified yet\n * (discoverable credentials), so the stored single-use challenge has no owner;\n * the credential the browser returns decides the user.\n *\n * @example\n * // POST /auth/passkeys/login/options\n * response.success(await generatePasskeyAuthenticationOptions());\n */\nexport async function generatePasskeyAuthenticationOptions(): Promise<PasskeyOptionsJSON> {\n const webauthn = await loadSimpleWebAuthn();\n\n const options = await webauthn.generateAuthenticationOptions({\n rpID: authConfig.passkeys.settings().rpID,\n userVerification: \"preferred\",\n });\n\n await storePasskeyChallenge(\"passkey-authentication\", options.challenge);\n\n return options;\n}\n\n/**\n * Verify a passkey assertion and log its owner in through\n * `authService.completeLogin` — the same outcome as password login.\n *\n * Checks, in order: the request `Origin` (CSRF), the single-use challenge\n * (consumed even if what follows fails), the credential is registered, the\n * assertion via `@simplewebauthn/server`, then that the signature counter\n * ADVANCED — a counter that did not move past the stored one (when either is\n * non-zero) means a cloned authenticator and is rejected. The new counter is\n * written with a compare-and-set.\n *\n * @throws InvalidPasskeyError (400, EC011) on any rejection.\n */\nexport async function verifyPasskeyAuthentication(\n request: Request,\n credential: PasskeyResponseJSON,\n deviceInfo?: DeviceInfo,\n): Promise<LoginResult<Auth>> {\n const webauthn = await loadSimpleWebAuthn();\n const origins = assertPasskeyOrigin(request);\n const { challenge } = await takePasskeyChallenge(\"passkey-authentication\", credential);\n\n const stored =\n typeof credential.id === \"string\"\n ? await PasskeyCredential.findByCredentialId(credential.id)\n : null;\n\n if (!stored) {\n throw new InvalidPasskeyError(\"unknown-credential\");\n }\n\n let verification: Awaited<ReturnType<typeof webauthn.verifyAuthenticationResponse>>;\n\n try {\n verification = await webauthn.verifyAuthenticationResponse({\n response: credential,\n expectedChallenge: challenge,\n expectedOrigin: origins,\n expectedRPID: authConfig.passkeys.settings().rpID,\n credential: {\n id: stored.credentialId,\n publicKey: new Uint8Array(Buffer.from(String(stored.get(\"public_key\")), \"base64url\")),\n counter: stored.counter,\n transports: stored.get(\"transports\") ?? undefined,\n },\n requireUserVerification: false,\n });\n } catch (error) {\n // The SDK enforces the counter rule itself and throws a generic Error for\n // it; keep clone detection visible as its own reason in the logs.\n const reason = counterRegressed(stored.counter, presentedCounter(credential))\n ? \"counter-regression\"\n : \"authentication-verification-failed\";\n\n throw new InvalidPasskeyError(reason, error);\n }\n\n if (!verification.verified) {\n throw new InvalidPasskeyError(\"authentication-not-verified\");\n }\n\n const previous = stored.counter;\n const next = Number(verification.authenticationInfo.newCounter);\n\n if (counterRegressed(previous, next)) {\n throw new InvalidPasskeyError(\"counter-regression\");\n }\n\n if (!(await stored.advanceCounter(previous, next))) {\n throw new InvalidPasskeyError(\"counter-changed-concurrently\");\n }\n\n const UserModel = config.key<ChildModel<Auth> | undefined>(`auth.userType.${stored.userType}`);\n const user = UserModel ? ((await UserModel.find(stored.userId)) as Auth | null) : null;\n\n if (!user) {\n throw new InvalidPasskeyError(\"credential-owner-missing\");\n }\n\n return authService.completeLogin(user, deviceInfo);\n}\n"],"mappings":";;;;;;;;;;;AAoBA,SAAS,iBAAiB,QAAgB,WAAwC;CAChF,IAAI,cAAc,QAAW,OAAO;CAEpC,QAAQ,SAAS,KAAK,YAAY,MAAM,EAAE,YAAY;AACxD;;;;;AAMA,SAAS,iBAAiB,YAAqD;CAC7E,MAAM,UAAU,WAAW,SAAS;CAEpC,IAAI,OAAO,YAAY,UAAU,OAAO;CAExC,MAAM,WAAW,OAAO,KAAK,SAAS,WAAW;CAEjD,OAAO,SAAS,UAAU,KAAK,SAAS,aAAa,EAAE,IAAI;AAC7D;;;;;;;;;;AAWA,eAAsB,uCAAoE;CAGxF,MAAM,UAAU,OAAM,MAFC,mBAAmB,EAEZ,CAAC,8BAA8B;EAC3D,MAAM,WAAW,SAAS,SAAS,CAAC,CAAC;EACrC,kBAAkB;CACpB,CAAC;CAED,MAAM,sBAAsB,0BAA0B,QAAQ,SAAS;CAEvE,OAAO;AACT;;;;;;;;;;;;;;AAeA,eAAsB,4BACpB,SACA,YACA,YAC4B;CAC5B,MAAM,WAAW,MAAM,mBAAmB;CAC1C,MAAM,UAAU,oBAAoB,OAAO;CAC3C,MAAM,EAAE,cAAc,MAAM,qBAAqB,0BAA0B,UAAU;CAErF,MAAM,SACJ,OAAO,WAAW,OAAO,WACrB,MAAM,kBAAkB,mBAAmB,WAAW,EAAE,IACxD;CAEN,IAAI,CAAC,QACH,MAAM,IAAI,oBAAoB,oBAAoB;CAGpD,IAAI;CAEJ,IAAI;EACF,eAAe,MAAM,SAAS,6BAA6B;GACzD,UAAU;GACV,mBAAmB;GACnB,gBAAgB;GAChB,cAAc,WAAW,SAAS,SAAS,CAAC,CAAC;GAC7C,YAAY;IACV,IAAI,OAAO;IACX,WAAW,IAAI,WAAW,OAAO,KAAK,OAAO,OAAO,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC;IACpF,SAAS,OAAO;IAChB,YAAY,OAAO,IAAI,YAAY,KAAK;GAC1C;GACA,yBAAyB;EAC3B,CAAC;CACH,SAAS,OAAO;EAOd,MAAM,IAAI,oBAJK,iBAAiB,OAAO,SAAS,iBAAiB,UAAU,CAAC,IACxE,uBACA,sCAEkC,KAAK;CAC7C;CAEA,IAAI,CAAC,aAAa,UAChB,MAAM,IAAI,oBAAoB,6BAA6B;CAG7D,MAAM,WAAW,OAAO;CACxB,MAAM,OAAO,OAAO,aAAa,mBAAmB,UAAU;CAE9D,IAAI,iBAAiB,UAAU,IAAI,GACjC,MAAM,IAAI,oBAAoB,oBAAoB;CAGpD,IAAI,CAAE,MAAM,OAAO,eAAe,UAAU,IAAI,GAC9C,MAAM,IAAI,oBAAoB,8BAA8B;CAG9D,MAAM,YAAY,OAAO,IAAkC,iBAAiB,OAAO,UAAU;CAC7F,MAAM,OAAO,YAAc,MAAM,UAAU,KAAK,OAAO,MAAM,IAAqB;CAElF,IAAI,CAAC,MACH,MAAM,IAAI,oBAAoB,0BAA0B;CAG1D,OAAO,YAAY,cAAc,MAAM,UAAU;AACnD"}
1
+ {"version":3,"file":"passkey-authentication.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/passkey-authentication.ts"],"sourcesContent":["import type { ChildModel } from \"@warlock.js/cascade\";\nimport { config, type Request } from \"@warlock.js/core\";\nimport type { DeviceInfo, LoginResult } from \"../contracts/types\";\nimport { InvalidPasskeyError } from \"../errors/invalid-passkey.error\";\nimport type { Auth } from \"../models/auth.model\";\nimport { PasskeyCredential } from \"../models/passkey-credential\";\nimport { authConfig } from \"../services/auth-config\";\nimport { authService } from \"../services/auth.service\";\nimport {\n assertPasskeyOrigin,\n storePasskeyChallenge,\n takePasskeyChallenge,\n} from \"./passkey-challenges\";\nimport {\n loadSimpleWebAuthn,\n type PasskeyOptionsJSON,\n type PasskeyResponseJSON,\n} from \"./simplewebauthn\";\n\n/** A counter that did not advance past the stored one (when either is non-zero): a cloned authenticator. */\nfunction counterRegressed(stored: number, presented: number | undefined): boolean {\n if (presented === undefined) return false;\n\n return (stored > 0 || presented > 0) && !(presented > stored);\n}\n\n/**\n * The signature counter an assertion CLAIMS (bytes 33–36 of authenticatorData).\n * Unverified — only used to label a rejection the SDK already made.\n */\nfunction presentedCounter(credential: PasskeyResponseJSON): number | undefined {\n const encoded = credential.response.authenticatorData;\n\n if (typeof encoded !== \"string\") return undefined;\n\n const authData = Buffer.from(encoded, \"base64url\");\n\n return authData.length >= 37 ? authData.readUInt32BE(33) : undefined;\n}\n\n/**\n * Authentication options for a passkey login. No user is identified yet\n * (discoverable credentials), so the stored single-use challenge has no owner;\n * the credential the browser returns decides the user.\n *\n * @example\n * // POST /auth/passkeys/login/options\n * response.success(await generatePasskeyAuthenticationOptions());\n */\nexport async function generatePasskeyAuthenticationOptions(): Promise<PasskeyOptionsJSON> {\n const webauthn = await loadSimpleWebAuthn();\n\n const options = await webauthn.generateAuthenticationOptions({\n rpID: authConfig.passkeys.settings().rpID,\n userVerification: \"preferred\",\n });\n\n await storePasskeyChallenge(\"passkey-authentication\", options.challenge);\n\n return options;\n}\n\n/**\n * Verify a passkey assertion and log its owner in through\n * `authService.completeLogin` — the same outcome as password login.\n *\n * Checks, in order: the request `Origin` (CSRF), the single-use challenge\n * (consumed even if what follows fails), the credential is registered, the\n * assertion via `@simplewebauthn/server`, then that the signature counter\n * ADVANCED — a counter that did not move past the stored one (when either is\n * non-zero) means a cloned authenticator and is rejected. The new counter is\n * written with a compare-and-set.\n *\n * @throws InvalidPasskeyError (400, EC011) on any rejection.\n */\nexport async function verifyPasskeyAuthentication(\n request: Request,\n credential: PasskeyResponseJSON,\n deviceInfo?: DeviceInfo,\n): Promise<LoginResult<Auth>> {\n const webauthn = await loadSimpleWebAuthn();\n const origins = assertPasskeyOrigin(request);\n const { challenge } = await takePasskeyChallenge(\"passkey-authentication\", credential);\n\n const stored =\n typeof credential.id === \"string\"\n ? await PasskeyCredential.findByCredentialId(credential.id)\n : null;\n\n if (!stored) {\n throw new InvalidPasskeyError(\"unknown-credential\");\n }\n\n let verification: Awaited<ReturnType<typeof webauthn.verifyAuthenticationResponse>>;\n\n try {\n verification = await webauthn.verifyAuthenticationResponse({\n response: credential,\n expectedChallenge: challenge,\n expectedOrigin: origins,\n expectedRPID: authConfig.passkeys.settings().rpID,\n credential: {\n id: stored.credentialId,\n publicKey: new Uint8Array(Buffer.from(String(stored.get(\"public_key\")), \"base64url\")),\n counter: stored.counter,\n transports: stored.get(\"transports\") ?? undefined,\n },\n requireUserVerification: false,\n });\n } catch (error) {\n // The SDK enforces the counter rule itself and throws a generic Error for\n // it; keep clone detection visible as its own reason in the logs.\n const reason = counterRegressed(stored.counter, presentedCounter(credential))\n ? \"counter-regression\"\n : \"authentication-verification-failed\";\n\n throw new InvalidPasskeyError(reason, error);\n }\n\n if (!verification.verified) {\n throw new InvalidPasskeyError(\"authentication-not-verified\");\n }\n\n const previous = stored.counter;\n const next = Number(verification.authenticationInfo.newCounter);\n\n if (counterRegressed(previous, next)) {\n throw new InvalidPasskeyError(\"counter-regression\");\n }\n\n if (!(await stored.advanceCounter(previous, next))) {\n throw new InvalidPasskeyError(\"counter-changed-concurrently\");\n }\n\n const UserModel = config.key<ChildModel<Auth> | undefined>(`auth.userType.${stored.userType}`);\n const user = UserModel ? ((await UserModel.find(stored.userId)) as Auth | null) : null;\n\n if (!user) {\n throw new InvalidPasskeyError(\"credential-owner-missing\");\n }\n\n return authService.completeLogin(user, deviceInfo);\n}\n"],"mappings":";;;;;;;;;;;AAoBA,SAAS,iBAAiB,QAAgB,WAAwC;CAChF,IAAI,cAAc,QAAW,OAAO;CAEpC,QAAQ,SAAS,KAAK,YAAY,MAAM,EAAE,YAAY;AACxD;;;;;AAMA,SAAS,iBAAiB,YAAqD;CAC7E,MAAM,UAAU,WAAW,SAAS;CAEpC,IAAI,OAAO,YAAY,UAAU,OAAO;CAExC,MAAM,WAAW,OAAO,KAAK,SAAS,WAAW;CAEjD,OAAO,SAAS,UAAU,KAAK,SAAS,aAAa,EAAE,IAAI;AAC7D;;;;;;;;;;AAWA,eAAsB,uCAAoE;CAGxF,MAAM,UAAU,OAAM,MAFC,mBAAmB,EAEZ,CAAC,8BAA8B;EAC3D,MAAM,WAAW,SAAS,SAAS,CAAC,CAAC;EACrC,kBAAkB;CACpB,CAAC;CAED,MAAM,sBAAsB,0BAA0B,QAAQ,SAAS;CAEvE,OAAO;AACT;;;;;;;;;;;;;;AAeA,eAAsB,4BACpB,SACA,YACA,YAC4B;CAC5B,MAAM,WAAW,MAAM,mBAAmB;CAC1C,MAAM,UAAU,oBAAoB,OAAO;CAC3C,MAAM,EAAE,cAAc,MAAM,qBAAqB,0BAA0B,UAAU;CAErF,MAAM,SACJ,OAAO,WAAW,OAAO,WACrB,MAAM,kBAAkB,mBAAmB,WAAW,EAAE,IACxD;CAEN,IAAI,CAAC,QACH,MAAM,IAAI,oBAAoB,oBAAoB;CAGpD,IAAI;CAEJ,IAAI;EACF,eAAe,MAAM,SAAS,6BAA6B;GACzD,UAAU;GACV,mBAAmB;GACnB,gBAAgB;GAChB,cAAc,WAAW,SAAS,SAAS,CAAC,CAAC;GAC7C,YAAY;IACV,IAAI,OAAO;IACX,WAAW,IAAI,WAAW,OAAO,KAAK,OAAO,OAAO,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC;IACpF,SAAS,OAAO;IAChB,YAAY,OAAO,IAAI,YAAY,KAAK;GAC1C;GACA,yBAAyB;EAC3B,CAAC;CACH,SAAS,OAAO;EAGd,MAAM,SAAS,iBAAiB,OAAO,SAAS,iBAAiB,UAAU,CAAC,IACxE,uBACA;EAEJ,MAAM,IAAI,oBAAoB,QAAQ,KAAK;CAC7C;CAEA,IAAI,CAAC,aAAa,UAChB,MAAM,IAAI,oBAAoB,6BAA6B;CAG7D,MAAM,WAAW,OAAO;CACxB,MAAM,OAAO,OAAO,aAAa,mBAAmB,UAAU;CAE9D,IAAI,iBAAiB,UAAU,IAAI,GACjC,MAAM,IAAI,oBAAoB,oBAAoB;CAGpD,IAAI,CAAE,MAAM,OAAO,eAAe,UAAU,IAAI,GAC9C,MAAM,IAAI,oBAAoB,8BAA8B;CAG9D,MAAM,YAAY,OAAO,IAAkC,iBAAiB,OAAO,UAAU;CAC7F,MAAM,OAAO,YAAc,MAAM,UAAU,KAAK,OAAO,MAAM,IAAqB;CAElF,IAAI,CAAC,MACH,MAAM,IAAI,oBAAoB,0BAA0B;CAG1D,OAAO,YAAY,cAAc,MAAM,UAAU;AACnD"}
@@ -1,8 +1,8 @@
1
1
  import { Auth } from "../models/auth.model.mjs";
2
2
  import { PasskeyCredential } from "../models/passkey-credential/passkey-credential.model.mjs";
3
+ import "../models/passkey-credential/index.mjs";
3
4
  import { PasskeyOptionsJSON, PasskeyResponseJSON } from "./simplewebauthn.mjs";
4
5
  import { Request } from "@warlock.js/core";
5
-
6
6
  //#region ../../packages/auth/src/passkeys/passkey-registration.d.ts
7
7
  /**
8
8
  * Registration options for a LOGGED-IN user adding a passkey. The challenge is
@@ -13,7 +13,7 @@ import { Request } from "@warlock.js/core";
13
13
  * // POST /auth/passkeys/register/options (authMiddleware)
14
14
  * response.success(await generatePasskeyRegistrationOptions(request.locals.user));
15
15
  */
16
- declare function generatePasskeyRegistrationOptions(user: Auth): Promise<PasskeyOptionsJSON>;
16
+ export declare function generatePasskeyRegistrationOptions(user: Auth): Promise<PasskeyOptionsJSON>;
17
17
  /**
18
18
  * Verify the browser's registration response and store the credential.
19
19
  * Checks, in order: the request `Origin` (CSRF), the single-use challenge
@@ -23,7 +23,6 @@ declare function generatePasskeyRegistrationOptions(user: Auth): Promise<Passkey
23
23
  *
24
24
  * @throws InvalidPasskeyError (400, EC011) on any rejection.
25
25
  */
26
- declare function verifyPasskeyRegistration(request: Request, user: Auth, credential: PasskeyResponseJSON): Promise<PasskeyCredential>;
26
+ export declare function verifyPasskeyRegistration(request: Request, user: Auth, credential: PasskeyResponseJSON): Promise<PasskeyCredential>;
27
27
  //#endregion
28
- export { generatePasskeyRegistrationOptions, verifyPasskeyRegistration };
29
28
  //# sourceMappingURL=passkey-registration.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passkey-registration.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/passkey-registration.ts"],"mappings":";;;;;;;;;AAoCA;;;;;;iBAAsB,kCAAA,CAAmC,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,kBAAA;;;;;;;AAAkB;AAgChG;;iBAAsB,yBAAA,CACpB,OAAA,EAAS,OAAA,EACT,IAAA,EAAM,IAAA,EACN,UAAA,EAAY,mBAAA,GACX,OAAA,CAAQ,iBAAA"}
1
+ {"version":3,"file":"passkey-registration.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/passkey-registration.ts"],"mappings":";;;;;;;;;;;;;;;wBAoCsB,mCAAmC,MAAM,OAAO,QAAQ;;;;;;;;;;wBAgCxD,0BACpB,SAAS,SACT,MAAM,MACN,YAAY,sBACX,QAAQ"}
@@ -1,6 +1,6 @@
1
1
  //#region ../../packages/auth/src/passkeys/simplewebauthn.d.ts
2
2
  /** The browser's JSON-serialized credential (`startRegistration` / `startAuthentication` result). */
3
- type PasskeyResponseJSON = {
3
+ export type PasskeyResponseJSON = {
4
4
  id: string;
5
5
  rawId: string;
6
6
  type: string;
@@ -12,10 +12,9 @@ type PasskeyResponseJSON = {
12
12
  [key: string]: unknown;
13
13
  };
14
14
  /** Options JSON handed to the browser; `challenge` is what auth stores. */
15
- type PasskeyOptionsJSON = {
15
+ export type PasskeyOptionsJSON = {
16
16
  challenge: string;
17
17
  [key: string]: unknown;
18
18
  };
19
19
  //#endregion
20
- export { PasskeyOptionsJSON, PasskeyResponseJSON };
21
20
  //# sourceMappingURL=simplewebauthn.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"simplewebauthn.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/simplewebauthn.ts"],"mappings":";;KAMY,mBAAA;EACV,EAAA;EACA,KAAA;EACA,IAAA;EACA,QAAA;IACE,cAAA;IACA,UAAA;IAAA,CACC,GAAA;EAAA;EAAA,CAEF,GAAA;AAAA;AAAW;AAAA,KAIF,kBAAA;EACV,SAAA;EAAA,CACC,GAAW;AAAA"}
1
+ {"version":3,"file":"simplewebauthn.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/passkeys/simplewebauthn.ts"],"mappings":";;YAMY;EACV;EACA;EACA;EACA;IACE;IACA;KACC;;GAEF;;;YAIS;EACV;GACC"}
@@ -9,5 +9,5 @@ function loadSimpleWebAuthn() {
9
9
  }
10
10
 
11
11
  //#endregion
12
- export { loadSimpleWebAuthn };
12
+ export { PASSKEYS_FEATURE, loadSimpleWebAuthn };
13
13
  //# sourceMappingURL=simplewebauthn.mjs.map
@@ -1,9 +1,8 @@
1
1
  import { AppleProviderConfig, AuthProvider, ProviderAuthorizationState, ProviderCallbackParams, ProviderProfile } from "../contracts/providers.mjs";
2
2
  import { JoseModule } from "./google-provider.mjs";
3
-
4
3
  //#region ../../packages/auth/src/providers/apple-provider.d.ts
5
4
  /** The `warlock add` feature that installs `jose`. */
6
- declare const APPLE_AUTH_FEATURE = "auth-apple";
5
+ export declare const APPLE_AUTH_FEATURE = "auth-apple";
7
6
  type AppleSignJwtBuilder = {
8
7
  setIssuer: (issuer: string) => AppleSignJwtBuilder;
9
8
  setIssuedAt: () => AppleSignJwtBuilder;
@@ -17,7 +16,7 @@ type AppleSignJwtBuilder = {
17
16
  * `importPKCS8` and `SignJWT` sign the ES256 client-secret JWT Apple requires
18
17
  * instead of a static client secret.
19
18
  */
20
- type AppleJoseModule = JoseModule & {
19
+ export type AppleJoseModule = JoseModule & {
21
20
  importPKCS8: (pkcs8: string, alg: string) => Promise<unknown>;
22
21
  SignJWT: new (payload: Record<string, unknown>) => {
23
22
  setProtectedHeader: (header: Record<string, unknown>) => AppleSignJwtBuilder;
@@ -51,17 +50,14 @@ type AppleJoseModule = JoseModule & {
51
50
  * `false`) as unverified. A private-relay address (`@privaterelay.appleid.com`)
52
51
  * is still a real, working forwarding address and is accepted as any other.
53
52
  */
54
- declare class AppleProvider implements AuthProvider {
53
+ export declare class AppleProvider implements AuthProvider {
55
54
  private readonly settings;
56
55
  readonly name = "apple";
57
56
  /** Apple's default scopes (`name`, `email`) force `response_mode=form_post`. */
58
57
  readonly callbackMode = "form_post";
59
58
  constructor(settings: AppleProviderConfig);
60
59
  authorizationUrl(state: ProviderAuthorizationState): string;
61
- handleCallback({
62
- query,
63
- expected
64
- }: ProviderCallbackParams): Promise<ProviderProfile>;
60
+ handleCallback({ query, expected }: ProviderCallbackParams): Promise<ProviderProfile>;
65
61
  /** Sign a fresh ES256 client-secret JWT — Apple has no static one. */
66
62
  private clientSecret;
67
63
  /** Redeem the authorization code (with the PKCE verifier) for an id_token. */
@@ -70,5 +66,5 @@ declare class AppleProvider implements AuthProvider {
70
66
  private verifyIdToken;
71
67
  }
72
68
  //#endregion
73
- export { APPLE_AUTH_FEATURE, AppleJoseModule, AppleProvider };
69
+ export {};
74
70
  //# sourceMappingURL=apple-provider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apple-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/apple-provider.ts"],"mappings":";;;;;cAqBa,kBAAA;AAAA,KAER,mBAAA;EACH,SAAA,GAAY,MAAA,aAAmB,mBAAA;EAC/B,WAAA,QAAmB,mBAAA;EACnB,iBAAA,GAAoB,IAAA,aAAiB,mBAAA;EACrC,WAAA,GAAc,QAAA,aAAqB,mBAAA;EACnC,UAAA,GAAa,OAAA,aAAoB,mBAAA;EACjC,IAAA,GAAO,GAAA,cAAiB,OAAA;AAAA;;;;;;KAQd,eAAA,GAAkB,UAAA;EAC5B,WAAA,GAAc,KAAA,UAAe,GAAA,aAAgB,OAAA;EAC7C,OAAA,OAAc,OAAA,EAAS,MAAA;IACrB,kBAAA,GAAqB,MAAA,EAAQ,MAAA,sBAA4B,mBAAA;EAAA;AAAA;;;;;;;;;;;;;;;;AAX5B;AAQjC;;;;;;;;;;;;cAsCa,aAAA,YAAyB,YAAA;EAAA,iBAKA,QAAA;EAAA,SAJpB,IAAA;EArChB;EAAA,SAuCgB,YAAA;cAEoB,QAAA,EAAU,mBAAA;EAEvC,gBAAA,CAAiB,KAAA,EAAO,0BAAA;EAqBlB,cAAA;IACX,KAAA;IACA;EAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,eAAA;EAlEb;EAAA,QAkGT,YAAA;EAlGgE;EAAA,QAqHhE,YAAA;EAlFH;EAAA,QAyHG,aAAA;AAAA"}
1
+ {"version":3,"file":"apple-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/apple-provider.ts"],"mappings":";;;;qBAqBa;KAER;EACH,YAAY,mBAAmB;EAC/B,mBAAmB;EACnB,oBAAoB,iBAAiB;EACrC,cAAc,qBAAqB;EACnC,aAAa,oBAAoB;EACjC,OAAO,iBAAiB;;;;;;;YAQd,kBAAkB;EAC5B,cAAc,eAAe,gBAAgB;EAC7C,cAAc,SAAS;IACrB,qBAAqB,QAAQ,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAmChD,yBAAyB;mBAKA;WAJpB;;WAEA;EAEhB,YAAoC,UAAU;EAEvC,iBAAiB,OAAO;EAqBlB,iBACX,OACA,YACC,yBAAyB,QAAQ;;UAgCtB;;UAmBA;;UAuCA"}
@@ -1,5 +1,4 @@
1
1
  import { AuthProvider, DiscordProviderConfig, ProviderAuthorizationState, ProviderCallbackParams, ProviderProfile } from "../contracts/providers.mjs";
2
-
3
2
  //#region ../../packages/auth/src/providers/discord-provider.d.ts
4
3
  /**
5
4
  * Discord sign-in: plain OAuth 2 authorization code flow with PKCE (S256).
@@ -7,19 +6,15 @@ import { AuthProvider, DiscordProviderConfig, ProviderAuthorizationState, Provid
7
6
  * access token is redeemed once for `/users/@me` over a direct HTTPS call.
8
7
  * No vendor SDK is involved.
9
8
  */
10
- declare class DiscordProvider implements AuthProvider {
9
+ export declare class DiscordProvider implements AuthProvider {
11
10
  private readonly settings;
12
11
  readonly name = "discord";
13
12
  constructor(settings: DiscordProviderConfig);
14
13
  authorizationUrl(state: ProviderAuthorizationState): string;
15
- handleCallback({
16
- query,
17
- expected
18
- }: ProviderCallbackParams): Promise<ProviderProfile>;
14
+ handleCallback({ query, expected }: ProviderCallbackParams): Promise<ProviderProfile>;
19
15
  /** Redeem the authorization code (with the PKCE verifier) for an access token. */
20
16
  private exchangeCode;
21
17
  private fetchUser;
22
18
  }
23
19
  //#endregion
24
- export { DiscordProvider };
25
20
  //# sourceMappingURL=discord-provider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discord-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/discord-provider.ts"],"mappings":";;;;;AA8BA;;;;cAAa,eAAA,YAA2B,YAAA;EAAA,iBAGF,QAAA;EAAA,SAFpB,IAAA;cAEoB,QAAA,EAAU,qBAAA;EAEvC,gBAAA,CAAiB,KAAA,EAAO,0BAAA;EAclB,cAAA;IACX,KAAA;IACA;EAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,eAAA;EAtBE;EAAA,QAkDxB,YAAA;EAAA,QAiCA,SAAA;AAAA"}
1
+ {"version":3,"file":"discord-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/discord-provider.ts"],"mappings":";;;;;;;;qBA8Ba,2BAA2B;mBAGF;WAFpB;EAEhB,YAAoC,UAAU;EAEvC,iBAAiB,OAAO;EAclB,iBACX,OACA,YACC,yBAAyB,QAAQ;;UA4BtB;UAiCA"}
@@ -1,5 +1,4 @@
1
1
  import { AuthProvider, FacebookProviderConfig, ProviderAuthorizationState, ProviderCallbackParams, ProviderProfile } from "../contracts/providers.mjs";
2
-
3
2
  //#region ../../packages/auth/src/providers/facebook-provider.d.ts
4
3
  /**
5
4
  * Facebook sign-in: plain OAuth 2 authorization code flow with PKCE (S256).
@@ -18,19 +17,15 @@ import { AuthProvider, FacebookProviderConfig, ProviderAuthorizationState, Provi
18
17
  * already rejects as an unverified/missing email, the same path GitHub's
19
18
  * unverified addresses take.
20
19
  */
21
- declare class FacebookProvider implements AuthProvider {
20
+ export declare class FacebookProvider implements AuthProvider {
22
21
  private readonly settings;
23
22
  readonly name = "facebook";
24
23
  constructor(settings: FacebookProviderConfig);
25
24
  authorizationUrl(state: ProviderAuthorizationState): string;
26
- handleCallback({
27
- query,
28
- expected
29
- }: ProviderCallbackParams): Promise<ProviderProfile>;
25
+ handleCallback({ query, expected }: ProviderCallbackParams): Promise<ProviderProfile>;
30
26
  /** Redeem the authorization code (with the PKCE verifier) for an access token. */
31
27
  private exchangeCode;
32
28
  private fetchUser;
33
29
  }
34
30
  //#endregion
35
- export { FacebookProvider };
36
31
  //# sourceMappingURL=facebook-provider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"facebook-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/facebook-provider.ts"],"mappings":";;;;;AAuCA;;;;;;;;;;;;;;;cAAa,gBAAA,YAA4B,YAAA;EAAA,iBAGH,QAAA;EAAA,SAFpB,IAAA;cAEoB,QAAA,EAAU,sBAAA;EAEvC,gBAAA,CAAiB,KAAA,EAAO,0BAAA;EAclB,cAAA;IACX,KAAA;IACA;EAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,eAAA;EAjBZ;EAAA,QA4CV,YAAA;EAAA,QAkCA,SAAA;AAAA"}
1
+ {"version":3,"file":"facebook-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/facebook-provider.ts"],"mappings":";;;;;;;;;;;;;;;;;;;qBAuCa,4BAA4B;mBAGH;WAFpB;EAEhB,YAAoC,UAAU;EAEvC,iBAAiB,OAAO;EAclB,iBACX,OACA,YACC,yBAAyB,QAAQ;;UA2BtB;UAkCA"}
@@ -1,5 +1,4 @@
1
1
  import { AuthProvider, GitHubProviderConfig, ProviderAuthorizationState, ProviderCallbackParams, ProviderProfile } from "../contracts/providers.mjs";
2
-
3
2
  //#region ../../packages/auth/src/providers/github-provider.d.ts
4
3
  /**
5
4
  * GitHub sign-in: plain OAuth 2 authorization code flow with PKCE (S256).
@@ -11,15 +10,12 @@ import { AuthProvider, GitHubProviderConfig, ProviderAuthorizationState, Provide
11
10
  * `/user.email` is `null` unless the user made it public — the emails
12
11
  * endpoint is also where GitHub reports whether an address is verified.
13
12
  */
14
- declare class GitHubProvider implements AuthProvider {
13
+ export declare class GitHubProvider implements AuthProvider {
15
14
  private readonly settings;
16
15
  readonly name = "github";
17
16
  constructor(settings: GitHubProviderConfig);
18
17
  authorizationUrl(state: ProviderAuthorizationState): string;
19
- handleCallback({
20
- query,
21
- expected
22
- }: ProviderCallbackParams): Promise<ProviderProfile>;
18
+ handleCallback({ query, expected }: ProviderCallbackParams): Promise<ProviderProfile>;
23
19
  /** Redeem the authorization code (with the PKCE verifier) for an access token. */
24
20
  private exchangeCode;
25
21
  private fetchUser;
@@ -27,5 +23,4 @@ declare class GitHubProvider implements AuthProvider {
27
23
  private fetchPrimaryEmail;
28
24
  }
29
25
  //#endregion
30
- export { GitHubProvider };
31
26
  //# sourceMappingURL=github-provider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/github-provider.ts"],"mappings":";;;;;AA0CA;;;;;;;;cAAa,cAAA,YAA0B,YAAA;EAAA,iBAGD,QAAA;EAAA,SAFpB,IAAA;cAEoB,QAAA,EAAU,oBAAA;EAEvC,gBAAA,CAAiB,KAAA,EAAO,0BAAA;EAclB,cAAA;IACX,KAAA;IACA;EAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,eAAA;EAnBA;EAAA,QA8CtB,YAAA;EAAA,QAwCA,SAAA;EAtFgC;EAAA,QA2GhC,iBAAA;AAAA"}
1
+ {"version":3,"file":"github-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/github-provider.ts"],"mappings":";;;;;;;;;;;;qBA0Ca,0BAA0B;mBAGD;WAFpB;EAEhB,YAAoC,UAAU;EAEvC,iBAAiB,OAAO;EAclB,iBACX,OACA,YACC,yBAAyB,QAAQ;;UA2BtB;UAwCA;;UAqBA"}
@@ -1,10 +1,9 @@
1
1
  import { AuthProvider, GoogleProviderConfig, ProviderAuthorizationState, ProviderCallbackParams, ProviderProfile } from "../contracts/providers.mjs";
2
-
3
2
  //#region ../../packages/auth/src/providers/google-provider.d.ts
4
3
  /** The `warlock add` feature that installs `jose`. */
5
- declare const GOOGLE_AUTH_FEATURE = "auth-google";
4
+ export declare const GOOGLE_AUTH_FEATURE = "auth-google";
6
5
  /** The slice of `jose` the Google provider uses — declared locally because `jose` is an optional peer. */
7
- type JoseModule = {
6
+ export type JoseModule = {
8
7
  createRemoteJWKSet: (url: URL) => unknown;
9
8
  jwtVerify: (token: string, key: unknown, options: {
10
9
  issuer: string[];
@@ -14,27 +13,23 @@ type JoseModule = {
14
13
  }>;
15
14
  };
16
15
  /** PKCE S256 code challenge for a verifier. */
17
- declare function pkceChallenge(codeVerifier: string): string;
16
+ export declare function pkceChallenge(codeVerifier: string): string;
18
17
  /**
19
18
  * Google sign-in: OpenID Connect authorization code flow with PKCE (S256),
20
19
  * `state` and `nonce`. The code is exchanged with plain `fetch`; the id_token
21
20
  * is verified with `jose` against Google's JWKS (signature, `iss`, `aud` = the
22
21
  * client id, `exp`), then its `nonce` is compared. No Google SDK.
23
22
  */
24
- declare class GoogleProvider implements AuthProvider {
23
+ export declare class GoogleProvider implements AuthProvider {
25
24
  private readonly settings;
26
25
  readonly name = "google";
27
26
  constructor(settings: GoogleProviderConfig);
28
27
  authorizationUrl(state: ProviderAuthorizationState): string;
29
- handleCallback({
30
- query,
31
- expected
32
- }: ProviderCallbackParams): Promise<ProviderProfile>;
28
+ handleCallback({ query, expected }: ProviderCallbackParams): Promise<ProviderProfile>;
33
29
  /** Redeem the authorization code (with the PKCE verifier) for an id_token. */
34
30
  private exchangeCode;
35
31
  /** Verify signature, issuer, audience and expiry; resolve the claims. */
36
32
  private verifyIdToken;
37
33
  }
38
34
  //#endregion
39
- export { GOOGLE_AUTH_FEATURE, GoogleProvider, JoseModule, pkceChallenge };
40
35
  //# sourceMappingURL=google-provider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"google-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/google-provider.ts"],"mappings":";;;;cAkBa,mBAAA;AAAb;AAAA,KAGY,UAAA;EACV,kBAAA,GAAqB,GAAA,EAAK,GAAA;EAC1B,SAAA,GACE,KAAA,UACA,GAAA,WACA,OAAA;IAAW,MAAA;IAAkB,QAAA;EAAA,MAC1B,OAAA;IAAU,OAAA,EAAS,MAAA;EAAA;AAAA;;iBAOV,aAAA,CAAc,YAAoB;;;;;;;cAUrC,cAAA,YAA0B,YAAA;EAAA,iBAGD,QAAA;EAAA,SAFpB,IAAA;cAEoB,QAAA,EAAU,oBAAA;EAEvC,gBAAA,CAAiB,KAAA,EAAO,0BAAA;EAelB,cAAA;IACX,KAAA;IACA;EAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,eAAA;EAxCZ;EAAA,QA0EV,YAAA;EA1EgB;EAAA,QA4GhB,aAAA;AAAA"}
1
+ {"version":3,"file":"google-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/google-provider.ts"],"mappings":";;;qBAkBa;;YAGD;EACV,qBAAqB,KAAK;EAC1B,YACE,eACA,cACA;IAAW;IAAkB;QAC1B;IAAU,SAAS;;;;wBAOV,cAAc;;;;;;;qBAUjB,0BAA0B;mBAGD;WAFpB;EAEhB,YAAoC,UAAU;EAEvC,iBAAiB,OAAO;EAelB,iBACX,OACA,YACC,yBAAyB,QAAQ;;UAkCtB;;UAkCA"}
@@ -5,4 +5,5 @@ import { FacebookProvider } from "./facebook-provider.mjs";
5
5
  import { GitHubProvider } from "./github-provider.mjs";
6
6
  import { LINKEDIN_AUTH_FEATURE, LinkedInProvider } from "./linkedin-provider.mjs";
7
7
  import { completeProviderLogin, resolveAuthProvider, startProviderLogin } from "./provider-login.mjs";
8
- import { XProvider } from "./x-provider.mjs";
8
+ import { XProvider } from "./x-provider.mjs";
9
+ export { APPLE_AUTH_FEATURE, AppleJoseModule, AppleProvider, DiscordProvider, FacebookProvider, GOOGLE_AUTH_FEATURE, GitHubProvider, GoogleProvider, JoseModule, LINKEDIN_AUTH_FEATURE, LinkedInProvider, XProvider, completeProviderLogin, pkceChallenge, resolveAuthProvider, startProviderLogin };
@@ -7,4 +7,4 @@ import { LINKEDIN_AUTH_FEATURE, LinkedInProvider } from "./linkedin-provider.mjs
7
7
  import { XProvider } from "./x-provider.mjs";
8
8
  import { completeProviderLogin, resolveAuthProvider, startProviderLogin } from "./provider-login.mjs";
9
9
 
10
- export { };
10
+ export { APPLE_AUTH_FEATURE, AppleProvider, DiscordProvider, FacebookProvider, GOOGLE_AUTH_FEATURE, GitHubProvider, GoogleProvider, LINKEDIN_AUTH_FEATURE, LinkedInProvider, XProvider, completeProviderLogin, pkceChallenge, resolveAuthProvider, startProviderLogin };
@@ -1,8 +1,7 @@
1
1
  import { AuthProvider, LinkedInProviderConfig, ProviderAuthorizationState, ProviderCallbackParams, ProviderProfile } from "../contracts/providers.mjs";
2
-
3
2
  //#region ../../packages/auth/src/providers/linkedin-provider.d.ts
4
3
  /** The `warlock add` feature that installs `jose`. */
5
- declare const LINKEDIN_AUTH_FEATURE = "auth-linkedin";
4
+ export declare const LINKEDIN_AUTH_FEATURE = "auth-linkedin";
6
5
  /**
7
6
  * LinkedIn sign-in: OpenID Connect authorization code flow with PKCE (S256)
8
7
  * and `state` and `nonce` — LinkedIn's "Sign In with LinkedIn using OpenID
@@ -16,20 +15,16 @@ declare const LINKEDIN_AUTH_FEATURE = "auth-linkedin";
16
15
  * OIDC docs, not from a live exchange — this package has no LinkedIn test
17
16
  * credentials. See the worker report for what is and is not proven.
18
17
  */
19
- declare class LinkedInProvider implements AuthProvider {
18
+ export declare class LinkedInProvider implements AuthProvider {
20
19
  private readonly settings;
21
20
  readonly name = "linkedin";
22
21
  constructor(settings: LinkedInProviderConfig);
23
22
  authorizationUrl(state: ProviderAuthorizationState): string;
24
- handleCallback({
25
- query,
26
- expected
27
- }: ProviderCallbackParams): Promise<ProviderProfile>;
23
+ handleCallback({ query, expected }: ProviderCallbackParams): Promise<ProviderProfile>;
28
24
  /** Redeem the authorization code (with the PKCE verifier) for an id_token. */
29
25
  private exchangeCode;
30
26
  /** Verify signature, issuer, audience and expiry; resolve the claims. */
31
27
  private verifyIdToken;
32
28
  }
33
29
  //#endregion
34
- export { LINKEDIN_AUTH_FEATURE, LinkedInProvider };
35
30
  //# sourceMappingURL=linkedin-provider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"linkedin-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/linkedin-provider.ts"],"mappings":";;;;cAmBa,qBAAA;AAAb;;;;AAAkC;AAkBlC;;;;;;;;AAlBA,cAkBa,gBAAA,YAA4B,YAAA;EAAA,iBAGH,QAAA;EAAA,SAFpB,IAAA;cAEoB,QAAA,EAAU,sBAAA;EAEvC,gBAAA,CAAiB,KAAA,EAAO,0BAAA;EAelB,cAAA;IACX,KAAA;IACA;EAAA,GACC,sBAAA,GAAyB,OAAA,CAAQ,eAAA;EApBA;EAAA,QAsDtB,YAAA;;UAkCA,aAAA;AAAA"}
1
+ {"version":3,"file":"linkedin-provider.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/providers/linkedin-provider.ts"],"mappings":";;;qBAmBa;;;;;;;;;;;;;;qBAkBA,4BAA4B;mBAGH;WAFpB;EAEhB,YAAoC,UAAU;EAEvC,iBAAiB,OAAO;EAelB,iBACX,OACA,YACC,yBAAyB,QAAQ;;UAkCtB;;UAkCA"}