@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.
- package/build/errors/bad-request-error.d.ts +9 -0
- package/build/errors/bad-request-error.js +16 -0
- package/build/errors/custom-error.d.ts +8 -0
- package/build/errors/custom-error.js +10 -0
- package/build/errors/database-connection-error.d.ts +9 -0
- package/build/errors/database-connection-error.js +16 -0
- package/build/errors/not-authorized-error.d.ts +8 -0
- package/build/errors/not-authorized-error.js +15 -0
- package/build/errors/not-found-error.d.ts +8 -0
- package/build/errors/not-found-error.js +15 -0
- package/build/errors/request-validation-error.d.ts +11 -0
- package/build/errors/request-validation-error.js +19 -0
- package/build/events/consumer.d.ts +2 -0
- package/build/events/consumer.js +161 -0
- package/build/events/event-utils.d.ts +7 -0
- package/build/events/event-utils.js +13 -0
- package/build/events/inbox.d.ts +8 -0
- package/build/events/inbox.js +47 -0
- package/build/events/outbox.d.ts +34 -0
- package/build/events/outbox.js +189 -0
- package/build/events/producer.d.ts +5 -0
- package/build/events/producer.js +143 -0
- package/build/events/publishers/user-created-publisher.d.ts +6 -0
- package/build/events/publishers/user-created-publisher.js +21 -0
- package/build/events/publishers/user-updated-publisher.d.ts +6 -0
- package/build/events/publishers/user-updated-publisher.js +21 -0
- package/build/events/types/index.d.ts +6 -0
- package/build/events/types/index.js +14 -0
- package/build/events/types/user-events.d.ts +131 -0
- package/build/events/types/user-events.js +6 -0
- package/build/index.d.ts +20 -0
- package/build/index.js +34 -0
- package/build/middlewares/current-user.d.ts +2 -0
- package/build/middlewares/current-user.js +20 -0
- package/build/middlewares/error-handler.d.ts +2 -0
- package/build/middlewares/error-handler.js +14 -0
- package/build/middlewares/require-auth.d.ts +12 -0
- package/build/middlewares/require-auth.js +91 -0
- package/build/middlewares/system-logger.d.ts +0 -0
- package/build/middlewares/system-logger.js +1 -0
- package/build/middlewares/validate-request.d.ts +2 -0
- package/build/middlewares/validate-request.js +13 -0
- package/build/types/auth.d.ts +22 -0
- package/build/types/auth.js +5 -0
- 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,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,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,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
|
+
}
|
package/build/index.d.ts
ADDED
|
@@ -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,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,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,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
|
+
}
|