@warlock.js/auth 4.1.15 → 4.2.1

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 (91) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/LICENSE +21 -0
  3. package/README.md +78 -37
  4. package/esm/commands/auth-cleanup-command.d.mts +1 -1
  5. package/esm/commands/auth-cleanup-command.d.mts.map +1 -1
  6. package/esm/commands/auth-cleanup-command.mjs +1 -1
  7. package/esm/commands/auth-cleanup-command.mjs.map +1 -1
  8. package/esm/commands/jwt-secret-generator-command.d.mts +1 -1
  9. package/esm/commands/jwt-secret-generator-command.d.mts.map +1 -1
  10. package/esm/commands/jwt-secret-generator-command.mjs +1 -1
  11. package/esm/commands/jwt-secret-generator-command.mjs.map +1 -1
  12. package/esm/contracts/auth-contract.d.mts +2 -2
  13. package/esm/contracts/auth-contract.d.mts.map +1 -1
  14. package/esm/contracts/index.d.mts +1 -1
  15. package/esm/contracts/types.d.mts +105 -76
  16. package/esm/contracts/types.d.mts.map +1 -1
  17. package/esm/contracts/types.mjs +2 -2
  18. package/esm/contracts/types.mjs.map +1 -1
  19. package/esm/index.d.mts +6 -5
  20. package/esm/index.mjs +4 -3
  21. package/esm/middleware/auth.middleware.d.mts +1 -1
  22. package/esm/middleware/auth.middleware.d.mts.map +1 -1
  23. package/esm/middleware/auth.middleware.mjs +9 -9
  24. package/esm/middleware/auth.middleware.mjs.map +1 -1
  25. package/esm/middleware/index.d.mts +2 -0
  26. package/esm/middleware/index.mjs +1 -0
  27. package/esm/middleware/login-throttle.middleware.d.mts +116 -0
  28. package/esm/middleware/login-throttle.middleware.d.mts.map +1 -0
  29. package/esm/middleware/login-throttle.middleware.mjs +105 -0
  30. package/esm/middleware/login-throttle.middleware.mjs.map +1 -0
  31. package/esm/models/access-token/access-token.model.d.mts +47 -5
  32. package/esm/models/access-token/access-token.model.d.mts.map +1 -1
  33. package/esm/models/access-token/access-token.model.mjs +70 -4
  34. package/esm/models/access-token/access-token.model.mjs.map +1 -1
  35. package/esm/models/access-token/index.d.mts +1 -1
  36. package/esm/models/access-token/index.mjs +1 -1
  37. package/esm/models/access-token/migration.mjs +2 -3
  38. package/esm/models/access-token/migration.mjs.map +1 -1
  39. package/esm/models/auth.model.d.mts +2 -2
  40. package/esm/models/auth.model.d.mts.map +1 -1
  41. package/esm/models/auth.model.mjs +1 -1
  42. package/esm/models/auth.model.mjs.map +1 -1
  43. package/esm/models/index.d.mts +4 -3
  44. package/esm/models/index.d.mts.map +1 -1
  45. package/esm/models/index.mjs +3 -3
  46. package/esm/models/index.mjs.map +1 -1
  47. package/esm/models/refresh-token/index.d.mts +1 -1
  48. package/esm/models/refresh-token/index.mjs +1 -1
  49. package/esm/models/refresh-token/migration.mjs +2 -1
  50. package/esm/models/refresh-token/migration.mjs.map +1 -1
  51. package/esm/models/refresh-token/refresh-token.model.d.mts +94 -16
  52. package/esm/models/refresh-token/refresh-token.model.d.mts.map +1 -1
  53. package/esm/models/refresh-token/refresh-token.model.mjs +152 -13
  54. package/esm/models/refresh-token/refresh-token.model.mjs.map +1 -1
  55. package/esm/services/auth-config.mjs +63 -0
  56. package/esm/services/auth-config.mjs.map +1 -0
  57. package/esm/services/auth-events.d.mts +2 -2
  58. package/esm/services/auth-events.d.mts.map +1 -1
  59. package/esm/services/auth-events.mjs +7 -2
  60. package/esm/services/auth-events.mjs.map +1 -1
  61. package/esm/services/auth.service.d.mts +48 -30
  62. package/esm/services/auth.service.d.mts.map +1 -1
  63. package/esm/services/auth.service.mjs +88 -102
  64. package/esm/services/auth.service.mjs.map +1 -1
  65. package/esm/services/generate-jwt-secret.d.mts +1 -1
  66. package/esm/services/generate-jwt-secret.d.mts.map +1 -1
  67. package/esm/services/generate-jwt-secret.mjs +4 -4
  68. package/esm/services/generate-jwt-secret.mjs.map +1 -1
  69. package/esm/services/index.d.mts +1 -1
  70. package/esm/services/jwt.d.mts +13 -4
  71. package/esm/services/jwt.d.mts.map +1 -1
  72. package/esm/services/jwt.mjs +30 -11
  73. package/esm/services/jwt.mjs.map +1 -1
  74. package/esm/utils/auth-error-codes.d.mts +9 -2
  75. package/esm/utils/auth-error-codes.d.mts.map +1 -1
  76. package/esm/utils/auth-error-codes.mjs +7 -1
  77. package/esm/utils/auth-error-codes.mjs.map +1 -1
  78. package/llms-full.txt +269 -20
  79. package/llms.txt +2 -0
  80. package/package.json +9 -11
  81. package/skills/auth-basics/SKILL.md +8 -7
  82. package/skills/customize-token-storage/SKILL.md +112 -0
  83. package/skills/customize-user-type/SKILL.md +7 -2
  84. package/skills/handle-login-and-logout/SKILL.md +1 -1
  85. package/skills/manage-tokens/SKILL.md +9 -9
  86. package/skills/overview/SKILL.md +7 -1
  87. package/skills/protect-routes/SKILL.md +1 -0
  88. package/skills/run-auth-commands/SKILL.md +1 -1
  89. package/skills/throttle-login-attempts/SKILL.md +116 -0
  90. package/cjs/index.cjs +0 -807
  91. package/cjs/index.cjs.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,44 @@
1
+ # Changelog — @warlock.js/auth
2
+
3
+ All notable changes to `@warlock.js/auth` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
+
7
+ ## [Unreleased]
8
+
9
+ ## 4.2.0
10
+
11
+ ### Added
12
+
13
+ - `loginThrottleMiddleware` — failure-aware brute-force / credential-stuffing protection that counts only failed logins, resets on a successful one, locks per-account and per-IP, and rejects pre-controller with `429` (cache-backed, fails open on a cache outage). Adds `AuthErrorCodes.TooManyAttempts` (`EC004`).
14
+ - `accessToken` / `refreshToken` configuration blocks, making a separate refresh-token secret first-class.
15
+ - Overridable token storage — register a custom model under `config.auth.accessToken.model` / `config.auth.refreshToken.model` and `.extend()` the exported `accessTokenSchema` / `refreshTokenSchema` to add columns (e.g. a multi-tenant `organization_id`). Models own issuance through `issue()` and expose named statics, so the service hard-codes no column names.
16
+ - `tokenType` (`access` | `refresh`) claim, stamped on issue and verified on read, so an access token can no longer be presented as a refresh token.
17
+ - `expires_at` on access tokens; `warlock auth.cleanup` now purges expired access tokens as well as refresh tokens.
18
+
19
+ ### Fixed
20
+
21
+ - Default access-token lifetime was ~3.6 seconds (a numeric `expiresIn` interpreted as milliseconds) and is now **1 hour**.
22
+ - Targeted revocation queried `userId` instead of the `user_id` column, so logout and refresh-token removal threw on Postgres and silently no-oped on MongoDB. The service now routes every token query through named model statics, so no column name is hard-coded.
23
+ - Token deletions were fire-and-forget inside `Promise<void>` methods (false success for callers, uncatchable rejections) and are now awaited.
24
+ - The route middleware matched on `userType` instead of the `user_type` column.
25
+ - `revokeAllTokens` / `revokeTokenFamily` reported an empty set — a re-query on `revoked_at: null` after the update matched nothing — so the `token.revoked` / `token.familyRevoked` events never fired. The revoked rows are now captured before revocation.
26
+ - A throwing synchronous auth-event listener no longer turns a completed login into a `500`.
27
+
28
+ ### Security
29
+
30
+ - `warlock jwt.generate` now derives `JWT_SECRET` / `JWT_REFRESH_SECRET` from a CSPRNG (`Random.token`) instead of `Math.random()`-backed `Random.string`.
31
+ - Refresh-token rotation is atomic: a guarded conditional `UPDATE` means two concurrent rotations of the same token can never both succeed, and a replayed token revokes its entire family.
32
+
33
+ ### Deprecated
34
+
35
+ - The `auth.jwt.*` configuration block (`jwt: { secret, expiresIn, refresh }`). Use `accessToken` / `refreshToken` instead — the legacy shape is still read and mapped forward with a one-time deprecation warning.
36
+
37
+ ### Removed
38
+
39
+ - Unread `access_tokens` columns `is_active` and `last_access`.
40
+ - The unused `auth.password.salt` configuration key.
41
+
42
+ ## 4.1.15
43
+
44
+ - Baseline — per-package changelog tracking starts at this version.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Hassan Zohdy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,37 +1,78 @@
1
- # Warlock Auth
2
-
3
- Auth System for Warlock.js
4
-
5
- ## Installation
6
-
7
- `yarn create @warlock.js/auth`
8
-
9
- Or
10
-
11
- `npx create @warlock.js/auth`
12
-
13
- Or
14
-
15
- `pnpm create @warlock.js/auth`
16
-
17
- ## Generate JWT Secret
18
-
19
- To generate JWT secret key, we need to add the following code to the `warlock.config.ts` file.
20
-
21
- ```ts
22
- import { registerJWTSecretGeneratorCommand } from "@warlock.js/auth";
23
- import { defineConfig } from "@warlock.js/core";
24
-
25
- export default defineConfig({
26
- // Other configurations
27
- cli: {
28
- commands: [registerJWTSecretGeneratorCommand()],
29
- },
30
- });
31
- ```
32
-
33
- Then run the following command:
34
-
35
- `warlock jwt.generate`
36
-
37
- It will generate
1
+ # Warlock Auth
2
+
3
+ JWT authentication for [Warlock.js](https://github.com/warlockjs/core) applications — a base `Auth` model your user types extend, an `authMiddleware` route gate, an `authService` for login / logout / refresh (with refresh-token rotation + replay detection), persisted access + refresh tokens, multi-user-type support, lifecycle events, brute-force throttling, and two CLI commands.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ yarn add @warlock.js/auth
9
+ ```
10
+
11
+ `@warlock.js/auth` is coupled to `@warlock.js/core` — install it inside a Warlock project.
12
+
13
+ ## Configure
14
+
15
+ ```ts title="src/config/auth.ts"
16
+ import { type AuthConfigurations } from "@warlock.js/auth";
17
+ import { env } from "@warlock.js/core";
18
+ import { User } from "app/users/models/user";
19
+
20
+ const authConfigurations: AuthConfigurations = {
21
+ userType: { user: User },
22
+ accessToken: {
23
+ secret: env("JWT_SECRET"),
24
+ expiresIn: "1h",
25
+ },
26
+ refreshToken: {
27
+ secret: env("JWT_REFRESH_SECRET"),
28
+ expiresIn: "30d",
29
+ rotation: true,
30
+ },
31
+ };
32
+
33
+ export default authConfigurations;
34
+ ```
35
+
36
+ The legacy `jwt: { secret, expiresIn, refresh: {…} }` block is still honored (with a deprecation warning), but prefer the `accessToken` / `refreshToken` blocks.
37
+
38
+ ## Documentation
39
+
40
+ Task-focused guides live under [`skills/`](./skills):
41
+
42
+ - **overview** — what the package does and when to reach for it
43
+ - **auth-basics** — the `Auth` model, middleware, and service
44
+ - **handle-login-and-logout** — issue and revoke tokens
45
+ - **register-user** — sign up + first token pair
46
+ - **protect-routes** — gate routes with `authMiddleware`
47
+ - **manage-tokens** — the full token lifecycle (rotation, revocation, cleanup)
48
+ - **customize-user-type** — multiple user types in one system
49
+ - **customize-token-storage** — override the token models (multi-tenant columns, custom storage)
50
+ - **throttle-login-attempts** — brute-force protection via `loginThrottleMiddleware`
51
+ - **run-auth-commands** — the bundled CLI commands
52
+
53
+ ## Generate the JWT secret
54
+
55
+ Register the command in `warlock.config.ts`:
56
+
57
+ ```ts
58
+ import { registerJWTSecretGeneratorCommand } from "@warlock.js/auth";
59
+ import { defineConfig } from "@warlock.js/core";
60
+
61
+ export default defineConfig({
62
+ cli: {
63
+ commands: [registerJWTSecretGeneratorCommand()],
64
+ },
65
+ });
66
+ ```
67
+
68
+ Then run:
69
+
70
+ ```bash
71
+ warlock jwt.generate
72
+ ```
73
+
74
+ It generates cryptographically-strong `JWT_SECRET` and `JWT_REFRESH_SECRET` values and writes them to your `.env` file. Existing values are left untouched, so it's safe to re-run.
75
+
76
+ ## License
77
+
78
+ MIT © Hasan Zohdy
@@ -1,4 +1,4 @@
1
- //#region ../../@warlock.js/auth/src/commands/auth-cleanup-command.d.ts
1
+ //#region ../@warlock.js/auth/src/commands/auth-cleanup-command.d.ts
2
2
  /**
3
3
  * Register the auth:cleanup CLI command
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"auth-cleanup-command.d.mts","names":[],"sources":["../../../../../../@warlock.js/auth/src/commands/auth-cleanup-command.ts"],"mappings":";;AAYA;;;;AAA0C;;;iBAA1B,0BAAA,CAAA"}
1
+ {"version":3,"file":"auth-cleanup-command.d.mts","names":[],"sources":["../../../../../../../@warlock.js/auth/src/commands/auth-cleanup-command.ts"],"mappings":";;AAYA;;;;AAA0C;;;iBAA1B,0BAAA"}
@@ -2,7 +2,7 @@ import { authService } from "../services/auth.service.mjs";
2
2
  import { colors } from "@mongez/copper";
3
3
  import { command } from "@warlock.js/core";
4
4
 
5
- //#region ../../@warlock.js/auth/src/commands/auth-cleanup-command.ts
5
+ //#region ../@warlock.js/auth/src/commands/auth-cleanup-command.ts
6
6
  /**
7
7
  * Register the auth:cleanup CLI command
8
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"auth-cleanup-command.mjs","names":[],"sources":["../../../../../../@warlock.js/auth/src/commands/auth-cleanup-command.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { command } from \"@warlock.js/core\";\nimport { authService } from \"../services/auth.service\";\n\n/**\n * Register the auth:cleanup CLI command\n *\n * @example\n * ```bash\n * warlock auth:cleanup\n * ```\n */\nexport function registerAuthCleanupCommand() {\n return command({\n name: \"auth.cleanup\",\n description: \"Remove expired refresh tokens from the database\",\n preload: {\n env: true,\n config: [\"auth\", \"database\"],\n connectors: [\"database\"],\n },\n action: async () => {\n console.log(colors.cyan(\"🧹 Cleaning up expired tokens...\"));\n\n const count = await authService.cleanupExpiredTokens();\n\n if (count === 0) {\n console.log(colors.green(\"✅ No expired tokens found.\"));\n } else {\n console.log(colors.green(`✅ Removed ${count} expired token(s).`));\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,6BAA6B;CAC3C,OAAO,QAAQ;EACb,MAAM;EACN,aAAa;EACb,SAAS;GACP,KAAK;GACL,QAAQ,CAAC,QAAQ,UAAU;GAC3B,YAAY,CAAC,UAAU;EACzB;EACA,QAAQ,YAAY;GAClB,QAAQ,IAAI,OAAO,KAAK,kCAAkC,CAAC;GAE3D,MAAM,QAAQ,MAAM,YAAY,qBAAqB;GAErD,IAAI,UAAU,GACZ,QAAQ,IAAI,OAAO,MAAM,4BAA4B,CAAC;QAEtD,QAAQ,IAAI,OAAO,MAAM,aAAa,MAAM,mBAAmB,CAAC;EAEpE;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"auth-cleanup-command.mjs","names":[],"sources":["../../../../../../../@warlock.js/auth/src/commands/auth-cleanup-command.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { command } from \"@warlock.js/core\";\nimport { authService } from \"../services/auth.service\";\n\n/**\n * Register the auth:cleanup CLI command\n *\n * @example\n * ```bash\n * warlock auth:cleanup\n * ```\n */\nexport function registerAuthCleanupCommand() {\n return command({\n name: \"auth.cleanup\",\n description: \"Remove expired refresh tokens from the database\",\n preload: {\n env: true,\n config: [\"auth\", \"database\"],\n connectors: [\"database\"],\n },\n action: async () => {\n console.log(colors.cyan(\"🧹 Cleaning up expired tokens...\"));\n\n const count = await authService.cleanupExpiredTokens();\n\n if (count === 0) {\n console.log(colors.green(\"✅ No expired tokens found.\"));\n } else {\n console.log(colors.green(`✅ Removed ${count} expired token(s).`));\n }\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,6BAA6B;CAC3C,OAAO,QAAQ;EACb,MAAM;EACN,aAAa;EACb,SAAS;GACP,KAAK;GACL,QAAQ,CAAC,QAAQ,UAAU;GAC3B,YAAY,CAAC,UAAU;EACzB;EACA,QAAQ,YAAY;GAClB,QAAQ,IAAI,OAAO,KAAK,kCAAkC,CAAC;GAE3D,MAAM,QAAQ,MAAM,YAAY,qBAAqB;GAErD,IAAI,UAAU,GACZ,QAAQ,IAAI,OAAO,MAAM,4BAA4B,CAAC;QAEtD,QAAQ,IAAI,OAAO,MAAM,aAAa,MAAM,mBAAmB,CAAC;EAEpE;CACF,CAAC;AACH"}
@@ -1,4 +1,4 @@
1
- //#region ../../@warlock.js/auth/src/commands/jwt-secret-generator-command.d.ts
1
+ //#region ../@warlock.js/auth/src/commands/jwt-secret-generator-command.d.ts
2
2
  declare function registerJWTSecretGeneratorCommand(): any;
3
3
  //#endregion
4
4
  export { registerJWTSecretGeneratorCommand };
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-secret-generator-command.d.mts","names":[],"sources":["../../../../../../@warlock.js/auth/src/commands/jwt-secret-generator-command.ts"],"mappings":";iBAGgB,iCAAA,CAAA"}
1
+ {"version":3,"file":"jwt-secret-generator-command.d.mts","names":[],"sources":["../../../../../../../@warlock.js/auth/src/commands/jwt-secret-generator-command.ts"],"mappings":";iBAGgB,iCAAA"}
@@ -1,7 +1,7 @@
1
1
  import { generateJWTSecret } from "../services/generate-jwt-secret.mjs";
2
2
  import { command } from "@warlock.js/core";
3
3
 
4
- //#region ../../@warlock.js/auth/src/commands/jwt-secret-generator-command.ts
4
+ //#region ../@warlock.js/auth/src/commands/jwt-secret-generator-command.ts
5
5
  function registerJWTSecretGeneratorCommand() {
6
6
  return command({
7
7
  name: "jwt.generate",
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-secret-generator-command.mjs","names":[],"sources":["../../../../../../@warlock.js/auth/src/commands/jwt-secret-generator-command.ts"],"sourcesContent":["import { command } from \"@warlock.js/core\";\r\nimport { generateJWTSecret } from \"../services/generate-jwt-secret\";\r\n\r\nexport function registerJWTSecretGeneratorCommand() {\r\n return command({\r\n name: \"jwt.generate\",\r\n description: \"Generate JWT Secret key in .env file\",\r\n action: generateJWTSecret,\r\n });\r\n}\r\n"],"mappings":";;;;AAGA,SAAgB,oCAAoC;CAClD,OAAO,QAAQ;EACb,MAAM;EACN,aAAa;EACb,QAAQ;CACV,CAAC;AACH"}
1
+ {"version":3,"file":"jwt-secret-generator-command.mjs","names":[],"sources":["../../../../../../../@warlock.js/auth/src/commands/jwt-secret-generator-command.ts"],"sourcesContent":["import { command } from \"@warlock.js/core\";\r\nimport { generateJWTSecret } from \"../services/generate-jwt-secret\";\r\n\r\nexport function registerJWTSecretGeneratorCommand() {\r\n return command({\r\n name: \"jwt.generate\",\r\n description: \"Generate JWT Secret key in .env file\",\r\n action: generateJWTSecret,\r\n });\r\n}\r\n"],"mappings":";;;;AAGA,SAAgB,oCAAoC;CAClD,OAAO,QAAQ;EACb,MAAM;EACN,aAAa;EACb,QAAQ;CACV,CAAC;AACH"}
@@ -1,7 +1,7 @@
1
- import { RefreshToken } from "../models/refresh-token/refresh-token.model.mjs";
2
1
  import { AccessTokenOutput, DeviceInfo, TokenPair } from "./types.mjs";
2
+ import { RefreshToken } from "../models/refresh-token/refresh-token.model.mjs";
3
3
 
4
- //#region ../../@warlock.js/auth/src/contracts/auth-contract.d.ts
4
+ //#region ../@warlock.js/auth/src/contracts/auth-contract.d.ts
5
5
  /**
6
6
  * Surface every authenticable user model exposes once it extends the
7
7
  * `Auth` base. The `Auth` class implements this contract; subclasses only
@@ -1 +1 @@
1
- {"version":3,"file":"auth-contract.d.mts","names":[],"sources":["../../../../../../@warlock.js/auth/src/contracts/auth-contract.ts"],"mappings":";;;;;;AAWA;;;;;;UAAiB,aAAA;EAiBwC;;;;EAAA,IAZnD,QAAA;EAsB+B;;;;EAhBnC,mBAAA,CAAoB,OAAA,GAAU,MAAA,oBAA0B,OAAA,CAAQ,iBAAA;EAAlC;;;;EAM9B,oBAAA,CAAqB,UAAA,GAAa,UAAA,GAAa,OAAA,CAAQ,YAAA;EAArB;;;EAKlC,eAAA,CAAgB,UAAA,GAAa,UAAA,GAAa,OAAA,CAAQ,SAAA;EAAlD;;;EAKA,eAAA,CAAgB,QAAA,WAAmB,OAAA;AAAA"}
1
+ {"version":3,"file":"auth-contract.d.mts","names":[],"sources":["../../../../../../../@warlock.js/auth/src/contracts/auth-contract.ts"],"mappings":";;;;;;AAWA;;;;;;UAAiB,aAAA;EAiBwC;;;;EAAA,IAZnD,QAAA;EAsB+B;;;;EAhBnC,mBAAA,CAAoB,OAAA,GAAU,MAAA,oBAA0B,OAAA,CAAQ,iBAAA;EAAlC;;;;EAM9B,oBAAA,CAAqB,UAAA,GAAa,UAAA,GAAa,OAAA,CAAQ,YAAA;EAArB;;;EAKlC,eAAA,CAAgB,UAAA,GAAa,UAAA,GAAa,OAAA,CAAQ,SAAA;EAAlD;;;EAKA,eAAA,CAAgB,QAAA,WAAmB,OAAA;AAAA"}
@@ -1,2 +1,2 @@
1
- import { AccessTokenOutput, AuthConfigurations, DeviceInfo, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, TokenPair } from "./types.mjs";
1
+ import { AccessTokenConfig, AccessTokenOutput, AuthConfigurations, DeviceInfo, LegacyJwtConfig, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, RefreshTokenConfig, TokenPair } from "./types.mjs";
2
2
  import { Authenticable } from "./auth-contract.mjs";
@@ -1,8 +1,10 @@
1
1
  import { Auth } from "../models/auth.model.mjs";
2
+ import { AccessToken } from "../models/access-token/access-token.model.mjs";
3
+ import { RefreshToken } from "../models/refresh-token/refresh-token.model.mjs";
2
4
  import { ChildModel } from "@warlock.js/cascade";
3
5
  import { Algorithm } from "fast-jwt";
4
6
 
5
- //#region ../../@warlock.js/auth/src/contracts/types.d.ts
7
+ //#region ../@warlock.js/auth/src/contracts/types.d.ts
6
8
  /**
7
9
  * Symbol to indicate no expiration for tokens
8
10
  * Use this when you explicitly want tokens to never expire
@@ -13,7 +15,7 @@ import { Algorithm } from "fast-jwt";
13
15
  * import { NO_EXPIRATION, type AuthConfigurations } from "@warlock.js/auth";
14
16
  *
15
17
  * const authConfigurations: AuthConfigurations = {
16
- * jwt: {
18
+ * accessToken: {
17
19
  * secret: env("JWT_SECRET"),
18
20
  * expiresIn: NO_EXPIRATION, // Token expires within 100 years
19
21
  * },
@@ -29,88 +31,115 @@ declare const NO_EXPIRATION = "100y";
29
31
  * - "error": Return an error requiring the refresh token
30
32
  */
31
33
  type LogoutWithoutTokenBehavior = "revoke-all" | "error";
34
+ /**
35
+ * Access-token configuration.
36
+ *
37
+ * `secret` may also be supplied via the deprecated `jwt.secret` (resolved by a
38
+ * backward-compatible shim); one of the two is required at runtime.
39
+ */
40
+ type AccessTokenConfig = {
41
+ /**
42
+ * Override the persisted access-token model — extend {@link AccessToken} to
43
+ * add columns (e.g. a tenant key) or rename them, then register the subclass
44
+ * here. Defaults to the package's `AccessToken`.
45
+ */
46
+ model?: typeof AccessToken;
47
+ /**
48
+ * Secret used to sign access tokens.
49
+ */
50
+ secret?: string;
51
+ /**
52
+ * JWT algorithm.
53
+ * @default "HS256"
54
+ */
55
+ algorithm?: Algorithm;
56
+ /**
57
+ * Access-token lifetime — any value the `ms` package accepts.
58
+ * @example "1h" or NO_EXPIRATION
59
+ * @default "1h"
60
+ */
61
+ expiresIn?: string;
62
+ };
63
+ /**
64
+ * Refresh-token configuration.
65
+ */
66
+ type RefreshTokenConfig = {
67
+ /**
68
+ * Override the persisted refresh-token model — extend {@link RefreshToken}.
69
+ * Defaults to the package's `RefreshToken`.
70
+ */
71
+ model?: typeof RefreshToken;
72
+ /**
73
+ * Enable refresh tokens.
74
+ * @default true
75
+ */
76
+ enabled?: boolean;
77
+ /**
78
+ * Separate secret for refresh tokens (recommended for security). Falls back
79
+ * to the access-token secret when omitted.
80
+ */
81
+ secret?: string;
82
+ /**
83
+ * Refresh-token lifetime — any value the `ms` package accepts.
84
+ * @example "7d" or "1w"
85
+ * @default "7d"
86
+ */
87
+ expiresIn?: string;
88
+ /**
89
+ * Rotate the refresh token on each use (old token revoked, replay detected).
90
+ * @default true
91
+ */
92
+ rotation?: boolean;
93
+ /**
94
+ * Maximum active refresh tokens per user; the oldest are revoked past it.
95
+ * @default 5
96
+ */
97
+ maxPerUser?: number;
98
+ /**
99
+ * Behavior when logout is called without a refresh token.
100
+ * @default "revoke-all"
101
+ */
102
+ logoutWithoutToken?: LogoutWithoutTokenBehavior;
103
+ };
104
+ /**
105
+ * Legacy JWT configuration shape. Still honored by the resolver shim with a
106
+ * deprecation warning.
107
+ *
108
+ * @deprecated Use the top-level `accessToken` / `refreshToken` blocks.
109
+ */
110
+ type LegacyJwtConfig = {
111
+ secret?: string;
112
+ algorithm?: Algorithm;
113
+ expiresIn?: string;
114
+ refresh?: {
115
+ secret?: string;
116
+ enabled?: boolean;
117
+ expiresIn?: string;
118
+ rotation?: boolean;
119
+ maxPerUser?: number;
120
+ logoutWithoutToken?: LogoutWithoutTokenBehavior;
121
+ };
122
+ };
32
123
  type AuthConfigurations = {
33
124
  /**
34
- * Define all user types
35
- * This is important to differentiate between user types when validating and generating tokens
125
+ * Define all user types — maps a user-type slug to its `Auth` model class so
126
+ * tokens and the middleware can resolve the right model.
36
127
  */
37
128
  userType: {
38
129
  [userType: string]: ChildModel<Auth>;
39
130
  };
40
131
  /**
41
- * JWT configurations
42
- */
43
- jwt: {
44
- /**
45
- * JWT secret key for signing access tokens
46
- */
47
- secret: string;
48
- /**
49
- * JWT algorithm
50
- * @default "HS256"
51
- */
52
- algorithm?: Algorithm;
53
- /**
54
- * Access token expiration time
55
- * It accepts any value `ms` package accepts
56
- * @example "1h" or NO_EXPIRATION
57
- * @default "1h"
58
- */
59
- expiresIn?: string;
60
- /**
61
- * Refresh token configurations
62
- */
63
- refresh?: {
64
- /**
65
- * Separate secret for refresh tokens (recommended for security)
66
- * If not provided, falls back to main JWT secret
67
- */
68
- secret?: string;
69
- /**
70
- * Enable refresh token
71
- * @default true
72
- */
73
- enabled?: boolean;
74
- /**
75
- * Refresh token expiration time
76
- * It accepts any value `ms` package accepts
77
- * @example "7d" or "1w"
78
- * @default "7d"
79
- */
80
- expiresIn?: string;
81
- /**
82
- * Enable token rotation (issue new refresh token on each use)
83
- * Old refresh token is invalidated after use
84
- * @default true
85
- */
86
- rotation?: boolean;
87
- /**
88
- * Maximum number of active refresh tokens per user
89
- * When exceeded, oldest tokens are revoked
90
- * @default 5
91
- */
92
- maxPerUser?: number;
93
- /**
94
- * Behavior when logout is called without a refresh token
95
- * - "revoke-all": Revoke all tokens for security (default)
96
- * - "error": Require refresh token, return error if missing
97
- * @default "revoke-all"
98
- */
99
- logoutWithoutToken?: LogoutWithoutTokenBehavior;
100
- };
101
- };
132
+ * Access-token configuration (secret, expiry, algorithm, model override).
133
+ */
134
+ accessToken?: AccessTokenConfig;
102
135
  /**
103
- * Password configurations
136
+ * Refresh-token configuration (rotation, lifetime, cap, model override).
104
137
  */
105
- password?: {
106
- /**
107
- * Password salt
108
- * The higher the salt, the more secure the password is
109
- * But, it will take more time to generate the password
110
- * @default 12
111
- */
112
- salt?: number;
113
- };
138
+ refreshToken?: RefreshTokenConfig;
139
+ /**
140
+ * @deprecated Use `accessToken` / `refreshToken`. Read via a backward-compatible shim.
141
+ */
142
+ jwt?: LegacyJwtConfig;
114
143
  };
115
144
  type AccessTokenOutput = {
116
145
  /**
@@ -166,5 +195,5 @@ type LoginResult<UserType extends Auth> = {
166
195
  tokens: TokenPair;
167
196
  };
168
197
  //#endregion
169
- export { AccessTokenOutput, AuthConfigurations, DeviceInfo, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, TokenPair };
198
+ export { AccessTokenConfig, AccessTokenOutput, AuthConfigurations, DeviceInfo, LegacyJwtConfig, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, RefreshTokenConfig, TokenPair };
170
199
  //# sourceMappingURL=types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../@warlock.js/auth/src/contracts/types.ts"],"mappings":";;;;;;;AAuBA;;;;AAA0B;AAO1B;;;;AAAsC;AAEtC;;;;;;;cATa,aAAA;;;;;;KAOD,0BAAA;AAAA,KAEA,kBAAA;EAoBR;;;;EAfF,QAAA;IAAA,CACG,QAAA,WAAmB,UAAA,CAAW,IAAA;EAAA;EAgD7B;;;EA3CJ,GAAA;IA8DA;;;IA1DE,MAAA;IAqEQ;;;;IAhER,SAAA,GAAY,SAAA;IA8EJ;;;;;;IAvER,SAAA;IA+Ea;;AAAiB;IA3E9B,OAAA;MAiFkB;;;;MA5EhB,MAAA;MAwFJ;;;;MAnFI,OAAA;MA4FY;AAGlB;;;;;MAxFM,SAAA;MA0Fa;;;;;MApFb,QAAA;MAoFJ;;;AAAiB;;MA9Eb,UAAA;;;;;;;MAOA,kBAAA,GAAqB,0BAAA;IAAA;EAAA;;;;EAMzB,QAAA;;;;;;;IAOE,IAAA;EAAA;AAAA;AAAA,KAIQ,iBAAA;;;;EAIV,KAAA;;;;EAIA,SAAS;AAAA;;;;KAMC,SAAA;;;;EAIV,WAAA,EAAa,iBAAA;;;;EAIb,YAAA,GAAe,iBAAiB;AAAA;;;;KAMtB,UAAA;;;;EAIV,SAAA;;;;EAIA,EAAA;;;;EAIA,QAAA;;;;;EAKA,QAAA;;;;EAIA,OAAA,GAAU,MAAM;AAAA;AAAA,KAGN,WAAA,kBAA6B,IAAA;EACvC,IAAA,EAAM,QAAA;EACN,MAAA,EAAQ,SAAA;AAAA"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../@warlock.js/auth/src/contracts/types.ts"],"mappings":";;;;;;;;;;;AAyBA;;;;AAA0B;AAO1B;;;;AAAsC;AAQtC;;;;;cAfa,aAAA;;;;;;KAOD,0BAAA;AAmCZ;;;;;;AAAA,KA3BY,iBAAA;EA0CV;;;;;EApCA,KAAA,UAAe,WAAA;EAyDgC;AAAA;AASjD;EA9DE,MAAA;;;;;EAKA,SAAA,GAAY,SAAS;EA4DrB;;;;;EAtDA,SAAA;AAAA;;;;KAMU,kBAAA;EA2DA;;;;EAtDV,KAAA,UAAe,YAAA;EAiED;;;;EA5Dd,OAAA;EAsDA;;;;EAjDA,MAAA;EAuDc;;;;;EAjDd,SAAA;EAyDqB;AAGvB;;;EAvDE,QAAA;EA+DS;AAMX;;;EAhEE,UAAA;EAoEA;;;;EA/DA,kBAAA,GAAqB,0BAA0B;AAAA;AAyEjD;;;;;;AAAA,KAhEY,eAAA;EACV,MAAA;EACA,SAAA,GAAY,SAAA;EACZ,SAAA;EACA,OAAA;IACE,MAAA;IACA,OAAA;IACA,SAAA;IACA,QAAA;IACA,UAAA;IACA,kBAAA,GAAqB,0BAA0B;EAAA;AAAA;AAAA,KAIvC,kBAAA;EA0EY;;;;EArEtB,QAAA;IAAA,CACG,QAAA,WAAmB,UAAA,CAAW,IAAA;EAAA;EAsEhB;;;EAjEjB,WAAA,GAAc,iBAAA;;;;EAId,YAAA,GAAe,kBAAA;;;;EAIf,GAAA,GAAM,eAAA;AAAA;AAAA,KAGI,iBAAA;;;;EAIV,KAAA;;;;EAIA,SAAS;AAAA;;;;KAMC,SAAA;;;;EAIV,WAAA,EAAa,iBAAA;;;;EAIb,YAAA,GAAe,iBAAiB;AAAA;;;;KAMtB,UAAA;;;;EAIV,SAAA;;;;EAIA,EAAA;;;;EAIA,QAAA;;;;;EAKA,QAAA;;;;EAIA,OAAA,GAAU,MAAM;AAAA;AAAA,KAGN,WAAA,kBAA6B,IAAA;EACvC,IAAA,EAAM,QAAA;EACN,MAAA,EAAQ,SAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- //#region ../../@warlock.js/auth/src/contracts/types.ts
1
+ //#region ../@warlock.js/auth/src/contracts/types.ts
2
2
  /**
3
3
  * Symbol to indicate no expiration for tokens
4
4
  * Use this when you explicitly want tokens to never expire
@@ -9,7 +9,7 @@
9
9
  * import { NO_EXPIRATION, type AuthConfigurations } from "@warlock.js/auth";
10
10
  *
11
11
  * const authConfigurations: AuthConfigurations = {
12
- * jwt: {
12
+ * accessToken: {
13
13
  * secret: env("JWT_SECRET"),
14
14
  * expiresIn: NO_EXPIRATION, // Token expires within 100 years
15
15
  * },
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","names":[],"sources":["../../../../../../@warlock.js/auth/src/contracts/types.ts"],"sourcesContent":["import { ChildModel } from \"@warlock.js/cascade\";\r\nimport { type Algorithm } from \"fast-jwt\";\r\nimport type { Auth } from \"../models/auth.model\";\r\n\r\n/**\r\n * Symbol to indicate no expiration for tokens\r\n * Use this when you explicitly want tokens to never expire\r\n *\r\n * @example\r\n * ```typescript\r\n * // src/config/auth.ts\r\n * import { NO_EXPIRATION, type AuthConfigurations } from \"@warlock.js/auth\";\r\n *\r\n * const authConfigurations: AuthConfigurations = {\r\n * jwt: {\r\n * secret: env(\"JWT_SECRET\"),\r\n * expiresIn: NO_EXPIRATION, // Token expires within 100 years\r\n * },\r\n * };\r\n *\r\n * export default authConfigurations;\r\n * ```\r\n */\r\nexport const NO_EXPIRATION = \"100y\";\r\n\r\n/**\r\n * Behavior when logout is called without a refresh token\r\n * - \"revoke-all\": Revoke all refresh tokens for the user (secure default)\r\n * - \"error\": Return an error requiring the refresh token\r\n */\r\nexport type LogoutWithoutTokenBehavior = \"revoke-all\" | \"error\";\r\n\r\nexport type AuthConfigurations = {\r\n /**\r\n * Define all user types\r\n * This is important to differentiate between user types when validating and generating tokens\r\n */\r\n userType: {\r\n [userType: string]: ChildModel<Auth>;\r\n };\r\n /**\r\n * JWT configurations\r\n */\r\n jwt: {\r\n /**\r\n * JWT secret key for signing access tokens\r\n */\r\n secret: string;\r\n /**\r\n * JWT algorithm\r\n * @default \"HS256\"\r\n */\r\n algorithm?: Algorithm;\r\n /**\r\n * Access token expiration time\r\n * It accepts any value `ms` package accepts\r\n * @example \"1h\" or NO_EXPIRATION\r\n * @default \"1h\"\r\n */\r\n expiresIn?: string;\r\n /**\r\n * Refresh token configurations\r\n */\r\n refresh?: {\r\n /**\r\n * Separate secret for refresh tokens (recommended for security)\r\n * If not provided, falls back to main JWT secret\r\n */\r\n secret?: string;\r\n /**\r\n * Enable refresh token\r\n * @default true\r\n */\r\n enabled?: boolean;\r\n /**\r\n * Refresh token expiration time\r\n * It accepts any value `ms` package accepts\r\n * @example \"7d\" or \"1w\"\r\n * @default \"7d\"\r\n */\r\n expiresIn?: string;\r\n /**\r\n * Enable token rotation (issue new refresh token on each use)\r\n * Old refresh token is invalidated after use\r\n * @default true\r\n */\r\n rotation?: boolean;\r\n /**\r\n * Maximum number of active refresh tokens per user\r\n * When exceeded, oldest tokens are revoked\r\n * @default 5\r\n */\r\n maxPerUser?: number;\r\n /**\r\n * Behavior when logout is called without a refresh token\r\n * - \"revoke-all\": Revoke all tokens for security (default)\r\n * - \"error\": Require refresh token, return error if missing\r\n * @default \"revoke-all\"\r\n */\r\n logoutWithoutToken?: LogoutWithoutTokenBehavior;\r\n };\r\n };\r\n /**\r\n * Password configurations\r\n */\r\n password?: {\r\n /**\r\n * Password salt\r\n * The higher the salt, the more secure the password is\r\n * But, it will take more time to generate the password\r\n * @default 12\r\n */\r\n salt?: number;\r\n };\r\n};\r\n\r\nexport type AccessTokenOutput = {\r\n /**\r\n * JWT Token\r\n */\r\n token: string;\r\n /**\r\n * Exprie time in ISO format UTC time\r\n */\r\n expiresAt: string;\r\n};\r\n\r\n/**\r\n * Token pair returned after login or token refresh\r\n */\r\nexport type TokenPair = {\r\n /**\r\n * JWT access token (short-lived)\r\n */\r\n accessToken: AccessTokenOutput;\r\n /**\r\n * JWT refresh token (long-lived)\r\n */\r\n refreshToken?: AccessTokenOutput;\r\n};\r\n\r\n/**\r\n * Device information for session tracking\r\n */\r\nexport type DeviceInfo = {\r\n /**\r\n * User agent string from request\r\n */\r\n userAgent?: string;\r\n /**\r\n * Client IP address\r\n */\r\n ip?: string;\r\n /**\r\n * Optional device identifier\r\n */\r\n deviceId?: string;\r\n /**\r\n * Token family ID (for rotation tracking)\r\n * @internal\r\n */\r\n familyId?: string;\r\n /**\r\n * Access token payload\r\n */\r\n payload?: Record<string, any>;\r\n};\r\n\r\nexport type LoginResult<UserType extends Auth> = {\r\n user: UserType;\r\n tokens: TokenPair;\r\n};\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,gBAAgB"}
1
+ {"version":3,"file":"types.mjs","names":[],"sources":["../../../../../../../@warlock.js/auth/src/contracts/types.ts"],"sourcesContent":["import { type ChildModel } from \"@warlock.js/cascade\";\nimport { type Algorithm } from \"fast-jwt\";\nimport type { AccessToken } from \"../models/access-token\";\nimport type { Auth } from \"../models/auth.model\";\nimport type { RefreshToken } from \"../models/refresh-token\";\n\n/**\n * Symbol to indicate no expiration for tokens\n * Use this when you explicitly want tokens to never expire\n *\n * @example\n * ```typescript\n * // src/config/auth.ts\n * import { NO_EXPIRATION, type AuthConfigurations } from \"@warlock.js/auth\";\n *\n * const authConfigurations: AuthConfigurations = {\n * accessToken: {\n * secret: env(\"JWT_SECRET\"),\n * expiresIn: NO_EXPIRATION, // Token expires within 100 years\n * },\n * };\n *\n * export default authConfigurations;\n * ```\n */\nexport const NO_EXPIRATION = \"100y\";\n\n/**\n * Behavior when logout is called without a refresh token\n * - \"revoke-all\": Revoke all refresh tokens for the user (secure default)\n * - \"error\": Return an error requiring the refresh token\n */\nexport type LogoutWithoutTokenBehavior = \"revoke-all\" | \"error\";\n\n/**\n * Access-token configuration.\n *\n * `secret` may also be supplied via the deprecated `jwt.secret` (resolved by a\n * backward-compatible shim); one of the two is required at runtime.\n */\nexport type AccessTokenConfig = {\n /**\n * Override the persisted access-token model — extend {@link AccessToken} to\n * add columns (e.g. a tenant key) or rename them, then register the subclass\n * here. Defaults to the package's `AccessToken`.\n */\n model?: typeof AccessToken;\n /**\n * Secret used to sign access tokens.\n */\n secret?: string;\n /**\n * JWT algorithm.\n * @default \"HS256\"\n */\n algorithm?: Algorithm;\n /**\n * Access-token lifetime any value the `ms` package accepts.\n * @example \"1h\" or NO_EXPIRATION\n * @default \"1h\"\n */\n expiresIn?: string;\n};\n\n/**\n * Refresh-token configuration.\n */\nexport type RefreshTokenConfig = {\n /**\n * Override the persisted refresh-token model extend {@link RefreshToken}.\n * Defaults to the package's `RefreshToken`.\n */\n model?: typeof RefreshToken;\n /**\n * Enable refresh tokens.\n * @default true\n */\n enabled?: boolean;\n /**\n * Separate secret for refresh tokens (recommended for security). Falls back\n * to the access-token secret when omitted.\n */\n secret?: string;\n /**\n * Refresh-token lifetime any value the `ms` package accepts.\n * @example \"7d\" or \"1w\"\n * @default \"7d\"\n */\n expiresIn?: string;\n /**\n * Rotate the refresh token on each use (old token revoked, replay detected).\n * @default true\n */\n rotation?: boolean;\n /**\n * Maximum active refresh tokens per user; the oldest are revoked past it.\n * @default 5\n */\n maxPerUser?: number;\n /**\n * Behavior when logout is called without a refresh token.\n * @default \"revoke-all\"\n */\n logoutWithoutToken?: LogoutWithoutTokenBehavior;\n};\n\n/**\n * Legacy JWT configuration shape. Still honored by the resolver shim with a\n * deprecation warning.\n *\n * @deprecated Use the top-level `accessToken` / `refreshToken` blocks.\n */\nexport type LegacyJwtConfig = {\n secret?: string;\n algorithm?: Algorithm;\n expiresIn?: string;\n refresh?: {\n secret?: string;\n enabled?: boolean;\n expiresIn?: string;\n rotation?: boolean;\n maxPerUser?: number;\n logoutWithoutToken?: LogoutWithoutTokenBehavior;\n };\n};\n\nexport type AuthConfigurations = {\n /**\n * Define all user types — maps a user-type slug to its `Auth` model class so\n * tokens and the middleware can resolve the right model.\n */\n userType: {\n [userType: string]: ChildModel<Auth>;\n };\n /**\n * Access-token configuration (secret, expiry, algorithm, model override).\n */\n accessToken?: AccessTokenConfig;\n /**\n * Refresh-token configuration (rotation, lifetime, cap, model override).\n */\n refreshToken?: RefreshTokenConfig;\n /**\n * @deprecated Use `accessToken` / `refreshToken`. Read via a backward-compatible shim.\n */\n jwt?: LegacyJwtConfig;\n};\n\nexport type AccessTokenOutput = {\n /**\n * JWT Token\n */\n token: string;\n /**\n * Exprie time in ISO format UTC time\n */\n expiresAt: string;\n};\n\n/**\n * Token pair returned after login or token refresh\n */\nexport type TokenPair = {\n /**\n * JWT access token (short-lived)\n */\n accessToken: AccessTokenOutput;\n /**\n * JWT refresh token (long-lived)\n */\n refreshToken?: AccessTokenOutput;\n};\n\n/**\n * Device information for session tracking\n */\nexport type DeviceInfo = {\n /**\n * User agent string from request\n */\n userAgent?: string;\n /**\n * Client IP address\n */\n ip?: string;\n /**\n * Optional device identifier\n */\n deviceId?: string;\n /**\n * Token family ID (for rotation tracking)\n * @internal\n */\n familyId?: string;\n /**\n * Access token payload\n */\n payload?: Record<string, any>;\n};\n\nexport type LoginResult<UserType extends Auth> = {\n user: UserType;\n tokens: TokenPair;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,gBAAgB"}
package/esm/index.d.mts CHANGED
@@ -1,15 +1,16 @@
1
1
  import { registerAuthCleanupCommand } from "./commands/auth-cleanup-command.mjs";
2
2
  import { registerJWTSecretGeneratorCommand } from "./commands/jwt-secret-generator-command.mjs";
3
- import { RefreshToken } from "./models/refresh-token/refresh-token.model.mjs";
4
3
  import { Auth } from "./models/auth.model.mjs";
5
- import { AccessTokenOutput, AuthConfigurations, DeviceInfo, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, TokenPair } from "./contracts/types.mjs";
4
+ import { AccessToken, accessTokenSchema } from "./models/access-token/access-token.model.mjs";
5
+ import { AccessTokenConfig, AccessTokenOutput, AuthConfigurations, DeviceInfo, LegacyJwtConfig, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, RefreshTokenConfig, TokenPair } from "./contracts/types.mjs";
6
+ import { RefreshToken, RefreshTokenIssueOptions, refreshTokenSchema } from "./models/refresh-token/refresh-token.model.mjs";
6
7
  import { Authenticable } from "./contracts/auth-contract.mjs";
7
8
  import { authMiddleware } from "./middleware/auth.middleware.mjs";
8
- import { AccessToken } from "./models/access-token/access-token.model.mjs";
9
+ import { LoginThrottleIdentifier, LoginThrottleOptions, loginThrottleMiddleware } from "./middleware/login-throttle.middleware.mjs";
9
10
  import { authMigrations } from "./models/index.mjs";
10
11
  import { AuthEventCallback, AuthEventName, AuthEventPayloads, authEvents } from "./services/auth-events.mjs";
11
12
  import { authService } from "./services/auth.service.mjs";
12
13
  import { generateJWTSecret } from "./services/generate-jwt-secret.mjs";
13
- import { jwt } from "./services/jwt.mjs";
14
+ import { TokenType, jwt } from "./services/jwt.mjs";
14
15
  import { AuthErrorCodes } from "./utils/auth-error-codes.mjs";
15
- export { AccessToken, AccessTokenOutput, Auth, AuthConfigurations, AuthErrorCodes, AuthEventCallback, AuthEventName, AuthEventPayloads, Authenticable, DeviceInfo, LoginResult, LogoutWithoutTokenBehavior, NO_EXPIRATION, RefreshToken, TokenPair, authEvents, authMiddleware, authMigrations, authService, generateJWTSecret, jwt, registerAuthCleanupCommand, registerJWTSecretGeneratorCommand };
16
+ export { AccessToken, AccessTokenConfig, AccessTokenOutput, Auth, AuthConfigurations, AuthErrorCodes, AuthEventCallback, AuthEventName, AuthEventPayloads, Authenticable, DeviceInfo, LegacyJwtConfig, LoginResult, LoginThrottleIdentifier, LoginThrottleOptions, LogoutWithoutTokenBehavior, NO_EXPIRATION, RefreshToken, RefreshTokenConfig, RefreshTokenIssueOptions, TokenPair, TokenType, accessTokenSchema, authEvents, authMiddleware, authMigrations, authService, generateJWTSecret, jwt, loginThrottleMiddleware, refreshTokenSchema, registerAuthCleanupCommand, registerJWTSecretGeneratorCommand };
package/esm/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { AccessToken } from "./models/access-token/access-token.model.mjs";
2
- import { RefreshToken } from "./models/refresh-token/refresh-token.model.mjs";
1
+ import { AccessToken, accessTokenSchema } from "./models/access-token/access-token.model.mjs";
2
+ import { RefreshToken, refreshTokenSchema } from "./models/refresh-token/refresh-token.model.mjs";
3
3
  import { authEvents } from "./services/auth-events.mjs";
4
4
  import { jwt } from "./services/jwt.mjs";
5
5
  import { authService } from "./services/auth.service.mjs";
@@ -9,9 +9,10 @@ import { registerJWTSecretGeneratorCommand } from "./commands/jwt-secret-generat
9
9
  import { NO_EXPIRATION } from "./contracts/types.mjs";
10
10
  import { AuthErrorCodes } from "./utils/auth-error-codes.mjs";
11
11
  import { authMiddleware } from "./middleware/auth.middleware.mjs";
12
+ import { loginThrottleMiddleware } from "./middleware/login-throttle.middleware.mjs";
12
13
  import "./middleware/index.mjs";
13
14
  import "./services/index.mjs";
14
15
  import { Auth } from "./models/auth.model.mjs";
15
16
  import { authMigrations } from "./models/index.mjs";
16
17
 
17
- export { AccessToken, Auth, AuthErrorCodes, NO_EXPIRATION, RefreshToken, authEvents, authMiddleware, authMigrations, authService, generateJWTSecret, jwt, registerAuthCleanupCommand, registerJWTSecretGeneratorCommand };
18
+ export { AccessToken, Auth, AuthErrorCodes, NO_EXPIRATION, RefreshToken, accessTokenSchema, authEvents, authMiddleware, authMigrations, authService, generateJWTSecret, jwt, loginThrottleMiddleware, refreshTokenSchema, registerAuthCleanupCommand, registerJWTSecretGeneratorCommand };
@@ -1,4 +1,4 @@
1
- //#region ../../@warlock.js/auth/src/middleware/auth.middleware.d.ts
1
+ //#region ../@warlock.js/auth/src/middleware/auth.middleware.d.ts
2
2
  /**
3
3
  * Build a route gate that always requires an authenticated request.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"auth.middleware.d.mts","names":[],"sources":["../../../../../../@warlock.js/auth/src/middleware/auth.middleware.ts"],"mappings":";;AAuBA;;;;AAAiE;;;;;;;;;;;;iBAAjD,cAAA,CAAe,eAAA,sBAAkC,UAAA"}
1
+ {"version":3,"file":"auth.middleware.d.mts","names":[],"sources":["../../../../../../../@warlock.js/auth/src/middleware/auth.middleware.ts"],"mappings":";;AAgCA;;;;AAAiE;;;;;;;;;;;;iBAAjD,cAAA,CAAe,eAAA,sBAAkC,UAAA"}