secure-auth-kit 1.0.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 (85) hide show
  1. package/dist/constants/index.d.ts +9 -0
  2. package/dist/constants/index.d.ts.map +1 -0
  3. package/dist/constants/index.js +9 -0
  4. package/dist/constants/index.js.map +1 -0
  5. package/dist/core/middleware/error.middleware.d.ts +3 -0
  6. package/dist/core/middleware/error.middleware.d.ts.map +1 -0
  7. package/dist/core/middleware/error.middleware.js +12 -0
  8. package/dist/core/middleware/error.middleware.js.map +1 -0
  9. package/dist/core/routes/auth.routes.d.ts +3 -0
  10. package/dist/core/routes/auth.routes.d.ts.map +1 -0
  11. package/dist/core/routes/auth.routes.js +15 -0
  12. package/dist/core/routes/auth.routes.js.map +1 -0
  13. package/dist/core/stores/config.store.d.ts +4 -0
  14. package/dist/core/stores/config.store.d.ts.map +1 -0
  15. package/dist/core/stores/config.store.js +12 -0
  16. package/dist/core/stores/config.store.js.map +1 -0
  17. package/dist/features/login/login.controller.d.ts +3 -0
  18. package/dist/features/login/login.controller.d.ts.map +1 -0
  19. package/dist/features/login/login.controller.js +16 -0
  20. package/dist/features/login/login.controller.js.map +1 -0
  21. package/dist/features/login/login.service.d.ts +4 -0
  22. package/dist/features/login/login.service.d.ts.map +1 -0
  23. package/dist/features/login/login.service.js +20 -0
  24. package/dist/features/login/login.service.js.map +1 -0
  25. package/dist/features/login/login.validator.d.ts +3 -0
  26. package/dist/features/login/login.validator.d.ts.map +1 -0
  27. package/dist/features/login/login.validator.js +15 -0
  28. package/dist/features/login/login.validator.js.map +1 -0
  29. package/dist/features/me/me.controller.d.ts +3 -0
  30. package/dist/features/me/me.controller.d.ts.map +1 -0
  31. package/dist/features/me/me.controller.js +21 -0
  32. package/dist/features/me/me.controller.js.map +1 -0
  33. package/dist/features/register/register.controller.d.ts +3 -0
  34. package/dist/features/register/register.controller.d.ts.map +1 -0
  35. package/dist/features/register/register.controller.js +16 -0
  36. package/dist/features/register/register.controller.js.map +1 -0
  37. package/dist/features/register/register.service.d.ts +4 -0
  38. package/dist/features/register/register.service.d.ts.map +1 -0
  39. package/dist/features/register/register.service.js +24 -0
  40. package/dist/features/register/register.service.js.map +1 -0
  41. package/dist/features/register/register.validator.d.ts +3 -0
  42. package/dist/features/register/register.validator.d.ts.map +1 -0
  43. package/dist/features/register/register.validator.js +34 -0
  44. package/dist/features/register/register.validator.js.map +1 -0
  45. package/dist/index.d.ts +4 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +33 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/middleware/authenticate.middleware.d.ts +4 -0
  50. package/dist/middleware/authenticate.middleware.d.ts.map +1 -0
  51. package/dist/middleware/authenticate.middleware.js +28 -0
  52. package/dist/middleware/authenticate.middleware.js.map +1 -0
  53. package/dist/types/auth.types.d.ts +32 -0
  54. package/dist/types/auth.types.d.ts.map +1 -0
  55. package/dist/types/auth.types.js +2 -0
  56. package/dist/types/auth.types.js.map +1 -0
  57. package/dist/types/config.types.d.ts +13 -0
  58. package/dist/types/config.types.d.ts.map +1 -0
  59. package/dist/types/config.types.js +2 -0
  60. package/dist/types/config.types.js.map +1 -0
  61. package/dist/types/jwt.types.d.ts +12 -0
  62. package/dist/types/jwt.types.d.ts.map +1 -0
  63. package/dist/types/jwt.types.js +2 -0
  64. package/dist/types/jwt.types.js.map +1 -0
  65. package/dist/utils/AppError.d.ts +12 -0
  66. package/dist/utils/AppError.d.ts.map +1 -0
  67. package/dist/utils/AppError.js +30 -0
  68. package/dist/utils/AppError.js.map +1 -0
  69. package/dist/utils/hash.d.ts +3 -0
  70. package/dist/utils/hash.d.ts.map +1 -0
  71. package/dist/utils/hash.js +9 -0
  72. package/dist/utils/hash.js.map +1 -0
  73. package/dist/utils/jwt.d.ts +5 -0
  74. package/dist/utils/jwt.d.ts.map +1 -0
  75. package/dist/utils/jwt.js +27 -0
  76. package/dist/utils/jwt.js.map +1 -0
  77. package/dist/utils/response.d.ts +17 -0
  78. package/dist/utils/response.d.ts.map +1 -0
  79. package/dist/utils/response.js +20 -0
  80. package/dist/utils/response.js.map +1 -0
  81. package/dist/utils/sanitizeUser.d.ts +4 -0
  82. package/dist/utils/sanitizeUser.d.ts.map +1 -0
  83. package/dist/utils/sanitizeUser.js +17 -0
  84. package/dist/utils/sanitizeUser.js.map +1 -0
  85. package/package.json +49 -0
@@ -0,0 +1,9 @@
1
+ export declare const SALT_ROUNDS = 10;
2
+ export declare const SENSITIVE_FIELDS: Set<string>;
3
+ export declare const EMAIL_REGEX: RegExp;
4
+ export declare const MIN_PASSWORD_LENGTH = 8;
5
+ export declare const PASSWORD_UPPERCASE_REGEX: RegExp;
6
+ export declare const PASSWORD_LOWERCASE_REGEX: RegExp;
7
+ export declare const PASSWORD_NUMBER_REGEX: RegExp;
8
+ export declare const PASSWORD_SPECIAL_CHARACTER_REGEX: RegExp;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,KAAK,CAAC;AAE9B,eAAO,MAAM,gBAAgB,aAA+B,CAAC;AAE7D,eAAO,MAAM,WAAW,QAA+B,CAAC;AAExD,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,eAAO,MAAM,wBAAwB,QAAU,CAAC;AAEhD,eAAO,MAAM,wBAAwB,QAAU,CAAC;AAEhD,eAAO,MAAM,qBAAqB,QAAO,CAAC;AAE1C,eAAO,MAAM,gCAAgC,QAAc,CAAC"}
@@ -0,0 +1,9 @@
1
+ export const SALT_ROUNDS = 10;
2
+ export const SENSITIVE_FIELDS = new Set(['password', '__v']);
3
+ export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
4
+ export const MIN_PASSWORD_LENGTH = 8;
5
+ export const PASSWORD_UPPERCASE_REGEX = /[A-Z]/;
6
+ export const PASSWORD_LOWERCASE_REGEX = /[a-z]/;
7
+ export const PASSWORD_NUMBER_REGEX = /\d/;
8
+ export const PASSWORD_SPECIAL_CHARACTER_REGEX = /[@$!%*?&]/;
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE9B,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;AAE7D,MAAM,CAAC,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAExD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEhD,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEhD,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,MAAM,CAAC,MAAM,gCAAgC,GAAG,WAAW,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { NextFunction, Request, Response } from 'express';
2
+ export declare function errorMiddleware(err: Error, req: Request, res: Response, next: NextFunction): void;
3
+ //# sourceMappingURL=error.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.middleware.d.ts","sourceRoot":"","sources":["../../../src/core/middleware/error.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI1D,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CASjG"}
@@ -0,0 +1,12 @@
1
+ import { AppError } from '../../utils/AppError.js';
2
+ import { sendError } from '../../utils/response.js';
3
+ export function errorMiddleware(err, req, res, next) {
4
+ if (err instanceof AppError && err.isOperational) {
5
+ sendError(res, err.message, err.statusCode, err.code);
6
+ return;
7
+ }
8
+ // Unknown Errors
9
+ console.error('[secure-auth-kit] Unhandled error', err);
10
+ sendError(res, 'An unexpected error occurred', 500, 'INTERNAL_ERROR');
11
+ }
12
+ //# sourceMappingURL=error.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.middleware.js","sourceRoot":"","sources":["../../../src/core/middleware/error.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,MAAM,UAAU,eAAe,CAAC,GAAU,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB;IACvF,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;QAC/C,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO;IACX,CAAC;IAED,iBAAiB;IACjB,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IACxD,SAAS,CAAC,GAAG,EAAE,8BAA8B,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ export declare const createAuthRouter: () => Router;
3
+ //# sourceMappingURL=auth.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.routes.d.ts","sourceRoot":"","sources":["../../../src/core/routes/auth.routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAMjC,eAAO,MAAM,gBAAgB,QAAO,MAWnC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Router } from 'express';
2
+ import { loginController } from '../../features/login/login.controller.js';
3
+ import { meController } from '../../features/me/me.controller.js';
4
+ import { registerController } from '../../features/register/register.controller.js';
5
+ import { authenticate } from '../../middleware/authenticate.middleware.js';
6
+ export const createAuthRouter = () => {
7
+ const router = Router();
8
+ // Public routes
9
+ router.post('/register', registerController);
10
+ router.post('/login', loginController);
11
+ // Protected routes
12
+ router.get('/me', authenticate, meController);
13
+ return router;
14
+ };
15
+ //# sourceMappingURL=auth.routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.routes.js","sourceRoot":"","sources":["../../../src/core/routes/auth.routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAE3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAW,EAAE;IACzC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,gBAAgB;IAChB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAEvC,mBAAmB;IACnB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IAE9C,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { SecureAuthConfig } from '../../types/config.types.js';
2
+ export declare function setConfig(config: SecureAuthConfig): void;
3
+ export declare function getConfig(): SecureAuthConfig;
4
+ //# sourceMappingURL=config.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.store.d.ts","sourceRoot":"","sources":["../../../src/core/stores/config.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAK/D,wBAAgB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAExD;AAED,wBAAgB,SAAS,IAAI,gBAAgB,CAQ5C"}
@@ -0,0 +1,12 @@
1
+ import { AppError } from '../../utils/AppError.js';
2
+ let _config = null;
3
+ export function setConfig(config) {
4
+ _config = config;
5
+ }
6
+ export function getConfig() {
7
+ if (!_config) {
8
+ throw AppError.internal('secure-auth-kit: config has not been initialized. Call secureAuth() first.');
9
+ }
10
+ return _config;
11
+ }
12
+ //# sourceMappingURL=config.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.store.js","sourceRoot":"","sources":["../../../src/core/stores/config.store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,IAAI,OAAO,GAA4B,IAAI,CAAC;AAE5C,MAAM,UAAU,SAAS,CAAC,MAAwB;IAC9C,OAAO,GAAG,MAAM,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,SAAS;IACrB,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,QAAQ,CAAC,QAAQ,CACnB,4EAA4E,CAC/E,CAAC;IACN,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { NextFunction, Request, Response } from 'express';
2
+ export declare const loginController: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3
+ //# sourceMappingURL=login.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.controller.d.ts","sourceRoot":"","sources":["../../../src/features/login/login.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM1D,eAAO,MAAM,eAAe,GACxB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACnB,OAAO,CAAC,IAAI,CAUd,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { getConfig } from '../../core/stores/config.store.js';
2
+ import { sendSuccess } from '../../utils/response.js';
3
+ import { validateRegisterInput } from '../register/register.validator.js';
4
+ import { loginUser } from './login.service.js';
5
+ export const loginController = async (req, res, next) => {
6
+ try {
7
+ const input = validateRegisterInput(req.body);
8
+ const config = getConfig();
9
+ const result = await loginUser(input, config);
10
+ sendSuccess(res, result, 'Login successful');
11
+ }
12
+ catch (err) {
13
+ next(err);
14
+ }
15
+ };
16
+ //# sourceMappingURL=login.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.controller.js","sourceRoot":"","sources":["../../../src/features/login/login.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAChC,GAAY,EACZ,GAAa,EACb,IAAkB,EACL,EAAE;IACf,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE9C,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { LoginInput, LoginResult } from '../../types/auth.types.js';
2
+ import { SecureAuthConfig } from '../../types/config.types.js';
3
+ export declare const loginUser: (input: LoginInput, config: SecureAuthConfig) => Promise<LoginResult>;
4
+ //# sourceMappingURL=login.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.service.d.ts","sourceRoot":"","sources":["../../../src/features/login/login.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAM/D,eAAO,MAAM,SAAS,GAClB,OAAO,UAAU,EACjB,QAAQ,gBAAgB,KACzB,OAAO,CAAC,WAAW,CAkBrB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { AppError } from '../../utils/AppError.js';
2
+ import { comparePassword } from '../../utils/hash.js';
3
+ import { generateAccessToken, generateRefreshToken } from '../../utils/jwt.js';
4
+ import { sanitizeUser } from '../../utils/sanitizeUser.js';
5
+ export const loginUser = async (input, config) => {
6
+ const { userModel, jwt: jwtConfig } = config;
7
+ const user = await userModel.findOne({ email: input.email }).select('+password');
8
+ if (!user) {
9
+ throw AppError.unauthorized('Invalid email or password', 'INVALID_CREDENTIALS');
10
+ }
11
+ const isMatch = await comparePassword(input.password, user.password);
12
+ if (!isMatch) {
13
+ throw AppError.unauthorized('Invalid email or password', 'INVALID_CREDENTIALS');
14
+ }
15
+ const tokenPayload = { userId: String(user._id), email: user.email };
16
+ const accessToken = generateAccessToken(tokenPayload, jwtConfig);
17
+ const refreshToken = generateRefreshToken(tokenPayload, jwtConfig);
18
+ return { user: sanitizeUser(user), tokens: { accessToken, refreshToken } };
19
+ };
20
+ //# sourceMappingURL=login.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.service.js","sourceRoot":"","sources":["../../../src/features/login/login.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC1B,KAAiB,EACjB,MAAwB,EACJ,EAAE;IACtB,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE7C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACjF,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,MAAM,QAAQ,CAAC,YAAY,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,QAAQ,CAAC,YAAY,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACrE,MAAM,WAAW,GAAG,mBAAmB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,oBAAoB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAEnE,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,CAAC;AAC/E,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { LoginInput } from '../../types/auth.types.js';
2
+ export declare const validateLoginInput: (body: unknown) => LoginInput;
3
+ //# sourceMappingURL=login.validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.validator.d.ts","sourceRoot":"","sources":["../../../src/features/login/login.validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAGvD,eAAO,MAAM,kBAAkB,GAAI,MAAM,OAAO,KAAG,UAgBlD,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { AppError } from '../../utils/AppError.js';
2
+ export const validateLoginInput = (body) => {
3
+ if (typeof body !== 'object' || body === null) {
4
+ throw AppError.badRequest('Request body is required', 'INVALID_BODY');
5
+ }
6
+ const { email, password } = body;
7
+ if (typeof email !== 'string' || !email.trim()) {
8
+ throw AppError.badRequest('Email is required', 'EMAIL_REQUIRED');
9
+ }
10
+ if (typeof password !== 'string' || !password) {
11
+ throw AppError.badRequest('Password is required', 'PASSWORD_REQUIRED');
12
+ }
13
+ return { email: email.toLowerCase().trim(), password };
14
+ };
15
+ //# sourceMappingURL=login.validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.validator.js","sourceRoot":"","sources":["../../../src/features/login/login.validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAa,EAAc,EAAE;IAC5D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,QAAQ,CAAC,UAAU,CAAC,0BAA0B,EAAE,cAAc,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAA+B,CAAC;IAE5D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,QAAQ,CAAC,UAAU,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,QAAQ,CAAC,UAAU,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC;AAC3D,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { NextFunction, Request, Response } from 'express';
2
+ export declare const meController: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3
+ //# sourceMappingURL=me.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"me.controller.d.ts","sourceRoot":"","sources":["../../../src/features/me/me.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM1D,eAAO,MAAM,YAAY,GACrB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACnB,OAAO,CAAC,IAAI,CAiBd,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { getConfig } from '../../core/stores/config.store.js';
2
+ import { AppError } from '../../utils/AppError.js';
3
+ import { sendSuccess } from '../../utils/response.js';
4
+ import { sanitizeUser } from '../../utils/sanitizeUser.js';
5
+ export const meController = async (req, res, next) => {
6
+ try {
7
+ if (!req.user) {
8
+ throw AppError.unauthorized('Authentication required');
9
+ }
10
+ const { userModel } = getConfig();
11
+ const user = await userModel.findById(req.user.id);
12
+ if (!user) {
13
+ throw AppError.notFound('User not found', 'USER_NOT_FOUND');
14
+ }
15
+ sendSuccess(res, sanitizeUser(user));
16
+ }
17
+ catch (err) {
18
+ next(err);
19
+ }
20
+ };
21
+ //# sourceMappingURL=me.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"me.controller.js","sourceRoot":"","sources":["../../../src/features/me/me.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC7B,GAAY,EACZ,GAAa,EACb,IAAkB,EACL,EAAE;IACf,IAAI,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACZ,MAAM,QAAQ,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC;QAElC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;QAChE,CAAC;QAED,WAAW,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { NextFunction, Request, Response } from 'express';
2
+ export declare const registerController: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3
+ //# sourceMappingURL=register.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.controller.d.ts","sourceRoot":"","sources":["../../../src/features/register/register.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM1D,eAAO,MAAM,kBAAkB,GAC3B,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACnB,OAAO,CAAC,IAAI,CAUd,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { getConfig } from '../../core/stores/config.store.js';
2
+ import { sendSuccess } from '../../utils/response.js';
3
+ import { registerUser } from './register.service.js';
4
+ import { validateRegisterInput } from './register.validator.js';
5
+ export const registerController = async (req, res, next) => {
6
+ try {
7
+ const input = validateRegisterInput(req.body);
8
+ const config = getConfig();
9
+ const result = await registerUser(input, config);
10
+ sendSuccess(res, result, 'Registration successful', 201);
11
+ }
12
+ catch (err) {
13
+ next(err);
14
+ }
15
+ };
16
+ //# sourceMappingURL=register.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.controller.js","sourceRoot":"","sources":["../../../src/features/register/register.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACnC,GAAY,EACZ,GAAa,EACb,IAAkB,EACL,EAAE;IACf,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAEjD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { RegisterInput, RegisterResult } from '../../types/auth.types.js';
2
+ import { SecureAuthConfig } from '../../types/config.types.js';
3
+ export declare const registerUser: (input: RegisterInput, config: SecureAuthConfig) => Promise<RegisterResult>;
4
+ //# sourceMappingURL=register.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.service.d.ts","sourceRoot":"","sources":["../../../src/features/register/register.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAM/D,eAAO,MAAM,YAAY,GACrB,OAAO,aAAa,EACpB,QAAQ,gBAAgB,KACzB,OAAO,CAAC,cAAc,CAuBxB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { AppError } from '../../utils/AppError.js';
2
+ import { hashPassword } from '../../utils/hash.js';
3
+ import { generateAccessToken, generateRefreshToken } from '../../utils/jwt.js';
4
+ import { sanitizeUser } from '../../utils/sanitizeUser.js';
5
+ export const registerUser = async (input, config) => {
6
+ const { userModel, jwt: jwtConfig } = config;
7
+ const existingUser = await userModel.findOne({ email: input.email });
8
+ if (existingUser) {
9
+ throw AppError.badRequest('Email is already registered', 'EMAIL_TAKEN');
10
+ }
11
+ const hash_password = await hashPassword(input.password);
12
+ const user = await userModel.create({
13
+ ...input,
14
+ password: hash_password,
15
+ });
16
+ const tokenPayload = { userId: String(user._id), email: user.email };
17
+ const accessToken = generateAccessToken(tokenPayload, jwtConfig);
18
+ const refreshToken = generateRefreshToken(tokenPayload, jwtConfig);
19
+ return {
20
+ user: sanitizeUser(user),
21
+ tokens: { accessToken, refreshToken },
22
+ };
23
+ };
24
+ //# sourceMappingURL=register.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.service.js","sourceRoot":"","sources":["../../../src/features/register/register.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC7B,KAAoB,EACpB,MAAwB,EACD,EAAE;IACzB,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE7C,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACrE,IAAI,YAAY,EAAE,CAAC;QACf,MAAM,QAAQ,CAAC,UAAU,CAAC,6BAA6B,EAAE,aAAa,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEzD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC;QAChC,GAAG,KAAK;QACR,QAAQ,EAAE,aAAa;KAC1B,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACrE,MAAM,WAAW,GAAG,mBAAmB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACjE,MAAM,YAAY,GAAG,oBAAoB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAEnE,OAAO;QACH,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC;QACxB,MAAM,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE;KACxC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { RegisterInput } from '../../types/auth.types.js';
2
+ export declare const validateRegisterInput: (body: unknown) => RegisterInput;
3
+ //# sourceMappingURL=register.validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.validator.d.ts","sourceRoot":"","sources":["../../../src/features/register/register.validator.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D,eAAO,MAAM,qBAAqB,GAAI,MAAM,OAAO,KAAG,aAuDrD,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { EMAIL_REGEX, MIN_PASSWORD_LENGTH, PASSWORD_LOWERCASE_REGEX, PASSWORD_NUMBER_REGEX, PASSWORD_SPECIAL_CHARACTER_REGEX, PASSWORD_UPPERCASE_REGEX, } from '../../constants/index.js';
2
+ import { AppError } from '../../utils/AppError.js';
3
+ export const validateRegisterInput = (body) => {
4
+ if (typeof body !== 'object' || body === null) {
5
+ throw AppError.badRequest('Request body is required', 'INVALID_BODY');
6
+ }
7
+ const { email, password, ...rest } = body;
8
+ if (typeof email !== 'string' || !email.trim()) {
9
+ throw AppError.badRequest('Email is required', 'EMAIL_REQUIRED');
10
+ }
11
+ if (!EMAIL_REGEX.test(email)) {
12
+ throw AppError.badRequest('Invalid email format', 'EMAIL_INVALID');
13
+ }
14
+ if (typeof password !== 'string' || !password) {
15
+ throw AppError.badRequest('Password is required', 'PASSWORD_REQUIRED');
16
+ }
17
+ if (password.length < MIN_PASSWORD_LENGTH) {
18
+ throw AppError.badRequest(`Password must be at least ${MIN_PASSWORD_LENGTH} characters`, 'PASSWORD_TOO_SHORT');
19
+ }
20
+ if (!PASSWORD_UPPERCASE_REGEX.test(password)) {
21
+ throw AppError.badRequest('Password must be at least one uppercase letter', 'PASSWORD_MISSING_UPPERCASE_LETTER');
22
+ }
23
+ if (!PASSWORD_LOWERCASE_REGEX.test(password)) {
24
+ throw AppError.badRequest('Password must be at least one lowercase letter', 'PASSWORD_MISSING_LOWERCASE_LETTER');
25
+ }
26
+ if (!PASSWORD_NUMBER_REGEX.test(password)) {
27
+ throw AppError.badRequest('Password must contain at least one number', 'PASSWORD_MISSING_NUMBER');
28
+ }
29
+ if (!PASSWORD_SPECIAL_CHARACTER_REGEX.test(password)) {
30
+ throw AppError.badRequest('Password must be at least one special character', 'PASSWORD_MISSING_SPECIAL_CHARACTER');
31
+ }
32
+ return { email: email.toLowerCase().trim(), password, ...rest };
33
+ };
34
+ //# sourceMappingURL=register.validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.validator.js","sourceRoot":"","sources":["../../../src/features/register/register.validator.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,gCAAgC,EAChC,wBAAwB,GAC3B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAa,EAAiB,EAAE;IAClE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,QAAQ,CAAC,UAAU,CAAC,0BAA0B,EAAE,cAAc,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,IAA+B,CAAC;IAErE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,QAAQ,CAAC,UAAU,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,QAAQ,CAAC,UAAU,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,QAAQ,CAAC,UAAU,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACxC,MAAM,QAAQ,CAAC,UAAU,CACrB,6BAA6B,mBAAmB,aAAa,EAC7D,oBAAoB,CACvB,CAAC;IACN,CAAC;IAED,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,MAAM,QAAQ,CAAC,UAAU,CACrB,gDAAgD,EAChD,mCAAmC,CACtC,CAAC;IACN,CAAC;IAED,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,MAAM,QAAQ,CAAC,UAAU,CACrB,gDAAgD,EAChD,mCAAmC,CACtC,CAAC;IACN,CAAC;IAED,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,MAAM,QAAQ,CAAC,UAAU,CACrB,2CAA2C,EAC3C,yBAAyB,CAC5B,CAAC;IACN,CAAC;IAED,IAAI,CAAC,gCAAgC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,MAAM,QAAQ,CAAC,UAAU,CACrB,iDAAiD,EACjD,oCAAoC,CACvC,CAAC;IACN,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC;AACpE,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Express } from 'express';
2
+ import { SecureAuthConfig } from './types/config.types.js';
3
+ export declare function secureAuth(app: Express, config: SecureAuthConfig): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAWvE"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ import { errorMiddleware } from './core/middleware/error.middleware.js';
2
+ import { createAuthRouter } from './core/routes/auth.routes.js';
3
+ import { setConfig } from './core/stores/config.store.js';
4
+ export function secureAuth(app, config) {
5
+ validateConfig(config);
6
+ setConfig(config);
7
+ const prefix = config.routePrefix ?? '/auth';
8
+ // Core auth router
9
+ app.use(prefix, createAuthRouter());
10
+ // Error Handler
11
+ app.use(errorMiddleware);
12
+ }
13
+ const validateConfig = (config) => {
14
+ if (!config.userModel) {
15
+ throw new Error('[secure-auth-kit] config.userModel is required. ' +
16
+ 'Pass your Mongoose User model: secureAuth(app, {userModel: User, ... })');
17
+ }
18
+ if (!config.jwt?.secret) {
19
+ throw new Error('[secure-auth-kit] config.jwt.secret is required. ' +
20
+ 'Set JWT_SECRET in your environment and pass it via: jwt: { secret: process.env.JWT_SECRET }');
21
+ }
22
+ const emailPath = config.userModel.schema.path('email');
23
+ if (!emailPath) {
24
+ throw new Error('[secure-auth-kit] Your User model is missing the required "email" field.' +
25
+ 'Add `email: { type: String, required: true, unique: true }` to your schema.');
26
+ }
27
+ const passwordPath = config.userModel.schema.path('password');
28
+ if (!passwordPath) {
29
+ throw new Error('[secure-auth-kit] Your User model is missing the required "password" field.' +
30
+ 'Add `password: { type: String, required: true}` to your schema.');
31
+ }
32
+ };
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAG1D,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,MAAwB;IAC7D,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,SAAS,CAAC,MAAM,CAAC,CAAC;IAElB,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,IAAI,OAAO,CAAC;IAC7C,mBAAmB;IACnB,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAEpC,gBAAgB;IAChB,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,MAAwB,EAAQ,EAAE;IACtD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACX,kDAAkD;YAC9C,yEAAyE,CAChF,CAAC;IACN,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACX,mDAAmD;YAC/C,6FAA6F,CACpG,CAAC;IACN,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACX,0EAA0E;YACtE,6EAA6E,CACpF,CAAC;IACN,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACX,6EAA6E;YACzE,iEAAiE,CACxE,CAAC;IACN,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { NextFunction, Request, Response } from 'express';
2
+ export declare const extractBearerToken: (authHeader: string | undefined) => string | null;
3
+ export declare const authenticate: (req: Request, res: Response, next: NextFunction) => void;
4
+ //# sourceMappingURL=authenticate.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/authenticate.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAK1D,eAAO,MAAM,kBAAkB,GAAI,YAAY,MAAM,GAAG,SAAS,KAAG,MAAM,GAAG,IAI5E,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IAqB9E,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { getConfig } from '../core/stores/config.store.js';
2
+ import { AppError } from '../utils/AppError.js';
3
+ import { verifyToken } from '../utils/jwt.js';
4
+ export const extractBearerToken = (authHeader) => {
5
+ if (!authHeader?.startsWith('Bearer '))
6
+ return null;
7
+ const token = authHeader.slice(7).trim();
8
+ return token || null;
9
+ };
10
+ export const authenticate = (req, res, next) => {
11
+ try {
12
+ const token = extractBearerToken(req.headers.authorization);
13
+ if (!token) {
14
+ throw AppError.unauthorized('Bearer token is required', 'TOKEN_MISSING');
15
+ }
16
+ const config = getConfig();
17
+ const payload = verifyToken(token, config.jwt);
18
+ if (payload.type === 'access') {
19
+ throw AppError.unauthorized('Invalid token type', 'TOKEN_TYPE_MISMATCH');
20
+ }
21
+ req.user = { id: payload.userId, email: payload.email };
22
+ next();
23
+ }
24
+ catch (err) {
25
+ next(err);
26
+ }
27
+ };
28
+ //# sourceMappingURL=authenticate.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.middleware.js","sourceRoot":"","sources":["../../src/middleware/authenticate.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAA8B,EAAiB,EAAE;IAChF,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,OAAO,KAAK,IAAI,IAAI,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;IAClF,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAE5D,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,QAAQ,CAAC,YAAY,CAAC,0BAA0B,EAAE,eAAe,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QAE/C,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,QAAQ,CAAC,YAAY,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;QAC7E,CAAC;QAED,GAAG,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAExD,IAAI,EAAE,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ export interface AuthenticatedUser {
2
+ id: string;
3
+ email: string;
4
+ [key: string]: unknown;
5
+ }
6
+ export interface RegisterInput {
7
+ email: string;
8
+ password: string;
9
+ [key: string]: unknown;
10
+ }
11
+ export interface LoginInput {
12
+ email: string;
13
+ password: string;
14
+ }
15
+ export interface SanitizedUser {
16
+ id: string;
17
+ email: string;
18
+ [key: string]: unknown;
19
+ }
20
+ export interface AuthTokens {
21
+ accessToken: string;
22
+ refreshToken: string;
23
+ }
24
+ export interface RegisterResult {
25
+ user: SanitizedUser;
26
+ tokens: AuthTokens;
27
+ }
28
+ export interface LoginResult {
29
+ user: SanitizedUser;
30
+ tokens: AuthTokens;
31
+ }
32
+ //# sourceMappingURL=auth.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.types.d.ts","sourceRoot":"","sources":["../../src/types/auth.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=auth.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.types.js","sourceRoot":"","sources":["../../src/types/auth.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { Document, Model } from 'mongoose';
2
+ import { JWTConfig } from './jwt.types.js';
3
+ export interface UserDocument extends Document {
4
+ email: string;
5
+ password: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface SecureAuthConfig {
9
+ userModel: Model<UserDocument>;
10
+ jwt: JWTConfig;
11
+ routePrefix?: string;
12
+ }
13
+ //# sourceMappingURL=config.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.types.d.ts","sourceRoot":"","sources":["../../src/types/config.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAC/B,GAAG,EAAE,SAAS,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.types.js","sourceRoot":"","sources":["../../src/types/config.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export interface TokenPayload {
2
+ userId: string;
3
+ email: string;
4
+ type: 'access' | 'refresh';
5
+ exp?: number;
6
+ }
7
+ export interface JWTConfig {
8
+ secret: string;
9
+ accessTokenExpiry?: string;
10
+ refreshTokenExpiry?: string;
11
+ }
12
+ //# sourceMappingURL=jwt.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.types.d.ts","sourceRoot":"","sources":["../../src/types/jwt.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jwt.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.types.js","sourceRoot":"","sources":["../../src/types/jwt.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export declare class AppError extends Error {
2
+ readonly statusCode: number;
3
+ readonly isOperational: boolean;
4
+ readonly code?: string;
5
+ constructor(message: string, statusCode: number, code?: string);
6
+ static badRequest(message: string, code?: string): AppError;
7
+ static unauthorized(message?: string, code?: string): AppError;
8
+ static forbidden(message?: string, code?: string): AppError;
9
+ static notFound(message?: string, code?: string): AppError;
10
+ static internal(message?: string, code?: string): AppError;
11
+ }
12
+ //# sourceMappingURL=AppError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppError.d.ts","sourceRoot":"","sources":["../../src/utils/AppError.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAS,SAAQ,KAAK;IAC/B,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,aAAa,EAAE,OAAO,CAAC;IACvC,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAW9D,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ;IAI3D,MAAM,CAAC,YAAY,CAAC,OAAO,SAAiB,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ;IAItE,MAAM,CAAC,SAAS,CAAC,OAAO,SAAc,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ;IAIhE,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAc,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ;IAI/D,MAAM,CAAC,QAAQ,CAAC,OAAO,SAA0B,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ;CAG9E"}
@@ -0,0 +1,30 @@
1
+ export class AppError extends Error {
2
+ statusCode;
3
+ isOperational;
4
+ code;
5
+ constructor(message, statusCode, code) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.isOperational = true;
9
+ this.code = code;
10
+ // Restore prototype chain
11
+ Object.setPrototypeOf(this, new.target.prototype);
12
+ Error.captureStackTrace(this, this.constructor);
13
+ }
14
+ static badRequest(message, code) {
15
+ return new AppError(message, 400, code);
16
+ }
17
+ static unauthorized(message = 'Unauthorized', code) {
18
+ return new AppError(message, 401, code);
19
+ }
20
+ static forbidden(message = 'Forbidden', code) {
21
+ return new AppError(message, 403, code);
22
+ }
23
+ static notFound(message = 'Not found', code) {
24
+ return new AppError(message, 404, code);
25
+ }
26
+ static internal(message = 'Internal server error', code) {
27
+ return new AppError(message, 500, code);
28
+ }
29
+ }
30
+ //# sourceMappingURL=AppError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppError.js","sourceRoot":"","sources":["../../src/utils/AppError.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACf,UAAU,CAAS;IACnB,aAAa,CAAU;IACvB,IAAI,CAAU;IAE9B,YAAY,OAAe,EAAE,UAAkB,EAAE,IAAa;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,0BAA0B;QAC1B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,OAAe,EAAE,IAAa;QAC5C,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAO,GAAG,cAAc,EAAE,IAAa;QACvD,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,WAAW,EAAE,IAAa;QACjD,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,WAAW,EAAE,IAAa;QAChD,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,uBAAuB,EAAE,IAAa;QAC5D,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;CACJ"}
@@ -0,0 +1,3 @@
1
+ export declare function hashPassword(plaintext: string): Promise<string>;
2
+ export declare function comparePassword(plaintext: string, hashed: string): Promise<boolean>;
3
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAGA,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAErE;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzF"}
@@ -0,0 +1,9 @@
1
+ import bcrypt from 'bcryptjs';
2
+ import { SALT_ROUNDS } from '../constants/index.js';
3
+ export async function hashPassword(plaintext) {
4
+ return bcrypt.hash(plaintext, SALT_ROUNDS);
5
+ }
6
+ export async function comparePassword(plaintext, hashed) {
7
+ return bcrypt.compare(plaintext, hashed);
8
+ }
9
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAChD,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,MAAc;IACnE,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { JWTConfig, TokenPayload } from '../types/jwt.types.js';
2
+ export declare function generateAccessToken(payload: Omit<TokenPayload, 'type' | 'exp'>, config: JWTConfig): string;
3
+ export declare function generateRefreshToken(payload: Omit<TokenPayload, 'type' | 'exp'>, config: JWTConfig): string;
4
+ export declare function verifyToken(token: string, config: JWTConfig): TokenPayload;
5
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/utils/jwt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGhE,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,EAC3C,MAAM,EAAE,SAAS,GAClB,MAAM,CAIR;AAED,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,EAC3C,MAAM,EAAE,SAAS,GAClB,MAAM,CAIR;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,YAAY,CAc1E"}
@@ -0,0 +1,27 @@
1
+ import jwt from 'jsonwebtoken';
2
+ import { AppError } from './AppError.js';
3
+ export function generateAccessToken(payload, config) {
4
+ return jwt.sign({ ...payload, type: 'access' }, config.secret, {
5
+ expiresIn: config.accessTokenExpiry ?? '15m',
6
+ });
7
+ }
8
+ export function generateRefreshToken(payload, config) {
9
+ return jwt.sign({ ...payload, type: 'refresh' }, config.secret, {
10
+ expiresIn: config.refreshTokenExpiry ?? '7d',
11
+ });
12
+ }
13
+ export function verifyToken(token, config) {
14
+ try {
15
+ return jwt.verify(token, config.secret);
16
+ }
17
+ catch (error) {
18
+ if (error instanceof jwt.TokenExpiredError) {
19
+ throw AppError.unauthorized('Token has expired', 'TOKEN_EXPIRED');
20
+ }
21
+ if (error instanceof jwt.JsonWebTokenError) {
22
+ throw AppError.unauthorized('Invalid token', 'TOKEN_INVALID');
23
+ }
24
+ throw AppError.unauthorized('Token verification failed');
25
+ }
26
+ }
27
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/utils/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,UAAU,mBAAmB,CAC/B,OAA2C,EAC3C,MAAiB;IAEjB,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE;QAC3D,SAAS,EAAE,MAAM,CAAC,iBAAiB,IAAI,KAAK;KAC5B,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAChC,OAA2C,EAC3C,MAAiB;IAEjB,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE;QAC5D,SAAS,EAAE,MAAM,CAAC,kBAAkB,IAAI,IAAI;KAC5B,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,MAAiB;IACxD,IAAI,CAAC;QACD,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAiB,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,YAAY,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,QAAQ,CAAC,YAAY,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,KAAK,YAAY,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,QAAQ,CAAC,YAAY,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,QAAQ,CAAC,YAAY,CAAC,2BAA2B,CAAC,CAAC;IAC7D,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Response } from 'express';
2
+ export interface SuccessResponse<T = unknown> {
3
+ success: true;
4
+ data: T;
5
+ message?: string;
6
+ }
7
+ export interface ErrorResponse {
8
+ success: false;
9
+ error: {
10
+ message: string;
11
+ code?: string;
12
+ statusCode: number;
13
+ };
14
+ }
15
+ export declare function sendSuccess<T>(res: Response, data: T, message?: string, statusCode?: number): void;
16
+ export declare function sendError(res: Response, message: string, statusCode?: number, code?: string): void;
17
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE;QACH,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACtB,CAAC;CACL;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,SAAM,GAAG,IAAI,CAO/F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,SAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAU/F"}
@@ -0,0 +1,20 @@
1
+ export function sendSuccess(res, data, message, statusCode = 200) {
2
+ const body = {
3
+ success: true,
4
+ data,
5
+ ...(message ? { message } : {}),
6
+ };
7
+ res.status(statusCode).json(body);
8
+ }
9
+ export function sendError(res, message, statusCode = 500, code) {
10
+ const body = {
11
+ success: false,
12
+ error: {
13
+ message,
14
+ statusCode,
15
+ ...(code ? { code } : {}),
16
+ },
17
+ };
18
+ res.status(statusCode).json(body);
19
+ }
20
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,WAAW,CAAI,GAAa,EAAE,IAAO,EAAE,OAAgB,EAAE,UAAU,GAAG,GAAG;IACrF,MAAM,IAAI,GAAuB;QAC7B,OAAO,EAAE,IAAI;QACb,IAAI;QACJ,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClC,CAAC;IACF,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAa,EAAE,OAAe,EAAE,UAAU,GAAG,GAAG,EAAE,IAAa;IACrF,MAAM,IAAI,GAAkB;QACxB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE;YACH,OAAO;YACP,UAAU;YACV,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5B;KACJ,CAAC;IACF,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { SanitizedUser } from '../types/auth.types.js';
2
+ import { UserDocument } from '../types/config.types.js';
3
+ export declare function sanitizeUser(user: UserDocument): SanitizedUser;
4
+ //# sourceMappingURL=sanitizeUser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeUser.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizeUser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAkB9D"}
@@ -0,0 +1,17 @@
1
+ import { SENSITIVE_FIELDS } from '../constants/index.js';
2
+ export function sanitizeUser(user) {
3
+ const raw = typeof user.toObject === 'function' ? user.toObject() : { ...user };
4
+ const sanitized = {};
5
+ for (const [key, val] of Object.entries(raw)) {
6
+ if (!SENSITIVE_FIELDS.has(key)) {
7
+ sanitized[key] = val;
8
+ }
9
+ }
10
+ // Normalize _id -> id
11
+ if (raw._id !== undefined) {
12
+ sanitized['id'] = String(raw._id);
13
+ delete sanitized['_id'];
14
+ }
15
+ return sanitized;
16
+ }
17
+ //# sourceMappingURL=sanitizeUser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeUser.js","sourceRoot":"","sources":["../../src/utils/sanitizeUser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,MAAM,UAAU,YAAY,CAAC,IAAkB;IAC3C,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;IAEhF,MAAM,SAAS,GAA4B,EAAE,CAAC;IAE9C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACzB,CAAC;IACL,CAAC;IAED,sBAAsB;IACtB,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QACxB,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,SAA0B,CAAC;AACtC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "secure-auth-kit",
3
+ "version": "1.0.1",
4
+ "description": "Authentication toolkit for Express and MongoDB",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc"
22
+ },
23
+ "keywords": [
24
+ "authentication",
25
+ "jwt",
26
+ "express",
27
+ "mongoose",
28
+ "typescript",
29
+ "auth"
30
+ ],
31
+ "license": "MIT",
32
+ "peerDependencies": {
33
+ "express": "^5.0.0",
34
+ "mongoose": "^8.0.0"
35
+ },
36
+ "dependencies": {
37
+ "bcryptjs": "^2.4.3",
38
+ "jsonwebtoken": "^9.0.2"
39
+ },
40
+ "devDependencies": {
41
+ "@types/bcryptjs": "^2.4.6",
42
+ "@types/express": "^5.0.0",
43
+ "@types/jsonwebtoken": "^9.0.6",
44
+ "@types/node": "^20.0.0",
45
+ "typescript": "^5.4.0",
46
+ "express": "^5.2.1",
47
+ "mongoose": "^8.24.0"
48
+ }
49
+ }