@taladel/common 1.0.6

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 (42) hide show
  1. package/dist/correlation/middleware.d.ts +5 -0
  2. package/dist/correlation/middleware.d.ts.map +1 -0
  3. package/dist/correlation/middleware.js +59 -0
  4. package/dist/correlation/middleware.js.map +1 -0
  5. package/dist/correlation/types.d.ts +28 -0
  6. package/dist/correlation/types.d.ts.map +1 -0
  7. package/dist/correlation/types.js +3 -0
  8. package/dist/correlation/types.js.map +1 -0
  9. package/dist/errors/custom-error.d.ts +6 -0
  10. package/dist/errors/custom-error.d.ts.map +1 -0
  11. package/dist/errors/custom-error.js +14 -0
  12. package/dist/errors/custom-error.js.map +1 -0
  13. package/dist/index.d.ts +9 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +10 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/middlewares/auth-req.d.ts +12 -0
  18. package/dist/middlewares/auth-req.d.ts.map +1 -0
  19. package/dist/middlewares/auth-req.js +21 -0
  20. package/dist/middlewares/auth-req.js.map +1 -0
  21. package/dist/middlewares/error-handler.d.ts +4 -0
  22. package/dist/middlewares/error-handler.d.ts.map +1 -0
  23. package/dist/middlewares/error-handler.js +12 -0
  24. package/dist/middlewares/error-handler.js.map +1 -0
  25. package/dist/services/jwt.service.d.ts +9 -0
  26. package/dist/services/jwt.service.d.ts.map +1 -0
  27. package/dist/services/jwt.service.js +27 -0
  28. package/dist/services/jwt.service.js.map +1 -0
  29. package/dist/services/password.service.d.ts +6 -0
  30. package/dist/services/password.service.d.ts.map +1 -0
  31. package/dist/services/password.service.js +18 -0
  32. package/dist/services/password.service.js.map +1 -0
  33. package/package.json +34 -0
  34. package/src/correlation/middleware.ts +33 -0
  35. package/src/correlation/types.ts +34 -0
  36. package/src/errors/custom-error.ts +13 -0
  37. package/src/index.ts +16 -0
  38. package/src/middlewares/auth-req.ts +35 -0
  39. package/src/middlewares/error-handler.ts +19 -0
  40. package/src/services/jwt.service.ts +32 -0
  41. package/src/services/password.service.ts +16 -0
  42. package/tsconfig.json +58 -0
@@ -0,0 +1,5 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { CorrelationIdOptions } from './types';
3
+ export declare function correlationIdMiddleware(options?: CorrelationIdOptions): (req: Request, res: Response, next: NextFunction) => void;
4
+ export declare function getCorrelationId(): string | undefined;
5
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/correlation/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAExD,OAAO,EAAE,oBAAoB,EAA0B,MAAM,SAAS,CAAC;AAIvE,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,oBAAyB,IAc9D,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAO1D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAErD"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.correlationIdMiddleware = correlationIdMiddleware;
37
+ exports.getCorrelationId = getCorrelationId;
38
+ const crypto_1 = require("crypto");
39
+ const rTracer = __importStar(require("cls-rtracer"));
40
+ const DEFAULT_HEADER_NAME = 'x-correlation-id';
41
+ function correlationIdMiddleware(options = {}) {
42
+ const { headerName = DEFAULT_HEADER_NAME, echoHeader = true, generator = crypto_1.randomUUID, } = options;
43
+ const rTracerMiddleware = rTracer.expressMiddleware({
44
+ useHeader: true,
45
+ headerName: headerName,
46
+ echoHeader: echoHeader,
47
+ requestIdFactory: generator,
48
+ });
49
+ return (req, res, next) => {
50
+ rTracerMiddleware(req, res, () => {
51
+ req.correlationId = () => rTracer.id();
52
+ next();
53
+ });
54
+ };
55
+ }
56
+ function getCorrelationId() {
57
+ return rTracer.id();
58
+ }
59
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/correlation/middleware.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,0DAqBC;AAED,4CAEC;AAhCD,mCAAoC;AAEpC,qDAAuC;AAGvC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAE/C,SAAgB,uBAAuB,CAAC,UAAgC,EAAE;IACtE,MAAM,EACF,UAAU,GAAG,mBAAmB,EAChC,UAAU,GAAG,IAAI,EACjB,SAAS,GAAG,mBAAU,GACzB,GAAG,OAAO,CAAC;IAEZ,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QAChD,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,UAAU;QACtB,UAAU,EAAE,UAAU;QACtB,gBAAgB,EAAE,SAAS;KAC9B,CAAC,CAAC;IAEH,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACvD,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;YAC5B,GAA8B,CAAC,aAAa,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,EAAwB,CAAC;YAEzF,IAAI,EAAE,CAAC;QACX,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC;AAED,SAAgB,gBAAgB;IAC5B,OAAO,OAAO,CAAC,EAAE,EAAwB,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { Request } from "express";
2
+ export interface CorrelationIdOptions {
3
+ /**
4
+ * Header name to use for correlation ID
5
+ * @default 'x-correlation-id'
6
+ */
7
+ headerName?: string;
8
+ /**
9
+ * send the correlation ID back to client in the response headers
10
+ * Whether to echo the correlation ID back in response headers
11
+ * @default true
12
+ */
13
+ echoHeader?: boolean;
14
+ /**
15
+ * Custom function to generate correlation IDs (som)
16
+ * If not provided, UUID v4 WILL BE USED
17
+ */
18
+ generator?: () => string;
19
+ }
20
+ export interface RequestWithCorrelation extends Request {
21
+ /**
22
+ * its not a default property ,this extends the request type
23
+ * its a function becouse its matches the pattern from cls-rtracer library
24
+ * Get the correlation ID for the current request
25
+ */
26
+ correlationId: () => string | undefined;
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/correlation/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,oBAAoB;IAEjC;;;OAGG;IAEH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IAEH,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAuB,SAAQ,OAAO;IACvD;;;;OAIG;IACC,aAAa,EAAE,MAAK,MAAM,GAAG,SAAS,CAAC;CAC1C"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/correlation/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ export declare class CustomError extends Error {
2
+ statusCode: number;
3
+ message: string;
4
+ constructor(statusCode: number, message: string);
5
+ }
6
+ //# sourceMappingURL=custom-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-error.d.ts","sourceRoot":"","sources":["../../src/errors/custom-error.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;gBAEX,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAQlD"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CustomError = void 0;
4
+ class CustomError extends Error {
5
+ constructor(statusCode, message) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.message = message;
9
+ Object.setPrototypeOf(this, CustomError.prototype);
10
+ Error.captureStackTrace(this, this.constructor);
11
+ }
12
+ }
13
+ exports.CustomError = CustomError;
14
+ //# sourceMappingURL=custom-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-error.js","sourceRoot":"","sources":["../../src/errors/custom-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,WAAY,SAAQ,KAAK;IAIlC,YAAY,UAAkB,EAAE,OAAe;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;QACnD,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;CACJ;AAZD,kCAYC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Export the middleware and getCorrelationId function
3
+ */
4
+ export { correlationIdMiddleware, getCorrelationId, } from './correlation/middleware';
5
+ /**
6
+ * Export the types
7
+ */
8
+ export type { CorrelationIdOptions, RequestWithCorrelation, } from './correlation/types';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACH,uBAAuB,EACvB,gBAAgB,GACnB,MAAM,0BAA0B,CAAC;AAGlC;;GAEG;AACH,YAAY,EACR,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCorrelationId = exports.correlationIdMiddleware = void 0;
4
+ /**
5
+ * Export the middleware and getCorrelationId function
6
+ */
7
+ var middleware_1 = require("./correlation/middleware");
8
+ Object.defineProperty(exports, "correlationIdMiddleware", { enumerable: true, get: function () { return middleware_1.correlationIdMiddleware; } });
9
+ Object.defineProperty(exports, "getCorrelationId", { enumerable: true, get: function () { return middleware_1.getCorrelationId; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,uDAGkC;AAF9B,qHAAA,uBAAuB,OAAA;AACvB,8GAAA,gBAAgB,OAAA"}
@@ -0,0 +1,12 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import { JwtPayload } from "jsonwebtoken";
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ currentUser?: JwtPayload;
7
+ }
8
+ }
9
+ }
10
+ declare const authenticate: (req: Request, _res: Response, next: NextFunction) => Promise<void>;
11
+ export default authenticate;
12
+ //# sourceMappingURL=auth-req.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-req.d.ts","sourceRoot":"","sources":["../../src/middlewares/auth-req.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,OAAO,CAAC;QACd,UAAU,OAAO;YACb,WAAW,CAAC,EAAE,UAAU,CAAC;SAC5B;KACJ;CACJ;AAED,QAAA,MAAM,YAAY,GACd,KAAK,OAAO,EACZ,MAAM,QAAQ,EACd,MAAM,YAAY,KACnB,OAAO,CAAC,IAAI,CAed,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const jwt_service_1 = __importDefault(require("../services/jwt.service"));
7
+ const custom_error_1 = require("../errors/custom-error");
8
+ const authenticate = async (req, _res, next) => {
9
+ const authHeader = req.headers.authorization;
10
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
11
+ throw new custom_error_1.CustomError(401, 'no token provided');
12
+ }
13
+ const token = authHeader.split(' ')[1];
14
+ if (!token) {
15
+ throw new custom_error_1.CustomError(401, 'no token provided');
16
+ }
17
+ req.currentUser = jwt_service_1.default.verifyToken(token);
18
+ next();
19
+ };
20
+ exports.default = authenticate;
21
+ //# sourceMappingURL=auth-req.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-req.js","sourceRoot":"","sources":["../../src/middlewares/auth-req.ts"],"names":[],"mappings":";;;;;AAAA,0EAAiE;AAEjE,yDAAqD;AAWrD,MAAM,YAAY,GAAG,KAAK,EACtB,GAAY,EACZ,IAAc,EACd,IAAkB,EACL,EAAE;IACf,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;IAE7C,IAAG,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,0BAAW,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvC,IAAG,CAAC,KAAK,EAAE,CAAC;QACR,MAAM,IAAI,0BAAW,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;IACpD,CAAC;IAED,GAAG,CAAC,WAAW,GAAG,qBAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,EAAE,CAAC;AACX,CAAC,CAAC;AAEF,kBAAe,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ declare const errorHandler: (err: Error, _req: Request, res: Response, _next: NextFunction) => void;
3
+ export default errorHandler;
4
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middlewares/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGxD,QAAA,MAAM,YAAY,GACf,KAAK,KAAK,EACV,MAAM,OAAO,EACb,KAAK,QAAQ,EACb,OAAO,YAAY,KACpB,IAQF,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const custom_error_1 = require("../errors/custom-error");
4
+ const errorHandler = (err, _req, res, _next) => {
5
+ if (err instanceof custom_error_1.CustomError) {
6
+ res.status(err.statusCode).json({ message: err.message });
7
+ }
8
+ console.error(err.stack);
9
+ res.status(500).json({ message: err.message || 'Internal Server Error' });
10
+ };
11
+ exports.default = errorHandler;
12
+ //# sourceMappingURL=error-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middlewares/error-handler.ts"],"names":[],"mappings":";;AACA,yDAAqD;AAEpD,MAAM,YAAY,GAAG,CAClB,GAAU,EACV,IAAa,EACb,GAAa,EACb,KAAmB,EACf,EAAE;IAEN,IAAG,GAAG,YAAY,0BAAW,EAAC,CAAC;QAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,uBAAuB,EAAE,CAAC,CAAC;AAC9E,CAAC,CAAC;AAEF,kBAAe,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface jwtPayload {
2
+ userId?: string;
3
+ email?: string;
4
+ }
5
+ export default class JwtService {
6
+ static generateToken(payload: jwtPayload): string;
7
+ static verifyToken(token: string): jwtPayload;
8
+ }
9
+ //# sourceMappingURL=jwt.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.service.d.ts","sourceRoot":"","sources":["../../src/services/jwt.service.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAElB;AAED,MAAM,CAAC,OAAO,OAAO,UAAU;IAC3B,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;IAWjD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;CAUhD"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
7
+ const custom_error_1 = require("../errors/custom-error");
8
+ class JwtService {
9
+ static generateToken(payload) {
10
+ return jsonwebtoken_1.default.sign(payload, process.env.JWT_SECRET, {
11
+ expiresIn: '1h',
12
+ algorithm: 'HS256'
13
+ });
14
+ }
15
+ static verifyToken(token) {
16
+ try {
17
+ return jsonwebtoken_1.default.verify(token, process.env.JWT_SECRET, {
18
+ algorithms: ['HS256']
19
+ });
20
+ }
21
+ catch (error) {
22
+ throw new custom_error_1.CustomError(401, 'invalid or expired token');
23
+ }
24
+ }
25
+ }
26
+ exports.default = JwtService;
27
+ //# sourceMappingURL=jwt.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.service.js","sourceRoot":"","sources":["../../src/services/jwt.service.ts"],"names":[],"mappings":";;;;;AAAA,gEAA+B;AAC/B,yDAAqD;AAQrD,MAAqB,UAAU;IAC3B,MAAM,CAAC,aAAa,CAAC,OAAmB;QACpC,OAAO,sBAAG,CAAC,IAAI,CACX,OAAO,EACP,OAAO,CAAC,GAAG,CAAC,UAAW,EACvB;YACE,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,OAAO;SACnB,CACJ,CAAC;IACN,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,KAAa;QAC5B,IAAI,CAAC;YACL,OAAO,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW,EAAE;gBACtC,UAAU,EAAE,CAAC,OAAO,CAAC;aAC5B,CAAe,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,0BAAW,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;CAEJ;AAtBD,6BAsBC"}
@@ -0,0 +1,6 @@
1
+ export declare class PasswordService {
2
+ private static readonly SALT_ROUNDS;
3
+ static hashPassword(plainPassword: string): Promise<string>;
4
+ static comparePassword(plainPassword: string, hashedPassword: string): Promise<boolean>;
5
+ }
6
+ //# sourceMappingURL=password.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.service.d.ts","sourceRoot":"","sources":["../../src/services/password.service.ts"],"names":[],"mappings":"AAEA,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAM;WAE5B,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAIpD,eAAe,CACxB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC;CAGtB"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PasswordService = void 0;
7
+ const bcryptjs_1 = __importDefault(require("bcryptjs"));
8
+ class PasswordService {
9
+ static async hashPassword(plainPassword) {
10
+ return bcryptjs_1.default.hash(plainPassword, this.SALT_ROUNDS);
11
+ }
12
+ static async comparePassword(plainPassword, hashedPassword) {
13
+ return bcryptjs_1.default.compare(plainPassword, hashedPassword);
14
+ }
15
+ }
16
+ exports.PasswordService = PasswordService;
17
+ PasswordService.SALT_ROUNDS = 10;
18
+ //# sourceMappingURL=password.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.service.js","sourceRoot":"","sources":["../../src/services/password.service.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA8B;AAE9B,MAAa,eAAe;IAGxB,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,aAAqB;QAC3C,OAAO,kBAAM,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,eAAe,CACxB,aAAqB,EACrB,cAAsB;QAEtB,OAAO,kBAAM,CAAC,OAAO,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IACzD,CAAC;;AAZL,0CAaC;AAZ2B,2BAAW,GAAG,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@taladel/common",
3
+ "version": "1.0.6",
4
+ "description": "common utilities for microservices",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "scripts": {
11
+ "clean": "rm -rf dist",
12
+ "build": "npm run clean && tsc",
13
+ "pub": "git add . && git commit -m \"Updates\" && npm version patch && npm run build && npm publish && git push && git push --tags"
14
+ },
15
+ "keywords": [],
16
+ "author": "",
17
+ "license": "ISC",
18
+ "type": "commonjs",
19
+ "peerDependencies": {
20
+ "express": "^5.2.1"
21
+ },
22
+ "dependencies": {
23
+ "cls-rtracer": "^2.6.3",
24
+ "jsonwebtoken": "^9.0.3",
25
+ "bcryptjs": "^3.0.3"
26
+ },
27
+ "devDependencies": {
28
+ "@types/express": "^5.0.6",
29
+ "@types/jsonwebtoken": "^9.0.10",
30
+ "@types/node": "^25.0.6",
31
+ "@types/bcryptjs": "^2.4.6",
32
+ "typescript": "^5.9.3"
33
+ }
34
+ }
@@ -0,0 +1,33 @@
1
+ import { randomUUID } from 'crypto';
2
+ import {Request, Response, NextFunction} from 'express';
3
+ import * as rTracer from 'cls-rtracer';
4
+ import { CorrelationIdOptions, RequestWithCorrelation } from './types';
5
+
6
+ const DEFAULT_HEADER_NAME = 'x-correlation-id';
7
+
8
+ export function correlationIdMiddleware(options: CorrelationIdOptions = {}){
9
+ const {
10
+ headerName = DEFAULT_HEADER_NAME,
11
+ echoHeader = true,
12
+ generator = randomUUID,
13
+ } = options;
14
+
15
+ const rTracerMiddleware = rTracer.expressMiddleware({
16
+ useHeader: true,
17
+ headerName: headerName,
18
+ echoHeader: echoHeader,
19
+ requestIdFactory: generator,
20
+ });
21
+
22
+ return (req: Request, res: Response, next: NextFunction) => {
23
+ rTracerMiddleware(req, res, () => {
24
+ (req as RequestWithCorrelation).correlationId = () => rTracer.id() as string | undefined;
25
+
26
+ next();
27
+ });
28
+ };
29
+ }
30
+
31
+ export function getCorrelationId(): string | undefined {
32
+ return rTracer.id() as string | undefined;
33
+ }
@@ -0,0 +1,34 @@
1
+ import { Request } from "express";
2
+
3
+ export interface CorrelationIdOptions{
4
+
5
+ /**
6
+ * Header name to use for correlation ID
7
+ * @default 'x-correlation-id'
8
+ */
9
+
10
+ headerName?: string;
11
+
12
+ /**
13
+ * send the correlation ID back to client in the response headers
14
+ * Whether to echo the correlation ID back in response headers
15
+ * @default true
16
+ */
17
+ echoHeader?: boolean;
18
+
19
+ /**
20
+ * Custom function to generate correlation IDs (som)
21
+ * If not provided, UUID v4 WILL BE USED
22
+ */
23
+
24
+ generator?: () => string;
25
+ }
26
+
27
+ export interface RequestWithCorrelation extends Request{
28
+ /**
29
+ * its not a default property ,this extends the request type
30
+ * its a function becouse its matches the pattern from cls-rtracer library
31
+ * Get the correlation ID for the current request
32
+ */
33
+ correlationId: ()=> string | undefined;
34
+ }
@@ -0,0 +1,13 @@
1
+ export class CustomError extends Error{
2
+ public statusCode: number;
3
+ public message: string;
4
+
5
+ constructor(statusCode: number, message: string) {
6
+ super(message);
7
+ this.statusCode = statusCode;
8
+ this.message = message;
9
+
10
+ Object.setPrototypeOf(this, CustomError.prototype);
11
+ Error.captureStackTrace(this, this.constructor);
12
+ }
13
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Export the middleware and getCorrelationId function
3
+ */
4
+ export {
5
+ correlationIdMiddleware,
6
+ getCorrelationId,
7
+ } from './correlation/middleware';
8
+
9
+
10
+ /**
11
+ * Export the types
12
+ */
13
+ export type {
14
+ CorrelationIdOptions,
15
+ RequestWithCorrelation,
16
+ } from './correlation/types';
@@ -0,0 +1,35 @@
1
+ import JwtService, { jwtPayload } from "../services/jwt.service";
2
+ import { Request, Response, NextFunction } from "express";
3
+ import { CustomError } from "../errors/custom-error";
4
+ import { JwtPayload } from "jsonwebtoken";
5
+
6
+ declare global {
7
+ namespace Express {
8
+ interface Request {
9
+ currentUser?: JwtPayload;
10
+ }
11
+ }
12
+ }
13
+
14
+ const authenticate = async (
15
+ req: Request,
16
+ _res: Response,
17
+ next: NextFunction
18
+ ): Promise<void> => {
19
+ const authHeader = req.headers.authorization;
20
+
21
+ if(!authHeader || !authHeader.startsWith('Bearer ')) {
22
+ throw new CustomError(401, 'no token provided');
23
+ }
24
+
25
+ const token = authHeader.split(' ')[1];
26
+
27
+ if(!token) {
28
+ throw new CustomError(401, 'no token provided');
29
+ }
30
+
31
+ req.currentUser = JwtService.verifyToken(token);
32
+ next();
33
+ };
34
+
35
+ export default authenticate;
@@ -0,0 +1,19 @@
1
+ import {Request, Response, NextFunction } from "express";
2
+ import { CustomError } from "../errors/custom-error";
3
+
4
+ const errorHandler = (
5
+ err: Error,
6
+ _req: Request,
7
+ res: Response,
8
+ _next: NextFunction
9
+ ): void => {
10
+
11
+ if(err instanceof CustomError){
12
+ res.status(err.statusCode).json({ message: err.message });
13
+ }
14
+
15
+ console.error(err.stack);
16
+ res.status(500).json({ message: err.message || 'Internal Server Error' });
17
+ };
18
+
19
+ export default errorHandler;
@@ -0,0 +1,32 @@
1
+ import jwt from 'jsonwebtoken';
2
+ import { CustomError } from '../errors/custom-error';
3
+
4
+ export interface jwtPayload {
5
+ userId?: string;
6
+ email?: string;
7
+
8
+ }
9
+
10
+ export default class JwtService{
11
+ static generateToken(payload: jwtPayload): string {
12
+ return jwt.sign(
13
+ payload,
14
+ process.env.JWT_SECRET!,
15
+ {
16
+ expiresIn: '1h',
17
+ algorithm: 'HS256'
18
+ }
19
+ );
20
+ }
21
+
22
+ static verifyToken(token: string): jwtPayload {
23
+ try {
24
+ return jwt.verify(token, process.env.JWT_SECRET!, {
25
+ algorithms: ['HS256']
26
+ }) as jwtPayload;
27
+ } catch (error) {
28
+ throw new CustomError(401, 'invalid or expired token');
29
+ }
30
+ }
31
+
32
+ }
@@ -0,0 +1,16 @@
1
+ import bcrypt from 'bcryptjs';
2
+
3
+ export class PasswordService {
4
+ private static readonly SALT_ROUNDS = 10;
5
+
6
+ static async hashPassword(plainPassword: string): Promise<string> {
7
+ return bcrypt.hash(plainPassword, this.SALT_ROUNDS);
8
+ }
9
+
10
+ static async comparePassword(
11
+ plainPassword: string,
12
+ hashedPassword: string
13
+ ): Promise<boolean> {
14
+ return bcrypt.compare(plainPassword, hashedPassword);
15
+ }
16
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ // "rootDir": "./src",
6
+ // "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+
11
+ "target": "ES2020",
12
+ "module": "commonjs",
13
+ "lib": ["ES2020"],
14
+ "outDir": "./dist",
15
+ "rootDir":"./src",
16
+ "declaration": true,
17
+ "sourceMap": true,
18
+ "declarationMap": true,
19
+ "types": [],
20
+ // For nodejs:
21
+ // "lib": ["esnext"],
22
+ // "types": ["node"],
23
+ // and npm install -D @types/node
24
+
25
+ // Other Outputs
26
+
27
+
28
+
29
+ // // Stricter Typechecking Options
30
+ // "noUncheckedIndexedAccess": true,
31
+ // "exactOptionalPropertyTypes": true,
32
+
33
+ // Style Options
34
+ // "noImplicitReturns": true,
35
+ // "noImplicitOverride": true,
36
+ // "noUnusedLocals": true,
37
+ // "noUnusedParameters": true,
38
+ // "noFallthroughCasesInSwitch": true,
39
+ // "noPropertyAccessFromIndexSignature": true,
40
+
41
+ // Recommended Options
42
+ "strict": true,
43
+ "esModuleInterop": true,
44
+ "skipLibCheck": true,
45
+ "forceConsistentCasingInFileNames": true,
46
+ "moduleResolution": "node",
47
+ "resolveJsonModule": true,
48
+
49
+ // "jsx": "react-jsx",
50
+ // "verbatimModuleSyntax": true,
51
+ // "isolatedModules": true,
52
+ // "noUncheckedSideEffectImports": true,
53
+ // "moduleDetection": "force",
54
+
55
+ },
56
+ "include": ["src/**/*"],
57
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
58
+ }