sentri 1.1.0 → 1.1.2

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 (46) hide show
  1. package/README.md +107 -43
  2. package/dist/client.d.ts +49 -14
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +3 -1
  5. package/dist/client.js.map +1 -1
  6. package/dist/errors/AuthError.d.ts +82 -24
  7. package/dist/errors/AuthError.d.ts.map +1 -1
  8. package/dist/errors/AuthError.js +87 -20
  9. package/dist/errors/AuthError.js.map +1 -1
  10. package/dist/index.d.ts +6 -3
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/libs/config.d.ts +2 -2
  15. package/dist/libs/config.js +8 -8
  16. package/dist/libs/config.js.map +1 -1
  17. package/dist/libs/token.d.ts +2 -2
  18. package/dist/libs/token.js +10 -10
  19. package/dist/libs/token.js.map +1 -1
  20. package/dist/middleware/authorize.d.ts +1 -1
  21. package/dist/middleware/authorize.js +4 -4
  22. package/dist/middleware/authorize.js.map +1 -1
  23. package/dist/middleware/errorHandler.d.ts +71 -0
  24. package/dist/middleware/errorHandler.d.ts.map +1 -0
  25. package/dist/middleware/errorHandler.js +74 -0
  26. package/dist/middleware/errorHandler.js.map +1 -0
  27. package/dist/middleware/permit.d.ts +1 -1
  28. package/dist/middleware/permit.js +4 -4
  29. package/dist/middleware/permit.js.map +1 -1
  30. package/dist/middleware/protect.d.ts +1 -1
  31. package/dist/middleware/protect.js +4 -4
  32. package/dist/middleware/protect.js.map +1 -1
  33. package/dist/middleware/router.d.ts.map +1 -1
  34. package/dist/middleware/router.js +11 -13
  35. package/dist/middleware/router.js.map +1 -1
  36. package/dist/services/auth.d.ts +5 -5
  37. package/dist/services/auth.d.ts.map +1 -1
  38. package/dist/services/auth.js +15 -15
  39. package/dist/services/auth.js.map +1 -1
  40. package/dist/types/auth.d.ts +21 -21
  41. package/dist/types/auth.d.ts.map +1 -1
  42. package/dist/types/auth.js +1 -1
  43. package/dist/types/auth.js.map +1 -1
  44. package/package.json +1 -1
  45. package/templates/drizzle/auth.ts +37 -2
  46. package/templates/prisma/auth.ts +37 -2
@@ -1 +1 @@
1
- {"version":3,"file":"AuthError.js","sourceRoot":"","sources":["../../src/errors/AuthError.ts"],"names":[],"mappings":"AA0BA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClB,IAAI,CAAgB;IAEpC,YAAY,IAAmB,EAAE,OAAe;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
1
+ {"version":3,"file":"AuthError.js","sourceRoot":"","sources":["../../src/errors/AuthError.ts"],"names":[],"mappings":"AA6BA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACvD,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,aAAa,EAAE,GAAG;IAClB,mBAAmB,EAAE,GAAG;IACxB,SAAS,EAAE,GAAG;IACd,cAAc,EAAE,GAAG;IACnB,mBAAmB,EAAE,GAAG;IACxB,YAAY,EAAE,GAAG;IACjB,gBAAgB,EAAE,GAAG;IACrB,mBAAmB,EAAE,GAAG;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC;;;;OAIG;IACa,IAAI,CAAS;IAE7B;;;;OAIG;IACa,UAAU,CAAS;IAEnC;;;;;;OAMG;IACH,YACE,IAAqC,EACrC,OAAe,EACf,UAAmB;QAEnB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;IACjE,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -6,10 +6,13 @@ declare global {
6
6
  }
7
7
  }
8
8
  }
9
- export type { AuthConfig, CookieConfig, AuthUser, ApiResponse, AuthAdapter, UserRecord, SessionRecord, CreateUserData, RouterHandlers, SignupInput, LoginInput, SignupResult, AuthResult, RefreshResult, AssignRolesResult, } from './types/auth.js';
10
- export type { AuthErrorCode } from './errors/AuthError.js';
9
+ export type { AuthConfig, CookieConfig, AuthUser, ApiResponse, AuthAdapter, UserRecord, SessionRecord, CreateUserData, RouterHandlers, RegisterInput, LoginInput, RegisterResult, AuthResult, RefreshResult, AssignRolesResult, } from './types/auth.js';
10
+ export type { SentriErrorCode } from './errors/AuthError.js';
11
11
  export type { AuthClient } from './client.js';
12
- export { AuthError } from './errors/AuthError.js';
12
+ export type { ErrorHandlerOptions } from './middleware/errorHandler.js';
13
+ export { SentriError, AUTH_ERROR_STATUS } from './errors/AuthError.js';
13
14
  export { createAuth } from './client.js';
15
+ export { createErrorHandler } from './middleware/errorHandler.js';
16
+ export { register } from './services/auth.js';
14
17
  export type { PermitCheck, PermitOptions } from './middleware/permit.js';
15
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIhD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE,QAAQ,CAAC;SACjB;KACF;CACF;AAED,YAAY,EACV,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,WAAW,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE,QAAQ,CAAC;SACjB;KACF;CACF;AAED,YAAY,EACV,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,EACb,UAAU,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
- export { AuthError } from './errors/AuthError.js';
1
+ export { SentriError, AUTH_ERROR_STATUS } from './errors/AuthError.js';
2
2
  export { createAuth } from './client.js';
3
+ export { createErrorHandler } from './middleware/errorHandler.js';
4
+ export { register } from './services/auth.js';
3
5
  //# 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":"AAgCA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
@@ -17,14 +17,14 @@ export interface ResolvedConfig {
17
17
  * Validate configuration at startup so misconfiguration is caught immediately,
18
18
  * not at the first login attempt.
19
19
  *
20
- * Throws {@link AuthError} with code `CONFIGURATION_ERROR` for any of:
20
+ * Throws {@link SentriError} with code `CONFIGURATION_ERROR` for any of:
21
21
  * - `secret` missing or shorter than 32 characters
22
22
  * - `saltRounds` outside the range 10–31
23
23
  * - `validRoles` is empty or missing
24
24
  * - `adapter` is missing
25
25
  *
26
26
  * @param config - The raw config passed to {@link createAuth}.
27
- * @throws {AuthError} With code `CONFIGURATION_ERROR` on any invalid field.
27
+ * @throws {SentriError} With code `CONFIGURATION_ERROR` on any invalid field.
28
28
  */
29
29
  export declare function validateConfig(config: AuthConfig): void;
30
30
  /**
@@ -1,4 +1,4 @@
1
- import { AuthError } from '../errors/AuthError.js';
1
+ import { SentriError } from '../errors/AuthError.js';
2
2
  const MIN_SECRET_LENGTH = 32;
3
3
  const MIN_SALT_ROUNDS = 10;
4
4
  const MAX_SALT_ROUNDS = 31;
@@ -6,31 +6,31 @@ const MAX_SALT_ROUNDS = 31;
6
6
  * Validate configuration at startup so misconfiguration is caught immediately,
7
7
  * not at the first login attempt.
8
8
  *
9
- * Throws {@link AuthError} with code `CONFIGURATION_ERROR` for any of:
9
+ * Throws {@link SentriError} with code `CONFIGURATION_ERROR` for any of:
10
10
  * - `secret` missing or shorter than 32 characters
11
11
  * - `saltRounds` outside the range 10–31
12
12
  * - `validRoles` is empty or missing
13
13
  * - `adapter` is missing
14
14
  *
15
15
  * @param config - The raw config passed to {@link createAuth}.
16
- * @throws {AuthError} With code `CONFIGURATION_ERROR` on any invalid field.
16
+ * @throws {SentriError} With code `CONFIGURATION_ERROR` on any invalid field.
17
17
  */
18
18
  export function validateConfig(config) {
19
19
  if (!config.secret || config.secret.trim().length === 0) {
20
- throw new AuthError('CONFIGURATION_ERROR', 'secret must not be empty');
20
+ throw new SentriError('CONFIGURATION_ERROR', 'secret must not be empty');
21
21
  }
22
22
  if (config.secret.length < MIN_SECRET_LENGTH) {
23
- throw new AuthError('CONFIGURATION_ERROR', `secret must be at least ${MIN_SECRET_LENGTH} characters to be cryptographically safe`);
23
+ throw new SentriError('CONFIGURATION_ERROR', `secret must be at least ${MIN_SECRET_LENGTH} characters to be cryptographically safe`);
24
24
  }
25
25
  const saltRounds = config.saltRounds ?? 12;
26
26
  if (!Number.isInteger(saltRounds) || saltRounds < MIN_SALT_ROUNDS || saltRounds > MAX_SALT_ROUNDS) {
27
- throw new AuthError('CONFIGURATION_ERROR', `saltRounds must be an integer between ${MIN_SALT_ROUNDS} and ${MAX_SALT_ROUNDS}`);
27
+ throw new SentriError('CONFIGURATION_ERROR', `saltRounds must be an integer between ${MIN_SALT_ROUNDS} and ${MAX_SALT_ROUNDS}`);
28
28
  }
29
29
  if (!config.validRoles || config.validRoles.length === 0) {
30
- throw new AuthError('CONFIGURATION_ERROR', 'validRoles must contain at least one role');
30
+ throw new SentriError('CONFIGURATION_ERROR', 'validRoles must contain at least one role');
31
31
  }
32
32
  if (!config.adapter) {
33
- throw new AuthError('CONFIGURATION_ERROR', 'adapter is required');
33
+ throw new SentriError('CONFIGURATION_ERROR', 'adapter is required');
34
34
  }
35
35
  }
36
36
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/libs/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/libs/config.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,7 @@ export declare function signRefreshToken(sessionId: string, config: AuthConfig):
29
29
  * @param token - Compact JWT access token string.
30
30
  * @param config - Auth configuration used to derive the secret and algorithm.
31
31
  * @returns Decoded `AuthUser` payload (id, identifier, roles).
32
- * @throws {AuthError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
32
+ * @throws {SentriError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
33
33
  */
34
34
  export declare function verifyAccessToken(token: string, config: AuthConfig): AuthUser;
35
35
  /**
@@ -38,7 +38,7 @@ export declare function verifyAccessToken(token: string, config: AuthConfig): Au
38
38
  * @param token - Compact JWT refresh token string.
39
39
  * @param config - Auth configuration used to derive the secret and algorithm.
40
40
  * @returns Object with `sessionId` matching the one passed to {@link signRefreshToken}.
41
- * @throws {AuthError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
41
+ * @throws {SentriError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
42
42
  */
43
43
  export declare function verifyRefreshToken(token: string, config: AuthConfig): {
44
44
  sessionId: string;
@@ -1,5 +1,5 @@
1
1
  import jwt, {} from 'jsonwebtoken';
2
- import { AuthError } from '../errors/AuthError.js';
2
+ import { SentriError } from '../errors/AuthError.js';
3
3
  import { resolveConfig } from './config.js';
4
4
  /**
5
5
  * Derive separate HMAC secrets for access and refresh tokens from a single
@@ -31,30 +31,30 @@ function sign(payload, secret, expiresIn, algorithm) {
31
31
  return jwt.sign(payload, secret, options);
32
32
  }
33
33
  /**
34
- * Verify and decode a JWT, mapping jsonwebtoken errors to typed {@link AuthError}s.
34
+ * Verify and decode a JWT, mapping jsonwebtoken errors to typed {@link SentriError}s.
35
35
  *
36
36
  * @param token - Compact JWT string to verify.
37
37
  * @param secret - HMAC key used to sign the token.
38
38
  * @param algorithm - Expected signing algorithm.
39
39
  * @returns Decoded payload cast to `T`.
40
- * @throws {AuthError} With `TOKEN_EXPIRED` if the token's `exp` claim is in the past.
41
- * @throws {AuthError} With `TOKEN_INVALID` for any other verification failure.
40
+ * @throws {SentriError} With `TOKEN_EXPIRED` if the token's `exp` claim is in the past.
41
+ * @throws {SentriError} With `TOKEN_INVALID` for any other verification failure.
42
42
  */
43
43
  function verify(token, secret, algorithm) {
44
44
  try {
45
45
  const decoded = jwt.verify(token, secret, { algorithms: [algorithm] });
46
46
  if (typeof decoded === 'string' || decoded === null) {
47
- throw new AuthError('TOKEN_INVALID', 'Token payload is not an object');
47
+ throw new SentriError('TOKEN_INVALID', 'Token payload is not an object');
48
48
  }
49
49
  return decoded;
50
50
  }
51
51
  catch (err) {
52
- if (err instanceof AuthError)
52
+ if (err instanceof SentriError)
53
53
  throw err;
54
54
  if (err instanceof jwt.TokenExpiredError) {
55
- throw new AuthError('TOKEN_EXPIRED', 'Token has expired');
55
+ throw new SentriError('TOKEN_EXPIRED', 'Token has expired');
56
56
  }
57
- throw new AuthError('TOKEN_INVALID', 'Token is invalid or malformed');
57
+ throw new SentriError('TOKEN_INVALID', 'Token is invalid or malformed');
58
58
  }
59
59
  }
60
60
  /**
@@ -95,7 +95,7 @@ export function signRefreshToken(sessionId, config) {
95
95
  * @param token - Compact JWT access token string.
96
96
  * @param config - Auth configuration used to derive the secret and algorithm.
97
97
  * @returns Decoded `AuthUser` payload (id, identifier, roles).
98
- * @throws {AuthError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
98
+ * @throws {SentriError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
99
99
  */
100
100
  export function verifyAccessToken(token, config) {
101
101
  const resolved = resolveConfig(config);
@@ -108,7 +108,7 @@ export function verifyAccessToken(token, config) {
108
108
  * @param token - Compact JWT refresh token string.
109
109
  * @param config - Auth configuration used to derive the secret and algorithm.
110
110
  * @returns Object with `sessionId` matching the one passed to {@link signRefreshToken}.
111
- * @throws {AuthError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
111
+ * @throws {SentriError} With `TOKEN_EXPIRED` if expired, `TOKEN_INVALID` otherwise.
112
112
  */
113
113
  export function verifyRefreshToken(token, config) {
114
114
  const resolved = resolveConfig(config);
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/libs/token.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/libs/token.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import type { RequestHandler } from 'express';
3
3
  * Express middleware factory for role-based access control (RBAC).
4
4
  *
5
5
  * Passes if the authenticated user (set by `protect()`) has **at least one**
6
- * of the specified `allowedRoles`. Calls `next(AuthError)` with code `FORBIDDEN`
6
+ * of the specified `allowedRoles`. Calls `next(SentriError)` with code `FORBIDDEN`
7
7
  * if no roles match, or `UNAUTHORIZED` if `req.user` is absent.
8
8
  *
9
9
  * Must be used **after** `protect()`.
@@ -1,9 +1,9 @@
1
- import { AuthError } from '../errors/AuthError.js';
1
+ import { SentriError } from '../errors/AuthError.js';
2
2
  /**
3
3
  * Express middleware factory for role-based access control (RBAC).
4
4
  *
5
5
  * Passes if the authenticated user (set by `protect()`) has **at least one**
6
- * of the specified `allowedRoles`. Calls `next(AuthError)` with code `FORBIDDEN`
6
+ * of the specified `allowedRoles`. Calls `next(SentriError)` with code `FORBIDDEN`
7
7
  * if no roles match, or `UNAUTHORIZED` if `req.user` is absent.
8
8
  *
9
9
  * Must be used **after** `protect()`.
@@ -17,12 +17,12 @@ import { AuthError } from '../errors/AuthError.js';
17
17
  export function authorize(...allowedRoles) {
18
18
  return (request, _response, next) => {
19
19
  if (!request.user) {
20
- return next(new AuthError('UNAUTHORIZED', 'Not authenticated'));
20
+ return next(new SentriError('UNAUTHORIZED', 'Not authenticated'));
21
21
  }
22
22
  const userRoles = request.user.roles;
23
23
  const hasRole = allowedRoles.some((role) => userRoles.includes(role));
24
24
  if (!hasRole) {
25
- return next(new AuthError('FORBIDDEN', `Requires one of roles: ${allowedRoles.join(', ')}`));
25
+ return next(new SentriError('FORBIDDEN', `Requires one of roles: ${allowedRoles.join(', ')}`));
26
26
  }
27
27
  next();
28
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAuB,GAAG,YAAqB;IACtE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,SAAS,GAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CACT,IAAI,SAAS,CAAC,WAAW,EAAE,0BAA0B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAChF,CAAC;QACJ,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAuB,GAAG,YAAqB;IACtE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QAClC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,IAAI,WAAW,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,SAAS,GAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QACxD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CACT,IAAI,WAAW,CAAC,WAAW,EAAE,0BAA0B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAClF,CAAC;QACJ,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,71 @@
1
+ import type { ErrorRequestHandler } from 'express';
2
+ /**
3
+ * Options for {@link createErrorHandler}.
4
+ */
5
+ export interface ErrorHandlerOptions {
6
+ /**
7
+ * Called for errors that are **not** a `SentriError` instance (or subclass).
8
+ *
9
+ * Use this to log unexpected server errors before the generic 500 response
10
+ * is sent. The error is passed as-is and may be any unknown value.
11
+ *
12
+ * @example
13
+ * app.use(auth.errorHandler({
14
+ * onUnhandled: (err) => logger.error('Unhandled error', { err }),
15
+ * }));
16
+ */
17
+ onUnhandled?: (error: unknown) => void;
18
+ }
19
+ /**
20
+ * Creates an Express error-handling middleware that formats every `SentriError`
21
+ * (including subclasses) into the standard sentri response envelope:
22
+ *
23
+ * ```json
24
+ * { "error": true, "statusCode": 401, "code": "UNAUTHORIZED", "message": "...", "data": null }
25
+ * ```
26
+ *
27
+ * Prefer using `auth.errorHandler()` instead of calling this directly:
28
+ *
29
+ * ```typescript
30
+ * app.use('/auth', auth.router());
31
+ * app.use('/api', apiRouter);
32
+ *
33
+ * // Must come after all route/middleware registrations
34
+ * app.use(auth.errorHandler());
35
+ * ```
36
+ *
37
+ * ---
38
+ *
39
+ * **Works with built-in sentri errors and your own subclasses**
40
+ *
41
+ * Because `instanceof SentriError` matches any subclass, you can define
42
+ * application-specific error types and have them automatically formatted
43
+ * by this handler:
44
+ *
45
+ * ```typescript
46
+ * import { SentriError } from 'sentri';
47
+ *
48
+ * // Extend SentriError for domain-specific failures
49
+ * export class NotFoundError extends SentriError {
50
+ * constructor(resource: string) {
51
+ * super('NOT_FOUND', `${resource} not found`, 404);
52
+ * }
53
+ * }
54
+ *
55
+ * export class PaymentError extends SentriError {
56
+ * constructor(message: string) {
57
+ * super('PAYMENT_FAILED', message, 402);
58
+ * }
59
+ * }
60
+ *
61
+ * // All of the above are caught and formatted by one handler
62
+ * app.use(auth.errorHandler({
63
+ * onUnhandled: (err) => console.error('Unexpected error:', err),
64
+ * }));
65
+ * ```
66
+ *
67
+ * @param options - Optional configuration (see {@link ErrorHandlerOptions}).
68
+ * @returns An Express `ErrorRequestHandler` (4-argument middleware).
69
+ */
70
+ export declare function createErrorHandler(options?: ErrorHandlerOptions): ErrorRequestHandler;
71
+ //# sourceMappingURL=errorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGnD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,CAsBrF"}
@@ -0,0 +1,74 @@
1
+ import { SentriError } from '../errors/AuthError.js';
2
+ /**
3
+ * Creates an Express error-handling middleware that formats every `SentriError`
4
+ * (including subclasses) into the standard sentri response envelope:
5
+ *
6
+ * ```json
7
+ * { "error": true, "statusCode": 401, "code": "UNAUTHORIZED", "message": "...", "data": null }
8
+ * ```
9
+ *
10
+ * Prefer using `auth.errorHandler()` instead of calling this directly:
11
+ *
12
+ * ```typescript
13
+ * app.use('/auth', auth.router());
14
+ * app.use('/api', apiRouter);
15
+ *
16
+ * // Must come after all route/middleware registrations
17
+ * app.use(auth.errorHandler());
18
+ * ```
19
+ *
20
+ * ---
21
+ *
22
+ * **Works with built-in sentri errors and your own subclasses**
23
+ *
24
+ * Because `instanceof SentriError` matches any subclass, you can define
25
+ * application-specific error types and have them automatically formatted
26
+ * by this handler:
27
+ *
28
+ * ```typescript
29
+ * import { SentriError } from 'sentri';
30
+ *
31
+ * // Extend SentriError for domain-specific failures
32
+ * export class NotFoundError extends SentriError {
33
+ * constructor(resource: string) {
34
+ * super('NOT_FOUND', `${resource} not found`, 404);
35
+ * }
36
+ * }
37
+ *
38
+ * export class PaymentError extends SentriError {
39
+ * constructor(message: string) {
40
+ * super('PAYMENT_FAILED', message, 402);
41
+ * }
42
+ * }
43
+ *
44
+ * // All of the above are caught and formatted by one handler
45
+ * app.use(auth.errorHandler({
46
+ * onUnhandled: (err) => console.error('Unexpected error:', err),
47
+ * }));
48
+ * ```
49
+ *
50
+ * @param options - Optional configuration (see {@link ErrorHandlerOptions}).
51
+ * @returns An Express `ErrorRequestHandler` (4-argument middleware).
52
+ */
53
+ export function createErrorHandler(options) {
54
+ return (err, _req, res, _next) => {
55
+ if (err instanceof SentriError) {
56
+ res.status(err.statusCode).json({
57
+ error: true,
58
+ statusCode: err.statusCode,
59
+ code: err.code,
60
+ message: err.message,
61
+ data: null,
62
+ });
63
+ return;
64
+ }
65
+ options?.onUnhandled?.(err);
66
+ res.status(500).json({
67
+ error: true,
68
+ statusCode: 500,
69
+ message: 'Internal server error',
70
+ data: null,
71
+ });
72
+ };
73
+ }
74
+ //# sourceMappingURL=errorHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAoBrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA6B;IAC9D,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAC/B,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;gBAC9B,KAAK,EAAE,IAAI;gBACX,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC;QAE5B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,uBAAuB;YAChC,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -31,7 +31,7 @@ export interface PermitOptions<TRole extends string> {
31
31
  * Express middleware factory for resource-level permission checks.
32
32
  *
33
33
  * Must be used **after** `protect()`. Evaluates a check function against the
34
- * current request; calls `next(AuthError)` with code `FORBIDDEN` if it returns `false`.
34
+ * current request; calls `next(SentriError)` with code `FORBIDDEN` if it returns `false`.
35
35
  *
36
36
  * Accepts either a bare check function or an options object with an optional
37
37
  * `roles` list whose members bypass the check entirely.
@@ -1,9 +1,9 @@
1
- import { AuthError } from '../errors/AuthError.js';
1
+ import { SentriError } from '../errors/AuthError.js';
2
2
  /**
3
3
  * Express middleware factory for resource-level permission checks.
4
4
  *
5
5
  * Must be used **after** `protect()`. Evaluates a check function against the
6
- * current request; calls `next(AuthError)` with code `FORBIDDEN` if it returns `false`.
6
+ * current request; calls `next(SentriError)` with code `FORBIDDEN` if it returns `false`.
7
7
  *
8
8
  * Accepts either a bare check function or an options object with an optional
9
9
  * `roles` list whose members bypass the check entirely.
@@ -36,7 +36,7 @@ export function permit(optionsOrCheck) {
36
36
  : optionsOrCheck;
37
37
  return async (request, _response, next) => {
38
38
  if (!request.user) {
39
- return next(new AuthError('UNAUTHORIZED', 'Not authenticated'));
39
+ return next(new SentriError('UNAUTHORIZED', 'Not authenticated'));
40
40
  }
41
41
  if (options.roles && options.roles.length > 0) {
42
42
  const userRoles = request.user.roles;
@@ -50,7 +50,7 @@ export function permit(optionsOrCheck) {
50
50
  next();
51
51
  }
52
52
  else {
53
- next(new AuthError('FORBIDDEN', 'You do not have permission to perform this action'));
53
+ next(new SentriError('FORBIDDEN', 'You do not have permission to perform this action'));
54
54
  }
55
55
  }
56
56
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"permit.js","sourceRoot":"","sources":["../../src/middleware/permit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAgCnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,MAAM,CACpB,cAAkD;IAElD,MAAM,OAAO,GACX,OAAO,cAAc,KAAK,UAAU;QAClC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE;QAC3B,CAAC,CAAC,cAAc,CAAC;IAErB,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QACxC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,SAAS,GAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YACxD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7E,IAAI,aAAa;gBAAE,OAAO,IAAI,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,EAAE,CAAC;YACT,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,mDAAmD,CAAC,CAAC,CAAC;YACxF,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"permit.js","sourceRoot":"","sources":["../../src/middleware/permit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAgCrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,MAAM,CACpB,cAAkD;IAElD,MAAM,OAAO,GACX,OAAO,cAAc,KAAK,UAAU;QAClC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE;QAC3B,CAAC,CAAC,cAAc,CAAC;IAErB,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QACxC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,IAAI,WAAW,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,SAAS,GAAsB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YACxD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7E,IAAI,aAAa;gBAAE,OAAO,IAAI,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,EAAE,CAAC;YACT,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,WAAW,CAAC,WAAW,EAAE,mDAAmD,CAAC,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -4,7 +4,7 @@ import type { AuthConfig } from '../types/auth.js';
4
4
  * Express middleware factory that enforces JWT authentication and session validity.
5
5
  *
6
6
  * Reads the `Authorization: Bearer <token>` header, verifies the access token,
7
- * and attaches the decoded payload to `req.user`. Calls `next(AuthError)` on
7
+ * and attaches the decoded payload to `req.user`. Calls `next(SentriError)` on
8
8
  * any failure so your error handler can convert it to an HTTP response.
9
9
  *
10
10
  * Since sentri 1.1.0 access tokens embed a `sessionId` claim. When this claim
@@ -1,10 +1,10 @@
1
- import { AuthError } from '../errors/AuthError.js';
1
+ import { SentriError } from '../errors/AuthError.js';
2
2
  import { verifyAccessToken } from '../libs/token.js';
3
3
  /**
4
4
  * Express middleware factory that enforces JWT authentication and session validity.
5
5
  *
6
6
  * Reads the `Authorization: Bearer <token>` header, verifies the access token,
7
- * and attaches the decoded payload to `req.user`. Calls `next(AuthError)` on
7
+ * and attaches the decoded payload to `req.user`. Calls `next(SentriError)` on
8
8
  * any failure so your error handler can convert it to an HTTP response.
9
9
  *
10
10
  * Since sentri 1.1.0 access tokens embed a `sessionId` claim. When this claim
@@ -31,7 +31,7 @@ export function protect(config) {
31
31
  return async (request, _response, next) => {
32
32
  const authHeader = request.headers['authorization'];
33
33
  if (!authHeader?.startsWith('Bearer ')) {
34
- return next(new AuthError('UNAUTHORIZED', 'Missing or malformed Authorization header'));
34
+ return next(new SentriError('UNAUTHORIZED', 'Missing or malformed Authorization header'));
35
35
  }
36
36
  const token = authHeader.slice(7);
37
37
  try {
@@ -41,7 +41,7 @@ export function protect(config) {
41
41
  if (payload.sessionId) {
42
42
  const session = await config.adapter.session.findById(payload.sessionId);
43
43
  if (!session) {
44
- return next(new AuthError('UNAUTHORIZED', 'Session has been revoked'));
44
+ return next(new SentriError('UNAUTHORIZED', 'Session has been revoked'));
45
45
  }
46
46
  }
47
47
  next();
@@ -1 +1 @@
1
- {"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,OAAO,CAAC,MAAkB;IACxC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE,2CAA2C,CAAC,CAAC,CAAC;QAC1F,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAuB,CAAC;YACvE,OAAO,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAExF,oFAAoF;YACpF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACzE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"protect.js","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,OAAO,CAAC,MAAkB;IACxC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,IAAI,WAAW,CAAC,cAAc,EAAE,2CAA2C,CAAC,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAuB,CAAC;YACvE,OAAO,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAExF,oFAAoF;YACpF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACzE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,IAAI,WAAW,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC;YAED,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/middleware/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AAEjF,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,kBAAkB,CAAC;AA+E5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,MAAM,CAwLxF"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/middleware/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkD,MAAM,SAAS,CAAC;AAEjF,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,kBAAkB,CAAC;AA4E9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,MAAM,CAwLxF"}
@@ -1,7 +1,6 @@
1
1
  import { Router } from 'express';
2
- import { AuthError } from '../errors/AuthError.js';
3
- import { authErrorStatus } from '../types/auth.js';
4
- import { signup, login, refresh, logout, logoutAll, assignRoles } from '../services/auth.js';
2
+ import { SentriError } from '../errors/AuthError.js';
3
+ import { register, login, refresh, logout, logoutAll, assignRoles } from '../services/auth.js';
5
4
  import { resolveConfig, parseExpiry } from '../libs/config.js';
6
5
  import { protect } from './protect.js';
7
6
  import { authorize } from './authorize.js';
@@ -12,18 +11,17 @@ const MIN_PASSWORD_LENGTH = 8;
12
11
  const MAX_PASSWORD_LENGTH = 72;
13
12
  const MAX_IDENTIFIER_LENGTH = 255;
14
13
  function badRequest(message) {
15
- return new AuthError('VALIDATION_ERROR', message);
14
+ return new SentriError('VALIDATION_ERROR', message);
16
15
  }
17
16
  function ok(response, statusCode, message, data) {
18
17
  response.status(statusCode).json({ error: false, statusCode, message, data });
19
18
  }
20
19
  function fail(response, error) {
21
- const statusCode = authErrorStatus(error.code);
22
- response.status(statusCode).json({ error: true, statusCode, message: error.message, data: null });
20
+ response.status(error.statusCode).json({ error: true, statusCode: error.statusCode, message: error.message, data: null });
23
21
  }
24
22
  function parseBody(body) {
25
23
  if (body === null || body === undefined || typeof body !== 'object' || Array.isArray(body)) {
26
- throw new AuthError('VALIDATION_ERROR', 'Request body is missing or not a JSON object. Did you apply express.json()?');
24
+ throw new SentriError('VALIDATION_ERROR', 'Request body is missing or not a JSON object. Did you apply express.json()?');
27
25
  }
28
26
  return body;
29
27
  }
@@ -58,14 +56,14 @@ function clearCookie(response, config) {
58
56
  }
59
57
  /**
60
58
  * Validate the `X-Api-Key` header when `config.apiKey` is set.
61
- * Throws `AuthError` with code `UNAUTHORIZED` on mismatch.
59
+ * Throws `SentriError` with code `UNAUTHORIZED` on mismatch.
62
60
  */
63
61
  function validateApiKey(request, config) {
64
62
  if (!config.apiKey)
65
63
  return;
66
64
  const provided = request.headers['x-api-key'];
67
65
  if (typeof provided !== 'string' || provided !== config.apiKey) {
68
- throw new AuthError('UNAUTHORIZED', 'Invalid or missing API key');
66
+ throw new SentriError('UNAUTHORIZED', 'Invalid or missing API key');
69
67
  }
70
68
  }
71
69
  /**
@@ -102,7 +100,7 @@ export function createAuthRouter(config) {
102
100
  const router = Router();
103
101
  // Resolve service functions — use custom override from config.router when provided, else fall back to the built-in service.
104
102
  const baseConfig = config;
105
- const registerFn = config.router?.register ?? ((input) => signup(input, baseConfig));
103
+ const registerFn = config.router?.register ?? ((input) => register(input, baseConfig));
106
104
  const loginFn = config.router?.login ?? ((input) => login(input, baseConfig));
107
105
  const refreshFn = config.router?.refresh ?? ((token) => refresh(token, baseConfig));
108
106
  const logoutFn = config.router?.logout ?? ((token) => token !== undefined ? logout(token, baseConfig) : Promise.resolve());
@@ -186,7 +184,7 @@ export function createAuthRouter(config) {
186
184
  try {
187
185
  const fromCookie = readCookie(request.headers['cookie'], getCookieName(config));
188
186
  if (!fromCookie) {
189
- throw new AuthError('UNAUTHORIZED', 'Refresh token cookie is missing');
187
+ throw new SentriError('UNAUTHORIZED', 'Refresh token cookie is missing');
190
188
  }
191
189
  const result = await refreshFn(fromCookie);
192
190
  if (!result.success) {
@@ -251,10 +249,10 @@ export function createAuthRouter(config) {
251
249
  next(error);
252
250
  }
253
251
  });
254
- // Centralized error handler — converts AuthError (and unexpected errors) to the
252
+ // Centralized error handler — converts SentriError (and unexpected errors) to the
255
253
  // standard envelope so every endpoint produces a consistent shape on failure.
256
254
  router.use((error, _request, response, _next) => {
257
- if (error instanceof AuthError) {
255
+ if (error instanceof SentriError) {
258
256
  fail(response, error);
259
257
  }
260
258
  else {