@warlock.js/auth 5.28.0 → 5.30.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 (274) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/esm/commands/auth-cleanup-command.d.mts +1 -1
  3. package/esm/commands/auth-cleanup-command.d.mts.map +1 -1
  4. package/esm/commands/auth-cleanup-command.mjs +1 -1
  5. package/esm/commands/auth-cleanup-command.mjs.map +1 -1
  6. package/esm/commands/auth-purge-never-expiring-command.d.mts +1 -1
  7. package/esm/commands/auth-purge-never-expiring-command.d.mts.map +1 -1
  8. package/esm/commands/auth-purge-never-expiring-command.mjs +1 -1
  9. package/esm/commands/auth-purge-never-expiring-command.mjs.map +1 -1
  10. package/esm/commands/jwt-secret-generator-command.d.mts +1 -1
  11. package/esm/commands/jwt-secret-generator-command.d.mts.map +1 -1
  12. package/esm/commands/jwt-secret-generator-command.mjs +1 -1
  13. package/esm/commands/jwt-secret-generator-command.mjs.map +1 -1
  14. package/esm/contracts/auth-contract.d.mts +1 -1
  15. package/esm/contracts/auth-contract.d.mts.map +1 -1
  16. package/esm/contracts/providers.d.mts +1 -1
  17. package/esm/contracts/providers.d.mts.map +1 -1
  18. package/esm/contracts/request-locals.d.mts +1 -1
  19. package/esm/contracts/request-locals.d.mts.map +1 -1
  20. package/esm/contracts/types.d.mts +1 -1
  21. package/esm/contracts/types.d.mts.map +1 -1
  22. package/esm/contracts/types.mjs +1 -1
  23. package/esm/contracts/types.mjs.map +1 -1
  24. package/esm/errors/auth-provider-sdk-missing.error.d.mts +1 -1
  25. package/esm/errors/auth-provider-sdk-missing.error.d.mts.map +1 -1
  26. package/esm/errors/auth-provider-sdk-missing.error.mjs +1 -1
  27. package/esm/errors/auth-provider-sdk-missing.error.mjs.map +1 -1
  28. package/esm/errors/email-not-verified.error.d.mts +1 -1
  29. package/esm/errors/email-not-verified.error.d.mts.map +1 -1
  30. package/esm/errors/email-not-verified.error.mjs +1 -1
  31. package/esm/errors/email-not-verified.error.mjs.map +1 -1
  32. package/esm/errors/invalid-one-time-token.error.d.mts +1 -1
  33. package/esm/errors/invalid-one-time-token.error.d.mts.map +1 -1
  34. package/esm/errors/invalid-one-time-token.error.mjs +1 -1
  35. package/esm/errors/invalid-one-time-token.error.mjs.map +1 -1
  36. package/esm/errors/invalid-passkey.error.d.mts +1 -1
  37. package/esm/errors/invalid-passkey.error.d.mts.map +1 -1
  38. package/esm/errors/invalid-passkey.error.mjs +1 -1
  39. package/esm/errors/invalid-passkey.error.mjs.map +1 -1
  40. package/esm/errors/invalid-provider-callback.error.d.mts +1 -1
  41. package/esm/errors/invalid-provider-callback.error.d.mts.map +1 -1
  42. package/esm/errors/invalid-provider-callback.error.mjs +1 -1
  43. package/esm/errors/invalid-provider-callback.error.mjs.map +1 -1
  44. package/esm/errors/notifications-unavailable.error.d.mts +1 -1
  45. package/esm/errors/notifications-unavailable.error.d.mts.map +1 -1
  46. package/esm/errors/notifications-unavailable.error.mjs +1 -1
  47. package/esm/errors/notifications-unavailable.error.mjs.map +1 -1
  48. package/esm/errors/provider-email-not-verified.error.d.mts +1 -1
  49. package/esm/errors/provider-email-not-verified.error.d.mts.map +1 -1
  50. package/esm/errors/provider-email-not-verified.error.mjs +1 -1
  51. package/esm/errors/provider-email-not-verified.error.mjs.map +1 -1
  52. package/esm/index.d.mts +2 -2
  53. package/esm/index.mjs +2 -2
  54. package/esm/localization/ar.translations.mjs +1 -1
  55. package/esm/localization/ar.translations.mjs.map +1 -1
  56. package/esm/localization/auth-default-translations.d.mts +1 -1
  57. package/esm/localization/auth-default-translations.d.mts.map +1 -1
  58. package/esm/localization/auth-default-translations.mjs +1 -1
  59. package/esm/localization/auth-default-translations.mjs.map +1 -1
  60. package/esm/localization/auth-translations.type.d.mts +1 -1
  61. package/esm/localization/auth-translations.type.d.mts.map +1 -1
  62. package/esm/localization/en.translations.mjs +1 -1
  63. package/esm/localization/en.translations.mjs.map +1 -1
  64. package/esm/localization/init.mjs +1 -1
  65. package/esm/localization/init.mjs.map +1 -1
  66. package/esm/localization/register-auth-translations.d.mts +1 -1
  67. package/esm/localization/register-auth-translations.d.mts.map +1 -1
  68. package/esm/localization/register-auth-translations.mjs +1 -1
  69. package/esm/localization/register-auth-translations.mjs.map +1 -1
  70. package/esm/middleware/auth.middleware.d.mts +1 -1
  71. package/esm/middleware/auth.middleware.d.mts.map +1 -1
  72. package/esm/middleware/auth.middleware.mjs +1 -1
  73. package/esm/middleware/auth.middleware.mjs.map +1 -1
  74. package/esm/middleware/csrf-origin-check.d.mts +1 -1
  75. package/esm/middleware/csrf-origin-check.d.mts.map +1 -1
  76. package/esm/middleware/csrf-origin-check.mjs +1 -1
  77. package/esm/middleware/csrf-origin-check.mjs.map +1 -1
  78. package/esm/middleware/index.d.mts +1 -1
  79. package/esm/middleware/index.mjs +1 -1
  80. package/esm/middleware/localized-login-path.mjs +1 -1
  81. package/esm/middleware/localized-login-path.mjs.map +1 -1
  82. package/esm/middleware/login-throttle.middleware.d.mts +17 -2
  83. package/esm/middleware/login-throttle.middleware.d.mts.map +1 -1
  84. package/esm/middleware/login-throttle.middleware.mjs +84 -6
  85. package/esm/middleware/login-throttle.middleware.mjs.map +1 -1
  86. package/esm/middleware/one-time-token-throttle.middleware.d.mts +1 -1
  87. package/esm/middleware/one-time-token-throttle.middleware.d.mts.map +1 -1
  88. package/esm/middleware/one-time-token-throttle.middleware.mjs +1 -1
  89. package/esm/middleware/one-time-token-throttle.middleware.mjs.map +1 -1
  90. package/esm/middleware/otp-throttle.middleware.d.mts +1 -1
  91. package/esm/middleware/otp-throttle.middleware.d.mts.map +1 -1
  92. package/esm/middleware/otp-throttle.middleware.mjs +1 -1
  93. package/esm/middleware/otp-throttle.middleware.mjs.map +1 -1
  94. package/esm/middleware/require-verified-email.middleware.d.mts +1 -1
  95. package/esm/middleware/require-verified-email.middleware.d.mts.map +1 -1
  96. package/esm/middleware/require-verified-email.middleware.mjs +1 -1
  97. package/esm/middleware/require-verified-email.middleware.mjs.map +1 -1
  98. package/esm/models/access-token/access-token.model.d.mts +27 -35
  99. package/esm/models/access-token/access-token.model.d.mts.map +1 -1
  100. package/esm/models/access-token/access-token.model.mjs +1 -1
  101. package/esm/models/access-token/access-token.model.mjs.map +1 -1
  102. package/esm/models/access-token/family-association.migration.mjs +1 -1
  103. package/esm/models/access-token/family-association.migration.mjs.map +1 -1
  104. package/esm/models/access-token/migration.mjs +1 -1
  105. package/esm/models/access-token/migration.mjs.map +1 -1
  106. package/esm/models/auth-token-family/auth-token-family.model.d.mts +27 -43
  107. package/esm/models/auth-token-family/auth-token-family.model.d.mts.map +1 -1
  108. package/esm/models/auth-token-family/auth-token-family.model.mjs +1 -1
  109. package/esm/models/auth-token-family/auth-token-family.model.mjs.map +1 -1
  110. package/esm/models/auth-token-family/migration.mjs +1 -1
  111. package/esm/models/auth-token-family/migration.mjs.map +1 -1
  112. package/esm/models/auth.model.d.mts +1 -1
  113. package/esm/models/auth.model.d.mts.map +1 -1
  114. package/esm/models/auth.model.mjs +1 -1
  115. package/esm/models/auth.model.mjs.map +1 -1
  116. package/esm/models/index.d.mts +1 -1
  117. package/esm/models/index.d.mts.map +1 -1
  118. package/esm/models/index.mjs +1 -1
  119. package/esm/models/index.mjs.map +1 -1
  120. package/esm/models/one-time-token/migration.mjs +1 -1
  121. package/esm/models/one-time-token/migration.mjs.map +1 -1
  122. package/esm/models/one-time-token/one-time-token.model.d.mts +35 -67
  123. package/esm/models/one-time-token/one-time-token.model.d.mts.map +1 -1
  124. package/esm/models/one-time-token/one-time-token.model.mjs +1 -1
  125. package/esm/models/one-time-token/one-time-token.model.mjs.map +1 -1
  126. package/esm/models/passkey-credential/migration.mjs +1 -1
  127. package/esm/models/passkey-credential/migration.mjs.map +1 -1
  128. package/esm/models/passkey-credential/passkey-credential.model.d.mts +31 -47
  129. package/esm/models/passkey-credential/passkey-credential.model.d.mts.map +1 -1
  130. package/esm/models/passkey-credential/passkey-credential.model.mjs +1 -1
  131. package/esm/models/passkey-credential/passkey-credential.model.mjs.map +1 -1
  132. package/esm/models/provider-account/migration.mjs +1 -1
  133. package/esm/models/provider-account/migration.mjs.map +1 -1
  134. package/esm/models/provider-account/provider-account.model.d.mts +27 -35
  135. package/esm/models/provider-account/provider-account.model.d.mts.map +1 -1
  136. package/esm/models/provider-account/provider-account.model.mjs +1 -1
  137. package/esm/models/provider-account/provider-account.model.mjs.map +1 -1
  138. package/esm/models/refresh-token/migration.mjs +1 -1
  139. package/esm/models/refresh-token/migration.mjs.map +1 -1
  140. package/esm/models/refresh-token/refresh-token.model.d.mts +47 -95
  141. package/esm/models/refresh-token/refresh-token.model.d.mts.map +1 -1
  142. package/esm/models/refresh-token/refresh-token.model.mjs +1 -1
  143. package/esm/models/refresh-token/refresh-token.model.mjs.map +1 -1
  144. package/esm/models/refresh-token/successor-association.migration.mjs +1 -1
  145. package/esm/models/refresh-token/successor-association.migration.mjs.map +1 -1
  146. package/esm/otp/otp.d.mts +1 -1
  147. package/esm/otp/otp.d.mts.map +1 -1
  148. package/esm/otp/otp.mjs +1 -1
  149. package/esm/otp/otp.mjs.map +1 -1
  150. package/esm/passkeys/passkey-authentication.d.mts +1 -1
  151. package/esm/passkeys/passkey-authentication.d.mts.map +1 -1
  152. package/esm/passkeys/passkey-authentication.mjs +1 -1
  153. package/esm/passkeys/passkey-authentication.mjs.map +1 -1
  154. package/esm/passkeys/passkey-challenges.mjs +1 -1
  155. package/esm/passkeys/passkey-challenges.mjs.map +1 -1
  156. package/esm/passkeys/passkey-registration.d.mts +1 -1
  157. package/esm/passkeys/passkey-registration.d.mts.map +1 -1
  158. package/esm/passkeys/passkey-registration.mjs +1 -1
  159. package/esm/passkeys/passkey-registration.mjs.map +1 -1
  160. package/esm/passkeys/simplewebauthn.d.mts +1 -1
  161. package/esm/passkeys/simplewebauthn.d.mts.map +1 -1
  162. package/esm/passkeys/simplewebauthn.mjs +1 -1
  163. package/esm/passkeys/simplewebauthn.mjs.map +1 -1
  164. package/esm/providers/apple-provider.d.mts +1 -1
  165. package/esm/providers/apple-provider.d.mts.map +1 -1
  166. package/esm/providers/apple-provider.mjs +1 -1
  167. package/esm/providers/apple-provider.mjs.map +1 -1
  168. package/esm/providers/discord-provider.d.mts +1 -1
  169. package/esm/providers/discord-provider.d.mts.map +1 -1
  170. package/esm/providers/discord-provider.mjs +1 -1
  171. package/esm/providers/discord-provider.mjs.map +1 -1
  172. package/esm/providers/facebook-provider.d.mts +1 -1
  173. package/esm/providers/facebook-provider.d.mts.map +1 -1
  174. package/esm/providers/facebook-provider.mjs +1 -1
  175. package/esm/providers/facebook-provider.mjs.map +1 -1
  176. package/esm/providers/github-provider.d.mts +1 -1
  177. package/esm/providers/github-provider.d.mts.map +1 -1
  178. package/esm/providers/github-provider.mjs +1 -1
  179. package/esm/providers/github-provider.mjs.map +1 -1
  180. package/esm/providers/google-provider.d.mts +1 -1
  181. package/esm/providers/google-provider.d.mts.map +1 -1
  182. package/esm/providers/google-provider.mjs +1 -1
  183. package/esm/providers/google-provider.mjs.map +1 -1
  184. package/esm/providers/linkedin-provider.d.mts +1 -1
  185. package/esm/providers/linkedin-provider.d.mts.map +1 -1
  186. package/esm/providers/linkedin-provider.mjs +1 -1
  187. package/esm/providers/linkedin-provider.mjs.map +1 -1
  188. package/esm/providers/provider-login.d.mts +1 -1
  189. package/esm/providers/provider-login.d.mts.map +1 -1
  190. package/esm/providers/provider-login.mjs +1 -1
  191. package/esm/providers/provider-login.mjs.map +1 -1
  192. package/esm/providers/provider-state-cookie.mjs +1 -1
  193. package/esm/providers/provider-state-cookie.mjs.map +1 -1
  194. package/esm/providers/resolve-provider-user.mjs +1 -1
  195. package/esm/providers/resolve-provider-user.mjs.map +1 -1
  196. package/esm/providers/x-provider.d.mts +1 -1
  197. package/esm/providers/x-provider.d.mts.map +1 -1
  198. package/esm/providers/x-provider.mjs +1 -1
  199. package/esm/providers/x-provider.mjs.map +1 -1
  200. package/esm/services/auth-config.mjs +1 -1
  201. package/esm/services/auth-config.mjs.map +1 -1
  202. package/esm/services/auth-events.d.mts +1 -1
  203. package/esm/services/auth-events.d.mts.map +1 -1
  204. package/esm/services/auth-events.mjs +1 -1
  205. package/esm/services/auth-events.mjs.map +1 -1
  206. package/esm/services/auth.service.d.mts +1 -1
  207. package/esm/services/auth.service.d.mts.map +1 -1
  208. package/esm/services/auth.service.mjs +1 -1
  209. package/esm/services/auth.service.mjs.map +1 -1
  210. package/esm/services/current-user.d.mts +1 -1
  211. package/esm/services/current-user.d.mts.map +1 -1
  212. package/esm/services/current-user.mjs +1 -1
  213. package/esm/services/current-user.mjs.map +1 -1
  214. package/esm/services/email-verification.d.mts +1 -1
  215. package/esm/services/email-verification.d.mts.map +1 -1
  216. package/esm/services/email-verification.mjs +1 -1
  217. package/esm/services/email-verification.mjs.map +1 -1
  218. package/esm/services/generate-jwt-secret.d.mts +1 -1
  219. package/esm/services/generate-jwt-secret.d.mts.map +1 -1
  220. package/esm/services/generate-jwt-secret.mjs +1 -1
  221. package/esm/services/generate-jwt-secret.mjs.map +1 -1
  222. package/esm/services/jwt.d.mts +1 -1
  223. package/esm/services/jwt.d.mts.map +1 -1
  224. package/esm/services/jwt.mjs +1 -1
  225. package/esm/services/jwt.mjs.map +1 -1
  226. package/esm/services/one-time-tokens.d.mts +1 -1
  227. package/esm/services/one-time-tokens.d.mts.map +1 -1
  228. package/esm/services/one-time-tokens.mjs +1 -1
  229. package/esm/services/one-time-tokens.mjs.map +1 -1
  230. package/esm/services/optional-peer.mjs +1 -1
  231. package/esm/services/optional-peer.mjs.map +1 -1
  232. package/esm/services/password-reset.d.mts +1 -1
  233. package/esm/services/password-reset.d.mts.map +1 -1
  234. package/esm/services/password-reset.mjs +1 -1
  235. package/esm/services/password-reset.mjs.map +1 -1
  236. package/esm/services/resolve-request-user.d.mts +1 -1
  237. package/esm/services/resolve-request-user.d.mts.map +1 -1
  238. package/esm/services/resolve-request-user.mjs +1 -1
  239. package/esm/services/resolve-request-user.mjs.map +1 -1
  240. package/esm/services/token-family-operation.mjs +1 -1
  241. package/esm/services/token-family-operation.mjs.map +1 -1
  242. package/esm/services/token-notifications.mjs +1 -1
  243. package/esm/services/token-notifications.mjs.map +1 -1
  244. package/esm/session/page-session.d.mts +1 -1
  245. package/esm/session/page-session.d.mts.map +1 -1
  246. package/esm/session/page-session.mjs +1 -1
  247. package/esm/session/page-session.mjs.map +1 -1
  248. package/esm/utils/auth-error-codes.d.mts +1 -1
  249. package/esm/utils/auth-error-codes.d.mts.map +1 -1
  250. package/esm/utils/auth-error-codes.mjs +1 -1
  251. package/esm/utils/auth-error-codes.mjs.map +1 -1
  252. package/esm/utils/safe-equal.d.mts +1 -1
  253. package/esm/utils/safe-equal.d.mts.map +1 -1
  254. package/esm/utils/safe-equal.mjs +1 -1
  255. package/esm/utils/safe-equal.mjs.map +1 -1
  256. package/esm/utils/token-expiry.d.mts +1 -1
  257. package/esm/utils/token-expiry.d.mts.map +1 -1
  258. package/esm/utils/token-expiry.mjs +1 -1
  259. package/esm/utils/token-expiry.mjs.map +1 -1
  260. package/llms-full.txt +76 -74
  261. package/llms.txt +10 -10
  262. package/package.json +10 -9
  263. package/skills/auth-basics/SKILL.md +10 -10
  264. package/skills/customize-token-storage/SKILL.md +5 -5
  265. package/skills/customize-user-type/SKILL.md +5 -5
  266. package/skills/handle-login-and-logout/SKILL.md +5 -5
  267. package/skills/login-with-providers/SKILL.md +4 -4
  268. package/skills/manage-tokens/SKILL.md +6 -6
  269. package/skills/overview/SKILL.md +12 -12
  270. package/skills/protect-routes/SKILL.md +7 -7
  271. package/skills/register-user/SKILL.md +7 -7
  272. package/skills/run-auth-commands/SKILL.md +4 -4
  273. package/skills/throttle-login-attempts/SKILL.md +7 -5
  274. package/skills/verify-email-and-reset-password/SKILL.md +4 -4
@@ -5,7 +5,7 @@ import { RefreshToken, RefreshTokenIssueOptions, refreshTokenSchema } from "./re
5
5
  import { AuthTokenFamily, authTokenFamilySchema } from "./auth-token-family/auth-token-family.model.mjs";
6
6
  import { PasskeyCredential, passkeyCredentialSchema } from "./passkey-credential/passkey-credential.model.mjs";
7
7
  import { ProviderAccount, providerAccountSchema } from "./provider-account/provider-account.model.mjs";
8
- //#region ../auth/src/models/index.d.ts
8
+ //#region ../../packages/auth/src/models/index.d.ts
9
9
  declare const authMigrations: import("@warlock.js/cascade").MigrationConstructor[];
10
10
  //#endregion
11
11
  export { authMigrations };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../../auth/src/models/index.ts"],"mappings":";;;;;;;;cAiBa,cAAA,gCAAc,oBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../../../packages/auth/src/models/index.ts"],"mappings":";;;;;;;;cAiBa,cAAA,gCAAc,oBAAA"}
@@ -20,7 +20,7 @@ import { Auth } from "./auth.model.mjs";
20
20
  import "./passkey-credential/index.mjs";
21
21
  import "./provider-account/index.mjs";
22
22
 
23
- //#region ../auth/src/models/index.ts
23
+ //#region ../../packages/auth/src/models/index.ts
24
24
  const authMigrations = [
25
25
  AccessTokenMigration,
26
26
  AccessTokenFamilyAssociationMigration,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../auth/src/models/index.ts"],"sourcesContent":["import { AccessTokenFamilyAssociationMigration } from \"./access-token/family-association.migration\";\nimport { AccessTokenMigration } from \"./access-token/migration\";\nimport { AuthTokenFamilyMigration } from \"./auth-token-family/migration\";\nimport { OneTimeTokenMigration } from \"./one-time-token/migration\";\nimport { PasskeyCredentialMigration } from \"./passkey-credential/migration\";\nimport { ProviderAccountMigration } from \"./provider-account/migration\";\nimport { RefreshTokenMigration } from \"./refresh-token/migration\";\nimport { RefreshTokenSuccessorAssociationMigration } from \"./refresh-token/successor-association.migration\";\n\nexport * from \"./access-token\";\nexport * from \"./auth-token-family\";\nexport * from \"./auth.model\";\nexport * from \"./one-time-token\";\nexport * from \"./passkey-credential\";\nexport * from \"./provider-account\";\nexport * from \"./refresh-token\";\n\nexport const authMigrations = [\n AccessTokenMigration,\n AccessTokenFamilyAssociationMigration,\n RefreshTokenMigration,\n RefreshTokenSuccessorAssociationMigration,\n AuthTokenFamilyMigration,\n OneTimeTokenMigration,\n ProviderAccountMigration,\n PasskeyCredentialMigration,\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiBA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../../packages/auth/src/models/index.ts"],"sourcesContent":["import { AccessTokenFamilyAssociationMigration } from \"./access-token/family-association.migration\";\nimport { AccessTokenMigration } from \"./access-token/migration\";\nimport { AuthTokenFamilyMigration } from \"./auth-token-family/migration\";\nimport { OneTimeTokenMigration } from \"./one-time-token/migration\";\nimport { PasskeyCredentialMigration } from \"./passkey-credential/migration\";\nimport { ProviderAccountMigration } from \"./provider-account/migration\";\nimport { RefreshTokenMigration } from \"./refresh-token/migration\";\nimport { RefreshTokenSuccessorAssociationMigration } from \"./refresh-token/successor-association.migration\";\n\nexport * from \"./access-token\";\nexport * from \"./auth-token-family\";\nexport * from \"./auth.model\";\nexport * from \"./one-time-token\";\nexport * from \"./passkey-credential\";\nexport * from \"./provider-account\";\nexport * from \"./refresh-token\";\n\nexport const authMigrations = [\n AccessTokenMigration,\n AccessTokenFamilyAssociationMigration,\n RefreshTokenMigration,\n RefreshTokenSuccessorAssociationMigration,\n AuthTokenFamilyMigration,\n OneTimeTokenMigration,\n ProviderAccountMigration,\n PasskeyCredentialMigration,\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiBA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { OneTimeToken } from "./one-time-token.model.mjs";
2
2
  import { migrate } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/one-time-token/migration.ts
4
+ //#region ../../packages/auth/src/models/one-time-token/migration.ts
5
5
  const OneTimeTokenMigration = migrate(OneTimeToken, {
6
6
  name: "oneTimeToken",
7
7
  up() {
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../auth/src/models/one-time-token/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { OneTimeToken } from \"./one-time-token.model\";\n\nexport const OneTimeTokenMigration = migrate(OneTimeToken, {\n name: \"oneTimeToken\",\n up() {\n this.createTableIfNotExists();\n\n this.primaryUuid();\n\n // SHA-256 hex digest of the raw token — the raw token is never stored.\n this.string(\"token_hash\", 64).unique();\n this.string(\"purpose\", 32);\n\n // `foreignId` follows the DataSource's default primary-key type, matching\n // the access/refresh token tables. Nullable only for a passkey\n // authentication challenge, which is issued before anyone is identified.\n this.foreignId(\"user_id\").nullable().index();\n this.string(\"user_type\", 50).nullable();\n\n this.timestamp(\"expires_at\").index().nullable();\n this.timestamp(\"consumed_at\").nullable();\n\n // Failed verify attempts — only OTP codes are capped on it.\n this.integer(\"attempts\").default(0);\n\n // Invalidating a user's previous reset tokens filters on these.\n this.index([\"user_id\", \"user_type\", \"purpose\"]);\n\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,wBAAwB,QAAQ,cAAc;CACzD,MAAM;CACN,KAAK;EACH,KAAK,uBAAuB;EAE5B,KAAK,YAAY;EAGjB,KAAK,OAAO,cAAc,EAAE,CAAC,CAAC,OAAO;EACrC,KAAK,OAAO,WAAW,EAAE;EAKzB,KAAK,UAAU,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM;EAC3C,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EAEtC,KAAK,UAAU,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;EAC9C,KAAK,UAAU,aAAa,CAAC,CAAC,SAAS;EAGvC,KAAK,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC;EAGlC,KAAK,MAAM;GAAC;GAAW;GAAa;EAAS,CAAC;EAE9C,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/one-time-token/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { OneTimeToken } from \"./one-time-token.model\";\n\nexport const OneTimeTokenMigration = migrate(OneTimeToken, {\n name: \"oneTimeToken\",\n up() {\n this.createTableIfNotExists();\n\n this.primaryUuid();\n\n // SHA-256 hex digest of the raw token — the raw token is never stored.\n this.string(\"token_hash\", 64).unique();\n this.string(\"purpose\", 32);\n\n // `foreignId` follows the DataSource's default primary-key type, matching\n // the access/refresh token tables. Nullable only for a passkey\n // authentication challenge, which is issued before anyone is identified.\n this.foreignId(\"user_id\").nullable().index();\n this.string(\"user_type\", 50).nullable();\n\n this.timestamp(\"expires_at\").index().nullable();\n this.timestamp(\"consumed_at\").nullable();\n\n // Failed verify attempts — only OTP codes are capped on it.\n this.integer(\"attempts\").default(0);\n\n // Invalidating a user's previous reset tokens filters on these.\n this.index([\"user_id\", \"user_type\", \"purpose\"]);\n\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,wBAAwB,QAAQ,cAAc;CACzD,MAAM;CACN,KAAK;EACH,KAAK,uBAAuB;EAE5B,KAAK,YAAY;EAGjB,KAAK,OAAO,cAAc,EAAE,CAAC,CAAC,OAAO;EACrC,KAAK,OAAO,WAAW,EAAE;EAKzB,KAAK,UAAU,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM;EAC3C,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EAEtC,KAAK,UAAU,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;EAC9C,KAAK,UAAU,aAAa,CAAC,CAAC,SAAS;EAGvC,KAAK,QAAQ,UAAU,CAAC,CAAC,QAAQ,CAAC;EAGlC,KAAK,MAAM;GAAC;GAAW;GAAa;EAAS,CAAC;EAE9C,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { Auth } from "../auth.model.mjs";
2
2
  import { Model } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/one-time-token/one-time-token.model.d.ts
4
+ //#region ../../packages/auth/src/models/one-time-token/one-time-token.model.d.ts
5
5
  /** What a one-time token may be used for. A token only ever satisfies its own purpose. */
6
6
  type OneTimeTokenPurpose = "email-verification" | "password-reset" | "otp" | "passkey-registration" | "passkey-authentication";
7
7
  /**
@@ -24,39 +24,23 @@ declare const oneTimeTokenSchema: import("@warlock.js/seal").ObjectValidator<{
24
24
  attempts: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number> & {
25
25
  isOptional: true;
26
26
  };
27
- }> & import("@warlock.js/seal").StandardSchemaV1<import("@warlock.js/seal").InferInputObjectShape<{
28
- token_hash: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
29
- purpose: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
30
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean> & {
31
- isOptional: true;
32
- };
33
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
34
- isOptional: true;
35
- };
36
- expires_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date>;
37
- consumed_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date> & {
38
- isOptional: true;
39
- };
40
- attempts: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number> & {
41
- isOptional: true;
42
- };
43
- }>, import("@warlock.js/seal").InferInputObjectShape<{
44
- token_hash: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
45
- purpose: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
46
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean> & {
47
- isOptional: true;
48
- };
49
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
50
- isOptional: true;
51
- };
52
- expires_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date>;
53
- consumed_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date> & {
54
- isOptional: true;
55
- };
56
- attempts: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number> & {
57
- isOptional: true;
58
- };
59
- }>>;
27
+ }> & import("@warlock.js/seal").StandardSchemaV1<{
28
+ user_id?: string | number | boolean | undefined;
29
+ user_type?: string | undefined;
30
+ consumed_at?: Date | undefined;
31
+ attempts?: number | undefined;
32
+ token_hash: string;
33
+ purpose: string;
34
+ expires_at: Date;
35
+ }, {
36
+ user_id?: string | number | boolean | undefined;
37
+ user_type?: string | undefined;
38
+ consumed_at?: Date | undefined;
39
+ attempts?: number | undefined;
40
+ token_hash: string;
41
+ purpose: string;
42
+ expires_at: Date;
43
+ }>;
60
44
  /**
61
45
  * Persisted one-time secret: email-verification / password-reset token, OTP
62
46
  * code, or passkey ceremony challenge.
@@ -84,39 +68,23 @@ declare class OneTimeToken extends Model {
84
68
  attempts: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number> & {
85
69
  isOptional: true;
86
70
  };
87
- }> & import("@warlock.js/seal").StandardSchemaV1<import("@warlock.js/seal").InferInputObjectShape<{
88
- token_hash: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
89
- purpose: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
90
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean> & {
91
- isOptional: true;
92
- };
93
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
94
- isOptional: true;
95
- };
96
- expires_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date>;
97
- consumed_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date> & {
98
- isOptional: true;
99
- };
100
- attempts: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number> & {
101
- isOptional: true;
102
- };
103
- }>, import("@warlock.js/seal").InferInputObjectShape<{
104
- token_hash: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
105
- purpose: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
106
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean> & {
107
- isOptional: true;
108
- };
109
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
110
- isOptional: true;
111
- };
112
- expires_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date>;
113
- consumed_at: import("@warlock.js/seal").DateValidator & import("@warlock.js/seal").StandardSchemaV1<Date, Date> & {
114
- isOptional: true;
115
- };
116
- attempts: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number> & {
117
- isOptional: true;
118
- };
119
- }>>;
71
+ }> & import("@warlock.js/seal").StandardSchemaV1<{
72
+ user_id?: string | number | boolean | undefined;
73
+ user_type?: string | undefined;
74
+ consumed_at?: Date | undefined;
75
+ attempts?: number | undefined;
76
+ token_hash: string;
77
+ purpose: string;
78
+ expires_at: Date;
79
+ }, {
80
+ user_id?: string | number | boolean | undefined;
81
+ user_type?: string | undefined;
82
+ consumed_at?: Date | undefined;
83
+ attempts?: number | undefined;
84
+ token_hash: string;
85
+ purpose: string;
86
+ expires_at: Date;
87
+ }>;
120
88
  /**
121
89
  * The SHA-256 of a one-time secret. For a short OTP code the hash is
122
90
  * brute-forceable offline, so it is as sensitive as the code itself — never
@@ -1 +1 @@
1
- {"version":3,"file":"one-time-token.model.d.mts","names":[],"sources":["../../../../../../../../auth/src/models/one-time-token/one-time-token.model.ts"],"mappings":";;;;;KAMY,mBAAA;AAAZ;;;;AAAA,cAWa,kBAAA,6BAAkB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoBlB,YAAA,SAAqB,KAAA;EAAA,OAClB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAHtB;;;SAUgB,MAAA;;;;;;;SAQA,cAAA;;MAGH,MAAA;;MAKA,QAAA;EAuBqB;EAAA,IAlBrB,UAAA;EAgCA;EAAA,IA3BA,SAAA;EA6BM;;;;;EAhBJ,eAAA,IAAmB,OAAA;EAqCnB;EAAA,OAzBC,KAAA,CACZ,IAAA,EAAM,IAAA,EACN,OAAA,EAAS,mBAAA,EACT,SAAA,UACA,SAAA,EAAW,IAAA,GAAI,OAAA,CAAA,YAAA;EAqCN;;;;EAAA,OApBG,cAAA,CACZ,OAAA,EAAS,mBAAA,EACT,SAAA,UACA,SAAA,EAAW,IAAA,EACX,IAAA,GAAO,IAAA,GAAI,OAAA,CAAA,YAAA;EAiEF;EAAA,OAnDG,aAAA,CACZ,IAAA,EAAM,IAAA,EACN,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,YAAA;EAiDR;;;;;EArCU,aAAA,CAAc,GAAA,WAAc,OAAA;EAnHJ;;;;;;EAAA,OAsIjB,UAAA,IAAc,OAAA;;SAepB,UAAA,CACZ,SAAA,UACA,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,YAAA;;;;;SAQG,mBAAA,CAAoB,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,mBAAA,GAAsB,OAAA;AAAA"}
1
+ {"version":3,"file":"one-time-token.model.d.mts","names":[],"sources":["../../../../../../../../../packages/auth/src/models/one-time-token/one-time-token.model.ts"],"mappings":";;;;;KAMY,mBAAA;AAAZ;;;;AAAA,cAWa,kBAAA,6BAAkB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoBlB,YAAA,SAAqB,KAAA;EAAA,OAClB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2DZ;;;;;EAAA,OApDM,MAAA;EA2ED;;;;;;EAAA,OAnEC,cAAA;EAqFX;EAAA,IAlFQ,MAAA;EAiHuB;EAAA,IA5GvB,QAAA;EA8HA;EAAA,IAzHA,UAAA;EAiI6B;EAAA,IA5H7B,SAAA;EA4HkE;;;;;EA/GhE,eAAA,IAAmB,OAAA;EA9ClB;EAAA,OA0DA,KAAA,CACZ,IAAA,EAAM,IAAA,EACN,OAAA,EAAS,mBAAA,EACT,SAAA,UACA,SAAA,EAAW,IAAA,GAAI,OAAA,CAAA,YAAA;;;;;SAiBH,cAAA,CACZ,OAAA,EAAS,mBAAA,EACT,SAAA,UACA,SAAA,EAAW,IAAA,EACX,IAAA,GAAO,IAAA,GAAI,OAAA,CAAA,YAAA;;SAcC,aAAA,CACZ,IAAA,EAAM,IAAA,EACN,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,YAAA;;;;;;EAYE,aAAA,CAAc,GAAA,WAAc,OAAA;;;;;;;SAmBrB,UAAA,IAAc,OAAA;;SAepB,UAAA,CACZ,SAAA,UACA,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,YAAA;;;;;SAQG,mBAAA,CAAoB,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,mBAAA,GAAsB,OAAA;AAAA"}
@@ -2,7 +2,7 @@ import { isUsableExpiry } from "../../utils/token-expiry.mjs";
2
2
  import { Model } from "@warlock.js/cascade";
3
3
  import { v } from "@warlock.js/seal";
4
4
 
5
- //#region ../auth/src/models/one-time-token/one-time-token.model.ts
5
+ //#region ../../packages/auth/src/models/one-time-token/one-time-token.model.ts
6
6
  /**
7
7
  * Seal schema for the persisted one-time token. Exported so an override can
8
8
  * extend it (e.g. a tenant key).
@@ -1 +1 @@
1
- {"version":3,"file":"one-time-token.model.mjs","names":[],"sources":["../../../../../../../../auth/src/models/one-time-token/one-time-token.model.ts"],"sourcesContent":["import { Model } from \"@warlock.js/cascade\";\nimport { v } from \"@warlock.js/seal\";\nimport { isUsableExpiry } from \"../../utils/token-expiry\";\nimport type { Auth } from \"../auth.model\";\n\n/** What a one-time token may be used for. A token only ever satisfies its own purpose. */\nexport type OneTimeTokenPurpose =\n | \"email-verification\"\n | \"password-reset\"\n | \"otp\"\n | \"passkey-registration\"\n | \"passkey-authentication\";\n\n/**\n * Seal schema for the persisted one-time token. Exported so an override can\n * extend it (e.g. a tenant key).\n */\nexport const oneTimeTokenSchema = v.object({\n token_hash: v.string().required(),\n purpose: v.string().required(),\n // Absent only on a passkey authentication challenge (no user identified yet).\n user_id: v.scalar().optional(),\n user_type: v.string().optional(),\n expires_at: v.date().required(),\n consumed_at: v.date().optional(),\n attempts: v.int().optional(),\n});\n\n/**\n * Persisted one-time secret: email-verification / password-reset token, OTP\n * code, or passkey ceremony challenge.\n *\n * **Only a SHA-256 hash is stored** — the raw token exists in the notification\n * and nowhere else, so a leaked table cannot be replayed. Single use is\n * enforced by {@link consumeIfActive}, a conditional update in the same shape\n * as `RefreshToken.revokeIfActive`. Override via `config.auth.oneTimeToken.model`.\n */\nexport class OneTimeToken extends Model {\n public static table = \"one_time_tokens\";\n\n public static schema = oneTimeTokenSchema;\n\n /**\n * The SHA-256 of a one-time secret. For a short OTP code the hash is\n * brute-forceable offline, so it is as sensitive as the code itself — never\n * serialize it. Only `toJSON()` is affected; `findByHash` still queries it.\n */\n public static hidden = [\"token_hash\"];\n\n /**\n * Permanent regardless of the data source default — Mongo's driver default\n * is `\"trash\"`, which would copy spent token hashes into\n * `one_time_tokensTrash` on every `destroy()`. A purged one-time token must\n * not survive anywhere.\n */\n public static deleteStrategy = \"permanent\" as const;\n\n /** The user this token was issued for. */\n public get userId() {\n return this.get(\"user_id\");\n }\n\n /** The user-type slug this token was issued for. */\n public get userType(): string {\n return this.get(\"user_type\");\n }\n\n /** Whether the token has been used (or invalidated by a newer one). */\n public get isConsumed(): boolean {\n return !!this.get(\"consumed_at\");\n }\n\n /** Whether the expiry has passed. Fails closed: an unusable `expires_at` counts as expired. */\n public get isExpired(): boolean {\n const expiresAt = this.get(\"expires_at\");\n\n if (!isUsableExpiry(expiresAt)) return true;\n\n return new Date(expiresAt).getTime() <= Date.now();\n }\n\n /**\n * Atomically mark this token consumed ONLY if nobody has yet. Resolves `true`\n * for the single caller that won; every concurrent or later caller gets\n * `false`.\n */\n public async consumeIfActive(): Promise<boolean> {\n const modelClass = this.constructor as typeof OneTimeToken;\n\n const consumed = await modelClass.atomic(\n { id: this.id, consumed_at: null },\n { $set: { consumed_at: new Date() } },\n );\n\n return consumed > 0;\n }\n\n /** Persist a new token row. `tokenHash` is the SHA-256 hex digest, never the raw token. */\n public static issue(\n user: Auth,\n purpose: OneTimeTokenPurpose,\n tokenHash: string,\n expiresAt: Date,\n ) {\n return this.create({\n token_hash: tokenHash,\n purpose,\n user_id: user.id,\n user_type: user.userType,\n expires_at: expiresAt,\n consumed_at: null,\n attempts: 0,\n });\n }\n\n /**\n * Persist a passkey ceremony challenge. `user` is omitted for an\n * authentication challenge, issued before anyone is identified.\n */\n public static issueChallenge(\n purpose: OneTimeTokenPurpose,\n tokenHash: string,\n expiresAt: Date,\n user?: Auth,\n ) {\n return this.create({\n token_hash: tokenHash,\n purpose,\n user_id: user?.id ?? null,\n user_type: user?.userType ?? null,\n expires_at: expiresAt,\n consumed_at: null,\n attempts: 0,\n });\n }\n\n /** The user's newest unconsumed token of `purpose` (at most one for OTP). */\n public static findActiveFor(\n user: Auth,\n purpose: OneTimeTokenPurpose,\n ): Promise<OneTimeToken | null> {\n return this.query()\n .where({ user_id: user.id, user_type: user.userType, purpose, consumed_at: null })\n .orderBy(\"created_at\", \"desc\")\n .first();\n }\n\n /**\n * Atomically count one verify attempt, ONLY while fewer than `max` have been\n * counted and the token is unconsumed. Resolves `false` once the cap is\n * reached — of N concurrent attempts, at most `max` ever resolve `true`.\n */\n public async recordAttempt(max: number): Promise<boolean> {\n const modelClass = this.constructor as typeof OneTimeToken;\n\n const counted = await modelClass.atomic(\n { id: this.id, consumed_at: null, attempts: { $lt: max } },\n { $inc: { attempts: 1 } },\n // Code-authored filter; nothing here comes from the request.\n { trustedFilter: true },\n );\n\n return counted > 0;\n }\n\n /**\n * Hard-delete every spent row — expired, or consumed (used, invalidated by a\n * newer token, or exhausted). Neither can ever be redeemed again, so nothing\n * reads them. Hard-deleted, never trashed. Returns the number removed. Runs from the `auth.cleanup` CLI\n * command (a cold batch path).\n */\n public static async purgeSpent(): Promise<number> {\n const expired = await this.query().where(\"expires_at\", \"<\", new Date()).get();\n const consumed = await this.query().whereNotNull(\"consumed_at\").get();\n const spent = new Map([...expired, ...consumed].map((token) => [String(token.id), token]));\n\n for (const token of spent.values()) {\n // `static deleteStrategy` above already forces \"permanent\" regardless\n // of the data source default (Mongo's is \"trash\").\n await token.destroy();\n }\n\n return spent.size;\n }\n\n /** Find a token by hash, scoped to a purpose — a token of the other purpose is not found. */\n public static findByHash(\n tokenHash: string,\n purpose: OneTimeTokenPurpose,\n ): Promise<OneTimeToken | null> {\n return this.first({ token_hash: tokenHash, purpose });\n }\n\n /**\n * Consume every still-unused token of `purpose` for the user, returning how\n * many were invalidated. Used before issuing a new password-reset token.\n */\n public static invalidateActiveFor(user: Auth, purpose: OneTimeTokenPurpose): Promise<number> {\n return this.atomic(\n { user_id: user.id, user_type: user.userType, purpose, consumed_at: null },\n { $set: { consumed_at: new Date() } },\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"one-time-token.model.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/one-time-token/one-time-token.model.ts"],"sourcesContent":["import { Model } from \"@warlock.js/cascade\";\nimport { v } from \"@warlock.js/seal\";\nimport { isUsableExpiry } from \"../../utils/token-expiry\";\nimport type { Auth } from \"../auth.model\";\n\n/** What a one-time token may be used for. A token only ever satisfies its own purpose. */\nexport type OneTimeTokenPurpose =\n | \"email-verification\"\n | \"password-reset\"\n | \"otp\"\n | \"passkey-registration\"\n | \"passkey-authentication\";\n\n/**\n * Seal schema for the persisted one-time token. Exported so an override can\n * extend it (e.g. a tenant key).\n */\nexport const oneTimeTokenSchema = v.object({\n token_hash: v.string().required(),\n purpose: v.string().required(),\n // Absent only on a passkey authentication challenge (no user identified yet).\n user_id: v.scalar().optional(),\n user_type: v.string().optional(),\n expires_at: v.date().required(),\n consumed_at: v.date().optional(),\n attempts: v.int().optional(),\n});\n\n/**\n * Persisted one-time secret: email-verification / password-reset token, OTP\n * code, or passkey ceremony challenge.\n *\n * **Only a SHA-256 hash is stored** — the raw token exists in the notification\n * and nowhere else, so a leaked table cannot be replayed. Single use is\n * enforced by {@link consumeIfActive}, a conditional update in the same shape\n * as `RefreshToken.revokeIfActive`. Override via `config.auth.oneTimeToken.model`.\n */\nexport class OneTimeToken extends Model {\n public static table = \"one_time_tokens\";\n\n public static schema = oneTimeTokenSchema;\n\n /**\n * The SHA-256 of a one-time secret. For a short OTP code the hash is\n * brute-forceable offline, so it is as sensitive as the code itself — never\n * serialize it. Only `toJSON()` is affected; `findByHash` still queries it.\n */\n public static hidden = [\"token_hash\"];\n\n /**\n * Permanent regardless of the data source default — Mongo's driver default\n * is `\"trash\"`, which would copy spent token hashes into\n * `one_time_tokensTrash` on every `destroy()`. A purged one-time token must\n * not survive anywhere.\n */\n public static deleteStrategy = \"permanent\" as const;\n\n /** The user this token was issued for. */\n public get userId() {\n return this.get(\"user_id\");\n }\n\n /** The user-type slug this token was issued for. */\n public get userType(): string {\n return this.get(\"user_type\");\n }\n\n /** Whether the token has been used (or invalidated by a newer one). */\n public get isConsumed(): boolean {\n return !!this.get(\"consumed_at\");\n }\n\n /** Whether the expiry has passed. Fails closed: an unusable `expires_at` counts as expired. */\n public get isExpired(): boolean {\n const expiresAt = this.get(\"expires_at\");\n\n if (!isUsableExpiry(expiresAt)) return true;\n\n return new Date(expiresAt).getTime() <= Date.now();\n }\n\n /**\n * Atomically mark this token consumed ONLY if nobody has yet. Resolves `true`\n * for the single caller that won; every concurrent or later caller gets\n * `false`.\n */\n public async consumeIfActive(): Promise<boolean> {\n const modelClass = this.constructor as typeof OneTimeToken;\n\n const consumed = await modelClass.atomic(\n { id: this.id, consumed_at: null },\n { $set: { consumed_at: new Date() } },\n );\n\n return consumed > 0;\n }\n\n /** Persist a new token row. `tokenHash` is the SHA-256 hex digest, never the raw token. */\n public static issue(\n user: Auth,\n purpose: OneTimeTokenPurpose,\n tokenHash: string,\n expiresAt: Date,\n ) {\n return this.create({\n token_hash: tokenHash,\n purpose,\n user_id: user.id,\n user_type: user.userType,\n expires_at: expiresAt,\n consumed_at: null,\n attempts: 0,\n });\n }\n\n /**\n * Persist a passkey ceremony challenge. `user` is omitted for an\n * authentication challenge, issued before anyone is identified.\n */\n public static issueChallenge(\n purpose: OneTimeTokenPurpose,\n tokenHash: string,\n expiresAt: Date,\n user?: Auth,\n ) {\n return this.create({\n token_hash: tokenHash,\n purpose,\n user_id: user?.id ?? null,\n user_type: user?.userType ?? null,\n expires_at: expiresAt,\n consumed_at: null,\n attempts: 0,\n });\n }\n\n /** The user's newest unconsumed token of `purpose` (at most one for OTP). */\n public static findActiveFor(\n user: Auth,\n purpose: OneTimeTokenPurpose,\n ): Promise<OneTimeToken | null> {\n return this.query()\n .where({ user_id: user.id, user_type: user.userType, purpose, consumed_at: null })\n .orderBy(\"created_at\", \"desc\")\n .first();\n }\n\n /**\n * Atomically count one verify attempt, ONLY while fewer than `max` have been\n * counted and the token is unconsumed. Resolves `false` once the cap is\n * reached — of N concurrent attempts, at most `max` ever resolve `true`.\n */\n public async recordAttempt(max: number): Promise<boolean> {\n const modelClass = this.constructor as typeof OneTimeToken;\n\n const counted = await modelClass.atomic(\n { id: this.id, consumed_at: null, attempts: { $lt: max } },\n { $inc: { attempts: 1 } },\n // Code-authored filter; nothing here comes from the request.\n { trustedFilter: true },\n );\n\n return counted > 0;\n }\n\n /**\n * Hard-delete every spent row — expired, or consumed (used, invalidated by a\n * newer token, or exhausted). Neither can ever be redeemed again, so nothing\n * reads them. Hard-deleted, never trashed. Returns the number removed. Runs from the `auth.cleanup` CLI\n * command (a cold batch path).\n */\n public static async purgeSpent(): Promise<number> {\n const expired = await this.query().where(\"expires_at\", \"<\", new Date()).get();\n const consumed = await this.query().whereNotNull(\"consumed_at\").get();\n const spent = new Map([...expired, ...consumed].map((token) => [String(token.id), token]));\n\n for (const token of spent.values()) {\n // `static deleteStrategy` above already forces \"permanent\" regardless\n // of the data source default (Mongo's is \"trash\").\n await token.destroy();\n }\n\n return spent.size;\n }\n\n /** Find a token by hash, scoped to a purpose — a token of the other purpose is not found. */\n public static findByHash(\n tokenHash: string,\n purpose: OneTimeTokenPurpose,\n ): Promise<OneTimeToken | null> {\n return this.first({ token_hash: tokenHash, purpose });\n }\n\n /**\n * Consume every still-unused token of `purpose` for the user, returning how\n * many were invalidated. Used before issuing a new password-reset token.\n */\n public static invalidateActiveFor(user: Auth, purpose: OneTimeTokenPurpose): Promise<number> {\n return this.atomic(\n { user_id: user.id, user_type: user.userType, purpose, consumed_at: null },\n { $set: { consumed_at: new Date() } },\n );\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { PasskeyCredential } from "./passkey-credential.model.mjs";
2
2
  import { migrate } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/passkey-credential/migration.ts
4
+ //#region ../../packages/auth/src/models/passkey-credential/migration.ts
5
5
  const PasskeyCredentialMigration = migrate(PasskeyCredential, {
6
6
  name: "passkeyCredential",
7
7
  up() {
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../auth/src/models/passkey-credential/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { PasskeyCredential } from \"./passkey-credential.model\";\n\nexport const PasskeyCredentialMigration = migrate(PasskeyCredential, {\n name: \"passkeyCredential\",\n up() {\n this.createTableIfNotExists();\n\n this.primaryUuid();\n\n this.text(\"credential_id\").unique();\n this.text(\"public_key\");\n this.bigInteger(\"counter\").default(0);\n this.json(\"transports\").nullable();\n this.foreignId(\"user_id\").index();\n this.string(\"user_type\", 50).nullable();\n\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,6BAA6B,QAAQ,mBAAmB;CACnE,MAAM;CACN,KAAK;EACH,KAAK,uBAAuB;EAE5B,KAAK,YAAY;EAEjB,KAAK,KAAK,eAAe,CAAC,CAAC,OAAO;EAClC,KAAK,KAAK,YAAY;EACtB,KAAK,WAAW,SAAS,CAAC,CAAC,QAAQ,CAAC;EACpC,KAAK,KAAK,YAAY,CAAC,CAAC,SAAS;EACjC,KAAK,UAAU,SAAS,CAAC,CAAC,MAAM;EAChC,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EAEtC,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/passkey-credential/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { PasskeyCredential } from \"./passkey-credential.model\";\n\nexport const PasskeyCredentialMigration = migrate(PasskeyCredential, {\n name: \"passkeyCredential\",\n up() {\n this.createTableIfNotExists();\n\n this.primaryUuid();\n\n this.text(\"credential_id\").unique();\n this.text(\"public_key\");\n this.bigInteger(\"counter\").default(0);\n this.json(\"transports\").nullable();\n this.foreignId(\"user_id\").index();\n this.string(\"user_type\", 50).nullable();\n\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,6BAA6B,QAAQ,mBAAmB;CACnE,MAAM;CACN,KAAK;EACH,KAAK,uBAAuB;EAE5B,KAAK,YAAY;EAEjB,KAAK,KAAK,eAAe,CAAC,CAAC,OAAO;EAClC,KAAK,KAAK,YAAY;EACtB,KAAK,WAAW,SAAS,CAAC,CAAC,QAAQ,CAAC;EACpC,KAAK,KAAK,YAAY,CAAC,CAAC,SAAS;EACjC,KAAK,UAAU,SAAS,CAAC,CAAC,MAAM;EAChC,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EAEtC,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { Auth } from "../auth.model.mjs";
2
2
  import { Model } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/passkey-credential/passkey-credential.model.d.ts
4
+ //#region ../../packages/auth/src/models/passkey-credential/passkey-credential.model.d.ts
5
5
  /** Seal schema for a stored passkey. Exported so an override can extend it. */
6
6
  declare const passkeyCredentialSchema: import("@warlock.js/seal").ObjectValidator<{
7
7
  credential_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
@@ -14,29 +14,21 @@ declare const passkeyCredentialSchema: import("@warlock.js/seal").ObjectValidato
14
14
  };
15
15
  user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
16
16
  user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
17
- }> & import("@warlock.js/seal").StandardSchemaV1<import("@warlock.js/seal").InferInputObjectShape<{
18
- credential_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
19
- public_key: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
20
- counter: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number>;
21
- transports: import("@warlock.js/seal").ArrayValidator & {
22
- validator: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
23
- } & import("@warlock.js/seal").StandardSchemaV1<string[], string[]> & {
24
- isOptional: true;
25
- };
26
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
27
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
28
- }>, import("@warlock.js/seal").InferInputObjectShape<{
29
- credential_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
30
- public_key: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
31
- counter: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number>;
32
- transports: import("@warlock.js/seal").ArrayValidator & {
33
- validator: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
34
- } & import("@warlock.js/seal").StandardSchemaV1<string[], string[]> & {
35
- isOptional: true;
36
- };
37
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
38
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
39
- }>>;
17
+ }> & import("@warlock.js/seal").StandardSchemaV1<{
18
+ transports?: string[] | undefined;
19
+ credential_id: string;
20
+ public_key: string;
21
+ counter: number;
22
+ user_id: string | number | boolean;
23
+ user_type: string;
24
+ }, {
25
+ transports?: string[] | undefined;
26
+ credential_id: string;
27
+ public_key: string;
28
+ counter: number;
29
+ user_id: string | number | boolean;
30
+ user_type: string;
31
+ }>;
40
32
  /**
41
33
  * A registered WebAuthn credential. `credential_id` and `public_key` are
42
34
  * base64url; `counter` is the last signature counter seen, which an
@@ -55,29 +47,21 @@ declare class PasskeyCredential extends Model {
55
47
  };
56
48
  user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
57
49
  user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
58
- }> & import("@warlock.js/seal").StandardSchemaV1<import("@warlock.js/seal").InferInputObjectShape<{
59
- credential_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
60
- public_key: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
61
- counter: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number>;
62
- transports: import("@warlock.js/seal").ArrayValidator & {
63
- validator: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
64
- } & import("@warlock.js/seal").StandardSchemaV1<string[], string[]> & {
65
- isOptional: true;
66
- };
67
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
68
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
69
- }>, import("@warlock.js/seal").InferInputObjectShape<{
70
- credential_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
71
- public_key: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
72
- counter: import("@warlock.js/seal").IntValidator & import("@warlock.js/seal").StandardSchemaV1<number, number>;
73
- transports: import("@warlock.js/seal").ArrayValidator & {
74
- validator: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
75
- } & import("@warlock.js/seal").StandardSchemaV1<string[], string[]> & {
76
- isOptional: true;
77
- };
78
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
79
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
80
- }>>;
50
+ }> & import("@warlock.js/seal").StandardSchemaV1<{
51
+ transports?: string[] | undefined;
52
+ credential_id: string;
53
+ public_key: string;
54
+ counter: number;
55
+ user_id: string | number | boolean;
56
+ user_type: string;
57
+ }, {
58
+ transports?: string[] | undefined;
59
+ credential_id: string;
60
+ public_key: string;
61
+ counter: number;
62
+ user_id: string | number | boolean;
63
+ user_type: string;
64
+ }>;
81
65
  /**
82
66
  * Permanent regardless of the data source default — Mongo's driver default
83
67
  * is `"trash"`. No call site deletes a credential today, but the public key
@@ -1 +1 @@
1
- {"version":3,"file":"passkey-credential.model.d.mts","names":[],"sources":["../../../../../../../../auth/src/models/passkey-credential/passkey-credential.model.ts"],"mappings":";;;;;cAKa,uBAAA,6BAAuB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAcvB,iBAAA,SAA0B,KAAA;EAAA,OACvB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAHtB;;;;SAWgB,cAAA;EA4Bc;EAAA,IAzBjB,YAAA;EAyBwB;EAAA,IApBxB,OAAA;EAnB0B;EAAA,IAwB1B,MAAA;EAxB+B;EAAA,IA6B/B,QAAA;EA5BG;EAAA,OAiCA,kBAAA,CAAmB,YAAA,WAAuB,OAAA,CAAQ,iBAAA;EA/B5C;EAAA,OAoCN,OAAA,CAAQ,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,iBAAA;;;;;EAQ9B,cAAA,CAAe,QAAA,UAAkB,UAAA,WAAqB,OAAA;AAAA"}
1
+ {"version":3,"file":"passkey-credential.model.d.mts","names":[],"sources":["../../../../../../../../../packages/auth/src/models/passkey-credential/passkey-credential.model.ts"],"mappings":";;;;;cAKa,uBAAA,6BAAuB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAcvB,iBAAA,SAA0B,KAAA;EAAA,OACvB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAQN,cAAA;;MAGH,YAAA;;MAKA,OAAA;;MAKA,MAAA;;MAKA,QAAA;;SAKG,kBAAA,CAAmB,YAAA,WAAuB,OAAA,CAAQ,iBAAA;;SAKlD,OAAA,CAAQ,IAAA,EAAM,IAAA,GAAO,OAAA,CAAQ,iBAAA;;;;;EAQ9B,cAAA,CAAe,QAAA,UAAkB,UAAA,WAAqB,OAAA;AAAA"}
@@ -1,7 +1,7 @@
1
1
  import { Model } from "@warlock.js/cascade";
2
2
  import { v } from "@warlock.js/seal";
3
3
 
4
- //#region ../auth/src/models/passkey-credential/passkey-credential.model.ts
4
+ //#region ../../packages/auth/src/models/passkey-credential/passkey-credential.model.ts
5
5
  /** Seal schema for a stored passkey. Exported so an override can extend it. */
6
6
  const passkeyCredentialSchema = v.object({
7
7
  credential_id: v.string().required(),
@@ -1 +1 @@
1
- {"version":3,"file":"passkey-credential.model.mjs","names":[],"sources":["../../../../../../../../auth/src/models/passkey-credential/passkey-credential.model.ts"],"sourcesContent":["import { Model } from \"@warlock.js/cascade\";\nimport { v } from \"@warlock.js/seal\";\nimport type { Auth } from \"../auth.model\";\n\n/** Seal schema for a stored passkey. Exported so an override can extend it. */\nexport const passkeyCredentialSchema = v.object({\n credential_id: v.string().required(),\n public_key: v.string().required(),\n counter: v.int().required(),\n transports: v.array(v.string()).optional(),\n user_id: v.scalar().required(),\n user_type: v.string().required(),\n});\n\n/**\n * A registered WebAuthn credential. `credential_id` and `public_key` are\n * base64url; `counter` is the last signature counter seen, which an\n * authentication must advance (a clone detector).\n */\nexport class PasskeyCredential extends Model {\n public static table = \"passkey_credentials\";\n\n public static schema = passkeyCredentialSchema;\n\n /**\n * Permanent regardless of the data source default — Mongo's driver default\n * is `\"trash\"`. No call site deletes a credential today, but the public key\n * is credential material, so a future `destroy()` here must not leave a\n * copy in `passkey_credentialsTrash`.\n */\n public static deleteStrategy = \"permanent\" as const;\n\n /** base64url credential id. */\n public get credentialId(): string {\n return this.get(\"credential_id\");\n }\n\n /** Last signature counter seen. */\n public get counter(): number {\n return Number(this.get(\"counter\") ?? 0);\n }\n\n /** The owner's id. */\n public get userId() {\n return this.get(\"user_id\");\n }\n\n /** The owner's type slug. */\n public get userType(): string {\n return this.get(\"user_type\");\n }\n\n /** Find a credential by its base64url id. */\n public static findByCredentialId(credentialId: string): Promise<PasskeyCredential | null> {\n return this.first({ credential_id: credentialId });\n }\n\n /** Every credential the user registered. */\n public static listFor(user: Auth): Promise<PasskeyCredential[]> {\n return this.query().where({ user_id: user.id, user_type: user.userType }).get();\n }\n\n /**\n * Store `newCounter` ONLY if the row still holds `expected` — a compare-and-set,\n * so two concurrent assertions with the same counter cannot both succeed.\n */\n public async advanceCounter(expected: number, newCounter: number): Promise<boolean> {\n const modelClass = this.constructor as typeof PasskeyCredential;\n\n const updated = await modelClass.atomic(\n { id: this.id, counter: expected },\n { $set: { counter: newCounter } },\n );\n\n return updated > 0;\n }\n}\n"],"mappings":";;;;;AAKA,MAAa,0BAA0B,EAAE,OAAO;CAC9C,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;CACnC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,SAAS,EAAE,IAAI,CAAC,CAAC,SAAS;CAC1B,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;CACzC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;;;AAOD,IAAa,oBAAb,cAAuC,MAAM;;eACrB;;;gBAEC;;;wBAQQ;;;CAG/B,IAAW,eAAuB;EAChC,OAAO,KAAK,IAAI,eAAe;CACjC;;CAGA,IAAW,UAAkB;EAC3B,OAAO,OAAO,KAAK,IAAI,SAAS,KAAK,CAAC;CACxC;;CAGA,IAAW,SAAS;EAClB,OAAO,KAAK,IAAI,SAAS;CAC3B;;CAGA,IAAW,WAAmB;EAC5B,OAAO,KAAK,IAAI,WAAW;CAC7B;;CAGA,OAAc,mBAAmB,cAAyD;EACxF,OAAO,KAAK,MAAM,EAAE,eAAe,aAAa,CAAC;CACnD;;CAGA,OAAc,QAAQ,MAA0C;EAC9D,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM;GAAE,SAAS,KAAK;GAAI,WAAW,KAAK;EAAS,CAAC,CAAC,CAAC,IAAI;CAChF;;;;;CAMA,MAAa,eAAe,UAAkB,YAAsC;EAQlF,OAAO,MAPY,KAAK,YAES,OAC/B;GAAE,IAAI,KAAK;GAAI,SAAS;EAAS,GACjC,EAAE,MAAM,EAAE,SAAS,WAAW,EAAE,CAClC,IAEiB;CACnB;AACF"}
1
+ {"version":3,"file":"passkey-credential.model.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/passkey-credential/passkey-credential.model.ts"],"sourcesContent":["import { Model } from \"@warlock.js/cascade\";\nimport { v } from \"@warlock.js/seal\";\nimport type { Auth } from \"../auth.model\";\n\n/** Seal schema for a stored passkey. Exported so an override can extend it. */\nexport const passkeyCredentialSchema = v.object({\n credential_id: v.string().required(),\n public_key: v.string().required(),\n counter: v.int().required(),\n transports: v.array(v.string()).optional(),\n user_id: v.scalar().required(),\n user_type: v.string().required(),\n});\n\n/**\n * A registered WebAuthn credential. `credential_id` and `public_key` are\n * base64url; `counter` is the last signature counter seen, which an\n * authentication must advance (a clone detector).\n */\nexport class PasskeyCredential extends Model {\n public static table = \"passkey_credentials\";\n\n public static schema = passkeyCredentialSchema;\n\n /**\n * Permanent regardless of the data source default — Mongo's driver default\n * is `\"trash\"`. No call site deletes a credential today, but the public key\n * is credential material, so a future `destroy()` here must not leave a\n * copy in `passkey_credentialsTrash`.\n */\n public static deleteStrategy = \"permanent\" as const;\n\n /** base64url credential id. */\n public get credentialId(): string {\n return this.get(\"credential_id\");\n }\n\n /** Last signature counter seen. */\n public get counter(): number {\n return Number(this.get(\"counter\") ?? 0);\n }\n\n /** The owner's id. */\n public get userId() {\n return this.get(\"user_id\");\n }\n\n /** The owner's type slug. */\n public get userType(): string {\n return this.get(\"user_type\");\n }\n\n /** Find a credential by its base64url id. */\n public static findByCredentialId(credentialId: string): Promise<PasskeyCredential | null> {\n return this.first({ credential_id: credentialId });\n }\n\n /** Every credential the user registered. */\n public static listFor(user: Auth): Promise<PasskeyCredential[]> {\n return this.query().where({ user_id: user.id, user_type: user.userType }).get();\n }\n\n /**\n * Store `newCounter` ONLY if the row still holds `expected` — a compare-and-set,\n * so two concurrent assertions with the same counter cannot both succeed.\n */\n public async advanceCounter(expected: number, newCounter: number): Promise<boolean> {\n const modelClass = this.constructor as typeof PasskeyCredential;\n\n const updated = await modelClass.atomic(\n { id: this.id, counter: expected },\n { $set: { counter: newCounter } },\n );\n\n return updated > 0;\n }\n}\n"],"mappings":";;;;;AAKA,MAAa,0BAA0B,EAAE,OAAO;CAC9C,eAAe,EAAE,OAAO,CAAC,CAAC,SAAS;CACnC,YAAY,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,SAAS,EAAE,IAAI,CAAC,CAAC,SAAS;CAC1B,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;CACzC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;;;AAOD,IAAa,oBAAb,cAAuC,MAAM;;eACrB;;;gBAEC;;;wBAQQ;;;CAG/B,IAAW,eAAuB;EAChC,OAAO,KAAK,IAAI,eAAe;CACjC;;CAGA,IAAW,UAAkB;EAC3B,OAAO,OAAO,KAAK,IAAI,SAAS,KAAK,CAAC;CACxC;;CAGA,IAAW,SAAS;EAClB,OAAO,KAAK,IAAI,SAAS;CAC3B;;CAGA,IAAW,WAAmB;EAC5B,OAAO,KAAK,IAAI,WAAW;CAC7B;;CAGA,OAAc,mBAAmB,cAAyD;EACxF,OAAO,KAAK,MAAM,EAAE,eAAe,aAAa,CAAC;CACnD;;CAGA,OAAc,QAAQ,MAA0C;EAC9D,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM;GAAE,SAAS,KAAK;GAAI,WAAW,KAAK;EAAS,CAAC,CAAC,CAAC,IAAI;CAChF;;;;;CAMA,MAAa,eAAe,UAAkB,YAAsC;EAQlF,OAAO,MAPY,KAAK,YAES,OAC/B;GAAE,IAAI,KAAK;GAAI,SAAS;EAAS,GACjC,EAAE,MAAM,EAAE,SAAS,WAAW,EAAE,CAClC,IAEiB;CACnB;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { ProviderAccount } from "./provider-account.model.mjs";
2
2
  import { migrate } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/provider-account/migration.ts
4
+ //#region ../../packages/auth/src/models/provider-account/migration.ts
5
5
  const ProviderAccountMigration = migrate(ProviderAccount, {
6
6
  name: "providerAccount",
7
7
  up() {
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../auth/src/models/provider-account/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { ProviderAccount } from \"./provider-account.model\";\n\nexport const ProviderAccountMigration = migrate(ProviderAccount, {\n name: \"providerAccount\",\n up() {\n this.createTableIfNotExists();\n\n this.primaryUuid();\n\n this.string(\"provider\", 50);\n this.string(\"provider_user_id\", 255);\n this.foreignId(\"user_id\").index();\n this.string(\"user_type\", 50).nullable();\n this.string(\"email\", 255).nullable();\n\n // One app user per provider identity.\n this.unique([\"provider\", \"provider_user_id\"]);\n\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,2BAA2B,QAAQ,iBAAiB;CAC/D,MAAM;CACN,KAAK;EACH,KAAK,uBAAuB;EAE5B,KAAK,YAAY;EAEjB,KAAK,OAAO,YAAY,EAAE;EAC1B,KAAK,OAAO,oBAAoB,GAAG;EACnC,KAAK,UAAU,SAAS,CAAC,CAAC,MAAM;EAChC,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EACtC,KAAK,OAAO,SAAS,GAAG,CAAC,CAAC,SAAS;EAGnC,KAAK,OAAO,CAAC,YAAY,kBAAkB,CAAC;EAE5C,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/provider-account/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { ProviderAccount } from \"./provider-account.model\";\n\nexport const ProviderAccountMigration = migrate(ProviderAccount, {\n name: \"providerAccount\",\n up() {\n this.createTableIfNotExists();\n\n this.primaryUuid();\n\n this.string(\"provider\", 50);\n this.string(\"provider_user_id\", 255);\n this.foreignId(\"user_id\").index();\n this.string(\"user_type\", 50).nullable();\n this.string(\"email\", 255).nullable();\n\n // One app user per provider identity.\n this.unique([\"provider\", \"provider_user_id\"]);\n\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,2BAA2B,QAAQ,iBAAiB;CAC/D,MAAM;CACN,KAAK;EACH,KAAK,uBAAuB;EAE5B,KAAK,YAAY;EAEjB,KAAK,OAAO,YAAY,EAAE;EAC1B,KAAK,OAAO,oBAAoB,GAAG;EACnC,KAAK,UAAU,SAAS,CAAC,CAAC,MAAM;EAChC,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EACtC,KAAK,OAAO,SAAS,GAAG,CAAC,CAAC,SAAS;EAGnC,KAAK,OAAO,CAAC,YAAY,kBAAkB,CAAC;EAE5C,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { Auth } from "../auth.model.mjs";
2
2
  import { Model } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/provider-account/provider-account.model.d.ts
4
+ //#region ../../packages/auth/src/models/provider-account/provider-account.model.d.ts
5
5
  /** Seal schema for a provider link. Exported so an override can extend it. */
6
6
  declare const providerAccountSchema: import("@warlock.js/seal").ObjectValidator<{
7
7
  provider: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
@@ -11,23 +11,19 @@ declare const providerAccountSchema: import("@warlock.js/seal").ObjectValidator<
11
11
  email: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
12
12
  isOptional: true;
13
13
  };
14
- }> & import("@warlock.js/seal").StandardSchemaV1<import("@warlock.js/seal").InferInputObjectShape<{
15
- provider: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
16
- provider_user_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
17
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
18
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
19
- email: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
20
- isOptional: true;
21
- };
22
- }>, import("@warlock.js/seal").InferInputObjectShape<{
23
- provider: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
24
- provider_user_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
25
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
26
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
27
- email: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
28
- isOptional: true;
29
- };
30
- }>>;
14
+ }> & import("@warlock.js/seal").StandardSchemaV1<{
15
+ email?: string | undefined;
16
+ provider: string;
17
+ provider_user_id: string;
18
+ user_id: string | number | boolean;
19
+ user_type: string;
20
+ }, {
21
+ email?: string | undefined;
22
+ provider: string;
23
+ provider_user_id: string;
24
+ user_id: string | number | boolean;
25
+ user_type: string;
26
+ }>;
31
27
  /**
32
28
  * Links a provider identity (`provider` + the provider's stable user id) to
33
29
  * an app user. Created the first time a VERIFIED provider email is matched or
@@ -44,23 +40,19 @@ declare class ProviderAccount extends Model {
44
40
  email: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
45
41
  isOptional: true;
46
42
  };
47
- }> & import("@warlock.js/seal").StandardSchemaV1<import("@warlock.js/seal").InferInputObjectShape<{
48
- provider: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
49
- provider_user_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
50
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
51
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
52
- email: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
53
- isOptional: true;
54
- };
55
- }>, import("@warlock.js/seal").InferInputObjectShape<{
56
- provider: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
57
- provider_user_id: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
58
- user_id: import("@warlock.js/seal").ScalarValidator & import("@warlock.js/seal").StandardSchemaV1<string | number | boolean, string | number | boolean>;
59
- user_type: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string>;
60
- email: import("@warlock.js/seal").StringValidator & import("@warlock.js/seal").StandardSchemaV1<string, string> & {
61
- isOptional: true;
62
- };
63
- }>>;
43
+ }> & import("@warlock.js/seal").StandardSchemaV1<{
44
+ email?: string | undefined;
45
+ provider: string;
46
+ provider_user_id: string;
47
+ user_id: string | number | boolean;
48
+ user_type: string;
49
+ }, {
50
+ email?: string | undefined;
51
+ provider: string;
52
+ provider_user_id: string;
53
+ user_id: string | number | boolean;
54
+ user_type: string;
55
+ }>;
64
56
  /** The linked user's id. */
65
57
  get userId(): any;
66
58
  /** The linked user's type slug. */
@@ -1 +1 @@
1
- {"version":3,"file":"provider-account.model.d.mts","names":[],"sources":["../../../../../../../../auth/src/models/provider-account/provider-account.model.ts"],"mappings":";;;;;cAKa,qBAAA,6BAAqB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAcrB,eAAA,SAAwB,KAAA;EAAA,OACrB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;MAGT,MAAA;EANgB;EAAA,IAWhB,QAAA;EAQA;EAAA,OAHG,QAAA,CACZ,QAAA,UACA,cAAA,WACC,OAAA,CAAQ,eAAA;EAKwD;EAAA,OAArD,IAAA,CAAK,QAAA,UAAkB,cAAA,UAAwB,IAAA,EAAM,IAAA,EAAM,KAAA,YAAc,OAAA,CAAA,eAAA;AAAA"}
1
+ {"version":3,"file":"provider-account.model.d.mts","names":[],"sources":["../../../../../../../../../packages/auth/src/models/provider-account/provider-account.model.ts"],"mappings":";;;;;cAKa,qBAAA,6BAAqB,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;cAcrB,eAAA,SAAwB,KAAA;EAAA,OACrB,KAAA;EAAA,OAEA,MAAA,6BAAM,eAAA;;;;;;;;;;;;;;;;;;;;;;MAGT,MAAA;;MAKA,QAAA;;SAKG,QAAA,CACZ,QAAA,UACA,cAAA,WACC,OAAA,CAAQ,eAAA;;SAKG,IAAA,CAAK,QAAA,UAAkB,cAAA,UAAwB,IAAA,EAAM,IAAA,EAAM,KAAA,YAAc,OAAA,CAAA,eAAA;AAAA"}
@@ -1,7 +1,7 @@
1
1
  import { Model } from "@warlock.js/cascade";
2
2
  import { v } from "@warlock.js/seal";
3
3
 
4
- //#region ../auth/src/models/provider-account/provider-account.model.ts
4
+ //#region ../../packages/auth/src/models/provider-account/provider-account.model.ts
5
5
  /** Seal schema for a provider link. Exported so an override can extend it. */
6
6
  const providerAccountSchema = v.object({
7
7
  provider: v.string().required(),
@@ -1 +1 @@
1
- {"version":3,"file":"provider-account.model.mjs","names":[],"sources":["../../../../../../../../auth/src/models/provider-account/provider-account.model.ts"],"sourcesContent":["import { Model } from \"@warlock.js/cascade\";\nimport { v } from \"@warlock.js/seal\";\nimport type { Auth } from \"../auth.model\";\n\n/** Seal schema for a provider link. Exported so an override can extend it. */\nexport const providerAccountSchema = v.object({\n provider: v.string().required(),\n provider_user_id: v.string().required(),\n user_id: v.scalar().required(),\n user_type: v.string().required(),\n email: v.string().optional(),\n});\n\n/**\n * Links a provider identity (`provider` + the provider's stable user id) to\n * an app user. Created the first time a VERIFIED provider email is matched or\n * a user is created for it; afterwards the link alone resolves the user, so a\n * later email change at the provider cannot move the login to another account.\n */\nexport class ProviderAccount extends Model {\n public static table = \"provider_accounts\";\n\n public static schema = providerAccountSchema;\n\n /** The linked user's id. */\n public get userId() {\n return this.get(\"user_id\");\n }\n\n /** The linked user's type slug. */\n public get userType(): string {\n return this.get(\"user_type\");\n }\n\n /** Find the link for a provider identity. */\n public static findLink(\n provider: string,\n providerUserId: string,\n ): Promise<ProviderAccount | null> {\n return this.first({ provider, provider_user_id: providerUserId });\n }\n\n /** Link a provider identity to a user. */\n public static link(provider: string, providerUserId: string, user: Auth, email?: string) {\n return this.create({\n provider,\n provider_user_id: providerUserId,\n user_id: user.id,\n user_type: user.userType,\n ...(email ? { email } : {}),\n });\n }\n}\n"],"mappings":";;;;;AAKA,MAAa,wBAAwB,EAAE,OAAO;CAC5C,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS;CACtC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC;;;;;;;AAQD,IAAa,kBAAb,cAAqC,MAAM;;eACnB;;;gBAEC;;;CAGvB,IAAW,SAAS;EAClB,OAAO,KAAK,IAAI,SAAS;CAC3B;;CAGA,IAAW,WAAmB;EAC5B,OAAO,KAAK,IAAI,WAAW;CAC7B;;CAGA,OAAc,SACZ,UACA,gBACiC;EACjC,OAAO,KAAK,MAAM;GAAE;GAAU,kBAAkB;EAAe,CAAC;CAClE;;CAGA,OAAc,KAAK,UAAkB,gBAAwB,MAAY,OAAgB;EACvF,OAAO,KAAK,OAAO;GACjB;GACA,kBAAkB;GAClB,SAAS,KAAK;GACd,WAAW,KAAK;GAChB,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;EAC3B,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"provider-account.model.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/provider-account/provider-account.model.ts"],"sourcesContent":["import { Model } from \"@warlock.js/cascade\";\nimport { v } from \"@warlock.js/seal\";\nimport type { Auth } from \"../auth.model\";\n\n/** Seal schema for a provider link. Exported so an override can extend it. */\nexport const providerAccountSchema = v.object({\n provider: v.string().required(),\n provider_user_id: v.string().required(),\n user_id: v.scalar().required(),\n user_type: v.string().required(),\n email: v.string().optional(),\n});\n\n/**\n * Links a provider identity (`provider` + the provider's stable user id) to\n * an app user. Created the first time a VERIFIED provider email is matched or\n * a user is created for it; afterwards the link alone resolves the user, so a\n * later email change at the provider cannot move the login to another account.\n */\nexport class ProviderAccount extends Model {\n public static table = \"provider_accounts\";\n\n public static schema = providerAccountSchema;\n\n /** The linked user's id. */\n public get userId() {\n return this.get(\"user_id\");\n }\n\n /** The linked user's type slug. */\n public get userType(): string {\n return this.get(\"user_type\");\n }\n\n /** Find the link for a provider identity. */\n public static findLink(\n provider: string,\n providerUserId: string,\n ): Promise<ProviderAccount | null> {\n return this.first({ provider, provider_user_id: providerUserId });\n }\n\n /** Link a provider identity to a user. */\n public static link(provider: string, providerUserId: string, user: Auth, email?: string) {\n return this.create({\n provider,\n provider_user_id: providerUserId,\n user_id: user.id,\n user_type: user.userType,\n ...(email ? { email } : {}),\n });\n }\n}\n"],"mappings":";;;;;AAKA,MAAa,wBAAwB,EAAE,OAAO;CAC5C,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,kBAAkB,EAAE,OAAO,CAAC,CAAC,SAAS;CACtC,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC;;;;;;;AAQD,IAAa,kBAAb,cAAqC,MAAM;;eACnB;;;gBAEC;;;CAGvB,IAAW,SAAS;EAClB,OAAO,KAAK,IAAI,SAAS;CAC3B;;CAGA,IAAW,WAAmB;EAC5B,OAAO,KAAK,IAAI,WAAW;CAC7B;;CAGA,OAAc,SACZ,UACA,gBACiC;EACjC,OAAO,KAAK,MAAM;GAAE;GAAU,kBAAkB;EAAe,CAAC;CAClE;;CAGA,OAAc,KAAK,UAAkB,gBAAwB,MAAY,OAAgB;EACvF,OAAO,KAAK,OAAO;GACjB;GACA,kBAAkB;GAClB,SAAS,KAAK;GACd,WAAW,KAAK;GAChB,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;EAC3B,CAAC;CACH;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { RefreshToken } from "./refresh-token.model.mjs";
2
2
  import { migrate } from "@warlock.js/cascade";
3
3
 
4
- //#region ../auth/src/models/refresh-token/migration.ts
4
+ //#region ../../packages/auth/src/models/refresh-token/migration.ts
5
5
  const RefreshTokenMigration = migrate(RefreshToken, {
6
6
  name: "refreshToken",
7
7
  up() {
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../auth/src/models/refresh-token/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { RefreshToken } from \"./refresh-token.model\";\n\nexport const RefreshTokenMigration = migrate(RefreshToken, {\n name: \"refreshToken\",\n up() {\n // Create table\n this.createTableIfNotExists();\n\n // Primary key\n this.primaryUuid();\n\n // Token fields\n this.text(\"token\").unique();\n // `foreignId` matches the DataSource's default primary-key type so the\n // column stays compatible with the user model's `id` (integer by default,\n // or uuid) — hardcoding uuid here 500'd login on integer-PK apps (5e47bdb3).\n this.foreignId(\"user_id\").index();\n this.string(\"user_type\", 50).nullable();\n this.text(\"family_id\").index().nullable();\n this.timestamp(\"expires_at\").index().nullable();\n this.timestamp(\"last_used_at\").nullable();\n this.timestamp(\"revoked_at\").nullable();\n this.json(\"device_info\").nullable();\n\n // Composite index for the per-user active-session lookups\n // (revokeAllFor / enforceMax / activeFor all filter on user_id + user_type).\n this.index([\"user_id\", \"user_type\"]);\n\n // Timestamps\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,wBAAwB,QAAQ,cAAc;CACzD,MAAM;CACN,KAAK;EAEH,KAAK,uBAAuB;EAG5B,KAAK,YAAY;EAGjB,KAAK,KAAK,OAAO,CAAC,CAAC,OAAO;EAI1B,KAAK,UAAU,SAAS,CAAC,CAAC,MAAM;EAChC,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EACtC,KAAK,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;EACxC,KAAK,UAAU,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;EAC9C,KAAK,UAAU,cAAc,CAAC,CAAC,SAAS;EACxC,KAAK,UAAU,YAAY,CAAC,CAAC,SAAS;EACtC,KAAK,KAAK,aAAa,CAAC,CAAC,SAAS;EAIlC,KAAK,MAAM,CAAC,WAAW,WAAW,CAAC;EAGnC,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../../../../../../../../../packages/auth/src/models/refresh-token/migration.ts"],"sourcesContent":["import { migrate } from \"@warlock.js/cascade\";\nimport { RefreshToken } from \"./refresh-token.model\";\n\nexport const RefreshTokenMigration = migrate(RefreshToken, {\n name: \"refreshToken\",\n up() {\n // Create table\n this.createTableIfNotExists();\n\n // Primary key\n this.primaryUuid();\n\n // Token fields\n this.text(\"token\").unique();\n // `foreignId` matches the DataSource's default primary-key type so the\n // column stays compatible with the user model's `id` (integer by default,\n // or uuid) — hardcoding uuid here 500'd login on integer-PK apps (5e47bdb3).\n this.foreignId(\"user_id\").index();\n this.string(\"user_type\", 50).nullable();\n this.text(\"family_id\").index().nullable();\n this.timestamp(\"expires_at\").index().nullable();\n this.timestamp(\"last_used_at\").nullable();\n this.timestamp(\"revoked_at\").nullable();\n this.json(\"device_info\").nullable();\n\n // Composite index for the per-user active-session lookups\n // (revokeAllFor / enforceMax / activeFor all filter on user_id + user_type).\n this.index([\"user_id\", \"user_type\"]);\n\n // Timestamps\n this.timestamps();\n },\n down() {\n this.dropTableIfExists();\n },\n});\n"],"mappings":";;;;AAGA,MAAa,wBAAwB,QAAQ,cAAc;CACzD,MAAM;CACN,KAAK;EAEH,KAAK,uBAAuB;EAG5B,KAAK,YAAY;EAGjB,KAAK,KAAK,OAAO,CAAC,CAAC,OAAO;EAI1B,KAAK,UAAU,SAAS,CAAC,CAAC,MAAM;EAChC,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,SAAS;EACtC,KAAK,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;EACxC,KAAK,UAAU,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS;EAC9C,KAAK,UAAU,cAAc,CAAC,CAAC,SAAS;EACxC,KAAK,UAAU,YAAY,CAAC,CAAC,SAAS;EACtC,KAAK,KAAK,aAAa,CAAC,CAAC,SAAS;EAIlC,KAAK,MAAM,CAAC,WAAW,WAAW,CAAC;EAGnC,KAAK,WAAW;CAClB;CACA,OAAO;EACL,KAAK,kBAAkB;CACzB;AACF,CAAC"}