@niledatabase/server 3.0.0-alpha.50 → 3.0.0-alpha.52
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/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +339 -335
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +339 -335
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var jose = require('jose');
|
|
4
3
|
require('dotenv/config');
|
|
5
4
|
var pg = require('pg');
|
|
5
|
+
var jose = require('jose');
|
|
6
6
|
|
|
7
7
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
8
|
|
|
@@ -62,62 +62,103 @@ function Logger(config, ...params) {
|
|
|
62
62
|
return { info, warn, error, debug };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
// src/utils/
|
|
66
|
-
var
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
};
|
|
65
|
+
// src/utils/constants.ts
|
|
66
|
+
var X_NILE_TENANT = "nile.tenant_id";
|
|
67
|
+
var X_NILE_USER_ID = "nile.user_id";
|
|
68
|
+
var X_NILE_ORIGIN = "nile.origin";
|
|
69
|
+
var X_NILE_SECURECOOKIES = "nile.secure_cookies";
|
|
72
70
|
|
|
73
|
-
// src/utils/
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
callback(value);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
71
|
+
// src/api/utils/request.ts
|
|
72
|
+
async function request(url, _init, config) {
|
|
73
|
+
const { info, error } = Logger(config, "[REQUEST]");
|
|
74
|
+
const { request: request2, ...init } = _init;
|
|
75
|
+
const requestUrl = new URL(request2.url);
|
|
76
|
+
const updatedHeaders = new Headers({});
|
|
77
|
+
if (request2.headers.get("cookie")) {
|
|
78
|
+
updatedHeaders.set("cookie", String(request2.headers.get("cookie")));
|
|
84
79
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.events[eventName].push(callback);
|
|
80
|
+
if (request2.headers.get(X_NILE_TENANT)) {
|
|
81
|
+
updatedHeaders.set(
|
|
82
|
+
X_NILE_TENANT,
|
|
83
|
+
String(request2.headers.get(X_NILE_TENANT))
|
|
84
|
+
);
|
|
91
85
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
if ("secureCookies" in config && config.secureCookies != null) {
|
|
87
|
+
updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
|
|
88
|
+
}
|
|
89
|
+
updatedHeaders.set("host", requestUrl.host);
|
|
90
|
+
updatedHeaders.set(X_NILE_ORIGIN, requestUrl.origin);
|
|
91
|
+
const params = { ...init, headers: updatedHeaders };
|
|
92
|
+
if (params.method === "POST" || params.method === "PUT") {
|
|
93
|
+
try {
|
|
94
|
+
updatedHeaders.set("content-type", "application/json");
|
|
95
|
+
const initBody = await new Response(_init.request.clone().body).json();
|
|
96
|
+
const requestBody = await new Response(request2.clone().body).json();
|
|
97
|
+
params.body = JSON.stringify(initBody ?? requestBody);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
|
|
100
|
+
const initBody = await new Response(_init.request.clone().body).text();
|
|
101
|
+
const requestBody = await new Response(request2.clone().body).text();
|
|
102
|
+
params.body = initBody ?? requestBody;
|
|
97
103
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
}
|
|
105
|
+
const fullUrl = `${url}${requestUrl.search}`;
|
|
106
|
+
try {
|
|
107
|
+
const res = await fetch(fullUrl, { ...params }).catch((e) => {
|
|
108
|
+
error("An error has occurred in the fetch", {
|
|
109
|
+
message: e.message,
|
|
110
|
+
stack: e.stack
|
|
111
|
+
});
|
|
112
|
+
return new Response(
|
|
113
|
+
"An unexpected (most likely configuration) problem has occurred",
|
|
114
|
+
{ status: 500 }
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
|
|
118
|
+
info(`[${params.method ?? "GET"}] ${fullUrl}`, {
|
|
119
|
+
status: res?.status,
|
|
120
|
+
statusText: res?.statusText,
|
|
121
|
+
text: await loggingRes?.text()
|
|
122
|
+
});
|
|
123
|
+
return res;
|
|
124
|
+
} catch (e) {
|
|
125
|
+
if (e instanceof Error) {
|
|
126
|
+
error("An error has occurred in the fetch", {
|
|
127
|
+
message: e.message,
|
|
128
|
+
stack: e.stack
|
|
129
|
+
});
|
|
101
130
|
}
|
|
102
|
-
|
|
103
|
-
|
|
131
|
+
return new Response(
|
|
132
|
+
"An unexpected (most likely configuration) problem has occurred",
|
|
133
|
+
{ status: 500 }
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/api/utils/auth.ts
|
|
139
|
+
async function auth(req, config) {
|
|
140
|
+
const { info, error } = Logger(config, "[nileauth]");
|
|
141
|
+
info("checking auth");
|
|
142
|
+
const sessionUrl = `${config.api.basePath}/auth/session`;
|
|
143
|
+
info(`using session${sessionUrl}`);
|
|
144
|
+
req.headers.delete("content-length");
|
|
145
|
+
const res = await request(sessionUrl, { request: req }, config);
|
|
146
|
+
if (!res) {
|
|
147
|
+
info("no session found");
|
|
148
|
+
return void 0;
|
|
149
|
+
}
|
|
150
|
+
info("session active");
|
|
151
|
+
try {
|
|
152
|
+
const session = await new Response(res.body).json();
|
|
153
|
+
if (Object.keys(session).length === 0) {
|
|
154
|
+
return void 0;
|
|
104
155
|
}
|
|
156
|
+
return session;
|
|
157
|
+
} catch (e) {
|
|
158
|
+
error(e);
|
|
159
|
+
return void 0;
|
|
105
160
|
}
|
|
106
|
-
}
|
|
107
|
-
var eventer = new Eventer();
|
|
108
|
-
var updateTenantId = (tenantId) => {
|
|
109
|
-
eventer.publish("tenantId" /* Tenant */, tenantId);
|
|
110
|
-
};
|
|
111
|
-
var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
|
|
112
|
-
var updateUserId = (userId) => {
|
|
113
|
-
eventer.publish("userId" /* User */, userId);
|
|
114
|
-
};
|
|
115
|
-
var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
|
|
116
|
-
var watchToken = (cb) => eventer.subscribe("token" /* Token */, cb);
|
|
117
|
-
var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
|
|
118
|
-
var evictPool = (val) => {
|
|
119
|
-
eventer.publish("EvictPool" /* EvictPool */, val);
|
|
120
|
-
};
|
|
161
|
+
}
|
|
121
162
|
var getSecureCookies = (cfg) => {
|
|
122
163
|
const { config } = cfg;
|
|
123
164
|
if (stringCheck(process.env.NILEDB_SECURECOOKIES)) {
|
|
@@ -318,293 +359,32 @@ function getDbPort(cfg) {
|
|
|
318
359
|
logger && info(`${logger}[config] ${config?.db.port}`);
|
|
319
360
|
return Number(config.db?.port);
|
|
320
361
|
}
|
|
321
|
-
if (stringCheck(process.env.NILEDB_PORT)) {
|
|
322
|
-
logger && info(`${logger}[NILEDB_PORT] ${process.env.NILEDB_PORT}`);
|
|
323
|
-
return Number(process.env.NILEDB_PORT);
|
|
324
|
-
}
|
|
325
|
-
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
326
|
-
if (pg2) {
|
|
327
|
-
try {
|
|
328
|
-
const pgUrl = new URL(pg2);
|
|
329
|
-
if (pgUrl.port) {
|
|
330
|
-
return Number(pgUrl.port);
|
|
331
|
-
}
|
|
332
|
-
} catch (e) {
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
logger && info(`${logger}[default] 5432`);
|
|
336
|
-
return 5432;
|
|
337
|
-
}
|
|
338
|
-
var logProtector = (logger) => {
|
|
339
|
-
return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test" ? logger : null;
|
|
340
|
-
};
|
|
341
|
-
var stringCheck = (str) => {
|
|
342
|
-
if (str && str !== "") {
|
|
343
|
-
return str;
|
|
344
|
-
}
|
|
345
|
-
return;
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
// src/utils/fetch.ts
|
|
349
|
-
var X_NILE_TENANT = "niledb-tenant-id";
|
|
350
|
-
var X_NILE_USER_ID = "niledb-user-id";
|
|
351
|
-
var X_NILE_SECURECOOKIES = "niledb-useSecureCookies";
|
|
352
|
-
function getTokenFromCookie(headers, cookieKey) {
|
|
353
|
-
const cookie = headers.get("cookie")?.split("; ");
|
|
354
|
-
const _cookies = {};
|
|
355
|
-
if (cookie) {
|
|
356
|
-
for (const parts of cookie) {
|
|
357
|
-
const cookieParts = parts.split("=");
|
|
358
|
-
const _cookie = cookieParts.slice(1).join("=");
|
|
359
|
-
const name = cookieParts[0];
|
|
360
|
-
_cookies[name] = _cookie;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
if (cookie) {
|
|
364
|
-
for (const parts of cookie) {
|
|
365
|
-
const cookieParts = parts.split("=");
|
|
366
|
-
const _cookie = cookieParts.slice(1).join("=");
|
|
367
|
-
const name = cookieParts[0];
|
|
368
|
-
_cookies[name] = _cookie;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
if (cookieKey) {
|
|
372
|
-
return _cookies[cookieKey];
|
|
373
|
-
}
|
|
374
|
-
return null;
|
|
375
|
-
}
|
|
376
|
-
function getTenantFromHttp(headers, config) {
|
|
377
|
-
const cookieTenant = getTokenFromCookie(headers, X_NILE_TENANT);
|
|
378
|
-
return cookieTenant ?? headers?.get(X_NILE_TENANT) ?? config?.tenantId;
|
|
379
|
-
}
|
|
380
|
-
function getUserFromHttp(headers, config) {
|
|
381
|
-
const token = getTokenFromCookie(headers, config.api.cookieKey);
|
|
382
|
-
if (token) {
|
|
383
|
-
const jwt = jose.decodeJwt(token);
|
|
384
|
-
return jwt.sub;
|
|
385
|
-
}
|
|
386
|
-
return headers?.get(X_NILE_USER_ID) ?? config.userId;
|
|
387
|
-
}
|
|
388
|
-
function makeBasicHeaders(config, opts) {
|
|
389
|
-
const headers = new Headers(opts?.headers);
|
|
390
|
-
headers.set("content-type", "application/json; charset=utf-8");
|
|
391
|
-
const cookieKey = config.api?.cookieKey;
|
|
392
|
-
const authHeader = headers.get("Authorization");
|
|
393
|
-
if (!authHeader) {
|
|
394
|
-
const token = getTokenFromCookie(headers, cookieKey);
|
|
395
|
-
if (token) {
|
|
396
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
397
|
-
} else if (getToken({ config })) {
|
|
398
|
-
headers.set("Authorization", `Bearer ${getToken({ config })}`);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
if ("secureCookies" in config && config.secureCookies != null) {
|
|
402
|
-
headers.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
|
|
403
|
-
}
|
|
404
|
-
return headers;
|
|
405
|
-
}
|
|
406
|
-
async function _fetch(config, path, opts) {
|
|
407
|
-
const { debug, error } = Logger(config, "[server]");
|
|
408
|
-
const url = `${config.api?.basePath}${path}`;
|
|
409
|
-
const headers = new Headers(opts?.headers);
|
|
410
|
-
const tenantId = getTenantFromHttp(headers, config);
|
|
411
|
-
const basicHeaders = makeBasicHeaders(config, opts);
|
|
412
|
-
updateTenantId(tenantId);
|
|
413
|
-
const userId = getUserFromHttp(headers, config);
|
|
414
|
-
updateUserId(userId);
|
|
415
|
-
if (url.includes("{tenantId}") && !tenantId) {
|
|
416
|
-
return new ResponseError("tenantId is not set for request", {
|
|
417
|
-
status: 400
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
const useableUrl = url.replace("{tenantId}", encodeURIComponent(String(tenantId))).replace("{userId}", encodeURIComponent(String(userId)));
|
|
421
|
-
debug(`[fetch] ${useableUrl}`);
|
|
422
|
-
try {
|
|
423
|
-
const response = await fetch(useableUrl, {
|
|
424
|
-
...opts,
|
|
425
|
-
headers: basicHeaders
|
|
426
|
-
}).catch((e) => {
|
|
427
|
-
error("[fetch][response]", {
|
|
428
|
-
message: e.message,
|
|
429
|
-
stack: e.stack,
|
|
430
|
-
debug: "Is nile-auth running?"
|
|
431
|
-
});
|
|
432
|
-
return new Error(e);
|
|
433
|
-
});
|
|
434
|
-
if (response instanceof Error) {
|
|
435
|
-
return new ResponseError("Failed to connect to database", {
|
|
436
|
-
status: 400
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
if (response && response.status >= 200 && response.status < 300) {
|
|
440
|
-
if (typeof response.clone === "function") {
|
|
441
|
-
try {
|
|
442
|
-
debug(
|
|
443
|
-
`[fetch][response][${opts?.method ?? "GET"}] ${response.status} ${useableUrl}`,
|
|
444
|
-
{
|
|
445
|
-
body: await response.clone().json()
|
|
446
|
-
}
|
|
447
|
-
);
|
|
448
|
-
} catch (e) {
|
|
449
|
-
debug(
|
|
450
|
-
`[fetch][response][${opts?.method ?? "GET"}] ${response.status} ${useableUrl}`,
|
|
451
|
-
{
|
|
452
|
-
body: await response.clone().text()
|
|
453
|
-
}
|
|
454
|
-
);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
return response;
|
|
458
|
-
}
|
|
459
|
-
if (response?.status === 404) {
|
|
460
|
-
return new ResponseError("Not found", { status: 404 });
|
|
461
|
-
}
|
|
462
|
-
if (response?.status === 401) {
|
|
463
|
-
return new ResponseError("Unauthorized", { status: 401 });
|
|
464
|
-
}
|
|
465
|
-
if (response?.status === 405) {
|
|
466
|
-
return new ResponseError("Method not allowed", { status: 405 });
|
|
467
|
-
}
|
|
468
|
-
let res;
|
|
469
|
-
const errorHandler = typeof response?.clone === "function" ? response.clone() : null;
|
|
470
|
-
let msg = "";
|
|
471
|
-
try {
|
|
472
|
-
res = await response?.json();
|
|
473
|
-
} catch (e) {
|
|
474
|
-
if (errorHandler) {
|
|
475
|
-
msg = await errorHandler.text();
|
|
476
|
-
if (msg) {
|
|
477
|
-
error(`[fetch][response][status: ${errorHandler.status}]`, {
|
|
478
|
-
message: msg
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
return e;
|
|
482
|
-
}
|
|
483
|
-
if (!msg) {
|
|
484
|
-
error("[fetch][response]", { e });
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
if (msg) {
|
|
488
|
-
return new ResponseError(msg, { status: errorHandler?.status });
|
|
489
|
-
}
|
|
490
|
-
if (res && "message" in res) {
|
|
491
|
-
const { message } = res;
|
|
492
|
-
error(`[fetch][response][status: ${errorHandler?.status}] ${message}`);
|
|
493
|
-
return new ResponseError(message, { status: 400 });
|
|
494
|
-
}
|
|
495
|
-
if (res && "errors" in res) {
|
|
496
|
-
const {
|
|
497
|
-
errors: [message]
|
|
498
|
-
} = res;
|
|
499
|
-
error(`[fetch][response] [status: ${errorHandler?.status}] ${message}`);
|
|
500
|
-
return new ResponseError(message, { status: 400 });
|
|
501
|
-
}
|
|
502
|
-
error(
|
|
503
|
-
`[fetch][response][status: ${errorHandler?.status}] UNHANDLED ERROR`,
|
|
504
|
-
{
|
|
505
|
-
res
|
|
506
|
-
}
|
|
507
|
-
);
|
|
508
|
-
return new ResponseError(null, {
|
|
509
|
-
status: response?.status ?? 500
|
|
510
|
-
});
|
|
511
|
-
} catch (e) {
|
|
512
|
-
return new ResponseError("an unexpected error has occurred", {
|
|
513
|
-
status: 500
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// src/api/utils/request.ts
|
|
519
|
-
async function request(url, _init, config) {
|
|
520
|
-
const { info, error } = Logger(config, "[REQUEST]");
|
|
521
|
-
const { request: request2, ...init } = _init;
|
|
522
|
-
const requestUrl = new URL(request2.url);
|
|
523
|
-
const updatedHeaders = new Headers({});
|
|
524
|
-
if (request2.headers.get("cookie")) {
|
|
525
|
-
updatedHeaders.set("cookie", String(request2.headers.get("cookie")));
|
|
526
|
-
}
|
|
527
|
-
if (request2.headers.get(X_NILE_TENANT)) {
|
|
528
|
-
updatedHeaders.set(
|
|
529
|
-
X_NILE_TENANT,
|
|
530
|
-
String(request2.headers.get(X_NILE_TENANT))
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
if ("secureCookies" in config && config.secureCookies != null) {
|
|
534
|
-
updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
|
|
535
|
-
}
|
|
536
|
-
updatedHeaders.set("host", requestUrl.host);
|
|
537
|
-
updatedHeaders.set("niledb-origin", requestUrl.origin);
|
|
538
|
-
const params = { ...init, headers: updatedHeaders };
|
|
539
|
-
if (params.method === "POST" || params.method === "PUT") {
|
|
540
|
-
try {
|
|
541
|
-
updatedHeaders.set("content-type", "application/json");
|
|
542
|
-
const initBody = await new Response(_init.request.clone().body).json();
|
|
543
|
-
const requestBody = await new Response(request2.clone().body).json();
|
|
544
|
-
params.body = JSON.stringify(initBody ?? requestBody);
|
|
545
|
-
} catch (e) {
|
|
546
|
-
updatedHeaders.set("content-type", "application/x-www-form-urlencoded");
|
|
547
|
-
const initBody = await new Response(_init.request.clone().body).text();
|
|
548
|
-
const requestBody = await new Response(request2.clone().body).text();
|
|
549
|
-
params.body = initBody ?? requestBody;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
try {
|
|
553
|
-
const res = await fetch(url, { ...params }).catch((e) => {
|
|
554
|
-
error("An error has occurred in the fetch", {
|
|
555
|
-
message: e.message,
|
|
556
|
-
stack: e.stack
|
|
557
|
-
});
|
|
558
|
-
return new Response(
|
|
559
|
-
"An unexpected (most likely configuration) problem has occurred",
|
|
560
|
-
{ status: 500 }
|
|
561
|
-
);
|
|
562
|
-
});
|
|
563
|
-
const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
|
|
564
|
-
info(`[${params.method ?? "GET"}] ${url}`, {
|
|
565
|
-
status: res?.status,
|
|
566
|
-
statusText: res?.statusText,
|
|
567
|
-
text: await loggingRes?.text()
|
|
568
|
-
});
|
|
569
|
-
return res;
|
|
570
|
-
} catch (e) {
|
|
571
|
-
if (e instanceof Error) {
|
|
572
|
-
error("An error has occurred in the fetch", {
|
|
573
|
-
message: e.message,
|
|
574
|
-
stack: e.stack
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
return new Response(
|
|
578
|
-
"An unexpected (most likely configuration) problem has occurred",
|
|
579
|
-
{ status: 500 }
|
|
580
|
-
);
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// src/api/utils/auth.ts
|
|
585
|
-
async function auth(req, config) {
|
|
586
|
-
const { info, error } = Logger(config, "[nileauth]");
|
|
587
|
-
info("checking auth");
|
|
588
|
-
const sessionUrl = `${config.api.basePath}/auth/session`;
|
|
589
|
-
info(`using session${sessionUrl}`);
|
|
590
|
-
req.headers.delete("content-length");
|
|
591
|
-
const res = await request(sessionUrl, { request: req }, config);
|
|
592
|
-
if (!res) {
|
|
593
|
-
info("no session found");
|
|
594
|
-
return void 0;
|
|
595
|
-
}
|
|
596
|
-
info("session active");
|
|
597
|
-
try {
|
|
598
|
-
const session = await new Response(res.body).json();
|
|
599
|
-
if (Object.keys(session).length === 0) {
|
|
600
|
-
return void 0;
|
|
362
|
+
if (stringCheck(process.env.NILEDB_PORT)) {
|
|
363
|
+
logger && info(`${logger}[NILEDB_PORT] ${process.env.NILEDB_PORT}`);
|
|
364
|
+
return Number(process.env.NILEDB_PORT);
|
|
365
|
+
}
|
|
366
|
+
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
367
|
+
if (pg2) {
|
|
368
|
+
try {
|
|
369
|
+
const pgUrl = new URL(pg2);
|
|
370
|
+
if (pgUrl.port) {
|
|
371
|
+
return Number(pgUrl.port);
|
|
372
|
+
}
|
|
373
|
+
} catch (e) {
|
|
601
374
|
}
|
|
602
|
-
return session;
|
|
603
|
-
} catch (e) {
|
|
604
|
-
error(e);
|
|
605
|
-
return void 0;
|
|
606
375
|
}
|
|
376
|
+
logger && info(`${logger}[default] 5432`);
|
|
377
|
+
return 5432;
|
|
607
378
|
}
|
|
379
|
+
var logProtector = (logger) => {
|
|
380
|
+
return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test" ? logger : null;
|
|
381
|
+
};
|
|
382
|
+
var stringCheck = (str) => {
|
|
383
|
+
if (str && str !== "") {
|
|
384
|
+
return str;
|
|
385
|
+
}
|
|
386
|
+
return;
|
|
387
|
+
};
|
|
608
388
|
|
|
609
389
|
// src/utils/Config/index.ts
|
|
610
390
|
var ApiConfig = class {
|
|
@@ -814,6 +594,55 @@ var Config = class {
|
|
|
814
594
|
};
|
|
815
595
|
};
|
|
816
596
|
|
|
597
|
+
// src/utils/Event/index.ts
|
|
598
|
+
var Eventer = class {
|
|
599
|
+
events = {};
|
|
600
|
+
// Publish event and notify all subscribers
|
|
601
|
+
publish(eventName, value) {
|
|
602
|
+
const callbackList = this.events[eventName];
|
|
603
|
+
if (callbackList) {
|
|
604
|
+
for (const callback of callbackList) {
|
|
605
|
+
callback(value);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
// Subscribe to events
|
|
610
|
+
subscribe(eventName, callback) {
|
|
611
|
+
if (!this.events[eventName]) {
|
|
612
|
+
this.events[eventName] = [];
|
|
613
|
+
}
|
|
614
|
+
this.events[eventName].push(callback);
|
|
615
|
+
}
|
|
616
|
+
// Unsubscribe from an event
|
|
617
|
+
unsubscribe(eventName, callback) {
|
|
618
|
+
const callbackList = this.events[eventName];
|
|
619
|
+
if (!callbackList) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const index = callbackList.indexOf(callback);
|
|
623
|
+
if (index !== -1) {
|
|
624
|
+
callbackList.splice(index, 1);
|
|
625
|
+
}
|
|
626
|
+
if (callbackList.length === 0) {
|
|
627
|
+
delete this.events[eventName];
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
var eventer = new Eventer();
|
|
632
|
+
var updateTenantId = (tenantId) => {
|
|
633
|
+
eventer.publish("tenantId" /* Tenant */, tenantId);
|
|
634
|
+
};
|
|
635
|
+
var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
|
|
636
|
+
var updateUserId = (userId) => {
|
|
637
|
+
eventer.publish("userId" /* User */, userId);
|
|
638
|
+
};
|
|
639
|
+
var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
|
|
640
|
+
var watchToken = (cb) => eventer.subscribe("token" /* Token */, cb);
|
|
641
|
+
var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
|
|
642
|
+
var evictPool = (val) => {
|
|
643
|
+
eventer.publish("EvictPool" /* EvictPool */, val);
|
|
644
|
+
};
|
|
645
|
+
|
|
817
646
|
// src/db/PoolProxy.ts
|
|
818
647
|
function createProxyForPool(pool, config) {
|
|
819
648
|
const { info, error } = Logger(config, "[pool]");
|
|
@@ -1097,6 +926,181 @@ function matches(configRoutes, request2) {
|
|
|
1097
926
|
return urlMatches(request2.url, configRoutes[key]);
|
|
1098
927
|
}
|
|
1099
928
|
|
|
929
|
+
// src/utils/ResponseError.ts
|
|
930
|
+
var ResponseError = class {
|
|
931
|
+
response;
|
|
932
|
+
constructor(body, init) {
|
|
933
|
+
this.response = new Response(body, init);
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
// src/utils/fetch.ts
|
|
938
|
+
function getTokenFromCookie(headers, cookieKey) {
|
|
939
|
+
const cookie = headers.get("cookie")?.split("; ");
|
|
940
|
+
const _cookies = {};
|
|
941
|
+
if (cookie) {
|
|
942
|
+
for (const parts of cookie) {
|
|
943
|
+
const cookieParts = parts.split("=");
|
|
944
|
+
const _cookie = cookieParts.slice(1).join("=");
|
|
945
|
+
const name = cookieParts[0];
|
|
946
|
+
_cookies[name] = _cookie;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
if (cookie) {
|
|
950
|
+
for (const parts of cookie) {
|
|
951
|
+
const cookieParts = parts.split("=");
|
|
952
|
+
const _cookie = cookieParts.slice(1).join("=");
|
|
953
|
+
const name = cookieParts[0];
|
|
954
|
+
_cookies[name] = _cookie;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
if (cookieKey) {
|
|
958
|
+
return _cookies[cookieKey];
|
|
959
|
+
}
|
|
960
|
+
return null;
|
|
961
|
+
}
|
|
962
|
+
function getTenantFromHttp(headers, config) {
|
|
963
|
+
const cookieTenant = getTokenFromCookie(headers, X_NILE_TENANT);
|
|
964
|
+
return cookieTenant ?? headers?.get(X_NILE_TENANT) ?? config?.tenantId;
|
|
965
|
+
}
|
|
966
|
+
function getUserFromHttp(headers, config) {
|
|
967
|
+
const token = getTokenFromCookie(headers, config.api.cookieKey);
|
|
968
|
+
if (token) {
|
|
969
|
+
const jwt = jose.decodeJwt(token);
|
|
970
|
+
return jwt.sub;
|
|
971
|
+
}
|
|
972
|
+
return headers?.get(X_NILE_USER_ID) ?? config.userId;
|
|
973
|
+
}
|
|
974
|
+
function makeBasicHeaders(config, opts) {
|
|
975
|
+
const headers = new Headers(opts?.headers);
|
|
976
|
+
headers.set("content-type", "application/json; charset=utf-8");
|
|
977
|
+
const cookieKey = config.api?.cookieKey;
|
|
978
|
+
const authHeader = headers.get("Authorization");
|
|
979
|
+
if (!authHeader) {
|
|
980
|
+
const token = getTokenFromCookie(headers, cookieKey);
|
|
981
|
+
if (token) {
|
|
982
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
983
|
+
} else if (getToken({ config })) {
|
|
984
|
+
headers.set("Authorization", `Bearer ${getToken({ config })}`);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if ("secureCookies" in config && config.secureCookies != null) {
|
|
988
|
+
headers.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
|
|
989
|
+
}
|
|
990
|
+
return headers;
|
|
991
|
+
}
|
|
992
|
+
async function _fetch(config, path, opts) {
|
|
993
|
+
const { debug, error } = Logger(config, "[server]");
|
|
994
|
+
const url = `${config.api?.basePath}${path}`;
|
|
995
|
+
const headers = new Headers(opts?.headers);
|
|
996
|
+
const tenantId = getTenantFromHttp(headers, config);
|
|
997
|
+
const basicHeaders = makeBasicHeaders(config, opts);
|
|
998
|
+
updateTenantId(tenantId);
|
|
999
|
+
const userId = getUserFromHttp(headers, config);
|
|
1000
|
+
updateUserId(userId);
|
|
1001
|
+
if (url.includes("{tenantId}") && !tenantId) {
|
|
1002
|
+
return new ResponseError("tenantId is not set for request", {
|
|
1003
|
+
status: 400
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
const useableUrl = url.replace("{tenantId}", encodeURIComponent(String(tenantId))).replace("{userId}", encodeURIComponent(String(userId)));
|
|
1007
|
+
debug(`[fetch] ${useableUrl}`);
|
|
1008
|
+
try {
|
|
1009
|
+
const response = await fetch(useableUrl, {
|
|
1010
|
+
...opts,
|
|
1011
|
+
headers: basicHeaders
|
|
1012
|
+
}).catch((e) => {
|
|
1013
|
+
error("[fetch][response]", {
|
|
1014
|
+
message: e.message,
|
|
1015
|
+
stack: e.stack,
|
|
1016
|
+
debug: "Is nile-auth running?"
|
|
1017
|
+
});
|
|
1018
|
+
return new Error(e);
|
|
1019
|
+
});
|
|
1020
|
+
if (response instanceof Error) {
|
|
1021
|
+
return new ResponseError("Failed to connect to database", {
|
|
1022
|
+
status: 400
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
if (response && response.status >= 200 && response.status < 300) {
|
|
1026
|
+
if (typeof response.clone === "function") {
|
|
1027
|
+
try {
|
|
1028
|
+
debug(
|
|
1029
|
+
`[fetch][response][${opts?.method ?? "GET"}] ${response.status} ${useableUrl}`,
|
|
1030
|
+
{
|
|
1031
|
+
body: await response.clone().json()
|
|
1032
|
+
}
|
|
1033
|
+
);
|
|
1034
|
+
} catch (e) {
|
|
1035
|
+
debug(
|
|
1036
|
+
`[fetch][response][${opts?.method ?? "GET"}] ${response.status} ${useableUrl}`,
|
|
1037
|
+
{
|
|
1038
|
+
body: await response.clone().text()
|
|
1039
|
+
}
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
return response;
|
|
1044
|
+
}
|
|
1045
|
+
if (response?.status === 404) {
|
|
1046
|
+
return new ResponseError("Not found", { status: 404 });
|
|
1047
|
+
}
|
|
1048
|
+
if (response?.status === 401) {
|
|
1049
|
+
return new ResponseError("Unauthorized", { status: 401 });
|
|
1050
|
+
}
|
|
1051
|
+
if (response?.status === 405) {
|
|
1052
|
+
return new ResponseError("Method not allowed", { status: 405 });
|
|
1053
|
+
}
|
|
1054
|
+
let res;
|
|
1055
|
+
const errorHandler = typeof response?.clone === "function" ? response.clone() : null;
|
|
1056
|
+
let msg = "";
|
|
1057
|
+
try {
|
|
1058
|
+
res = await response?.json();
|
|
1059
|
+
} catch (e) {
|
|
1060
|
+
if (errorHandler) {
|
|
1061
|
+
msg = await errorHandler.text();
|
|
1062
|
+
if (msg) {
|
|
1063
|
+
error(`[fetch][response][status: ${errorHandler.status}]`, {
|
|
1064
|
+
message: msg
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
return e;
|
|
1068
|
+
}
|
|
1069
|
+
if (!msg) {
|
|
1070
|
+
error("[fetch][response]", { e });
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
if (msg) {
|
|
1074
|
+
return new ResponseError(msg, { status: errorHandler?.status });
|
|
1075
|
+
}
|
|
1076
|
+
if (res && "message" in res) {
|
|
1077
|
+
const { message } = res;
|
|
1078
|
+
error(`[fetch][response][status: ${errorHandler?.status}] ${message}`);
|
|
1079
|
+
return new ResponseError(message, { status: 400 });
|
|
1080
|
+
}
|
|
1081
|
+
if (res && "errors" in res) {
|
|
1082
|
+
const {
|
|
1083
|
+
errors: [message]
|
|
1084
|
+
} = res;
|
|
1085
|
+
error(`[fetch][response] [status: ${errorHandler?.status}] ${message}`);
|
|
1086
|
+
return new ResponseError(message, { status: 400 });
|
|
1087
|
+
}
|
|
1088
|
+
error(
|
|
1089
|
+
`[fetch][response][status: ${errorHandler?.status}] UNHANDLED ERROR`,
|
|
1090
|
+
{
|
|
1091
|
+
res
|
|
1092
|
+
}
|
|
1093
|
+
);
|
|
1094
|
+
return new ResponseError(null, {
|
|
1095
|
+
status: response?.status ?? 500
|
|
1096
|
+
});
|
|
1097
|
+
} catch (e) {
|
|
1098
|
+
return new ResponseError("an unexpected error has occurred", {
|
|
1099
|
+
status: 500
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1100
1104
|
// src/api/routes/users/POST.ts
|
|
1101
1105
|
async function POST(config, init) {
|
|
1102
1106
|
init.body = init.request.body;
|
|
@@ -1870,7 +1874,7 @@ function serverLogin(config, handlers) {
|
|
|
1870
1874
|
const sessionUrl = new URL(`${ORIGIN}${routes.PROVIDERS}`);
|
|
1871
1875
|
const baseHeaders = {
|
|
1872
1876
|
host: sessionUrl.host,
|
|
1873
|
-
|
|
1877
|
+
[X_NILE_ORIGIN]: ORIGIN
|
|
1874
1878
|
};
|
|
1875
1879
|
info(`Obtaining providers for ${email}`);
|
|
1876
1880
|
const sessionReq = new Request(sessionUrl, {
|