@estopia/shared 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/broker/eventTypes.d.ts +27 -0
- package/dist/broker/eventTypes.d.ts.map +1 -0
- package/dist/broker/eventTypes.js +9 -0
- package/dist/broker/eventTypes.js.map +1 -0
- package/dist/broker/publisher.d.ts +16 -0
- package/dist/broker/publisher.d.ts.map +1 -0
- package/dist/broker/publisher.js +124 -0
- package/dist/broker/publisher.js.map +1 -0
- package/dist/broker/subscriber.d.ts +14 -0
- package/dist/broker/subscriber.d.ts.map +1 -0
- package/dist/broker/subscriber.js +60 -0
- package/dist/broker/subscriber.js.map +1 -0
- package/dist/database/cockroach.d.ts +11 -0
- package/dist/database/cockroach.d.ts.map +1 -0
- package/dist/database/cockroach.js +27 -0
- package/dist/database/cockroach.js.map +1 -0
- package/dist/database/dataTypes.d.ts +99 -0
- package/dist/database/dataTypes.d.ts.map +1 -0
- package/dist/database/dataTypes.js +7 -0
- package/dist/database/dataTypes.js.map +1 -0
- package/{src/database/types.ts → dist/database/types.d.ts} +8 -9
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +3 -0
- package/dist/database/types.js.map +1 -0
- package/dist/helpers/middlware/auth.d.ts +10 -0
- package/dist/helpers/middlware/auth.d.ts.map +1 -0
- package/dist/helpers/middlware/auth.js +55 -0
- package/dist/helpers/middlware/auth.js.map +1 -0
- package/dist/helpers/middlware/secure.d.ts +11 -0
- package/dist/helpers/middlware/secure.d.ts.map +1 -0
- package/dist/helpers/middlware/secure.js +42 -0
- package/dist/helpers/middlware/secure.js.map +1 -0
- package/dist/helpers/validateJWTToken.d.ts +16 -0
- package/dist/helpers/validateJWTToken.d.ts.map +1 -0
- package/dist/helpers/validateJWTToken.js +36 -0
- package/dist/helpers/validateJWTToken.js.map +1 -0
- package/{src/index.ts → dist/index.d.ts} +16 -24
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/logger.d.ts +13 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +81 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/types/ENUMS.d.ts +32 -0
- package/dist/types/ENUMS.d.ts.map +1 -0
- package/dist/types/ENUMS.js +41 -0
- package/dist/types/ENUMS.js.map +1 -0
- package/dist/types/directs.d.ts +16 -0
- package/dist/types/directs.d.ts.map +1 -0
- package/dist/types/directs.js +3 -0
- package/dist/types/directs.js.map +1 -0
- package/dist/types/medical.d.ts +32 -0
- package/dist/types/medical.d.ts.map +1 -0
- package/dist/types/medical.js +3 -0
- package/dist/types/medical.js.map +1 -0
- package/dist/types/messages.d.ts +24 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/messages.js +3 -0
- package/dist/types/messages.js.map +1 -0
- package/{src/types/request.ts → dist/types/request.d.ts} +22 -23
- package/dist/types/request.d.ts.map +1 -0
- package/dist/types/request.js +3 -0
- package/dist/types/request.js.map +1 -0
- package/dist/types/servers.d.ts +32 -0
- package/dist/types/servers.d.ts.map +1 -0
- package/dist/types/servers.js +3 -0
- package/dist/types/servers.js.map +1 -0
- package/dist/types/servicePayloads.d.ts +32 -0
- package/dist/types/servicePayloads.d.ts.map +1 -0
- package/dist/types/servicePayloads.js +10 -0
- package/dist/types/servicePayloads.js.map +1 -0
- package/dist/types/ticketsAndReporting.d.ts +29 -0
- package/dist/types/ticketsAndReporting.d.ts.map +1 -0
- package/dist/types/ticketsAndReporting.js +3 -0
- package/dist/types/ticketsAndReporting.js.map +1 -0
- package/dist/types/user.d.ts +29 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +3 -0
- package/dist/types/user.js.map +1 -0
- package/package.json +10 -4
- package/.github/workflows/tests.yml +0 -29
- package/scripts/migrations/1670000000000-initial.js +0 -107
- package/scripts/package.json +0 -20
- package/src/broker/eventTypes.ts +0 -23
- package/src/broker/publisher.ts +0 -82
- package/src/broker/subscriber.ts +0 -51
- package/src/database/cockroach.ts +0 -27
- package/src/helpers/middlware/auth.ts +0 -55
- package/src/helpers/middlware/secure.ts +0 -48
- package/src/helpers/validateJWTToken.ts +0 -38
- package/src/logging/logger.ts +0 -103
- package/src/types/ENUMS.ts +0 -45
- package/src/types/directs.ts +0 -18
- package/src/types/medical.ts +0 -36
- package/src/types/messages.ts +0 -27
- package/src/types/servers.ts +0 -36
- package/src/types/servicePayloads.ts +0 -40
- package/src/types/ticketsAndReporting.ts +0 -32
- package/src/types/user.ts +0 -34
- package/tests/verifyJWTToken.test.ts +0 -27
- package/tsconfig.json +0 -48
- package/vitest.config.ts +0 -9
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface UserRegisteredEvent {
|
|
2
|
+
userId: string;
|
|
3
|
+
email: string;
|
|
4
|
+
verificationCode: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PasswordResetEvent {
|
|
7
|
+
userId: string;
|
|
8
|
+
email: string;
|
|
9
|
+
resetToken: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SecureTokenEmailRequestEvent {
|
|
12
|
+
userId: string;
|
|
13
|
+
email: string;
|
|
14
|
+
secureToken: string;
|
|
15
|
+
}
|
|
16
|
+
export type EventPayloads = UserRegisteredEvent | PasswordResetEvent | SecureTokenEmailRequestEvent;
|
|
17
|
+
export interface EventMap {
|
|
18
|
+
USER_REGISTERED: UserRegisteredEvent;
|
|
19
|
+
PASSWORD_RESET: PasswordResetEvent;
|
|
20
|
+
SECURE_TOKEN_EMAIL_REQUEST: SecureTokenEmailRequestEvent;
|
|
21
|
+
}
|
|
22
|
+
export declare const EVENTS: {
|
|
23
|
+
readonly USER_REGISTERED: "user.registered";
|
|
24
|
+
readonly PASSWORD_RESET: "password.reset";
|
|
25
|
+
readonly SECURE_TOKEN_EMAIL_REQUEST: "secure.token.email.request";
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=eventTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventTypes.d.ts","sourceRoot":"","sources":["../../src/broker/eventTypes.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,4BAA4B,CAAC;AAEpG,MAAM,WAAW,QAAQ;IACvB,eAAe,EAAE,mBAAmB,CAAC;IACrC,cAAc,EAAE,kBAAkB,CAAC;IACnC,0BAA0B,EAAE,4BAA4B,CAAC;CAC1D;AAED,eAAO,MAAM,MAAM;;;;CAIT,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EVENTS = void 0;
|
|
4
|
+
exports.EVENTS = {
|
|
5
|
+
USER_REGISTERED: 'user.registered',
|
|
6
|
+
PASSWORD_RESET: 'password.reset',
|
|
7
|
+
SECURE_TOKEN_EMAIL_REQUEST: 'secure.token.email.request',
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=eventTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventTypes.js","sourceRoot":"","sources":["../../src/broker/eventTypes.ts"],"names":[],"mappings":";;;AA0Ba,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,0BAA0B,EAAE,4BAA4B;CAChD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EventMap } from './eventTypes';
|
|
2
|
+
export declare class EventPublisher {
|
|
3
|
+
private url;
|
|
4
|
+
private connection?;
|
|
5
|
+
private channel?;
|
|
6
|
+
private exchange;
|
|
7
|
+
constructor(url: string);
|
|
8
|
+
connect(): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Publish an event. The payload type is keyed by the same keys used in your EventPayloads map.
|
|
11
|
+
* Ensures the routing key exists in EVENTS and that the publisher is connected.
|
|
12
|
+
*/
|
|
13
|
+
publish<K extends keyof EventMap>(eventName: K, payload: EventMap[K]): Promise<void>;
|
|
14
|
+
close(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/broker/publisher.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,QAAQ,EAAU,MAAM,cAAc,CAAC;AAE/D,qBAAa,cAAc;IAKb,OAAO,CAAC,GAAG;IAJvB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,OAAO,CAAC,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAoB;gBAEhB,GAAG,EAAE,MAAM;IAEzB,OAAO;IAOb;;;OAGG;IACG,OAAO,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IA8CpE,KAAK;CAcZ"}
|
|
@@ -0,0 +1,124 @@
|
|
|
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.EventPublisher = void 0;
|
|
37
|
+
const amqplib = __importStar(require("amqplib"));
|
|
38
|
+
const eventTypes_1 = require("./eventTypes");
|
|
39
|
+
class EventPublisher {
|
|
40
|
+
url;
|
|
41
|
+
connection;
|
|
42
|
+
channel;
|
|
43
|
+
exchange = 'estopia.events';
|
|
44
|
+
constructor(url) {
|
|
45
|
+
this.url = url;
|
|
46
|
+
}
|
|
47
|
+
async connect() {
|
|
48
|
+
if (this.connection && this.channel)
|
|
49
|
+
return; // already connected
|
|
50
|
+
this.connection = await amqplib.connect(this.url);
|
|
51
|
+
this.channel = await this.connection.createChannel();
|
|
52
|
+
await this.channel.assertExchange(this.exchange, 'topic', { durable: true });
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Publish an event. The payload type is keyed by the same keys used in your EventPayloads map.
|
|
56
|
+
* Ensures the routing key exists in EVENTS and that the publisher is connected.
|
|
57
|
+
*/
|
|
58
|
+
async publish(eventName, payload) {
|
|
59
|
+
// Auto-connect if needed
|
|
60
|
+
if (!this.channel) {
|
|
61
|
+
await this.connect();
|
|
62
|
+
}
|
|
63
|
+
const routingKey = eventTypes_1.EVENTS[eventName];
|
|
64
|
+
if (!routingKey || typeof routingKey !== 'string') {
|
|
65
|
+
throw new Error(`No routing key configured for event ${String(eventName)}`);
|
|
66
|
+
}
|
|
67
|
+
let body;
|
|
68
|
+
try {
|
|
69
|
+
body = Buffer.from(JSON.stringify(payload));
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw new Error('Failed to serialize payload for publish');
|
|
73
|
+
}
|
|
74
|
+
// Basic retry with exponential backoff
|
|
75
|
+
const maxRetries = 3;
|
|
76
|
+
const baseBackoffMs = 200;
|
|
77
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
78
|
+
try {
|
|
79
|
+
// channel.publish is synchronous; wrap in try/catch in case of closed channel
|
|
80
|
+
this.channel.publish(this.exchange, routingKey, body, { persistent: true });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
// if last attempt, rethrow
|
|
85
|
+
if (attempt === maxRetries)
|
|
86
|
+
throw err;
|
|
87
|
+
// try reconnect + backoff
|
|
88
|
+
try {
|
|
89
|
+
// reset connection and attempt reconnect
|
|
90
|
+
await this.close();
|
|
91
|
+
}
|
|
92
|
+
catch (_) { }
|
|
93
|
+
try {
|
|
94
|
+
await this.connect();
|
|
95
|
+
}
|
|
96
|
+
catch (_) {
|
|
97
|
+
// failed to reconnect, will backoff and retry loop
|
|
98
|
+
}
|
|
99
|
+
const backoff = baseBackoffMs * Math.pow(2, attempt);
|
|
100
|
+
await new Promise((res) => setTimeout(res, backoff));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async close() {
|
|
105
|
+
try {
|
|
106
|
+
if (this.channel)
|
|
107
|
+
await this.channel.close();
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
// ignore
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
if (this.connection)
|
|
114
|
+
await this.connection.close();
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
// ignore
|
|
118
|
+
}
|
|
119
|
+
this.channel = undefined;
|
|
120
|
+
this.connection = undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.EventPublisher = EventPublisher;
|
|
124
|
+
//# sourceMappingURL=publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/broker/publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EventMap } from './eventTypes';
|
|
2
|
+
type EventHandler<T> = (payload: T) => Promise<void> | void;
|
|
3
|
+
export declare class EventSubscriber {
|
|
4
|
+
private url;
|
|
5
|
+
private connection?;
|
|
6
|
+
private channel?;
|
|
7
|
+
private exchange;
|
|
8
|
+
constructor(url: string);
|
|
9
|
+
connect(): Promise<void>;
|
|
10
|
+
subscribe<K extends keyof EventMap>(eventName: K, handler: EventHandler<EventMap[K]>): Promise<void>;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=subscriber.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriber.d.ts","sourceRoot":"","sources":["../../src/broker/subscriber.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEhD,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE5D,qBAAa,eAAe;IAKd,OAAO,CAAC,GAAG;IAJvB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,OAAO,CAAC,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAoB;gBAEhB,GAAG,EAAE,MAAM;IAEzB,OAAO;IAOP,SAAS,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAyBpF,KAAK;CAMZ"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventSubscriber = void 0;
|
|
4
|
+
const amqplib = require('amqplib');
|
|
5
|
+
const eventTypes_1 = require("./eventTypes");
|
|
6
|
+
class EventSubscriber {
|
|
7
|
+
url;
|
|
8
|
+
connection;
|
|
9
|
+
channel;
|
|
10
|
+
exchange = 'estopia.events';
|
|
11
|
+
constructor(url) {
|
|
12
|
+
this.url = url;
|
|
13
|
+
}
|
|
14
|
+
async connect() {
|
|
15
|
+
if (this.connection && this.channel)
|
|
16
|
+
return;
|
|
17
|
+
this.connection = await amqplib.connect(this.url);
|
|
18
|
+
this.channel = await this.connection.createChannel();
|
|
19
|
+
await this.channel.assertExchange(this.exchange, 'topic', { durable: true });
|
|
20
|
+
}
|
|
21
|
+
async subscribe(eventName, handler) {
|
|
22
|
+
if (!this.channel)
|
|
23
|
+
throw new Error('Subscriber not connected');
|
|
24
|
+
const q = await this.channel.assertQueue('', { exclusive: true });
|
|
25
|
+
const routing = eventTypes_1.EVENTS[eventName];
|
|
26
|
+
await this.channel.bindQueue(q.queue, this.exchange, routing);
|
|
27
|
+
await this.channel.consume(q.queue, (msg) => {
|
|
28
|
+
if (msg) {
|
|
29
|
+
let payload;
|
|
30
|
+
try {
|
|
31
|
+
payload = JSON.parse(msg.content.toString());
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
// malformed message -> nack and requeue false
|
|
35
|
+
this.channel?.nack(msg, false, false);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
Promise.resolve(handler(payload))
|
|
39
|
+
.then(() => this.channel?.ack(msg))
|
|
40
|
+
.catch(() => this.channel?.nack(msg, false, true));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async close() {
|
|
45
|
+
try {
|
|
46
|
+
if (this.channel)
|
|
47
|
+
await this.channel.close();
|
|
48
|
+
}
|
|
49
|
+
catch (e) { }
|
|
50
|
+
try {
|
|
51
|
+
if (this.connection)
|
|
52
|
+
await this.connection.close();
|
|
53
|
+
}
|
|
54
|
+
catch (e) { }
|
|
55
|
+
this.channel = undefined;
|
|
56
|
+
this.connection = undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.EventSubscriber = EventSubscriber;
|
|
60
|
+
//# sourceMappingURL=subscriber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriber.js","sourceRoot":"","sources":["../../src/broker/subscriber.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AACnC,6CAAgD;AAIhD,MAAa,eAAe;IAKN;IAJZ,UAAU,CAAO;IACjB,OAAO,CAAO;IACd,QAAQ,GAAG,gBAAgB,CAAC;IAEpC,YAAoB,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;IAAG,CAAC;IAEnC,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAC5C,IAAI,CAAC,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;QACrD,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,SAAS,CAA2B,SAAY,EAAE,OAAkC;QACxF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE/D,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,mBAAM,CAAC,SAAgC,CAAC,CAAC;QACzD,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE5D,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAe,EAAE,EAAE;YACtD,IAAI,GAAG,EAAE,CAAC;gBACR,IAAI,OAAoB,CAAC;gBACzB,IAAI,CAAC;oBACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,8CAA8C;oBAC9C,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;oBACtC,OAAO;gBACT,CAAC;gBAED,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;qBAC9B,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;qBAClC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YAAC,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC;YAAC,IAAI,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;CACF;AA7CD,0CA6CC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CockroachConfig } from './types';
|
|
2
|
+
import { Kysely } from 'kysely';
|
|
3
|
+
import { DB } from './dataTypes';
|
|
4
|
+
/**
|
|
5
|
+
* Creates and tests a new connection pool for a CockroachDB cluster.
|
|
6
|
+
* * @param config - The connection configuration for CockroachDB.
|
|
7
|
+
* @returns A promise that resolves to a connected Pool instance.
|
|
8
|
+
* @throws Will throw an error if the connection fails.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createCockroachDBConnection(config: CockroachConfig): Promise<Kysely<DB>>;
|
|
11
|
+
//# sourceMappingURL=cockroach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cockroach.d.ts","sourceRoot":"","sources":["../../src/database/cockroach.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAmB,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAe9F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCockroachDBConnection = createCockroachDBConnection;
|
|
4
|
+
const pg_1 = require("pg");
|
|
5
|
+
const kysely_1 = require("kysely");
|
|
6
|
+
/**
|
|
7
|
+
* Creates and tests a new connection pool for a CockroachDB cluster.
|
|
8
|
+
* * @param config - The connection configuration for CockroachDB.
|
|
9
|
+
* @returns A promise that resolves to a connected Pool instance.
|
|
10
|
+
* @throws Will throw an error if the connection fails.
|
|
11
|
+
*/
|
|
12
|
+
async function createCockroachDBConnection(config) {
|
|
13
|
+
try {
|
|
14
|
+
const db = new kysely_1.Kysely({
|
|
15
|
+
dialect: new kysely_1.PostgresDialect({
|
|
16
|
+
pool: new pg_1.Pool(config)
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
console.log('Successfully connected to CockroachDB.');
|
|
20
|
+
return db;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error('Failed to connect to CockroachDB:', error);
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=cockroach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cockroach.js","sourceRoot":"","sources":["../../src/database/cockroach.ts"],"names":[],"mappings":";;AAWA,kEAeC;AA1BD,2BAA0B;AAE1B,mCAAiD;AAGjD;;;;;GAKG;AACI,KAAK,UAAU,2BAA2B,CAAC,MAAuB;IACvE,IAAI,CAAC;QAEH,MAAM,EAAE,GAAG,IAAI,eAAM,CAAK;YACxB,OAAO,EAAE,IAAI,wBAAe,CAAC;gBAC3B,IAAI,EAAE,IAAI,SAAI,CAAC,MAAM,CAAC;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was generated by kysely-codegen.
|
|
3
|
+
* Please do not edit it manually.
|
|
4
|
+
*/
|
|
5
|
+
import type { ColumnType } from "kysely";
|
|
6
|
+
export type AppType = "medAndroid" | "medIOS" | "web";
|
|
7
|
+
export type FactorAuthType = "email" | "whatsapp";
|
|
8
|
+
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
9
|
+
export type Int8 = ColumnType<string, bigint | number | string, bigint | number | string>;
|
|
10
|
+
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
|
11
|
+
export type VerificationType = "email" | "password_reset" | "phone";
|
|
12
|
+
export interface AuthApps {
|
|
13
|
+
id: Generated<Int8>;
|
|
14
|
+
name: string;
|
|
15
|
+
secret: string;
|
|
16
|
+
user_id: Int8;
|
|
17
|
+
}
|
|
18
|
+
export interface FactorAuthentication {
|
|
19
|
+
code: string;
|
|
20
|
+
data: string;
|
|
21
|
+
expiry_at: Timestamp;
|
|
22
|
+
id: Generated<Int8>;
|
|
23
|
+
is_verified: Generated<boolean | null>;
|
|
24
|
+
type: FactorAuthType;
|
|
25
|
+
user_id: Int8;
|
|
26
|
+
}
|
|
27
|
+
export interface NotificationSettings {
|
|
28
|
+
added_to_dm: Generated<boolean | null>;
|
|
29
|
+
direct_call: Generated<boolean | null>;
|
|
30
|
+
direct_message: Generated<boolean | null>;
|
|
31
|
+
group_dm_mention: Generated<boolean | null>;
|
|
32
|
+
group_dm_message: Generated<boolean | null>;
|
|
33
|
+
id: Generated<Int8>;
|
|
34
|
+
server_everyone_mention: Generated<boolean | null>;
|
|
35
|
+
server_mention: Generated<boolean | null>;
|
|
36
|
+
server_reply: Generated<boolean | null>;
|
|
37
|
+
user_id: Int8;
|
|
38
|
+
}
|
|
39
|
+
export interface Passkeys {
|
|
40
|
+
counter: Int8;
|
|
41
|
+
id: Generated<Int8>;
|
|
42
|
+
key_id: Buffer;
|
|
43
|
+
name: string | null;
|
|
44
|
+
public_key: Buffer;
|
|
45
|
+
transports: string[] | null;
|
|
46
|
+
user_id: Int8;
|
|
47
|
+
}
|
|
48
|
+
export interface Pgmigrations {
|
|
49
|
+
id: Generated<Int8>;
|
|
50
|
+
name: string;
|
|
51
|
+
run_on: Timestamp;
|
|
52
|
+
}
|
|
53
|
+
export interface SecureTokens {
|
|
54
|
+
created_at: Generated<Timestamp>;
|
|
55
|
+
expiry_at: Timestamp;
|
|
56
|
+
id: Generated<Int8>;
|
|
57
|
+
token_uuid: string;
|
|
58
|
+
user_id: Int8;
|
|
59
|
+
}
|
|
60
|
+
export interface Tokens {
|
|
61
|
+
app: AppType | null;
|
|
62
|
+
created_at: Generated<Timestamp>;
|
|
63
|
+
expiry_at: Timestamp;
|
|
64
|
+
fcm_token: string | null;
|
|
65
|
+
id: Generated<Int8>;
|
|
66
|
+
refresh_token: string;
|
|
67
|
+
user_id: Int8;
|
|
68
|
+
}
|
|
69
|
+
export interface Users {
|
|
70
|
+
created_at: Generated<Timestamp>;
|
|
71
|
+
disabled: Generated<boolean | null>;
|
|
72
|
+
icon_url: string | null;
|
|
73
|
+
id: Generated<Int8>;
|
|
74
|
+
is_admin: Generated<boolean | null>;
|
|
75
|
+
password_hash: string;
|
|
76
|
+
username: string;
|
|
77
|
+
}
|
|
78
|
+
export interface UserVerifications {
|
|
79
|
+
created_at: Generated<Timestamp>;
|
|
80
|
+
data: string | null;
|
|
81
|
+
expiry_at: Timestamp;
|
|
82
|
+
id: Generated<Int8>;
|
|
83
|
+
is_verified: Generated<boolean | null>;
|
|
84
|
+
ownership_code: string;
|
|
85
|
+
type: VerificationType;
|
|
86
|
+
user_id: Int8;
|
|
87
|
+
}
|
|
88
|
+
export interface DB {
|
|
89
|
+
auth_apps: AuthApps;
|
|
90
|
+
factor_authentication: FactorAuthentication;
|
|
91
|
+
notification_settings: NotificationSettings;
|
|
92
|
+
passkeys: Passkeys;
|
|
93
|
+
pgmigrations: Pgmigrations;
|
|
94
|
+
secure_tokens: SecureTokens;
|
|
95
|
+
tokens: Tokens;
|
|
96
|
+
user_verifications: UserVerifications;
|
|
97
|
+
users: Users;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=dataTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataTypes.d.ts","sourceRoot":"","sources":["../../src/database/dataTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataTypes.js","sourceRoot":"","sources":["../../src/database/dataTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { PoolConfig as CockroachOptions } from 'pg';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
import { PoolConfig as CockroachOptions } from 'pg';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for connecting to a CockroachDB cluster.
|
|
4
|
+
* This extends the 'pg' PoolConfig type for full compatibility.
|
|
5
|
+
*/
|
|
6
|
+
export interface CockroachConfig extends CockroachOptions {
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,IAAI,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;CAExD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EstopiaRequest } from '../../types/request';
|
|
2
|
+
/**
|
|
3
|
+
* Middleware to require authentication.
|
|
4
|
+
* - Supports Authorization: Bearer <token> header (case-insensitive)
|
|
5
|
+
* - Falls back to cookies.auth_token
|
|
6
|
+
* - On success: sets req.auth = { ...payload, token } and calls next()
|
|
7
|
+
* - On failure: responds with 401 and an appropriate error message
|
|
8
|
+
*/
|
|
9
|
+
export declare function requireAuth(req: EstopiaRequest, res: any, next: any): any;
|
|
10
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/helpers/middlware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OA4CnE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requireAuth = requireAuth;
|
|
4
|
+
const validateJWTToken_1 = require("../validateJWTToken");
|
|
5
|
+
/**
|
|
6
|
+
* Middleware to require authentication.
|
|
7
|
+
* - Supports Authorization: Bearer <token> header (case-insensitive)
|
|
8
|
+
* - Falls back to cookies.auth_token
|
|
9
|
+
* - On success: sets req.auth = { ...payload, token } and calls next()
|
|
10
|
+
* - On failure: responds with 401 and an appropriate error message
|
|
11
|
+
*/
|
|
12
|
+
function requireAuth(req, res, next) {
|
|
13
|
+
// Get Authorization header (many frameworks provide case-insensitive header lookup)
|
|
14
|
+
const authHeader = typeof req.header === 'function' ? req.header('Authorization') : undefined;
|
|
15
|
+
// Extract token from "Bearer <token>" or use header value directly
|
|
16
|
+
let token;
|
|
17
|
+
if (typeof authHeader === 'string' && authHeader.trim() !== '') {
|
|
18
|
+
const bearerMatch = authHeader.match(/^\s*Bearer\s+(.+)\s*$/i);
|
|
19
|
+
token = bearerMatch ? bearerMatch[1] : authHeader.trim();
|
|
20
|
+
}
|
|
21
|
+
// Fallback to cookie
|
|
22
|
+
if (!token && req && req.cookies && typeof req.cookies.auth_token === 'string') {
|
|
23
|
+
token = req.cookies.auth_token;
|
|
24
|
+
}
|
|
25
|
+
if (!token) {
|
|
26
|
+
return res.status(401).json({ error: 'Missing authorization token' });
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const payload = (0, validateJWTToken_1.validateJWTToken)(token);
|
|
30
|
+
if (!payload) {
|
|
31
|
+
return res.status(401).json({ error: 'Invalid token' });
|
|
32
|
+
}
|
|
33
|
+
// Attach auth info to request
|
|
34
|
+
req.auth = { ...payload, token };
|
|
35
|
+
return next();
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
// Log warning if logger available, otherwise fallback to console
|
|
39
|
+
try {
|
|
40
|
+
if (req && req.logger && typeof req.logger.warn === 'function') {
|
|
41
|
+
req.logger.warn('Auth verification failed', err);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Keep message concise for logs
|
|
45
|
+
// eslint-disable-next-line no-console
|
|
46
|
+
console.warn('Auth verification failed', err);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// swallow logging errors
|
|
51
|
+
}
|
|
52
|
+
return res.status(401).json({ error: 'Invalid authorization' });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/helpers/middlware/auth.ts"],"names":[],"mappings":";;AAUA,kCA4CC;AArDD,0DAAuD;AAEvD;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,GAAmB,EAAE,GAAQ,EAAE,IAAS;IAClE,oFAAoF;IACpF,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9F,mEAAmE;IACnE,IAAI,KAAyB,CAAC;IAC9B,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/D,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC/D,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;IAED,qBAAqB;IACrB,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC/E,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,mCAAgB,EAAC,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,8BAA8B;QAC9B,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC;QACjC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,iEAAiE;QACjE,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC/D,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,gCAAgC;gBAChC,sCAAsC;gBACtC,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;QACD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Response } from 'express';
|
|
2
|
+
import { EstopiaRequest } from '../../types/request';
|
|
3
|
+
/**
|
|
4
|
+
* Middleware to require authentication.
|
|
5
|
+
* - Supports Authorization: Bearer <token> header (case-insensitive)
|
|
6
|
+
* - Falls back to cookies.auth_token
|
|
7
|
+
* - On success: sets req.auth = { ...payload, token } and calls next()
|
|
8
|
+
* - On failure: responds with 401 and an appropriate error message
|
|
9
|
+
*/
|
|
10
|
+
export declare function requireSecure(req: EstopiaRequest, res: Response, next: any): Promise<any>;
|
|
11
|
+
//# sourceMappingURL=secure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure.d.ts","sourceRoot":"","sources":["../../../src/helpers/middlware/secure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,gBAmChF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requireSecure = requireSecure;
|
|
4
|
+
/**
|
|
5
|
+
* Middleware to require authentication.
|
|
6
|
+
* - Supports Authorization: Bearer <token> header (case-insensitive)
|
|
7
|
+
* - Falls back to cookies.auth_token
|
|
8
|
+
* - On success: sets req.auth = { ...payload, token } and calls next()
|
|
9
|
+
* - On failure: responds with 401 and an appropriate error message
|
|
10
|
+
*/
|
|
11
|
+
async function requireSecure(req, res, next) {
|
|
12
|
+
// This middleware only validates the Secure-Token cookie against the DB.
|
|
13
|
+
// It does NOT require a valid JWT — per request: "it doesn't matter if the JWT token exists".
|
|
14
|
+
// Read secure token from cookie
|
|
15
|
+
const secureToken = req && req.cookies['Secure-Token'];
|
|
16
|
+
if (!secureToken) {
|
|
17
|
+
return res.status(403).json({ error: 'Missing secure token' });
|
|
18
|
+
}
|
|
19
|
+
// Expect a Kysely DB instance to be available on app.locals.db
|
|
20
|
+
const cockroachPool = req.cockroachPool;
|
|
21
|
+
try {
|
|
22
|
+
const db = cockroachPool;
|
|
23
|
+
// Query secure_tokens table by token_uuid
|
|
24
|
+
const row = await db.selectFrom('secure_tokens').selectAll().where('token_uuid', '=', secureToken).executeTakeFirst();
|
|
25
|
+
if (!row) {
|
|
26
|
+
return res.status(403).json({ error: 'Secure token not found' });
|
|
27
|
+
}
|
|
28
|
+
// expiry_at may be a Date or string depending on driver; normalize
|
|
29
|
+
const expiry = row.expiry_at ? new Date(row.expiry_at) : null;
|
|
30
|
+
if (!expiry || expiry.getTime() <= Date.now()) {
|
|
31
|
+
return res.status(403).json({ error: 'Secure token expired' });
|
|
32
|
+
}
|
|
33
|
+
// Attach minimal auth context to request (no JWT required)
|
|
34
|
+
req.auth = { secureToken, userId: row.user_id.toString() };
|
|
35
|
+
return next();
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error('Failed to validate secure token', err?.message || err);
|
|
39
|
+
return res.status(500).json({ error: 'Failed to validate secure token' });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=secure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure.js","sourceRoot":"","sources":["../../../src/helpers/middlware/secure.ts"],"names":[],"mappings":";;AAYA,sCAmCC;AA1CD;;;;;;GAMG;AACI,KAAK,UAAU,aAAa,CAAC,GAAmB,EAAE,GAAa,EAAE,IAAS;IAC/E,yEAAyE;IACzE,8FAA8F;IAE9F,gCAAgC;IAChC,MAAM,WAAW,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACvD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,+DAA+D;IAC/D,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,aAA2B,CAAC;QACvC,0CAA0C;QAC1C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAEtH,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,mEAAmE;QACnE,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,2DAA2D;QAC3D,GAAG,CAAC,IAAI,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC3D,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface DecodedJWT {
|
|
2
|
+
userId: string;
|
|
3
|
+
jti?: string;
|
|
4
|
+
iat?: number;
|
|
5
|
+
exp?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Verify a JWT and return the decoded payload. Throws on invalid/expired token.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateJWTToken(token: string): DecodedJWT;
|
|
11
|
+
/**
|
|
12
|
+
* Try to verify a token and return the decoded payload, or null if invalid.
|
|
13
|
+
*/
|
|
14
|
+
export declare function tryValidateJWTToken(token: string): DecodedJWT | null;
|
|
15
|
+
export default validateJWTToken;
|
|
16
|
+
//# sourceMappingURL=validateJWTToken.d.ts.map
|