@helpio/common 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 (45) hide show
  1. package/build/errors/bad-request-error.d.ts +9 -0
  2. package/build/errors/bad-request-error.js +16 -0
  3. package/build/errors/custom-error.d.ts +8 -0
  4. package/build/errors/custom-error.js +10 -0
  5. package/build/errors/database-connection-error.d.ts +9 -0
  6. package/build/errors/database-connection-error.js +16 -0
  7. package/build/errors/not-authorized-error.d.ts +8 -0
  8. package/build/errors/not-authorized-error.js +15 -0
  9. package/build/errors/not-found-error.d.ts +8 -0
  10. package/build/errors/not-found-error.js +15 -0
  11. package/build/errors/request-validation-error.d.ts +11 -0
  12. package/build/errors/request-validation-error.js +19 -0
  13. package/build/events/consumer.d.ts +2 -0
  14. package/build/events/consumer.js +161 -0
  15. package/build/events/event-utils.d.ts +7 -0
  16. package/build/events/event-utils.js +13 -0
  17. package/build/events/inbox.d.ts +8 -0
  18. package/build/events/inbox.js +47 -0
  19. package/build/events/outbox.d.ts +34 -0
  20. package/build/events/outbox.js +189 -0
  21. package/build/events/producer.d.ts +5 -0
  22. package/build/events/producer.js +143 -0
  23. package/build/events/publishers/user-created-publisher.d.ts +6 -0
  24. package/build/events/publishers/user-created-publisher.js +21 -0
  25. package/build/events/publishers/user-updated-publisher.d.ts +6 -0
  26. package/build/events/publishers/user-updated-publisher.js +21 -0
  27. package/build/events/types/index.d.ts +6 -0
  28. package/build/events/types/index.js +14 -0
  29. package/build/events/types/user-events.d.ts +131 -0
  30. package/build/events/types/user-events.js +6 -0
  31. package/build/index.d.ts +20 -0
  32. package/build/index.js +34 -0
  33. package/build/middlewares/current-user.d.ts +2 -0
  34. package/build/middlewares/current-user.js +20 -0
  35. package/build/middlewares/error-handler.d.ts +2 -0
  36. package/build/middlewares/error-handler.js +14 -0
  37. package/build/middlewares/require-auth.d.ts +12 -0
  38. package/build/middlewares/require-auth.js +91 -0
  39. package/build/middlewares/system-logger.d.ts +0 -0
  40. package/build/middlewares/system-logger.js +1 -0
  41. package/build/middlewares/validate-request.d.ts +2 -0
  42. package/build/middlewares/validate-request.js +13 -0
  43. package/build/types/auth.d.ts +22 -0
  44. package/build/types/auth.js +5 -0
  45. package/package.json +40 -0
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.publishEvent = exports.publishEventWithMeta = exports.connectProducer = void 0;
32
+ const amqp = __importStar(require("amqplib"));
33
+ const event_utils_1 = require("./event-utils");
34
+ const outbox_1 = require("./outbox");
35
+ let rabbitConnection;
36
+ let channel;
37
+ const DEFAULT_EXCHANGE = process.env.RABBITMQ_EXCHANGE || "rentbase.events";
38
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
39
+ const publishWithConfirm = (exchange, routingKey, payload, options) => {
40
+ if (!channel) {
41
+ return Promise.reject(new Error("RabbitMQ channel not initialized. Call connectProducer() first."));
42
+ }
43
+ return new Promise((resolve, reject) => {
44
+ channel.publish(exchange, routingKey, payload, options, (err) => {
45
+ if (err)
46
+ return reject(err);
47
+ resolve();
48
+ });
49
+ });
50
+ };
51
+ const sendToQueueWithConfirm = (queueName, payload, options) => {
52
+ if (!channel) {
53
+ return Promise.reject(new Error("RabbitMQ channel not initialized. Call connectProducer() first."));
54
+ }
55
+ return new Promise((resolve, reject) => {
56
+ channel.sendToQueue(queueName, payload, options, (err) => {
57
+ if (err)
58
+ return reject(err);
59
+ resolve();
60
+ });
61
+ });
62
+ };
63
+ const connectProducer = (rabbitUrl, retries = 5, delay = 3000) => __awaiter(void 0, void 0, void 0, function* () {
64
+ try {
65
+ const connection = yield amqp.connect(rabbitUrl);
66
+ rabbitConnection = connection;
67
+ connection.on("error", (err) => {
68
+ console.error("[RabbitMQ Producer ❌] connection error:", err);
69
+ });
70
+ connection.on("close", () => {
71
+ console.error("[RabbitMQ Producer ❌] connection closed");
72
+ rabbitConnection = undefined;
73
+ channel = undefined;
74
+ });
75
+ channel = yield connection.createConfirmChannel();
76
+ yield channel.assertExchange(DEFAULT_EXCHANGE, "topic", { durable: true });
77
+ if (process.env.RABBITMQ_OUTBOX_AUTO_DISPATCH === "true") {
78
+ try {
79
+ (0, outbox_1.startOutboxDispatcher)(rabbitUrl);
80
+ }
81
+ catch (err) {
82
+ console.error("[Outbox] Failed to start dispatcher", (err === null || err === void 0 ? void 0 : err.message) || err);
83
+ }
84
+ }
85
+ console.log("[RabbitMQ Producer ✅] Connected successfully (confirm channel)");
86
+ }
87
+ catch (err) {
88
+ console.error(`[RabbitMQ Producer ❌] Connection failed. Retries left: ${retries}`, (err === null || err === void 0 ? void 0 : err.message) || err);
89
+ if (retries > 0) {
90
+ yield sleep(delay);
91
+ return (0, exports.connectProducer)(rabbitUrl, retries - 1, delay);
92
+ }
93
+ console.error("[RabbitMQ Producer 💥] Exhausted all retries. RabbitMQ unavailable.");
94
+ }
95
+ });
96
+ exports.connectProducer = connectProducer;
97
+ const publishEventWithMeta = (queue, message, meta = {}) => __awaiter(void 0, void 0, void 0, function* () {
98
+ if (!channel)
99
+ throw new Error("RabbitMQ channel not initialized. Call connectProducer() first.");
100
+ // Topic exchange enables pub/sub (each service can bind its own durable queue).
101
+ yield channel.assertExchange(DEFAULT_EXCHANGE, "topic", { durable: true });
102
+ const payload = Buffer.from(JSON.stringify(message));
103
+ const routingKey = String(queue);
104
+ const eventId = meta.eventId || (0, event_utils_1.generateEventId)();
105
+ const occurredAt = meta.occurredAt || new Date();
106
+ const sourceService = meta.sourceService ||
107
+ process.env.SERVICE_NAME ||
108
+ process.env.npm_package_name;
109
+ const headers = Object.assign(Object.assign(Object.assign({}, (meta.headers || {})), { "x-event-id": eventId, "x-occurred-at": occurredAt.toISOString() }), (sourceService ? { "x-source-service": sourceService } : {}));
110
+ yield publishWithConfirm(DEFAULT_EXCHANGE, routingKey, payload, {
111
+ persistent: true,
112
+ contentType: "application/json",
113
+ messageId: eventId,
114
+ headers,
115
+ });
116
+ // Optional legacy mode for old consumers that still read directly from a shared queue.
117
+ if (process.env.RABBITMQ_LEGACY_QUEUE === "true") {
118
+ yield channel.assertQueue(routingKey, { durable: true });
119
+ yield sendToQueueWithConfirm(routingKey, payload, {
120
+ persistent: true,
121
+ contentType: "application/json",
122
+ messageId: eventId,
123
+ headers,
124
+ });
125
+ }
126
+ console.log(`[Producer ➡️] Published ${routingKey} on ${DEFAULT_EXCHANGE}:`, message);
127
+ });
128
+ exports.publishEventWithMeta = publishEventWithMeta;
129
+ const publishEvent = (queue, message) => __awaiter(void 0, void 0, void 0, function* () {
130
+ // Optional Outbox mode: persist first, then let dispatcher publish.
131
+ if (process.env.RABBITMQ_USE_OUTBOX === "true") {
132
+ try {
133
+ const eventId = yield (0, outbox_1.enqueueOutboxEvent)(queue, message);
134
+ console.log(`[Producer ➕Outbox] Enqueued ${String(queue)} (${eventId})`);
135
+ return;
136
+ }
137
+ catch (err) {
138
+ console.warn("[Producer ➕Outbox] Enqueue failed; falling back to direct publish:", (err === null || err === void 0 ? void 0 : err.message) || err);
139
+ }
140
+ }
141
+ yield (0, exports.publishEventWithMeta)(queue, message);
142
+ });
143
+ exports.publishEvent = publishEvent;
@@ -0,0 +1,6 @@
1
+ import { UserCreatedEvent } from "../types/user-events";
2
+ /**
3
+ * Publish user.created event
4
+ * Called when a new user is created
5
+ */
6
+ export declare const publishUserCreated: (data: UserCreatedEvent) => Promise<void>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.publishUserCreated = void 0;
13
+ const producer_1 = require("../producer");
14
+ /**
15
+ * Publish user.created event
16
+ * Called when a new user is created
17
+ */
18
+ const publishUserCreated = (data) => __awaiter(void 0, void 0, void 0, function* () {
19
+ yield (0, producer_1.publishEvent)("user.created", data);
20
+ });
21
+ exports.publishUserCreated = publishUserCreated;
@@ -0,0 +1,6 @@
1
+ import { UserUpdatedEvent } from "../types/user-events";
2
+ /**
3
+ * Publish user.updated event
4
+ * Called when a user's information is updated
5
+ */
6
+ export declare const publishUserUpdated: (data: UserUpdatedEvent) => Promise<void>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.publishUserUpdated = void 0;
13
+ const producer_1 = require("../producer");
14
+ /**
15
+ * Publish user.updated event
16
+ * Called when a user's information is updated
17
+ */
18
+ const publishUserUpdated = (data) => __awaiter(void 0, void 0, void 0, function* () {
19
+ yield (0, producer_1.publishEvent)("user.updated", data);
20
+ });
21
+ exports.publishUserUpdated = publishUserUpdated;
@@ -0,0 +1,6 @@
1
+ import { UserCreatedEvent, UserUpdatedEvent } from "./user-events";
2
+ export interface EventMap {
3
+ "user.created": UserCreatedEvent;
4
+ "user.updated": UserUpdatedEvent;
5
+ }
6
+ export * from "./user-events";
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ // Export all event types
14
+ __exportStar(require("./user-events"), exports);
@@ -0,0 +1,131 @@
1
+ /**
2
+ * User Event Types for Property Marketplace
3
+ * Updated to match auth-service User model schema
4
+ */
5
+ export declare type UserRole = "tenant" | "landlord" | "property_agent" | "support_agent" | "city_admin" | "super_admin";
6
+ export declare type UserStatus = "active" | "suspended" | "banned" | "deleted";
7
+ export declare type KycStatus = "unverified" | "pending" | "verified" | "needs_info" | "rejected";
8
+ export declare type VerificationLevel = "none" | "basic" | "verified" | "super_verified";
9
+ export declare type UserActiveMode = "tenant" | "landlord" | "admin";
10
+ export interface UserCreatedEvent {
11
+ id: string;
12
+ accountNumber: number;
13
+ firstName: string;
14
+ lastName: string;
15
+ email?: string;
16
+ phoneNumber: string;
17
+ roles: UserRole[];
18
+ activeMode: UserActiveMode;
19
+ address?: string;
20
+ city?: string;
21
+ country?: string;
22
+ countryCode?: string;
23
+ languagePreference: string;
24
+ avatarUrl?: string;
25
+ kycStatus: KycStatus;
26
+ verificationLevel: VerificationLevel;
27
+ emailVerifiedAt?: Date;
28
+ phoneVerifiedAt?: Date;
29
+ trustScore: number;
30
+ cancellationCount: number;
31
+ cancellationStrikes: number;
32
+ totalPropertiesListed?: number;
33
+ totalPropertiesRented?: number;
34
+ landlordRating?: number;
35
+ tenantRating?: number;
36
+ landlordRatingCount?: number;
37
+ tenantRatingCount?: number;
38
+ oauthProvider?: "google" | "facebook" | "github" | "apple";
39
+ oauthId?: string;
40
+ biometricEnabled?: boolean;
41
+ biometricPublicKey?: string;
42
+ biometricDeviceId?: string;
43
+ status: UserStatus;
44
+ createdAt: Date;
45
+ updatedAt: Date;
46
+ }
47
+ export interface UserUpdatedEvent {
48
+ id: string;
49
+ accountNumber: number;
50
+ firstName: string;
51
+ lastName: string;
52
+ email?: string;
53
+ phoneNumber: string;
54
+ roles: UserRole[];
55
+ activeMode: UserActiveMode;
56
+ address?: string;
57
+ city?: string;
58
+ country?: string;
59
+ countryCode?: string;
60
+ languagePreference: string;
61
+ avatarUrl?: string;
62
+ kycStatus: KycStatus;
63
+ verificationLevel: VerificationLevel;
64
+ emailVerifiedAt?: Date;
65
+ phoneVerifiedAt?: Date;
66
+ trustScore: number;
67
+ cancellationCount: number;
68
+ cancellationStrikes: number;
69
+ totalPropertiesListed?: number;
70
+ totalPropertiesRented?: number;
71
+ landlordRating?: number;
72
+ tenantRating?: number;
73
+ landlordRatingCount?: number;
74
+ tenantRatingCount?: number;
75
+ oauthProvider?: "google" | "facebook" | "github" | "apple";
76
+ oauthId?: string;
77
+ biometricEnabled?: boolean;
78
+ biometricPublicKey?: string;
79
+ biometricDeviceId?: string;
80
+ status: UserStatus;
81
+ createdAt: Date;
82
+ updatedAt: Date;
83
+ }
84
+ export interface UserDeletedEvent {
85
+ id: string;
86
+ accountNumber: number;
87
+ email?: string;
88
+ phoneNumber: string;
89
+ deletedAt: Date;
90
+ reason?: string;
91
+ }
92
+ export interface UserStatusChangedEvent {
93
+ id: string;
94
+ accountNumber: number;
95
+ oldStatus: UserStatus;
96
+ newStatus: UserStatus;
97
+ reason?: string;
98
+ changedBy?: string;
99
+ changedAt: Date;
100
+ }
101
+ export interface UserRolesUpdatedEvent {
102
+ id: string;
103
+ accountNumber: number;
104
+ oldRoles: UserRole[];
105
+ newRoles: UserRole[];
106
+ updatedBy?: string;
107
+ updatedAt: Date;
108
+ }
109
+ export interface UserModeChangedEvent {
110
+ id: string;
111
+ accountNumber: number;
112
+ oldMode: UserActiveMode;
113
+ newMode: UserActiveMode;
114
+ changedAt: Date;
115
+ }
116
+ export interface UserVerifiedEvent {
117
+ id: string;
118
+ accountNumber: number;
119
+ verificationType: "email" | "phone";
120
+ verifiedAt: Date;
121
+ }
122
+ export interface UserKycUpdatedEvent {
123
+ id: string;
124
+ accountNumber: number;
125
+ oldKycStatus: KycStatus;
126
+ newKycStatus: KycStatus;
127
+ oldVerificationLevel: VerificationLevel;
128
+ newVerificationLevel: VerificationLevel;
129
+ updatedBy?: string;
130
+ updatedAt: Date;
131
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * User Event Types for Property Marketplace
4
+ * Updated to match auth-service User model schema
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,20 @@
1
+ export * from "./errors/bad-request-error";
2
+ export * from "./errors/custom-error";
3
+ export * from "./errors/database-connection-error";
4
+ export * from "./errors/not-authorized-error";
5
+ export * from "./errors/not-found-error";
6
+ export * from "./errors/request-validation-error";
7
+ export * from "./types/auth";
8
+ export * from "./middlewares/current-user";
9
+ export * from "./middlewares/error-handler";
10
+ export * from "./middlewares/require-auth";
11
+ export * from "./middlewares/validate-request";
12
+ export * from "./events/consumer";
13
+ export * from "./events/producer";
14
+ export * from "./events/event-utils";
15
+ export * from "./events/outbox";
16
+ export * from "./events/inbox";
17
+ export * from "./events/types/user-events";
18
+ export * from "./events/types";
19
+ export * from "./events/publishers/user-created-publisher";
20
+ export * from "./events/publishers/user-updated-publisher";
package/build/index.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ // Re-export stuff from errors and middlewares
14
+ __exportStar(require("./errors/bad-request-error"), exports);
15
+ __exportStar(require("./errors/custom-error"), exports);
16
+ __exportStar(require("./errors/database-connection-error"), exports);
17
+ __exportStar(require("./errors/not-authorized-error"), exports);
18
+ __exportStar(require("./errors/not-found-error"), exports);
19
+ __exportStar(require("./errors/request-validation-error"), exports);
20
+ __exportStar(require("./types/auth"), exports);
21
+ __exportStar(require("./middlewares/current-user"), exports);
22
+ __exportStar(require("./middlewares/error-handler"), exports);
23
+ __exportStar(require("./middlewares/require-auth"), exports);
24
+ __exportStar(require("./middlewares/validate-request"), exports);
25
+ __exportStar(require("./events/consumer"), exports);
26
+ __exportStar(require("./events/producer"), exports);
27
+ __exportStar(require("./events/event-utils"), exports);
28
+ __exportStar(require("./events/outbox"), exports);
29
+ __exportStar(require("./events/inbox"), exports);
30
+ __exportStar(require("./events/types/user-events"), exports);
31
+ __exportStar(require("./events/types"), exports);
32
+ // User event publishers
33
+ __exportStar(require("./events/publishers/user-created-publisher"), exports);
34
+ __exportStar(require("./events/publishers/user-updated-publisher"), exports);
@@ -0,0 +1,2 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ export declare const currentUser: (req: Request, res: Response, next: NextFunction) => void;
@@ -0,0 +1,20 @@
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.currentUser = void 0;
7
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
+ const currentUser = (req, res, next) => {
9
+ var _a;
10
+ if (!((_a = req.session) === null || _a === void 0 ? void 0 : _a.jwt)) {
11
+ return next();
12
+ }
13
+ try {
14
+ const payload = jsonwebtoken_1.default.verify(req.session.jwt, process.env.JWT_KEY);
15
+ req.currentUser = payload;
16
+ }
17
+ catch (err) { }
18
+ next();
19
+ };
20
+ exports.currentUser = currentUser;
@@ -0,0 +1,2 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ export declare const errorHandler: (err: Error, req: Request, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.errorHandler = void 0;
4
+ const custom_error_1 = require("../errors/custom-error");
5
+ const errorHandler = (err, req, res, next) => {
6
+ if (err instanceof custom_error_1.CustomError) {
7
+ return res.status(err.statusCode).send({ errors: err.serializeErrors() });
8
+ }
9
+ console.error(err);
10
+ res.status(400).send({
11
+ errors: [{ message: 'Something went wrong' }],
12
+ });
13
+ };
14
+ exports.errorHandler = errorHandler;
@@ -0,0 +1,12 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ /**
3
+ * Middleware: Require authentication
4
+ * Verifies JWT access token and attaches user payload to request
5
+ * Works across all microservices
6
+ */
7
+ export declare const requireAuth: (req: Request, res: Response, next: NextFunction) => Response<any, Record<string, any>> | undefined;
8
+ /**
9
+ * Middleware: Optional authentication
10
+ * Loads user if token is present, but doesn't require it
11
+ */
12
+ export declare const optionalAuth: (req: Request, res: Response, next: NextFunction) => void;
@@ -0,0 +1,91 @@
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.optionalAuth = exports.requireAuth = void 0;
7
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
+ const not_authorized_error_1 = require("../errors/not-authorized-error");
9
+ const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key-change-in-production";
10
+ /**
11
+ * Middleware: Require authentication
12
+ * Verifies JWT access token and attaches user payload to request
13
+ * Works across all microservices
14
+ */
15
+ const requireAuth = (req, res, next) => {
16
+ var _a;
17
+ try {
18
+ // Extract token from Authorization header or cookies
19
+ const authHeader = req.headers.authorization;
20
+ const token = (authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith("Bearer "))
21
+ ? authHeader.substring(7)
22
+ : (_a = req.cookies) === null || _a === void 0 ? void 0 : _a.accessToken;
23
+ // Check if token exists
24
+ if (!token) {
25
+ console.log("[requireAuth] No token provided");
26
+ throw new not_authorized_error_1.NotAuthorizedError();
27
+ }
28
+ // Verify token
29
+ const payload = jsonwebtoken_1.default.verify(token, JWT_SECRET);
30
+ console.log("[requireAuth] Token verified successfully:", {
31
+ userId: payload.userId,
32
+ id: payload.id,
33
+ email: payload.email,
34
+ hasAccountNumber: !!payload.accountNumber
35
+ });
36
+ // Attach user payload to request
37
+ req.currentUser = payload;
38
+ // Support both legacy 'id' and new 'userId' formats
39
+ req.userId = payload.userId || payload.id;
40
+ req.sessionId = payload.sessionId;
41
+ next();
42
+ }
43
+ catch (err) {
44
+ console.error("[requireAuth] Error:", err.message, err.name);
45
+ if (err.name === "TokenExpiredError") {
46
+ return res.status(401).json({
47
+ error: "TOKEN_EXPIRED",
48
+ message: "Authentication token has expired",
49
+ });
50
+ }
51
+ if (err.name === "JsonWebTokenError") {
52
+ return res.status(401).json({
53
+ error: "INVALID_TOKEN",
54
+ message: "Invalid authentication token",
55
+ });
56
+ }
57
+ // For NotAuthorizedError or other errors
58
+ return res.status(401).json({
59
+ error: "UNAUTHORIZED",
60
+ message: "Authentication required",
61
+ });
62
+ }
63
+ };
64
+ exports.requireAuth = requireAuth;
65
+ /**
66
+ * Middleware: Optional authentication
67
+ * Loads user if token is present, but doesn't require it
68
+ */
69
+ const optionalAuth = (req, res, next) => {
70
+ var _a;
71
+ try {
72
+ const authHeader = req.headers.authorization;
73
+ const token = (authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith("Bearer "))
74
+ ? authHeader.substring(7)
75
+ : (_a = req.cookies) === null || _a === void 0 ? void 0 : _a.accessToken;
76
+ if (!token) {
77
+ return next();
78
+ }
79
+ const payload = jsonwebtoken_1.default.verify(token, JWT_SECRET);
80
+ req.currentUser = payload;
81
+ // Support both legacy 'id' and new 'userId' formats
82
+ req.userId = payload.userId || payload.id;
83
+ req.sessionId = payload.sessionId;
84
+ next();
85
+ }
86
+ catch (error) {
87
+ // Silently fail for optional auth
88
+ next();
89
+ }
90
+ };
91
+ exports.optionalAuth = optionalAuth;
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,2 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ export declare const validateRequest: (req: Request, res: Response, next: NextFunction) => void;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateRequest = void 0;
4
+ const express_validator_1 = require("express-validator");
5
+ const request_validation_error_1 = require("../errors/request-validation-error");
6
+ const validateRequest = (req, res, next) => {
7
+ const errors = (0, express_validator_1.validationResult)(req);
8
+ if (!errors.isEmpty()) {
9
+ throw new request_validation_error_1.RequestValidationError(errors.array());
10
+ }
11
+ next();
12
+ };
13
+ exports.validateRequest = validateRequest;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Common types for authentication across all services
3
+ */
4
+ export interface UserPayload {
5
+ id?: string;
6
+ userId?: string;
7
+ email?: string;
8
+ phoneNumber?: string;
9
+ roles?: string[];
10
+ activeMode?: string;
11
+ sessionId?: string;
12
+ [key: string]: any;
13
+ }
14
+ declare global {
15
+ namespace Express {
16
+ interface Request {
17
+ currentUser?: UserPayload;
18
+ userId?: string;
19
+ sessionId?: string;
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * Common types for authentication across all services
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });