@nik2208/node-auth 1.1.0 → 1.1.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 (51) hide show
  1. package/dist/index.d.ts +8 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +3 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/interfaces/roles-permissions-store.interface.d.ts +82 -0
  6. package/dist/interfaces/roles-permissions-store.interface.d.ts.map +1 -0
  7. package/dist/interfaces/roles-permissions-store.interface.js +3 -0
  8. package/dist/interfaces/roles-permissions-store.interface.js.map +1 -0
  9. package/dist/interfaces/session-store.interface.d.ts +82 -0
  10. package/dist/interfaces/session-store.interface.d.ts.map +1 -0
  11. package/dist/interfaces/session-store.interface.js +3 -0
  12. package/dist/interfaces/session-store.interface.js.map +1 -0
  13. package/dist/interfaces/tenant-store.interface.d.ts +97 -0
  14. package/dist/interfaces/tenant-store.interface.d.ts.map +1 -0
  15. package/dist/interfaces/tenant-store.interface.js +3 -0
  16. package/dist/interfaces/tenant-store.interface.js.map +1 -0
  17. package/dist/interfaces/user-metadata-store.interface.d.ts +50 -0
  18. package/dist/interfaces/user-metadata-store.interface.d.ts.map +1 -0
  19. package/dist/interfaces/user-metadata-store.interface.js +3 -0
  20. package/dist/interfaces/user-metadata-store.interface.js.map +1 -0
  21. package/dist/interfaces/user-store.interface.d.ts +41 -0
  22. package/dist/interfaces/user-store.interface.d.ts.map +1 -1
  23. package/dist/models/auth-config.model.d.ts +29 -0
  24. package/dist/models/auth-config.model.d.ts.map +1 -1
  25. package/dist/models/session.model.d.ts +28 -0
  26. package/dist/models/session.model.d.ts.map +1 -0
  27. package/dist/models/session.model.js +3 -0
  28. package/dist/models/session.model.js.map +1 -0
  29. package/dist/models/tenant.model.d.ts +20 -0
  30. package/dist/models/tenant.model.d.ts.map +1 -0
  31. package/dist/models/tenant.model.js +3 -0
  32. package/dist/models/tenant.model.js.map +1 -0
  33. package/dist/models/token.model.d.ts +2 -0
  34. package/dist/models/token.model.d.ts.map +1 -1
  35. package/dist/models/user.model.d.ts +12 -0
  36. package/dist/models/user.model.d.ts.map +1 -1
  37. package/dist/router/admin.router.d.ts +21 -0
  38. package/dist/router/admin.router.d.ts.map +1 -0
  39. package/dist/router/admin.router.js +627 -0
  40. package/dist/router/admin.router.js.map +1 -0
  41. package/dist/router/auth.router.d.ts.map +1 -1
  42. package/dist/router/auth.router.js +180 -8
  43. package/dist/router/auth.router.js.map +1 -1
  44. package/dist/services/mailer.service.d.ts +2 -0
  45. package/dist/services/mailer.service.d.ts.map +1 -1
  46. package/dist/services/mailer.service.js +46 -0
  47. package/dist/services/mailer.service.js.map +1 -1
  48. package/dist/services/token.service.d.ts.map +1 -1
  49. package/dist/services/token.service.js +4 -3
  50. package/dist/services/token.service.js.map +1 -1
  51. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -2,9 +2,15 @@ export { AuthConfigurator } from './auth-configurator';
2
2
  export type { IUserStore } from './interfaces/user-store.interface';
3
3
  export type { ITokenStore } from './interfaces/token-store.interface';
4
4
  export type { IAuthStrategy } from './interfaces/auth-strategy.interface';
5
+ export type { IUserMetadataStore } from './interfaces/user-metadata-store.interface';
6
+ export type { IRolesPermissionsStore } from './interfaces/roles-permissions-store.interface';
7
+ export type { ISessionStore } from './interfaces/session-store.interface';
8
+ export type { ITenantStore } from './interfaces/tenant-store.interface';
5
9
  export type { BaseUser } from './models/user.model';
6
10
  export type { TokenPair, AccessTokenPayload } from './models/token.model';
7
11
  export type { AuthConfig } from './models/auth-config.model';
12
+ export type { SessionInfo } from './models/session.model';
13
+ export type { Tenant } from './models/tenant.model';
8
14
  export { AuthError } from './models/errors';
9
15
  export { BaseAuthStrategy } from './abstract/base-auth-strategy.abstract';
10
16
  export { BaseOAuthStrategy } from './abstract/base-oauth-strategy.abstract';
@@ -22,4 +28,6 @@ export type { MailerConfig } from './models/auth-config.model';
22
28
  export { createAuthMiddleware } from './middleware/auth.middleware';
23
29
  export { createAuthRouter } from './router/auth.router';
24
30
  export type { RouterOptions } from './router/auth.router';
31
+ export { createAdminRouter } from './router/admin.router';
32
+ export type { AdminOptions } from './router/admin.router';
25
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,YAAY,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAE1E,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,YAAY,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,YAAY,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AACrF,YAAY,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AAC7F,YAAY,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAExE,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createAuthRouter = exports.createAuthMiddleware = exports.MailerService = exports.SmsService = exports.PasswordService = exports.TokenService = exports.TotpStrategy = exports.SmsStrategy = exports.MagicLinkStrategy = exports.GithubStrategy = exports.GoogleStrategy = exports.LocalStrategy = exports.BaseOAuthStrategy = exports.BaseAuthStrategy = exports.AuthError = exports.AuthConfigurator = void 0;
3
+ exports.createAdminRouter = exports.createAuthRouter = exports.createAuthMiddleware = exports.MailerService = exports.SmsService = exports.PasswordService = exports.TokenService = exports.TotpStrategy = exports.SmsStrategy = exports.MagicLinkStrategy = exports.GithubStrategy = exports.GoogleStrategy = exports.LocalStrategy = exports.BaseOAuthStrategy = exports.BaseAuthStrategy = exports.AuthError = exports.AuthConfigurator = void 0;
4
4
  var auth_configurator_1 = require("./auth-configurator");
5
5
  Object.defineProperty(exports, "AuthConfigurator", { enumerable: true, get: function () { return auth_configurator_1.AuthConfigurator; } });
6
6
  var errors_1 = require("./models/errors");
@@ -33,4 +33,6 @@ var auth_middleware_1 = require("./middleware/auth.middleware");
33
33
  Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return auth_middleware_1.createAuthMiddleware; } });
34
34
  var auth_router_1 = require("./router/auth.router");
35
35
  Object.defineProperty(exports, "createAuthRouter", { enumerable: true, get: function () { return auth_router_1.createAuthRouter; } });
36
+ var admin_router_1 = require("./router/admin.router");
37
+ Object.defineProperty(exports, "createAdminRouter", { enumerable: true, get: function () { return admin_router_1.createAdminRouter; } });
36
38
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AASzB,0CAA4C;AAAnC,mGAAA,SAAS,OAAA;AAElB,sFAA0E;AAAjE,+HAAA,gBAAgB,OAAA;AACzB,wFAA4E;AAAnE,iIAAA,iBAAiB,OAAA;AAE1B,oEAAkE;AAAzD,+GAAA,aAAa,OAAA;AACtB,sEAAoE;AAA3D,iHAAA,cAAc,OAAA;AACvB,sEAAoE;AAA3D,iHAAA,cAAc,OAAA;AACvB,mFAAgF;AAAvE,wHAAA,iBAAiB,OAAA;AAC1B,8DAA4D;AAAnD,2GAAA,WAAW,OAAA;AACpB,uEAAqE;AAA5D,6GAAA,YAAY,OAAA;AAErB,0DAAwD;AAA/C,6GAAA,YAAY,OAAA;AACrB,gEAA8D;AAArD,mHAAA,eAAe,OAAA;AACxB,sDAAoD;AAA3C,yGAAA,UAAU,OAAA;AACnB,4DAA0D;AAAjD,+GAAA,aAAa,OAAA;AAGtB,gEAAoE;AAA3D,uHAAA,oBAAoB,OAAA;AAC7B,oDAAwD;AAA/C,+GAAA,gBAAgB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AAezB,0CAA4C;AAAnC,mGAAA,SAAS,OAAA;AAElB,sFAA0E;AAAjE,+HAAA,gBAAgB,OAAA;AACzB,wFAA4E;AAAnE,iIAAA,iBAAiB,OAAA;AAE1B,oEAAkE;AAAzD,+GAAA,aAAa,OAAA;AACtB,sEAAoE;AAA3D,iHAAA,cAAc,OAAA;AACvB,sEAAoE;AAA3D,iHAAA,cAAc,OAAA;AACvB,mFAAgF;AAAvE,wHAAA,iBAAiB,OAAA;AAC1B,8DAA4D;AAAnD,2GAAA,WAAW,OAAA;AACpB,uEAAqE;AAA5D,6GAAA,YAAY,OAAA;AAErB,0DAAwD;AAA/C,6GAAA,YAAY,OAAA;AACrB,gEAA8D;AAArD,mHAAA,eAAe,OAAA;AACxB,sDAAoD;AAA3C,yGAAA,UAAU,OAAA;AACnB,4DAA0D;AAAjD,+GAAA,aAAa,OAAA;AAGtB,gEAAoE;AAA3D,uHAAA,oBAAoB,OAAA;AAC7B,oDAAwD;AAA/C,+GAAA,gBAAgB,OAAA;AAEzB,sDAA0D;AAAjD,iHAAA,iBAAiB,OAAA"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Optional store for role-based access control (RBAC).
3
+ *
4
+ * Implement this interface to assign roles to users, attach fine-grained
5
+ * permissions to roles, and perform permission checks. All tenant-aware
6
+ * methods accept an optional `tenantId` parameter so the same interface
7
+ * works for both single-tenant and multi-tenant applications.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { IRolesPermissionsStore } from 'node-auth';
12
+ *
13
+ * export class MyRbacStore implements IRolesPermissionsStore {
14
+ * async addRoleToUser(userId, role, tenantId?) { ... }
15
+ * async removeRoleFromUser(userId, role, tenantId?) { ... }
16
+ * async getRolesForUser(userId, tenantId?) { ... }
17
+ * async createRole(role, permissions?) { ... }
18
+ * async deleteRole(role) { ... }
19
+ * async addPermissionToRole(role, permission) { ... }
20
+ * async removePermissionFromRole(role, permission) { ... }
21
+ * async getPermissionsForRole(role) { ... }
22
+ * async getPermissionsForUser(userId, tenantId?) { ... }
23
+ * async userHasPermission(userId, permission, tenantId?) { ... }
24
+ * }
25
+ * ```
26
+ */
27
+ export interface IRolesPermissionsStore {
28
+ /**
29
+ * Assign `role` to the given user.
30
+ * When `tenantId` is provided the assignment is scoped to that tenant.
31
+ */
32
+ addRoleToUser(userId: string, role: string, tenantId?: string): Promise<void>;
33
+ /**
34
+ * Remove `role` from the given user.
35
+ * When `tenantId` is provided only the tenant-scoped assignment is removed.
36
+ */
37
+ removeRoleFromUser(userId: string, role: string, tenantId?: string): Promise<void>;
38
+ /**
39
+ * Return the list of roles assigned to the given user.
40
+ * When `tenantId` is provided only roles scoped to that tenant are returned.
41
+ */
42
+ getRolesForUser(userId: string, tenantId?: string): Promise<string[]>;
43
+ /**
44
+ * Create a new role, optionally pre-loading it with a set of permissions.
45
+ * Idempotent — calling it on an existing role should not throw.
46
+ */
47
+ createRole(role: string, permissions?: string[]): Promise<void>;
48
+ /**
49
+ * Delete a role and all its permission assignments.
50
+ * User ↔ role assignments for this role should also be removed.
51
+ */
52
+ deleteRole(role: string): Promise<void>;
53
+ /**
54
+ * Add `permission` to `role`.
55
+ * Idempotent — adding an already-assigned permission should not throw.
56
+ */
57
+ addPermissionToRole(role: string, permission: string): Promise<void>;
58
+ /**
59
+ * Remove `permission` from `role`.
60
+ */
61
+ removePermissionFromRole(role: string, permission: string): Promise<void>;
62
+ /**
63
+ * Return all permissions assigned to `role`.
64
+ */
65
+ getPermissionsForRole(role: string): Promise<string[]>;
66
+ /**
67
+ * Return all permissions the user has, aggregated across all their roles.
68
+ * When `tenantId` is provided only roles scoped to that tenant are considered.
69
+ */
70
+ getPermissionsForUser(userId: string, tenantId?: string): Promise<string[]>;
71
+ /**
72
+ * Check whether the user has a specific permission (across any of their roles).
73
+ * When `tenantId` is provided only roles scoped to that tenant are checked.
74
+ */
75
+ userHasPermission(userId: string, permission: string, tenantId?: string): Promise<boolean>;
76
+ /**
77
+ * Return all role names defined in the store.
78
+ * Used by the optional admin router to display the roles & permissions table.
79
+ */
80
+ getAllRoles?(): Promise<string[]>;
81
+ }
82
+ //# sourceMappingURL=roles-permissions-store.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles-permissions-store.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/roles-permissions-store.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,sBAAsB;IAKrC;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAMtE;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAMxC;;;OAGG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE;;OAEG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E;;OAEG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAMvD;;;OAGG;IACH,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5E;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3F;;;OAGG;IACH,WAAW,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACnC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=roles-permissions-store.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles-permissions-store.interface.js","sourceRoot":"","sources":["../../src/interfaces/roles-permissions-store.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,82 @@
1
+ import { SessionInfo } from '../models/session.model';
2
+ /**
3
+ * Optional store for device-aware session management.
4
+ *
5
+ * Implement this interface when you need to give users visibility into
6
+ * (and control over) their active sessions — similar to "Manage devices"
7
+ * screens in modern applications.
8
+ *
9
+ * Each session is identified by an opaque `sessionHandle` (e.g. a UUID or a
10
+ * hex token) that is independent of the JWT. This lets you list, inspect,
11
+ * and revoke individual sessions without invalidating all tokens at once.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { ISessionStore } from 'node-auth';
16
+ *
17
+ * export class MySessionStore implements ISessionStore {
18
+ * async createSession(info) {
19
+ * const handle = crypto.randomUUID();
20
+ * await db('sessions').insert({ handle, ...info });
21
+ * return { sessionHandle: handle, ...info };
22
+ * }
23
+ * async getSession(handle) {
24
+ * return db('sessions').where({ handle }).first() ?? null;
25
+ * }
26
+ * async getSessionsForUser(userId) {
27
+ * return db('sessions').where({ userId });
28
+ * }
29
+ * async updateSessionLastActive(handle) {
30
+ * await db('sessions').where({ handle }).update({ lastActiveAt: new Date() });
31
+ * }
32
+ * async revokeSession(handle) {
33
+ * await db('sessions').where({ handle }).delete();
34
+ * }
35
+ * async revokeAllSessionsForUser(userId) {
36
+ * await db('sessions').where({ userId }).delete();
37
+ * }
38
+ * }
39
+ * ```
40
+ */
41
+ export interface ISessionStore {
42
+ /**
43
+ * Persist a new session and return it with the generated `sessionHandle`.
44
+ */
45
+ createSession(info: Omit<SessionInfo, 'sessionHandle'>): Promise<SessionInfo>;
46
+ /**
47
+ * Retrieve a session by its handle.
48
+ * Returns `null` when the session does not exist or has expired.
49
+ */
50
+ getSession(sessionHandle: string): Promise<SessionInfo | null>;
51
+ /**
52
+ * Return all active sessions for the given user.
53
+ * When `tenantId` is provided only sessions belonging to that tenant are
54
+ * returned.
55
+ */
56
+ getSessionsForUser(userId: string, tenantId?: string): Promise<SessionInfo[]>;
57
+ /**
58
+ * Bump the `lastActiveAt` timestamp for the given session.
59
+ * Call this on every authenticated request to keep session activity up to date.
60
+ */
61
+ updateSessionLastActive(sessionHandle: string): Promise<void>;
62
+ /**
63
+ * Invalidate (delete) a single session.
64
+ * The associated JWT will still be technically valid until it expires, so
65
+ * you should also call `tokenService.clearTokenCookies()` on the response.
66
+ */
67
+ revokeSession(sessionHandle: string): Promise<void>;
68
+ /**
69
+ * Invalidate all sessions for the given user (e.g. "log out everywhere").
70
+ * When `tenantId` is provided only sessions for that tenant are revoked.
71
+ */
72
+ revokeAllSessionsForUser(userId: string, tenantId?: string): Promise<void>;
73
+ /**
74
+ * Return all active sessions across all users.
75
+ * Used by the optional admin router to display the sessions table.
76
+ *
77
+ * @param limit Maximum number of records to return.
78
+ * @param offset Zero-based offset for pagination.
79
+ */
80
+ getAllSessions?(limit: number, offset: number): Promise<SessionInfo[]>;
81
+ }
82
+ //# sourceMappingURL=session-store.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/session-store.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,aAAa,CACX,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,GACvC,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB;;;OAGG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE/D;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAE9E;;;OAGG;IACH,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;;;OAIG;IACH,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD;;;OAGG;IACH,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,cAAc,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CACxE"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=session-store.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.interface.js","sourceRoot":"","sources":["../../src/interfaces/session-store.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ import { Tenant } from '../models/tenant.model';
2
+ /**
3
+ * Optional store for multi-tenant applications.
4
+ *
5
+ * Implement this interface when your application serves multiple independent
6
+ * tenants (organisations, workspaces, teams, etc.) and you need to isolate
7
+ * users, data, and configuration per tenant.
8
+ *
9
+ * The interface covers three concerns:
10
+ * 1. **Tenant CRUD** — create, read, update and delete tenants.
11
+ * 2. **User ↔ Tenant association** — which users belong to which tenant.
12
+ * 3. **Per-tenant auth config** — optional overrides such as allowed auth
13
+ * methods, custom OAuth clients, or token lifetimes per tenant.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { ITenantStore } from 'node-auth';
18
+ *
19
+ * export class MyTenantStore implements ITenantStore {
20
+ * async createTenant(data) {
21
+ * const id = slugify(data.name);
22
+ * await db('tenants').insert({ id, ...data });
23
+ * return { id, ...data };
24
+ * }
25
+ * async getTenantById(id) {
26
+ * return db('tenants').where({ id }).first() ?? null;
27
+ * }
28
+ * async getAllTenants() {
29
+ * return db('tenants').select();
30
+ * }
31
+ * async updateTenant(id, data) {
32
+ * await db('tenants').where({ id }).update(data);
33
+ * }
34
+ * async deleteTenant(id) {
35
+ * await db('tenants').where({ id }).delete();
36
+ * }
37
+ * async associateUserWithTenant(userId, tenantId) {
38
+ * await db('tenant_users').insert({ userId, tenantId });
39
+ * }
40
+ * async disassociateUserFromTenant(userId, tenantId) {
41
+ * await db('tenant_users').where({ userId, tenantId }).delete();
42
+ * }
43
+ * async getTenantsForUser(userId) {
44
+ * return db('tenant_users').join('tenants', ...).where({ userId });
45
+ * }
46
+ * async getUsersForTenant(tenantId) {
47
+ * return db('tenant_users').where({ tenantId }).pluck('userId');
48
+ * }
49
+ * }
50
+ * ```
51
+ */
52
+ export interface ITenantStore {
53
+ /**
54
+ * Create a new tenant. The `id` is generated by the implementation
55
+ * (e.g. a UUID or a URL-safe slug derived from `name`).
56
+ */
57
+ createTenant(data: Omit<Tenant, 'id'>): Promise<Tenant>;
58
+ /**
59
+ * Fetch a tenant by its unique identifier.
60
+ * Returns `null` when no tenant with that ID exists.
61
+ */
62
+ getTenantById(id: string): Promise<Tenant | null>;
63
+ /**
64
+ * Return all tenants. For large deployments consider adding pagination
65
+ * in your own implementation.
66
+ */
67
+ getAllTenants(): Promise<Tenant[]>;
68
+ /**
69
+ * Partially update a tenant's fields.
70
+ * Only the fields present in `data` are changed.
71
+ */
72
+ updateTenant(id: string, data: Partial<Omit<Tenant, 'id'>>): Promise<void>;
73
+ /**
74
+ * Permanently delete a tenant and all its associated data.
75
+ * This should also remove all user ↔ tenant associations for the tenant.
76
+ */
77
+ deleteTenant(id: string): Promise<void>;
78
+ /**
79
+ * Add `userId` as a member of `tenantId`.
80
+ * Idempotent — calling it when the association already exists should not throw.
81
+ */
82
+ associateUserWithTenant(userId: string, tenantId: string): Promise<void>;
83
+ /**
84
+ * Remove `userId` from `tenantId`.
85
+ * No-op when the association does not exist.
86
+ */
87
+ disassociateUserFromTenant(userId: string, tenantId: string): Promise<void>;
88
+ /**
89
+ * Return all tenants the given user belongs to.
90
+ */
91
+ getTenantsForUser(userId: string): Promise<Tenant[]>;
92
+ /**
93
+ * Return the IDs of all users that belong to the given tenant.
94
+ */
95
+ getUsersForTenant(tenantId: string): Promise<string[]>;
96
+ }
97
+ //# sourceMappingURL=tenant-store.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-store.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/tenant-store.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,WAAW,YAAY;IAK3B;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExD;;;OAGG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAElD;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEnC;;;OAGG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3E;;;OAGG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAMxC;;;OAGG;IACH,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;OAGG;IACH,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5E;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAErD;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACxD"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=tenant-store.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-store.interface.js","sourceRoot":"","sources":["../../src/interfaces/tenant-store.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Optional store for arbitrary per-user metadata.
3
+ *
4
+ * Implement this interface when you need to attach project-specific data to
5
+ * users without extending `BaseUser` (e.g. preferences, profile fields,
6
+ * feature flags, or any other key/value pairs).
7
+ *
8
+ * The interface is intentionally generic — your database schema can store
9
+ * metadata as a JSON column, a separate key-value table, or any other way
10
+ * that suits your project.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { IUserMetadataStore } from 'node-auth';
15
+ *
16
+ * export class MyUserMetadataStore implements IUserMetadataStore {
17
+ * async getMetadata(userId: string) {
18
+ * const row = await db.from('user_metadata').where({ userId }).first();
19
+ * return row?.data ?? {};
20
+ * }
21
+ * async updateMetadata(userId: string, metadata: Record<string, unknown>) {
22
+ * await db('user_metadata')
23
+ * .insert({ userId, data: JSON.stringify(metadata) })
24
+ * .onConflict('userId')
25
+ * .merge();
26
+ * }
27
+ * async clearMetadata(userId: string) {
28
+ * await db('user_metadata').where({ userId }).delete();
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ export interface IUserMetadataStore {
34
+ /**
35
+ * Retrieve all metadata for the given user.
36
+ * Returns an empty object when no metadata exists.
37
+ */
38
+ getMetadata(userId: string): Promise<Record<string, unknown>>;
39
+ /**
40
+ * Merge (shallow-patch) the provided key/value pairs into the user's
41
+ * existing metadata. Fields not present in `metadata` are left untouched.
42
+ */
43
+ updateMetadata(userId: string, metadata: Record<string, unknown>): Promise<void>;
44
+ /**
45
+ * Delete all metadata for the given user.
46
+ * Useful when a user account is deleted.
47
+ */
48
+ clearMetadata(userId: string): Promise<void>;
49
+ }
50
+ //# sourceMappingURL=user-metadata-store.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-metadata-store.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/user-metadata-store.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAE9D;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=user-metadata-store.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-metadata-store.interface.js","sourceRoot":"","sources":["../../src/interfaces/user-metadata-store.interface.ts"],"names":[],"mappings":""}
@@ -19,5 +19,46 @@ export interface IUserStore<U extends BaseUser = BaseUser> {
19
19
  * Required to support the POST /auth/magic-link/verify endpoint.
20
20
  */
21
21
  findByMagicLinkToken?(token: string): Promise<U | null>;
22
+ /**
23
+ * Set (or clear) the email-verification token and its expiry.
24
+ * Required to support POST /auth/send-verification-email and GET /auth/verify-email.
25
+ */
26
+ updateEmailVerificationToken?(userId: string, token: string | null, expiry: Date | null): Promise<void>;
27
+ /**
28
+ * Mark the user's primary email as verified (or unverified).
29
+ * Required to support GET /auth/verify-email.
30
+ */
31
+ updateEmailVerified?(userId: string, isVerified: boolean): Promise<void>;
32
+ /**
33
+ * Find a user by their email-verification token.
34
+ * Required to support GET /auth/verify-email.
35
+ */
36
+ findByEmailVerificationToken?(token: string): Promise<U | null>;
37
+ /**
38
+ * Store the pending new email address together with a confirmation token
39
+ * and expiry. Set all three to `null` to cancel an in-progress change.
40
+ * Required to support POST /auth/change-email/request and
41
+ * POST /auth/change-email/confirm.
42
+ */
43
+ updateEmailChangeToken?(userId: string, pendingEmail: string | null, token: string | null, expiry: Date | null): Promise<void>;
44
+ /**
45
+ * Commit the pending email change: overwrite the user's primary email with
46
+ * `newEmail` and clear the change-token fields.
47
+ * Required to support POST /auth/change-email/confirm.
48
+ */
49
+ updateEmail?(userId: string, newEmail: string): Promise<void>;
50
+ /**
51
+ * Find a user by their email-change confirmation token.
52
+ * Required to support POST /auth/change-email/confirm.
53
+ */
54
+ findByEmailChangeToken?(token: string): Promise<U | null>;
55
+ /**
56
+ * Return a paginated list of users.
57
+ * Used by the optional admin router to display the users table.
58
+ *
59
+ * @param limit Maximum number of records to return.
60
+ * @param offset Zero-based offset for pagination.
61
+ */
62
+ listUsers?(limit: number, offset: number): Promise<U[]>;
22
63
  }
23
64
  //# sourceMappingURL=user-store.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-store.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/user-store.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IACvD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrC,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3F,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvF;;;OAGG;IACH,gBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpD;;;OAGG;IACH,oBAAoB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACzD"}
1
+ {"version":3,"file":"user-store.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/user-store.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IACvD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACrC,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3F,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvF;;;OAGG;IACH,gBAAgB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEpD;;;OAGG;IACH,oBAAoB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAIxD;;;OAGG;IACH,4BAA4B,CAAC,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,MAAM,EAAE,IAAI,GAAG,IAAI,GAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;OAGG;IACH,mBAAmB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;OAGG;IACH,4BAA4B,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAIhE;;;;;OAKG;IACH,sBAAsB,CAAC,CACrB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,MAAM,EAAE,IAAI,GAAG,IAAI,GAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,WAAW,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;;OAGG;IACH,sBAAsB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAI1D;;;;;;OAMG;IACH,SAAS,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACzD"}
@@ -1,3 +1,4 @@
1
+ import { BaseUser } from './user.model';
1
2
  /**
2
3
  * Configuration for the built-in HTTP-based mailer transport.
3
4
  *
@@ -75,6 +76,17 @@ export interface AuthConfig {
75
76
  * When provided, this callback is used instead of `mailer`.
76
77
  */
77
78
  sendWelcome?: (to: string, data: Record<string, unknown>, lang?: string) => Promise<void>;
79
+ /**
80
+ * Override: custom email-verification sender.
81
+ * When provided, this callback is used instead of `mailer`.
82
+ */
83
+ sendVerificationEmail?: (to: string, token: string, link: string, lang?: string) => Promise<void>;
84
+ /**
85
+ * Override: custom email-changed notification sender.
86
+ * Called after the change-email flow completes.
87
+ * When provided, this callback is used instead of `mailer`.
88
+ */
89
+ sendEmailChanged?: (to: string, newEmail: string, lang?: string) => Promise<void>;
78
90
  };
79
91
  oauth?: {
80
92
  google?: {
@@ -92,5 +104,22 @@ export interface AuthConfig {
92
104
  twoFactor?: {
93
105
  appName?: string;
94
106
  };
107
+ /**
108
+ * Optional callback to inject custom claims into both the access and refresh JWTs.
109
+ *
110
+ * Called with the authenticated/resolved `user` object every time a token pair is
111
+ * generated. The object returned by this callback is **merged** on top of the
112
+ * standard `{ sub, email, role }` claims, so you can add roles, permissions, tenant
113
+ * IDs, or any other project-specific data.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * buildTokenPayload: (user) => ({
118
+ * permissions: user.permissions,
119
+ * tenantId: user.tenantId,
120
+ * }),
121
+ * ```
122
+ */
123
+ buildTokenPayload?: (user: BaseUser) => Record<string, unknown>;
95
124
  }
96
125
  //# sourceMappingURL=auth-config.model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-config.model.d.ts","sourceRoot":"","sources":["../../src/models/auth-config.model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;QACrC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;IACF,KAAK,CAAC,EAAE;QACN;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;QAEjB;;;;;WAKG;QACH,MAAM,CAAC,EAAE,YAAY,CAAC;QAEtB;;;WAGG;QACH,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAE1F;;;WAGG;QACH,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAE9F;;;WAGG;QACH,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3F,CAAC;IACF,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE;YACP,QAAQ,EAAE,MAAM,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,MAAM,CAAC,EAAE;YACP,QAAQ,EAAE,MAAM,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;KACH,CAAC;IACF,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH"}
1
+ {"version":3,"file":"auth-config.model.d.ts","sourceRoot":"","sources":["../../src/models/auth-config.model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Represents an active user session with optional device/context metadata.
3
+ *
4
+ * Implementations of `ISessionStore` use this shape to persist and retrieve
5
+ * session records. All fields beyond `sessionHandle`, `userId`, `createdAt`,
6
+ * and `expiresAt` are optional so you only store what you actually need.
7
+ */
8
+ export interface SessionInfo {
9
+ /** Unique opaque identifier for this session (e.g. a UUID or a hex token). */
10
+ sessionHandle: string;
11
+ /** ID of the user who owns this session. */
12
+ userId: string;
13
+ /** Tenant ID — set when multi-tenancy is enabled. */
14
+ tenantId?: string;
15
+ /** When the session was created. */
16
+ createdAt: Date;
17
+ /** When the session expires. */
18
+ expiresAt: Date;
19
+ /** When the session was last used (updated on each authenticated request). */
20
+ lastActiveAt?: Date;
21
+ /** User-Agent header from the client that created the session. */
22
+ userAgent?: string;
23
+ /** IP address that created the session. */
24
+ ipAddress?: string;
25
+ /** Arbitrary session-level data (e.g. device name, geo-location, etc.). */
26
+ data?: Record<string, unknown>;
27
+ }
28
+ //# sourceMappingURL=session.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.model.d.ts","sourceRoot":"","sources":["../../src/models/session.model.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,SAAS,EAAE,IAAI,CAAC;IAChB,gCAAgC;IAChC,SAAS,EAAE,IAAI,CAAC;IAChB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=session.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.model.js","sourceRoot":"","sources":["../../src/models/session.model.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Represents a tenant in a multi-tenant application.
3
+ *
4
+ * `ITenantStore` implementations use this shape to create and query tenants.
5
+ * The `config` field can hold arbitrary per-tenant settings (e.g. allowed
6
+ * OAuth providers, custom branding, feature flags).
7
+ */
8
+ export interface Tenant {
9
+ /** Unique identifier for the tenant (e.g. slug, UUID, or subdomain). */
10
+ id: string;
11
+ /** Human-readable display name. */
12
+ name: string;
13
+ /** Whether the tenant is currently active. Defaults to `true`. */
14
+ isActive?: boolean;
15
+ /** Arbitrary per-tenant configuration (allowed auth methods, branding, etc.). */
16
+ config?: Record<string, unknown>;
17
+ /** When the tenant was created. */
18
+ createdAt?: Date;
19
+ }
20
+ //# sourceMappingURL=tenant.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant.model.d.ts","sourceRoot":"","sources":["../../src/models/tenant.model.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,MAAM;IACrB,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,mCAAmC;IACnC,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=tenant.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant.model.js","sourceRoot":"","sources":["../../src/models/tenant.model.ts"],"names":[],"mappings":""}
@@ -8,5 +8,7 @@ export interface AccessTokenPayload {
8
8
  role?: string;
9
9
  iat?: number;
10
10
  exp?: number;
11
+ /** Any additional custom claims embedded in the JWT. */
12
+ [key: string]: unknown;
11
13
  }
12
14
  //# sourceMappingURL=token.model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"token.model.d.ts","sourceRoot":"","sources":["../../src/models/token.model.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
1
+ {"version":3,"file":"token.model.d.ts","sourceRoot":"","sources":["../../src/models/token.model.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}