@kedaruma/revlm-server 1.0.0 → 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/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +490 -0
- package/dist/server.js.map +1 -0
- package/dist/start.d.ts +2 -0
- package/dist/start.d.ts.map +1 -0
- package/dist/start.js +75 -0
- package/dist/start.js.map +1 -0
- package/package.json +2 -2
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { User } from '@kedaruma/revlm-shared/models/user-types';
|
|
2
|
+
import type { MongoClient as MongoClientType } from 'mongodb';
|
|
3
|
+
import http from "http";
|
|
4
|
+
export declare let client: MongoClientType | undefined;
|
|
5
|
+
export interface ServerConfig {
|
|
6
|
+
mongoUri: string;
|
|
7
|
+
usersDbName: string;
|
|
8
|
+
usersCollectionName: string;
|
|
9
|
+
provisionalLoginEnabled?: boolean;
|
|
10
|
+
provisionalAuthId?: string;
|
|
11
|
+
provisionalAuthSecretMaster?: string;
|
|
12
|
+
provisionalAuthDomain?: string;
|
|
13
|
+
jwtSecret: string;
|
|
14
|
+
jwtExpiresIn?: string;
|
|
15
|
+
refreshWindowSec?: number;
|
|
16
|
+
port: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function registerUserRaw(user: User, password: string): Promise<User>;
|
|
19
|
+
export declare function deleteUserRaw(_id: any, authId?: string): Promise<number>;
|
|
20
|
+
export declare function startServer(config: ServerConfig): Promise<http.Server>;
|
|
21
|
+
export declare function stopServer(): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,SAAS,CAAC;AAO9D,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,eAAO,IAAI,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;AAG/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AA2JD,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,iBAiBjE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,mBAY5D;AAUD,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAiP5E;AAED,wBAAsB,UAAU,kBAU/B"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.client = void 0;
|
|
4
|
+
exports.registerUserRaw = registerUserRaw;
|
|
5
|
+
exports.deleteUserRaw = deleteUserRaw;
|
|
6
|
+
exports.startServer = startServer;
|
|
7
|
+
exports.stopServer = stopServer;
|
|
8
|
+
const auth_token_1 = require("@kedaruma/revlm-shared/auth-token");
|
|
9
|
+
const express = require('express');
|
|
10
|
+
const mongodb_1 = require("mongodb");
|
|
11
|
+
const bson_1 = require("bson");
|
|
12
|
+
const jwt = require('jsonwebtoken');
|
|
13
|
+
const bcrypt = require('bcrypt');
|
|
14
|
+
const app = express();
|
|
15
|
+
app.use(express.text({ type: 'application/ejson' }));
|
|
16
|
+
app.use(express.json());
|
|
17
|
+
const serverConfigDefaults = {
|
|
18
|
+
provisionalLoginEnabled: false,
|
|
19
|
+
jwtExpiresIn: '1h',
|
|
20
|
+
refreshWindowSec: 300
|
|
21
|
+
};
|
|
22
|
+
let serverConfig;
|
|
23
|
+
let plpaServer;
|
|
24
|
+
let JWT_SECRET;
|
|
25
|
+
let JWT_EXPIRES_IN;
|
|
26
|
+
let REFRESH_WINDOW_SEC;
|
|
27
|
+
let PROVISIONAL_LOGIN_ENABLED;
|
|
28
|
+
let PROVISIONAL_AUTH_ID;
|
|
29
|
+
let PROVISIONAL_AUTH_SECRET_MASTER;
|
|
30
|
+
let PROVISIONAL_AUTH_DOMAIN;
|
|
31
|
+
let USERS_DB_NAME;
|
|
32
|
+
let USERS_COLLECTION;
|
|
33
|
+
let MONGO_URI;
|
|
34
|
+
let server;
|
|
35
|
+
// Helper to ensure server started
|
|
36
|
+
function ensureStarted() {
|
|
37
|
+
if (!serverConfig)
|
|
38
|
+
throw new Error('Server not started: call startServer(config) before using this function');
|
|
39
|
+
}
|
|
40
|
+
// Helper to ensure client is initialized and narrow its type
|
|
41
|
+
function getClient() {
|
|
42
|
+
if (!exports.client)
|
|
43
|
+
throw new Error('MongoClient not initialized (call startServer)');
|
|
44
|
+
return exports.client;
|
|
45
|
+
}
|
|
46
|
+
function sendResponse(req, res, obj, status = 200) {
|
|
47
|
+
if (status)
|
|
48
|
+
res.status(status);
|
|
49
|
+
const acceptHeader = (req.headers && (req.headers['accept'] || req.headers['Accept'])) || '';
|
|
50
|
+
const explicitlyWantsEjson = typeof acceptHeader === 'string' && acceptHeader.includes('application/ejson');
|
|
51
|
+
if (explicitlyWantsEjson) {
|
|
52
|
+
res.type('application/ejson').send(bson_1.EJSON.stringify(obj));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
res.json(obj);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function verifyToken(req, res, next) {
|
|
59
|
+
const header = req.headers['authorization'];
|
|
60
|
+
const token = header && header.split(' ')[1];
|
|
61
|
+
if (!token)
|
|
62
|
+
return sendResponse(req, res, { ok: false, error: 'No token provided' }, 401);
|
|
63
|
+
const result = verifyJwtToken(token);
|
|
64
|
+
if (!result.ok) {
|
|
65
|
+
const reason = result.reason;
|
|
66
|
+
if (reason === 'token_expired')
|
|
67
|
+
return sendResponse(req, res, { ok: false, error: 'Token expired' }, 401);
|
|
68
|
+
return sendResponse(req, res, { ok: false, error: 'Invalid token' }, 403);
|
|
69
|
+
}
|
|
70
|
+
req.user = result.payload;
|
|
71
|
+
const provisionalAllowedPaths = new Set(['/registerUser', '/login']);
|
|
72
|
+
const userType = req.user && req.user.userType;
|
|
73
|
+
if (userType === 'provisional') {
|
|
74
|
+
const path = req.path || req.originalUrl || '';
|
|
75
|
+
if (!provisionalAllowedPaths.has(path)) {
|
|
76
|
+
return sendResponse(req, res, { ok: false, error: 'provisional user cannot access this endpoint' }, 403);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
next();
|
|
80
|
+
}
|
|
81
|
+
// Helper: verifies a JWT and returns normalized result
|
|
82
|
+
function verifyJwtToken(token) {
|
|
83
|
+
ensureStarted();
|
|
84
|
+
try {
|
|
85
|
+
const payload = jwt.verify(token, JWT_SECRET);
|
|
86
|
+
return { ok: true, payload };
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
console.log('verifyJwtToken error - Error name:', err && err.name, 'Error message:', err && err.message);
|
|
90
|
+
if (err && err.name === 'TokenExpiredError')
|
|
91
|
+
return { ok: false, reason: 'token_expired' };
|
|
92
|
+
return { ok: false, reason: 'invalid_token' };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Helper: refresh an expired JWT within a grace window. Does not refresh provisional tokens.
|
|
96
|
+
function refreshJwtToken(token) {
|
|
97
|
+
ensureStarted();
|
|
98
|
+
// If token is still valid, don't refresh
|
|
99
|
+
try {
|
|
100
|
+
jwt.verify(token, JWT_SECRET);
|
|
101
|
+
return { ok: false, reason: 'not_expired' };
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.log('refreshJwtToken verify error - Error name:', err && err.name, 'Error message:', err && err.message);
|
|
105
|
+
if (!err || err.name !== 'TokenExpiredError')
|
|
106
|
+
return { ok: false, reason: 'invalid_token' };
|
|
107
|
+
// Token expired — verify signature ignoring expiration
|
|
108
|
+
let payload;
|
|
109
|
+
try {
|
|
110
|
+
payload = jwt.verify(token, JWT_SECRET, { ignoreExpiration: true });
|
|
111
|
+
}
|
|
112
|
+
catch (_e) {
|
|
113
|
+
console.log('refreshJwtToken ignoreExpiration verify error - Error name:', _e && _e.name, 'Error message:', _e && _e.message);
|
|
114
|
+
return { ok: false, reason: 'invalid_token' };
|
|
115
|
+
}
|
|
116
|
+
// Do not refresh provisional tokens
|
|
117
|
+
if (payload && payload.userType === 'provisional')
|
|
118
|
+
return { ok: false, reason: 'provisional_forbidden' };
|
|
119
|
+
// Check expiry field and grace window
|
|
120
|
+
const exp = payload && payload.exp ? Number(payload.exp) : undefined;
|
|
121
|
+
if (!exp)
|
|
122
|
+
return { ok: false, reason: 'invalid_token' };
|
|
123
|
+
const now = Math.floor(Date.now() / 1000);
|
|
124
|
+
const refreshWindow = REFRESH_WINDOW_SEC;
|
|
125
|
+
if (now - exp > refreshWindow)
|
|
126
|
+
return { ok: false, reason: 'refresh_window_exceeded' };
|
|
127
|
+
// Remove iat/exp/nbf before signing new token
|
|
128
|
+
const { iat, exp: _exp, nbf, ...rest } = payload;
|
|
129
|
+
const expiresIn = JWT_EXPIRES_IN;
|
|
130
|
+
const newToken = jwt.sign(rest, JWT_SECRET, { expiresIn });
|
|
131
|
+
return { ok: true, token: newToken, expiresIn };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Endpoint: token verification API
|
|
135
|
+
app.post('/verify-token', (req, res) => {
|
|
136
|
+
const header = req.headers['authorization'];
|
|
137
|
+
const tokenFromHeader = header && header.split(' ')[1];
|
|
138
|
+
const token = (req.body && req.body.token) || tokenFromHeader;
|
|
139
|
+
if (!token)
|
|
140
|
+
return sendResponse(req, res, { ok: false, reason: 'no_token' }, 400);
|
|
141
|
+
const result = verifyJwtToken(token);
|
|
142
|
+
if (result.ok)
|
|
143
|
+
return sendResponse(req, res, { ok: true, payload: result.payload }, 200);
|
|
144
|
+
const reason = result.reason;
|
|
145
|
+
if (reason === 'token_expired')
|
|
146
|
+
return sendResponse(req, res, { ok: false, reason: 'token_expired' }, 401);
|
|
147
|
+
return sendResponse(req, res, { ok: false, reason: 'invalid_token' }, 403);
|
|
148
|
+
});
|
|
149
|
+
// Endpoint: refresh an expired token within grace window
|
|
150
|
+
app.post('/refresh-token', (req, res) => {
|
|
151
|
+
const header = req.headers['authorization'];
|
|
152
|
+
const tokenFromHeader = header && header.split(' ')[1];
|
|
153
|
+
const token = (req.body && req.body.token) || tokenFromHeader;
|
|
154
|
+
if (!token)
|
|
155
|
+
return sendResponse(req, res, { ok: false, reason: 'no_token' }, 400);
|
|
156
|
+
const result = refreshJwtToken(token);
|
|
157
|
+
if (result.ok)
|
|
158
|
+
return sendResponse(req, res, { ok: true, token: result.token, expiresIn: result.expiresIn }, 200);
|
|
159
|
+
// Map reasons to status
|
|
160
|
+
switch (result.reason) {
|
|
161
|
+
case 'not_expired':
|
|
162
|
+
return sendResponse(req, res, { ok: false, reason: 'not_expired' }, 400);
|
|
163
|
+
case 'provisional_forbidden':
|
|
164
|
+
return sendResponse(req, res, { ok: false, reason: 'provisional_forbidden' }, 403);
|
|
165
|
+
case 'refresh_window_exceeded':
|
|
166
|
+
return sendResponse(req, res, { ok: false, reason: 'refresh_window_exceeded' }, 403);
|
|
167
|
+
default:
|
|
168
|
+
return sendResponse(req, res, { ok: false, reason: 'invalid_token' }, 403);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
function toObjectId(id) {
|
|
172
|
+
if (!id)
|
|
173
|
+
return undefined;
|
|
174
|
+
if (typeof id === 'string')
|
|
175
|
+
return new bson_1.ObjectId(id);
|
|
176
|
+
return id;
|
|
177
|
+
}
|
|
178
|
+
async function registerUserRaw(user, password) {
|
|
179
|
+
ensureStarted();
|
|
180
|
+
if (!user || typeof user !== 'object')
|
|
181
|
+
throw new Error('User document is required');
|
|
182
|
+
if (!user.authId)
|
|
183
|
+
throw new Error('authId is required');
|
|
184
|
+
if (!password)
|
|
185
|
+
throw new Error('Password is required');
|
|
186
|
+
const userCol = getClient().db(USERS_DB_NAME).collection(USERS_COLLECTION);
|
|
187
|
+
const exists = await userCol.findOne({ authId: user.authId });
|
|
188
|
+
if (exists)
|
|
189
|
+
throw new Error('authId already exists');
|
|
190
|
+
const passwordHash = await bcrypt.hash(password, 10);
|
|
191
|
+
if (!user._id) {
|
|
192
|
+
user._id = new bson_1.ObjectId();
|
|
193
|
+
}
|
|
194
|
+
user.passwordHash = passwordHash;
|
|
195
|
+
// Ensure _id is an ObjectId for Mongo driver compatibility
|
|
196
|
+
const insertDoc = { ...user, _id: toObjectId(user._id) };
|
|
197
|
+
await userCol.insertOne(insertDoc);
|
|
198
|
+
return user;
|
|
199
|
+
}
|
|
200
|
+
async function deleteUserRaw(_id, authId) {
|
|
201
|
+
ensureStarted();
|
|
202
|
+
if (!_id && !authId)
|
|
203
|
+
throw new Error('Either _id or authId must be provided');
|
|
204
|
+
const userCol = getClient().db(USERS_DB_NAME).collection(USERS_COLLECTION);
|
|
205
|
+
let filter = {};
|
|
206
|
+
if (_id) {
|
|
207
|
+
filter._id = toObjectId(_id) ?? _id;
|
|
208
|
+
}
|
|
209
|
+
else if (authId) {
|
|
210
|
+
filter.authId = authId;
|
|
211
|
+
}
|
|
212
|
+
const result = await userCol.deleteOne(filter);
|
|
213
|
+
return result.deletedCount;
|
|
214
|
+
}
|
|
215
|
+
function isServerListening(s) {
|
|
216
|
+
try {
|
|
217
|
+
return !!(s && typeof s.listening === 'boolean' ? s.listening : s.address && s.address());
|
|
218
|
+
}
|
|
219
|
+
catch (_e) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async function startServer(config) {
|
|
224
|
+
// validate existence
|
|
225
|
+
if (!config)
|
|
226
|
+
throw new Error('Configuration object is required');
|
|
227
|
+
// filter undefined values so defaults are preserved
|
|
228
|
+
const filteredConfig = Object.fromEntries(Object.entries(config).filter(([, v]) => v !== undefined));
|
|
229
|
+
const merged = { ...serverConfigDefaults, ...filteredConfig };
|
|
230
|
+
// required checks
|
|
231
|
+
if (!merged.mongoUri)
|
|
232
|
+
throw new Error('mongoUri is required in ServerConfig');
|
|
233
|
+
if (!merged.usersDbName)
|
|
234
|
+
throw new Error('usersDbName is required in ServerConfig');
|
|
235
|
+
if (!merged.usersCollectionName)
|
|
236
|
+
throw new Error('usersCollectionName is required in ServerConfig');
|
|
237
|
+
if (!merged.jwtSecret)
|
|
238
|
+
throw new Error('jwtSecret is required in ServerConfig');
|
|
239
|
+
// provisional checks
|
|
240
|
+
const provisionalEnabled = !!merged.provisionalLoginEnabled;
|
|
241
|
+
if (provisionalEnabled) {
|
|
242
|
+
if (!merged.provisionalAuthId)
|
|
243
|
+
throw new Error('provisionalAuthId is required when provisionalLoginEnabled is true');
|
|
244
|
+
if (!merged.provisionalAuthSecretMaster)
|
|
245
|
+
throw new Error('provisionalAuthSecretMaster is required when provisionalLoginEnabled is true');
|
|
246
|
+
if (!merged.provisionalAuthDomain)
|
|
247
|
+
throw new Error('provisionalAuthDomain is required when provisionalLoginEnabled is true');
|
|
248
|
+
}
|
|
249
|
+
// persist config into module variables
|
|
250
|
+
serverConfig = merged;
|
|
251
|
+
MONGO_URI = merged.mongoUri;
|
|
252
|
+
USERS_DB_NAME = merged.usersDbName;
|
|
253
|
+
USERS_COLLECTION = merged.usersCollectionName;
|
|
254
|
+
PROVISIONAL_LOGIN_ENABLED = !!merged.provisionalLoginEnabled;
|
|
255
|
+
PROVISIONAL_AUTH_ID = merged.provisionalAuthId;
|
|
256
|
+
PROVISIONAL_AUTH_SECRET_MASTER = merged.provisionalAuthSecretMaster;
|
|
257
|
+
PROVISIONAL_AUTH_DOMAIN = merged.provisionalAuthDomain;
|
|
258
|
+
JWT_SECRET = merged.jwtSecret;
|
|
259
|
+
JWT_EXPIRES_IN = merged.jwtExpiresIn;
|
|
260
|
+
REFRESH_WINDOW_SEC = merged.refreshWindowSec;
|
|
261
|
+
if (PROVISIONAL_LOGIN_ENABLED) {
|
|
262
|
+
plpaServer = new auth_token_1.AuthServer({ secretMaster: PROVISIONAL_AUTH_SECRET_MASTER, authDomain: PROVISIONAL_AUTH_DOMAIN });
|
|
263
|
+
}
|
|
264
|
+
if (isServerListening(server))
|
|
265
|
+
return server;
|
|
266
|
+
const port = Number.isFinite(merged.port) ? 0 : merged.port;
|
|
267
|
+
const c = new mongodb_1.MongoClient(MONGO_URI);
|
|
268
|
+
exports.client = c;
|
|
269
|
+
try {
|
|
270
|
+
await c.connect();
|
|
271
|
+
await c.db().admin().ping();
|
|
272
|
+
// connection ok
|
|
273
|
+
console.log('MongoDB connected');
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
console.log('MongoDB connection error - Error name:', err && err.name, 'Error message:', err && err.message);
|
|
277
|
+
if (err && err.stack)
|
|
278
|
+
console.log(err.stack);
|
|
279
|
+
try {
|
|
280
|
+
await c.close(true);
|
|
281
|
+
}
|
|
282
|
+
catch (closeErr) {
|
|
283
|
+
console.log('Error closing MongoClient after failed connect - Error name:', closeErr && closeErr.name, 'Error message:', closeErr && closeErr.message);
|
|
284
|
+
}
|
|
285
|
+
exports.client = undefined;
|
|
286
|
+
throw err;
|
|
287
|
+
}
|
|
288
|
+
app.use((req, res, next) => {
|
|
289
|
+
if (req.is && req.is('application/ejson')) {
|
|
290
|
+
try {
|
|
291
|
+
req.body = bson_1.EJSON.parse(req.body);
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
return sendResponse(req, res, { ok: false, error: 'Invalid EJSON body' }, 400);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
next();
|
|
298
|
+
});
|
|
299
|
+
if (PROVISIONAL_LOGIN_ENABLED) {
|
|
300
|
+
app.post('/provisional-login', async (req, res) => {
|
|
301
|
+
const { authId, password } = req.body;
|
|
302
|
+
if (!authId || !password)
|
|
303
|
+
return sendResponse(req, res, { ok: false, error: 'authId and password are required' }, 400);
|
|
304
|
+
try {
|
|
305
|
+
if (authId !== PROVISIONAL_AUTH_ID)
|
|
306
|
+
return sendResponse(req, res, { ok: false, error: 'Authentication failed' }, 401);
|
|
307
|
+
const passwordValid = await plpaServer.validatePassword(password);
|
|
308
|
+
if (!passwordValid || !passwordValid.ok)
|
|
309
|
+
return sendResponse(req, res, { ok: false, error: 'Authentication failed' }, 401);
|
|
310
|
+
const token = jwt.sign({ userType: 'provisional' }, JWT_SECRET, { expiresIn: '5s' });
|
|
311
|
+
try {
|
|
312
|
+
const decoded = jwt.decode(token);
|
|
313
|
+
console.log('TOKEN PAYLOAD (provisional-login):', decoded);
|
|
314
|
+
}
|
|
315
|
+
catch (e) {
|
|
316
|
+
console.log('Failed to decode provisional token payload', e);
|
|
317
|
+
}
|
|
318
|
+
return sendResponse(req, res, { ok: true, token, user: {} });
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
const statusCode = err.statusCode || 500;
|
|
322
|
+
return sendResponse(req, res, { ok: false, error: err.message }, statusCode);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
console.log('PROVISIONAL_LOGIN_ENABLED is false; /provisional-login route not registered');
|
|
328
|
+
}
|
|
329
|
+
app.post('/login', async (req, res) => {
|
|
330
|
+
const { authId, password } = req.body;
|
|
331
|
+
if (!authId || !password)
|
|
332
|
+
return sendResponse(req, res, { ok: false, error: 'authId and password are required' }, 400);
|
|
333
|
+
try {
|
|
334
|
+
const userCol = getClient().db(USERS_DB_NAME).collection(USERS_COLLECTION);
|
|
335
|
+
const user = await userCol.findOne({ authId });
|
|
336
|
+
if (!user || !user.passwordHash)
|
|
337
|
+
return sendResponse(req, res, { ok: false, error: 'Authentication failed' }, 401);
|
|
338
|
+
const valid = await bcrypt.compare(password, user.passwordHash);
|
|
339
|
+
if (!valid)
|
|
340
|
+
return sendResponse(req, res, { ok: false, error: 'Authentication failed' }, 401);
|
|
341
|
+
const { _id, userType, roles, merchantId } = user;
|
|
342
|
+
const token = jwt.sign({ _id, userType, roles, merchantId }, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
|
|
343
|
+
try {
|
|
344
|
+
const decoded = jwt.decode(token);
|
|
345
|
+
console.log('TOKEN PAYLOAD (login):', decoded);
|
|
346
|
+
}
|
|
347
|
+
catch (e) {
|
|
348
|
+
console.log('Failed to decode login token payload', e);
|
|
349
|
+
}
|
|
350
|
+
return sendResponse(req, res, { ok: true, token, user });
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
const statusCode = err.statusCode || 500;
|
|
354
|
+
return sendResponse(req, res, { ok: false, error: err.message }, statusCode);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
app.post('/registerUser', verifyToken, async (req, res) => {
|
|
358
|
+
const { user, password } = req.body;
|
|
359
|
+
try {
|
|
360
|
+
const newUser = await registerUserRaw(user, password);
|
|
361
|
+
return sendResponse(req, res, { ok: true, user: newUser });
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
return sendResponse(req, res, { ok: false, error: err.message }, 400);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
app.post('/deleteUser', verifyToken, async (req, res) => {
|
|
368
|
+
if (req.user && req.user.userType === 'provisional') {
|
|
369
|
+
return sendResponse(req, res, { ok: false, error: 'provisional user cannot delete users' }, 403);
|
|
370
|
+
}
|
|
371
|
+
const { _id, authId } = req.body;
|
|
372
|
+
try {
|
|
373
|
+
const deletedCount = await deleteUserRaw(_id, authId);
|
|
374
|
+
return sendResponse(req, res, { ok: true, deletedCount });
|
|
375
|
+
}
|
|
376
|
+
catch (err) {
|
|
377
|
+
return sendResponse(req, res, { ok: false, error: err.message }, 400);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
app.post('/revlm-gate', verifyToken, async (req, res) => {
|
|
381
|
+
const { db, collection, method, document, options, filter, update, replacement, pipeline, documents } = req.body;
|
|
382
|
+
try {
|
|
383
|
+
const _db = getClient().db(db);
|
|
384
|
+
if (!_db)
|
|
385
|
+
return sendResponse(req, res, { ok: false, error: 'Invalid db parameter' }, 400);
|
|
386
|
+
const col = _db.collection(collection);
|
|
387
|
+
if (!col)
|
|
388
|
+
return sendResponse(req, res, { ok: false, error: 'Invalid collection parameter' }, 400);
|
|
389
|
+
let result;
|
|
390
|
+
switch (method) {
|
|
391
|
+
case 'find':
|
|
392
|
+
result = await col.find(filter || {}, options || {}).toArray();
|
|
393
|
+
break;
|
|
394
|
+
case 'findOne':
|
|
395
|
+
result = await col.findOne(filter || {}, options || {});
|
|
396
|
+
break;
|
|
397
|
+
case 'findOneAndUpdate':
|
|
398
|
+
result = await col.findOneAndUpdate(filter, update, options || {});
|
|
399
|
+
break;
|
|
400
|
+
case 'findOneAndReplace':
|
|
401
|
+
result = await col.findOneAndReplace(filter, replacement, options || {});
|
|
402
|
+
break;
|
|
403
|
+
case 'findOneAndDelete':
|
|
404
|
+
result = await col.findOneAndDelete(filter || {}, options || {});
|
|
405
|
+
break;
|
|
406
|
+
case 'aggregate':
|
|
407
|
+
result = await col.aggregate(pipeline).toArray();
|
|
408
|
+
break;
|
|
409
|
+
case 'count':
|
|
410
|
+
result = await col.countDocuments(filter || {}, options || {});
|
|
411
|
+
break;
|
|
412
|
+
case 'insertOne':
|
|
413
|
+
result = await col.insertOne(document);
|
|
414
|
+
break;
|
|
415
|
+
case 'insertMany':
|
|
416
|
+
result = await col.insertMany(documents);
|
|
417
|
+
break;
|
|
418
|
+
case 'deleteOne':
|
|
419
|
+
result = await col.deleteOne(filter || {});
|
|
420
|
+
break;
|
|
421
|
+
case 'deleteMany':
|
|
422
|
+
result = await col.deleteMany(filter || {});
|
|
423
|
+
break;
|
|
424
|
+
case 'updateOne':
|
|
425
|
+
result = await col.updateOne(filter, update, options || {});
|
|
426
|
+
break;
|
|
427
|
+
case 'updateMany':
|
|
428
|
+
result = await col.updateMany(filter, update, options || {});
|
|
429
|
+
break;
|
|
430
|
+
case 'watch':
|
|
431
|
+
const changeStream = col.watch(options || {});
|
|
432
|
+
result = [];
|
|
433
|
+
for await (const change of changeStream) {
|
|
434
|
+
result.push(change);
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
case 'drop':
|
|
438
|
+
result = await col.drop();
|
|
439
|
+
break;
|
|
440
|
+
default:
|
|
441
|
+
return sendResponse(req, res, { ok: false, error: 'Unsupported method' }, 400);
|
|
442
|
+
}
|
|
443
|
+
return sendResponse(req, res, { ok: true, result });
|
|
444
|
+
}
|
|
445
|
+
catch (err) {
|
|
446
|
+
const statusCode = err.statusCode || 500;
|
|
447
|
+
return sendResponse(req, res, { ok: false, error: err.message }, statusCode);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
try {
|
|
451
|
+
server = app.listen(port);
|
|
452
|
+
}
|
|
453
|
+
catch (err) {
|
|
454
|
+
if (err && err.code === 'EADDRINUSE') {
|
|
455
|
+
console.log(`Port ${port} already in use (sync), assuming server is started elsewhere`);
|
|
456
|
+
server = undefined;
|
|
457
|
+
return server;
|
|
458
|
+
}
|
|
459
|
+
throw err;
|
|
460
|
+
}
|
|
461
|
+
await new Promise((resolve, reject) => {
|
|
462
|
+
server.once('listening', () => {
|
|
463
|
+
console.log(`🚀 Revlm API server started on port ${port}`);
|
|
464
|
+
resolve();
|
|
465
|
+
});
|
|
466
|
+
server.once('error', (err) => {
|
|
467
|
+
if (err && err.code === 'EADDRINUSE') {
|
|
468
|
+
console.log(`Port ${port} already in use, assuming server is started elsewhere`);
|
|
469
|
+
server = undefined;
|
|
470
|
+
resolve();
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
reject(err);
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
return server;
|
|
478
|
+
}
|
|
479
|
+
async function stopServer() {
|
|
480
|
+
if (server) {
|
|
481
|
+
await new Promise((resolve, reject) => {
|
|
482
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
483
|
+
});
|
|
484
|
+
server = undefined;
|
|
485
|
+
}
|
|
486
|
+
if (exports.client) {
|
|
487
|
+
await exports.client.close(true);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/start.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":""}
|
package/dist/start.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const server_1 = require("./server");
|
|
4
|
+
function toBool(v) {
|
|
5
|
+
if (v === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
return v === 'true' || v === '1';
|
|
8
|
+
}
|
|
9
|
+
function toNumber(v) {
|
|
10
|
+
if (v === undefined || v === '')
|
|
11
|
+
return undefined;
|
|
12
|
+
const n = Number(v);
|
|
13
|
+
return Number.isFinite(n) ? n : undefined;
|
|
14
|
+
}
|
|
15
|
+
function getEnvOrUndefined(name) {
|
|
16
|
+
const v = process.env[name];
|
|
17
|
+
if (v === undefined || v === '')
|
|
18
|
+
return undefined;
|
|
19
|
+
return v;
|
|
20
|
+
}
|
|
21
|
+
async function main() {
|
|
22
|
+
const raw = {
|
|
23
|
+
mongoUri: getEnvOrUndefined('MONGO_URI'),
|
|
24
|
+
usersDbName: getEnvOrUndefined('USERS_DB_NAME'),
|
|
25
|
+
usersCollectionName: getEnvOrUndefined('USERS_COLLECTION_NAME'),
|
|
26
|
+
provisionalLoginEnabled: toBool(getEnvOrUndefined('PROVISIONAL_LOGIN_ENABLED')),
|
|
27
|
+
provisionalAuthId: getEnvOrUndefined('PROVISIONAL_AUTH_ID'),
|
|
28
|
+
provisionalAuthSecretMaster: getEnvOrUndefined('PROVISIONAL_AUTH_SECRET_MASTER'),
|
|
29
|
+
provisionalAuthDomain: getEnvOrUndefined('PROVISIONAL_AUTH_DOMAIN'),
|
|
30
|
+
jwtSecret: getEnvOrUndefined('JWT_SECRET'),
|
|
31
|
+
jwtExpiresIn: getEnvOrUndefined('JWT_EXPIRES_IN'),
|
|
32
|
+
refreshWindowSec: toNumber(getEnvOrUndefined('REFRESH_WINDOW_SEC')),
|
|
33
|
+
port: toNumber(getEnvOrUndefined('PORT')),
|
|
34
|
+
};
|
|
35
|
+
// Remove undefined entries so optional properties are omitted (satisfies exactOptionalPropertyTypes)
|
|
36
|
+
const cfgPartial = Object.fromEntries(Object.entries(raw).filter(([, v]) => v !== undefined));
|
|
37
|
+
try {
|
|
38
|
+
await (0, server_1.startServer)(cfgPartial);
|
|
39
|
+
console.log('startServer called successfully');
|
|
40
|
+
// Attach shutdown handlers only after successful start (Ctrl+C will trigger SIGINT)
|
|
41
|
+
const shutdown = async (signal, err) => {
|
|
42
|
+
if (signal)
|
|
43
|
+
console.log(`Received ${signal}, shutting down...`);
|
|
44
|
+
if (err)
|
|
45
|
+
console.log('Shutdown triggered by error - Error name:', err && err.name, 'Error message:', err && err.message);
|
|
46
|
+
try {
|
|
47
|
+
await (0, server_1.stopServer)();
|
|
48
|
+
console.log('Server stopped cleanly');
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
catch (stopErr) {
|
|
52
|
+
console.log('stopServer failed - Error name:', stopErr && stopErr.name, 'Error message:', stopErr && stopErr.message);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
57
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
58
|
+
process.on('uncaughtException', (ex) => {
|
|
59
|
+
console.log('uncaughtException - Error name:', ex && ex.name, 'Error message:', ex && ex.message);
|
|
60
|
+
shutdown(undefined, ex);
|
|
61
|
+
});
|
|
62
|
+
process.on('unhandledRejection', (reason) => {
|
|
63
|
+
console.log('unhandledRejection -', reason && (reason.name || ''), reason && reason.message ? reason.message : reason);
|
|
64
|
+
shutdown(undefined, reason);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.log('start failed - Error name:', err && err.name, 'Error message:', err && err.message);
|
|
69
|
+
if (err && err.stack)
|
|
70
|
+
console.log(err.stack);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
void main();
|
|
75
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kedaruma/revlm-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Self-hosted replacement for MongoDB Realm App Services that brokers auth and MongoDB calls.",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"mongodb": "^6.20.0",
|
|
20
20
|
"jsonwebtoken": "^9.0.2",
|
|
21
21
|
"bcrypt": "^6.0.0",
|
|
22
|
-
"@kedaruma/revlm-shared": "1.0.
|
|
22
|
+
"@kedaruma/revlm-shared": "1.0.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"mongodb-memory-server": "^8.12.2"
|