@niledatabase/server 5.0.0-alpha.26 → 5.0.0-alpha.28
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 +48 -38
- package/dist/index.d.ts +48 -38
- package/dist/index.js +1144 -945
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1144 -946
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var async_hooks = require('async_hooks');
|
|
3
4
|
require('dotenv/config');
|
|
4
5
|
var pg = require('pg');
|
|
5
6
|
|
|
@@ -12,6 +13,7 @@ var ExtensionState = /* @__PURE__ */ ((ExtensionState2) => {
|
|
|
12
13
|
ExtensionState2["onHandleRequest"] = "onHandleRequest";
|
|
13
14
|
ExtensionState2["onRequest"] = "onRequest";
|
|
14
15
|
ExtensionState2["onResponse"] = "onResponse";
|
|
16
|
+
ExtensionState2["withContext"] = "withContext";
|
|
15
17
|
return ExtensionState2;
|
|
16
18
|
})(ExtensionState || {});
|
|
17
19
|
var APIErrorErrorCodeEnum = {
|
|
@@ -69,21 +71,18 @@ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
|
|
|
69
71
|
INVITE: `${prefix}${"/tenants/{tenantId}/invite" /* INVITE */}`,
|
|
70
72
|
LOG: `${prefix}/_log`
|
|
71
73
|
});
|
|
72
|
-
var apiRoutes = (
|
|
73
|
-
ME: makeRestUrl(
|
|
74
|
-
USERS: (qp) => makeRestUrl(
|
|
75
|
-
USER: (userId) => makeRestUrl(
|
|
76
|
-
TENANTS: makeRestUrl(
|
|
77
|
-
TENANT: (tenantId) => makeRestUrl(
|
|
78
|
-
SIGNUP: makeRestUrl(
|
|
79
|
-
TENANT_USERS: (tenantId) => makeRestUrl(
|
|
80
|
-
INVITES: (tenantId) => makeRestUrl(
|
|
81
|
-
INVITE: (tenantId) => makeRestUrl(
|
|
82
|
-
TENANT_USER: makeRestUrl(
|
|
83
|
-
|
|
84
|
-
`/tenants/${config.tenantId}/users/${config.userId}`
|
|
85
|
-
),
|
|
86
|
-
USER_TENANTS: (userId) => makeRestUrl(config, `/users/${userId}/tenants`)
|
|
74
|
+
var apiRoutes = (apiUrl) => ({
|
|
75
|
+
ME: makeRestUrl(apiUrl, "/me"),
|
|
76
|
+
USERS: (qp) => makeRestUrl(apiUrl, "/users", qp),
|
|
77
|
+
USER: (userId) => makeRestUrl(apiUrl, `/users/${userId}`),
|
|
78
|
+
TENANTS: makeRestUrl(apiUrl, "/tenants"),
|
|
79
|
+
TENANT: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}`),
|
|
80
|
+
SIGNUP: makeRestUrl(apiUrl, "/signup"),
|
|
81
|
+
TENANT_USERS: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users`),
|
|
82
|
+
INVITES: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invites`),
|
|
83
|
+
INVITE: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invite`),
|
|
84
|
+
TENANT_USER: (tenantId, userId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users/${userId}`),
|
|
85
|
+
USER_TENANTS: (userId) => makeRestUrl(apiUrl, `/users/${userId}/tenants`)
|
|
87
86
|
});
|
|
88
87
|
var proxyRoutes = (config) => ({
|
|
89
88
|
SIGNIN: makeRestUrl(config, "/auth/signin" /* SIGNIN */),
|
|
@@ -107,8 +106,8 @@ function filterNullUndefined(obj) {
|
|
|
107
106
|
)
|
|
108
107
|
);
|
|
109
108
|
}
|
|
110
|
-
function makeRestUrl(
|
|
111
|
-
const url =
|
|
109
|
+
function makeRestUrl(apiUrl, path, qp) {
|
|
110
|
+
const url = apiUrl || NILEDB_API_URL;
|
|
112
111
|
if (!url) {
|
|
113
112
|
throw new Error(
|
|
114
113
|
"An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?"
|
|
@@ -265,10 +264,309 @@ async function auth(req, config) {
|
|
|
265
264
|
}
|
|
266
265
|
}
|
|
267
266
|
|
|
267
|
+
// src/utils/Logger.ts
|
|
268
|
+
var red = "\x1B[31m";
|
|
269
|
+
var yellow = "\x1B[38;2;255;255;0m";
|
|
270
|
+
var purple = "\x1B[38;2;200;160;255m";
|
|
271
|
+
var orange = "\x1B[38;2;255;165;0m";
|
|
272
|
+
var reset = "\x1B[0m";
|
|
273
|
+
var baseLogger = (config, ...params) => ({
|
|
274
|
+
silly(message, meta) {
|
|
275
|
+
if (config?.debug && process.env.LOG_LEVEL === "silly") {
|
|
276
|
+
console.log(
|
|
277
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
278
|
+
""
|
|
279
|
+
)}${reset} ${message}`,
|
|
280
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
info(message, meta) {
|
|
285
|
+
if (config?.debug) {
|
|
286
|
+
console.info(
|
|
287
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
288
|
+
""
|
|
289
|
+
)}${reset} ${message}`,
|
|
290
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
debug(message, meta) {
|
|
295
|
+
if (config?.debug) {
|
|
296
|
+
console.log(
|
|
297
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
298
|
+
""
|
|
299
|
+
)}${reset} ${message}`,
|
|
300
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
warn(message, meta) {
|
|
305
|
+
if (config?.debug) {
|
|
306
|
+
console.warn(
|
|
307
|
+
`${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
|
|
308
|
+
""
|
|
309
|
+
)}${reset} ${message}`,
|
|
310
|
+
meta ? JSON.stringify(meta) : ""
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
error(message, meta) {
|
|
315
|
+
console.error(
|
|
316
|
+
`${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
|
|
317
|
+
""
|
|
318
|
+
)}${red} ${message}`,
|
|
319
|
+
meta ? meta : "",
|
|
320
|
+
`${reset}`
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
function Logger(config) {
|
|
325
|
+
return (prefixes) => {
|
|
326
|
+
const { info, debug, warn: warn2, error, silly: silly2 } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
|
|
327
|
+
return {
|
|
328
|
+
info,
|
|
329
|
+
debug,
|
|
330
|
+
warn: warn2,
|
|
331
|
+
error,
|
|
332
|
+
silly: silly2
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function matchesLog(configRoutes, request2) {
|
|
337
|
+
return urlMatches(request2.url, configRoutes.LOG);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/api/utils/extensions.ts
|
|
341
|
+
function getRequestConfig(params) {
|
|
342
|
+
if (typeof params[1] === "object") {
|
|
343
|
+
return params[1];
|
|
344
|
+
}
|
|
345
|
+
return {};
|
|
346
|
+
}
|
|
347
|
+
function bindRunExtensions(instance) {
|
|
348
|
+
return async function runExtensions(toRun, config, params, _init) {
|
|
349
|
+
const { debug } = config.logger("[EXTENSIONS]");
|
|
350
|
+
const extensionConfig = getRequestConfig(
|
|
351
|
+
Array.isArray(params) ? params : [null, params]
|
|
352
|
+
);
|
|
353
|
+
if (config.extensions) {
|
|
354
|
+
for (const create2 of config.extensions) {
|
|
355
|
+
if (typeof create2 !== "function") {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
const ext = create2(instance);
|
|
359
|
+
if (extensionConfig.disableExtensions?.includes(ext.id)) {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (ext.withContext && toRun === "withContext" /* withContext */) {
|
|
363
|
+
await ext.withContext(ctx);
|
|
364
|
+
}
|
|
365
|
+
if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
|
|
366
|
+
const result = await ext.onHandleRequest(
|
|
367
|
+
Array.isArray(params) ? params : [params]
|
|
368
|
+
);
|
|
369
|
+
debug(`${ext.id ?? create2.name} ran onHandleRequest`);
|
|
370
|
+
if (result != null) {
|
|
371
|
+
return result;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const [param] = Array.isArray(params) ? params : [params];
|
|
375
|
+
if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
|
|
376
|
+
const { ...previousContext } = ctx.get();
|
|
377
|
+
const preserveHeaders = previousContext.preserveHeaders;
|
|
378
|
+
if (preserveHeaders) {
|
|
379
|
+
ctx.set({ preserveHeaders: false });
|
|
380
|
+
}
|
|
381
|
+
if (!_init) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const previousHeaders = new Headers(previousContext.headers);
|
|
385
|
+
await ext.onRequest(_init.request, ctx);
|
|
386
|
+
const updatedContext = ctx.get();
|
|
387
|
+
if (updatedContext?.headers) {
|
|
388
|
+
const cookie = updatedContext.headers.get("cookie");
|
|
389
|
+
if (cookie && param.headers) {
|
|
390
|
+
const updatedCookies = mergeCookies(
|
|
391
|
+
preserveHeaders ? previousHeaders?.get("cookie") : null,
|
|
392
|
+
updatedContext.headers.get("cookie")
|
|
393
|
+
);
|
|
394
|
+
param.headers.set("cookie", updatedCookies);
|
|
395
|
+
}
|
|
396
|
+
if (updatedContext.tenantId && param.headers) {
|
|
397
|
+
param.headers.set(
|
|
398
|
+
TENANT_COOKIE,
|
|
399
|
+
String(updatedContext.headers.get(TENANT_COOKIE))
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
ctx.set({ headers: param.headers });
|
|
403
|
+
}
|
|
404
|
+
debug(`${ext.id ?? create2.name} ran onRequest`);
|
|
405
|
+
}
|
|
406
|
+
if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
|
|
407
|
+
const result = await ext.onResponse(param, ctx);
|
|
408
|
+
debug(`${ext.id ?? create2.name} ran onResponse`);
|
|
409
|
+
if (result != null) {
|
|
410
|
+
return result;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return void 0;
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function buildExtensionConfig(instance) {
|
|
419
|
+
return {
|
|
420
|
+
runExtensions: bindRunExtensions(instance)
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function mergeCookies(...cookieStrings) {
|
|
424
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
425
|
+
for (const str of cookieStrings) {
|
|
426
|
+
if (!str) continue;
|
|
427
|
+
for (const part of str.split(";")) {
|
|
428
|
+
const [key17, value] = part.split("=").map((s) => s.trim());
|
|
429
|
+
if (key17 && value) cookieMap.set(key17, value);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
|
|
433
|
+
}
|
|
434
|
+
async function runExtensionContext(config) {
|
|
435
|
+
await config?.extensionCtx?.runExtensions("withContext" /* withContext */, config);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// src/api/utils/request-context.ts
|
|
439
|
+
var { warn, silly } = Logger({ debug: true })("[REQUEST CONTEXT]");
|
|
440
|
+
var storage = new async_hooks.AsyncLocalStorage();
|
|
441
|
+
var defaultContext = {
|
|
442
|
+
headers: new Headers(),
|
|
443
|
+
tenantId: void 0,
|
|
444
|
+
userId: void 0,
|
|
445
|
+
preserveHeaders: false
|
|
446
|
+
};
|
|
447
|
+
var lastUsedContext = defaultContext;
|
|
448
|
+
var ctx = {
|
|
449
|
+
run(ctx2, fn) {
|
|
450
|
+
const merged = {
|
|
451
|
+
...defaultContext,
|
|
452
|
+
...ctx2,
|
|
453
|
+
headers: ctx2.headers instanceof Headers ? ctx2.headers : new Headers(ctx2.headers)
|
|
454
|
+
};
|
|
455
|
+
lastUsedContext = merged;
|
|
456
|
+
return storage.run(merged, fn);
|
|
457
|
+
},
|
|
458
|
+
get: () => {
|
|
459
|
+
const ctx2 = storage.getStore();
|
|
460
|
+
if (!ctx2) {
|
|
461
|
+
return { ...defaultContext };
|
|
462
|
+
}
|
|
463
|
+
silly(`[GET] ${serializeContext(ctx2)}`);
|
|
464
|
+
return ctx2;
|
|
465
|
+
},
|
|
466
|
+
/**
|
|
467
|
+
* This is a mirror of Server.getContext, but only for requests. We keep only the request
|
|
468
|
+
* information around, everything else is :above_my_pay_grade:
|
|
469
|
+
* @param partial A partial context to override
|
|
470
|
+
*/
|
|
471
|
+
set: (partial) => {
|
|
472
|
+
const store = storage.getStore();
|
|
473
|
+
if (!store) {
|
|
474
|
+
warn("ctx.set() called outside of ctx.run(). This will not persist.");
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
if (partial.headers === null) {
|
|
478
|
+
store.headers = new Headers();
|
|
479
|
+
} else if (partial.headers && store.headers instanceof Headers) {
|
|
480
|
+
for (const [key17, value] of new Headers(partial.headers).entries()) {
|
|
481
|
+
if (key17.toLowerCase() === "cookie") {
|
|
482
|
+
const existingCookies = parseCookieHeader(
|
|
483
|
+
store.headers.get("cookie") || ""
|
|
484
|
+
);
|
|
485
|
+
const newCookies = parseCookieHeader(value);
|
|
486
|
+
const mergedCookies = { ...existingCookies, ...newCookies };
|
|
487
|
+
store.headers.set("cookie", serializeCookies(mergedCookies));
|
|
488
|
+
} else {
|
|
489
|
+
store.headers.set(key17, value);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if ("tenantId" in partial)
|
|
494
|
+
store.tenantId = partial.tenantId ?? store.tenantId;
|
|
495
|
+
if ("userId" in partial) store.userId = partial.userId ?? store.userId;
|
|
496
|
+
if ("preserveHeaders" in partial)
|
|
497
|
+
store.preserveHeaders = Boolean(partial.preserveHeaders);
|
|
498
|
+
silly(`[SET] ${serializeContext(store)}`);
|
|
499
|
+
lastUsedContext = { ...store };
|
|
500
|
+
},
|
|
501
|
+
// for convenience only
|
|
502
|
+
getLastUsed: () => lastUsedContext
|
|
503
|
+
};
|
|
504
|
+
function withNileContext(config, fn, name = "unknown") {
|
|
505
|
+
const initialContext = config.context;
|
|
506
|
+
const existing = ctx.get();
|
|
507
|
+
const mergedHeaders = new Headers(existing.headers);
|
|
508
|
+
if (initialContext instanceof Request) {
|
|
509
|
+
initialContext.headers.forEach((value, key17) => {
|
|
510
|
+
mergedHeaders.set(key17, value);
|
|
511
|
+
});
|
|
512
|
+
const context2 = {
|
|
513
|
+
headers: mergedHeaders,
|
|
514
|
+
tenantId: existing.tenantId,
|
|
515
|
+
userId: existing.userId,
|
|
516
|
+
preserveHeaders: existing.preserveHeaders ?? false
|
|
517
|
+
};
|
|
518
|
+
silly(`${name} [INITIAL - Request] ${serializeContext(context2)}`);
|
|
519
|
+
return ctx.run(context2, fn);
|
|
520
|
+
}
|
|
521
|
+
if (initialContext.headers) {
|
|
522
|
+
const incoming = initialContext.headers instanceof Headers ? initialContext.headers : new Headers(initialContext.headers);
|
|
523
|
+
incoming.forEach((value, key17) => {
|
|
524
|
+
mergedHeaders.set(key17, value);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
const tenantId = "tenantId" in initialContext && initialContext.tenantId;
|
|
528
|
+
const userId = "userId" in initialContext && initialContext.userId;
|
|
529
|
+
const preserveHeaders = "preserveHeaders" in initialContext && initialContext.preserveHeaders;
|
|
530
|
+
const context = {
|
|
531
|
+
headers: mergedHeaders,
|
|
532
|
+
tenantId: tenantId ? tenantId : existing.tenantId,
|
|
533
|
+
userId: userId ? userId : existing.userId,
|
|
534
|
+
preserveHeaders: preserveHeaders ? preserveHeaders : existing.preserveHeaders ?? false
|
|
535
|
+
};
|
|
536
|
+
silly(`${name} [INITIAL - Partial<Context>] ${serializeContext(context)}`);
|
|
537
|
+
return ctx.run(context, async () => {
|
|
538
|
+
await runExtensionContext(config);
|
|
539
|
+
return fn();
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
function serializeContext(context) {
|
|
543
|
+
const headers = {};
|
|
544
|
+
const rawHeaders = new Headers(context.headers);
|
|
545
|
+
rawHeaders.forEach((value, key17) => {
|
|
546
|
+
headers[key17] = value;
|
|
547
|
+
});
|
|
548
|
+
return JSON.stringify({
|
|
549
|
+
headers,
|
|
550
|
+
tenantId: context.tenantId,
|
|
551
|
+
userId: context.userId,
|
|
552
|
+
preserveHeaders: context.preserveHeaders
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
function parseCookieHeader(header) {
|
|
556
|
+
return header.split(";").map((c) => c.trim()).filter(Boolean).reduce((acc, curr) => {
|
|
557
|
+
const [key17, ...val] = curr.split("=");
|
|
558
|
+
if (key17) acc[key17] = val.join("=");
|
|
559
|
+
return acc;
|
|
560
|
+
}, {});
|
|
561
|
+
}
|
|
562
|
+
function serializeCookies(cookies) {
|
|
563
|
+
return Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join("; ");
|
|
564
|
+
}
|
|
565
|
+
|
|
268
566
|
// src/api/routes/me/index.ts
|
|
269
567
|
var key = "ME";
|
|
270
568
|
async function route(request2, config) {
|
|
271
|
-
const url = apiRoutes(config)[key];
|
|
569
|
+
const url = apiRoutes(config.apiUrl)[key];
|
|
272
570
|
if (request2.method === "GET") {
|
|
273
571
|
return await GET(url, { request: request2 }, config);
|
|
274
572
|
}
|
|
@@ -289,8 +587,9 @@ function matches(configRoutes, request2) {
|
|
|
289
587
|
}
|
|
290
588
|
async function fetchMe(config, method, body) {
|
|
291
589
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
|
|
590
|
+
const { headers } = ctx.get();
|
|
292
591
|
const init = {
|
|
293
|
-
headers
|
|
592
|
+
headers,
|
|
294
593
|
method: method ?? "GET"
|
|
295
594
|
};
|
|
296
595
|
if (method === "PUT") {
|
|
@@ -342,9 +641,9 @@ function getTokenFromCookie(headers, cookieKey) {
|
|
|
342
641
|
return _cookies[cookieKey];
|
|
343
642
|
}
|
|
344
643
|
}
|
|
345
|
-
function getTenantFromHttp(headers,
|
|
644
|
+
function getTenantFromHttp(headers, context) {
|
|
346
645
|
const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
|
|
347
|
-
return cookieTenant ? cookieTenant :
|
|
646
|
+
return cookieTenant ? cookieTenant : context?.tenantId;
|
|
348
647
|
}
|
|
349
648
|
|
|
350
649
|
// src/api/routes/users/POST.ts
|
|
@@ -354,8 +653,11 @@ async function POST(config, init) {
|
|
|
354
653
|
const yurl = new URL(init.request.url);
|
|
355
654
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
356
655
|
const newTenantName = yurl.searchParams.get("newTenantName");
|
|
357
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers
|
|
358
|
-
const url = apiRoutes(config).USERS({
|
|
656
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
657
|
+
const url = apiRoutes(config.apiUrl).USERS({
|
|
658
|
+
tenantId: tenant,
|
|
659
|
+
newTenantName
|
|
660
|
+
});
|
|
359
661
|
return await request(url, init, config);
|
|
360
662
|
}
|
|
361
663
|
|
|
@@ -363,13 +665,13 @@ async function POST(config, init) {
|
|
|
363
665
|
async function GET2(config, init, log) {
|
|
364
666
|
const yurl = new URL(init.request.url);
|
|
365
667
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
366
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
|
|
668
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config.context);
|
|
367
669
|
if (!tenant) {
|
|
368
670
|
log("[GET] No tenant id provided.");
|
|
369
671
|
return new Response(null, { status: 404 });
|
|
370
672
|
}
|
|
371
673
|
init.method = "GET";
|
|
372
|
-
const url = apiRoutes(config).TENANT_USERS(tenant);
|
|
674
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenant);
|
|
373
675
|
return await request(url, init, config);
|
|
374
676
|
}
|
|
375
677
|
|
|
@@ -378,7 +680,7 @@ async function PUT2(config, init) {
|
|
|
378
680
|
init.body = init.request.body;
|
|
379
681
|
init.method = "PUT";
|
|
380
682
|
const [userId] = new URL(init.request.url).pathname.split("/").reverse();
|
|
381
|
-
const url = apiRoutes(config).USER(userId);
|
|
683
|
+
const url = apiRoutes(config.apiUrl).USER(userId);
|
|
382
684
|
return await request(url, init, config);
|
|
383
685
|
}
|
|
384
686
|
|
|
@@ -405,7 +707,7 @@ function matches2(configRoutes, request2) {
|
|
|
405
707
|
async function GET3(config, init) {
|
|
406
708
|
const yurl = new URL(init.request.url);
|
|
407
709
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
408
|
-
const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
|
|
710
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USERS(tenantId)}`;
|
|
409
711
|
return await request(url, init, config);
|
|
410
712
|
}
|
|
411
713
|
|
|
@@ -419,7 +721,7 @@ async function POST2(config, init) {
|
|
|
419
721
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
420
722
|
init.body = JSON.stringify({ email: session.email });
|
|
421
723
|
init.method = "POST";
|
|
422
|
-
const url = apiRoutes(config).TENANT_USERS(tenantId);
|
|
724
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenantId);
|
|
423
725
|
return await request(url, init, config);
|
|
424
726
|
}
|
|
425
727
|
|
|
@@ -453,12 +755,13 @@ function matches3(configRoutes, request2) {
|
|
|
453
755
|
}
|
|
454
756
|
async function fetchTenantUsers(config, method, payload) {
|
|
455
757
|
const { body, params } = {};
|
|
456
|
-
|
|
758
|
+
const { tenantId, headers } = ctx.get();
|
|
759
|
+
if (!tenantId) {
|
|
457
760
|
throw new Error(
|
|
458
761
|
"Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
459
762
|
);
|
|
460
763
|
}
|
|
461
|
-
if (!isUUID(
|
|
764
|
+
if (!isUUID(tenantId)) {
|
|
462
765
|
config.logger("fetchTenantUsers").warn(
|
|
463
766
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
464
767
|
);
|
|
@@ -470,14 +773,11 @@ async function fetchTenantUsers(config, method, payload) {
|
|
|
470
773
|
if (params?.tenantId) {
|
|
471
774
|
q.set("tenantId", params.tenantId);
|
|
472
775
|
}
|
|
473
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
|
|
474
|
-
"{tenantId}",
|
|
475
|
-
config.tenantId
|
|
476
|
-
)}`;
|
|
776
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace("{tenantId}", tenantId)}`;
|
|
477
777
|
const m = method;
|
|
478
778
|
const init = {
|
|
479
779
|
method: m,
|
|
480
|
-
headers
|
|
780
|
+
headers
|
|
481
781
|
};
|
|
482
782
|
const req = new Request(clientUrl, init);
|
|
483
783
|
return await config.handlers[m](req);
|
|
@@ -494,7 +794,7 @@ async function PUT3(config, init) {
|
|
|
494
794
|
init.body = new URLSearchParams(yurl.searchParams).toString();
|
|
495
795
|
}
|
|
496
796
|
init.method = "PUT";
|
|
497
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
797
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
498
798
|
const res = await request(url, init, config);
|
|
499
799
|
const location = res?.headers?.get("location");
|
|
500
800
|
if (location) {
|
|
@@ -518,7 +818,7 @@ async function POST3(config, init) {
|
|
|
518
818
|
}
|
|
519
819
|
init.method = "POST";
|
|
520
820
|
init.body = init.request.body;
|
|
521
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
821
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
522
822
|
return await request(url, init, config);
|
|
523
823
|
}
|
|
524
824
|
|
|
@@ -544,21 +844,22 @@ function matches4(configRoutes, request2) {
|
|
|
544
844
|
return urlMatches(request2.url, route20);
|
|
545
845
|
}
|
|
546
846
|
async function fetchInvite(config, method, body) {
|
|
547
|
-
|
|
847
|
+
const { headers, tenantId } = ctx.get();
|
|
848
|
+
if (!tenantId) {
|
|
548
849
|
throw new Error(
|
|
549
850
|
"Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
550
851
|
);
|
|
551
852
|
}
|
|
552
|
-
if (!isUUID(
|
|
853
|
+
if (!isUUID(tenantId)) {
|
|
553
854
|
config.logger("fetchInvite").warn(
|
|
554
855
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
555
856
|
);
|
|
556
857
|
}
|
|
557
|
-
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}",
|
|
858
|
+
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", tenantId)}`;
|
|
558
859
|
const m = method ?? "GET";
|
|
559
860
|
const init = {
|
|
560
861
|
method: m,
|
|
561
|
-
headers
|
|
862
|
+
headers
|
|
562
863
|
};
|
|
563
864
|
if (method === "POST" || method === "PUT") {
|
|
564
865
|
init.body = body;
|
|
@@ -578,7 +879,7 @@ async function GET4(config, init) {
|
|
|
578
879
|
return new Response(null, { status: 404 });
|
|
579
880
|
}
|
|
580
881
|
init.method = "GET";
|
|
581
|
-
const url = `${apiRoutes(config).INVITES(tenantId)}`;
|
|
882
|
+
const url = `${apiRoutes(config.apiUrl).INVITES(tenantId)}`;
|
|
582
883
|
return await request(url, init, config);
|
|
583
884
|
}
|
|
584
885
|
|
|
@@ -599,29 +900,29 @@ function matches5(configRoutes, request2) {
|
|
|
599
900
|
return url.pathname.endsWith(route20);
|
|
600
901
|
}
|
|
601
902
|
async function fetchInvites(config) {
|
|
602
|
-
|
|
903
|
+
const { tenantId, headers } = ctx.get();
|
|
904
|
+
if (!tenantId) {
|
|
603
905
|
throw new Error(
|
|
604
906
|
"Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
605
907
|
);
|
|
606
908
|
}
|
|
607
|
-
if (!isUUID(
|
|
909
|
+
if (!isUUID(tenantId)) {
|
|
608
910
|
config.logger("fetchInvites").warn(
|
|
609
911
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
610
912
|
);
|
|
611
913
|
}
|
|
612
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}",
|
|
613
|
-
const req = new Request(clientUrl, { headers
|
|
914
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", tenantId)}`;
|
|
915
|
+
const req = new Request(clientUrl, { headers });
|
|
614
916
|
return await config.handlers.GET(req);
|
|
615
917
|
}
|
|
616
918
|
|
|
617
919
|
// src/api/routes/tenants/GET.ts
|
|
618
920
|
async function GET5(config, session, init) {
|
|
619
|
-
let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
|
|
921
|
+
let url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.id)}`;
|
|
620
922
|
if (typeof session === "object" && "user" in session && session.user) {
|
|
621
|
-
url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
|
|
923
|
+
url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.user.id)}`;
|
|
622
924
|
}
|
|
623
|
-
|
|
624
|
-
return res;
|
|
925
|
+
return await request(url, init, config);
|
|
625
926
|
}
|
|
626
927
|
|
|
627
928
|
// src/api/routes/tenants/[tenantId]/GET.ts
|
|
@@ -633,7 +934,7 @@ async function GET6(config, init, log) {
|
|
|
633
934
|
return new Response(null, { status: 404 });
|
|
634
935
|
}
|
|
635
936
|
init.method = "GET";
|
|
636
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
937
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
637
938
|
return await request(url, init, config);
|
|
638
939
|
}
|
|
639
940
|
|
|
@@ -645,7 +946,7 @@ async function DELETE2(config, init) {
|
|
|
645
946
|
return new Response(null, { status: 404 });
|
|
646
947
|
}
|
|
647
948
|
init.method = "DELETE";
|
|
648
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
949
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
649
950
|
return await request(url, init, config);
|
|
650
951
|
}
|
|
651
952
|
|
|
@@ -658,7 +959,7 @@ async function PUT4(config, init) {
|
|
|
658
959
|
}
|
|
659
960
|
init.body = init.request.body;
|
|
660
961
|
init.method = "PUT";
|
|
661
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
962
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
662
963
|
return await request(url, init, config);
|
|
663
964
|
}
|
|
664
965
|
|
|
@@ -666,7 +967,7 @@ async function PUT4(config, init) {
|
|
|
666
967
|
async function POST4(config, init) {
|
|
667
968
|
init.body = init.request.body;
|
|
668
969
|
init.method = "POST";
|
|
669
|
-
const url = `${apiRoutes(config).TENANTS}`;
|
|
970
|
+
const url = `${apiRoutes(config.apiUrl).TENANTS}`;
|
|
670
971
|
return await request(url, init, config);
|
|
671
972
|
}
|
|
672
973
|
|
|
@@ -700,10 +1001,11 @@ function matches6(configRoutes, request2) {
|
|
|
700
1001
|
return urlMatches(request2.url, configRoutes[key6]);
|
|
701
1002
|
}
|
|
702
1003
|
async function fetchTenants(config, method, body) {
|
|
1004
|
+
const { headers } = ctx.get();
|
|
703
1005
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
704
1006
|
const init = {
|
|
705
1007
|
method,
|
|
706
|
-
headers
|
|
1008
|
+
headers
|
|
707
1009
|
};
|
|
708
1010
|
{
|
|
709
1011
|
init.body = body;
|
|
@@ -712,21 +1014,22 @@ async function fetchTenants(config, method, body) {
|
|
|
712
1014
|
return await config.handlers.POST(req);
|
|
713
1015
|
}
|
|
714
1016
|
async function fetchTenant(config, method, body) {
|
|
715
|
-
|
|
1017
|
+
const { headers, tenantId } = ctx.get();
|
|
1018
|
+
if (!tenantId) {
|
|
716
1019
|
throw new Error(
|
|
717
1020
|
"Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
718
1021
|
);
|
|
719
1022
|
}
|
|
720
|
-
if (!isUUID(
|
|
1023
|
+
if (!isUUID(tenantId)) {
|
|
721
1024
|
config.logger("fetch tenant").warn(
|
|
722
1025
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
723
1026
|
);
|
|
724
1027
|
}
|
|
725
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}",
|
|
1028
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", tenantId)}`;
|
|
726
1029
|
const m = method ?? "GET";
|
|
727
1030
|
const init = {
|
|
728
1031
|
method: m,
|
|
729
|
-
headers
|
|
1032
|
+
headers
|
|
730
1033
|
};
|
|
731
1034
|
if (m === "PUT") {
|
|
732
1035
|
init.body = body;
|
|
@@ -735,32 +1038,33 @@ async function fetchTenant(config, method, body) {
|
|
|
735
1038
|
return await config.handlers[m](req);
|
|
736
1039
|
}
|
|
737
1040
|
async function fetchTenantsByUser(config) {
|
|
738
|
-
const { warn } = config.logger("fetchTenantsByUser");
|
|
739
|
-
|
|
740
|
-
|
|
1041
|
+
const { warn: warn2 } = config.logger(" fetchTenantsByUser ");
|
|
1042
|
+
const { userId, headers } = ctx.get();
|
|
1043
|
+
if (!userId) {
|
|
1044
|
+
warn2(
|
|
741
1045
|
"nile.userId is not set. The call will still work for the API, but the database context is not set properly and may lead to unexpected behavior in your application."
|
|
742
1046
|
);
|
|
743
|
-
} else if (!isUUID(
|
|
744
|
-
|
|
1047
|
+
} else if (!isUUID(userId)) {
|
|
1048
|
+
warn2(
|
|
745
1049
|
"nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
746
1050
|
);
|
|
747
1051
|
}
|
|
748
1052
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
749
|
-
const req = new Request(clientUrl, { headers
|
|
1053
|
+
const req = new Request(clientUrl, { headers });
|
|
750
1054
|
return await config.handlers.GET(req);
|
|
751
1055
|
}
|
|
752
1056
|
|
|
753
1057
|
// src/api/routes/auth/signin.ts
|
|
754
1058
|
var key7 = "SIGNIN";
|
|
755
1059
|
async function route7(req, config) {
|
|
756
|
-
let url = proxyRoutes(config)[key7];
|
|
1060
|
+
let url = proxyRoutes(config.apiUrl)[key7];
|
|
757
1061
|
const init = {
|
|
758
1062
|
method: req.method,
|
|
759
1063
|
headers: req.headers
|
|
760
1064
|
};
|
|
761
1065
|
if (req.method === "POST") {
|
|
762
1066
|
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
763
|
-
url = `${proxyRoutes(config)[key7]}/${provider}`;
|
|
1067
|
+
url = `${proxyRoutes(config.apiUrl)[key7]}/${provider}`;
|
|
764
1068
|
}
|
|
765
1069
|
const passThroughUrl = new URL(req.url);
|
|
766
1070
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
@@ -773,10 +1077,11 @@ function matches7(configRoutes, request2) {
|
|
|
773
1077
|
}
|
|
774
1078
|
async function fetchSignIn(config, provider, body) {
|
|
775
1079
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
|
|
1080
|
+
const { headers } = ctx.get();
|
|
776
1081
|
const req = new Request(clientUrl, {
|
|
777
1082
|
method: "POST",
|
|
778
|
-
|
|
779
|
-
|
|
1083
|
+
body,
|
|
1084
|
+
headers
|
|
780
1085
|
});
|
|
781
1086
|
return await config.handlers.POST(req);
|
|
782
1087
|
}
|
|
@@ -784,7 +1089,7 @@ async function fetchSignIn(config, provider, body) {
|
|
|
784
1089
|
// src/api/routes/auth/session.ts
|
|
785
1090
|
async function route8(req, config) {
|
|
786
1091
|
return request(
|
|
787
|
-
proxyRoutes(config).SESSION,
|
|
1092
|
+
proxyRoutes(config.apiUrl).SESSION,
|
|
788
1093
|
{
|
|
789
1094
|
method: req.method,
|
|
790
1095
|
request: req
|
|
@@ -797,9 +1102,10 @@ function matches8(configRoutes, request2) {
|
|
|
797
1102
|
}
|
|
798
1103
|
async function fetchSession(config) {
|
|
799
1104
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
|
|
1105
|
+
const { headers } = ctx.get();
|
|
800
1106
|
const req = new Request(clientUrl, {
|
|
801
1107
|
method: "GET",
|
|
802
|
-
headers
|
|
1108
|
+
headers
|
|
803
1109
|
});
|
|
804
1110
|
return await config.handlers.GET(req);
|
|
805
1111
|
}
|
|
@@ -807,7 +1113,7 @@ async function fetchSession(config) {
|
|
|
807
1113
|
// src/api/routes/auth/providers.ts
|
|
808
1114
|
async function route9(req, config) {
|
|
809
1115
|
return request(
|
|
810
|
-
proxyRoutes(config).PROVIDERS,
|
|
1116
|
+
proxyRoutes(config.apiUrl).PROVIDERS,
|
|
811
1117
|
{
|
|
812
1118
|
method: req.method,
|
|
813
1119
|
request: req
|
|
@@ -820,9 +1126,10 @@ function matches9(configRoutes, request2) {
|
|
|
820
1126
|
}
|
|
821
1127
|
async function fetchProviders(config) {
|
|
822
1128
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
|
|
1129
|
+
const { headers } = ctx.get();
|
|
823
1130
|
const req = new Request(clientUrl, {
|
|
824
1131
|
method: "GET",
|
|
825
|
-
headers
|
|
1132
|
+
headers
|
|
826
1133
|
});
|
|
827
1134
|
return await config.handlers.GET(req);
|
|
828
1135
|
}
|
|
@@ -830,7 +1137,7 @@ async function fetchProviders(config) {
|
|
|
830
1137
|
// src/api/routes/auth/csrf.ts
|
|
831
1138
|
async function route10(req, config) {
|
|
832
1139
|
return request(
|
|
833
|
-
proxyRoutes(config).CSRF,
|
|
1140
|
+
proxyRoutes(config.apiUrl).CSRF,
|
|
834
1141
|
{
|
|
835
1142
|
method: req.method,
|
|
836
1143
|
request: req
|
|
@@ -843,9 +1150,10 @@ function matches10(configRoutes, request2) {
|
|
|
843
1150
|
}
|
|
844
1151
|
async function fetchCsrf(config) {
|
|
845
1152
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
|
|
1153
|
+
const { headers } = ctx.get();
|
|
846
1154
|
const req = new Request(clientUrl, {
|
|
847
1155
|
method: "GET",
|
|
848
|
-
headers
|
|
1156
|
+
headers
|
|
849
1157
|
});
|
|
850
1158
|
return await config.handlers.GET(req);
|
|
851
1159
|
}
|
|
@@ -858,7 +1166,7 @@ async function route11(req, config) {
|
|
|
858
1166
|
try {
|
|
859
1167
|
const passThroughUrl = new URL(req.url);
|
|
860
1168
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
861
|
-
const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
1169
|
+
const url = `${proxyRoutes(config.apiUrl)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
862
1170
|
const res = await request(
|
|
863
1171
|
url,
|
|
864
1172
|
{
|
|
@@ -889,10 +1197,11 @@ function matches11(configRoutes, request2) {
|
|
|
889
1197
|
return urlMatches(request2.url, configRoutes.CALLBACK);
|
|
890
1198
|
}
|
|
891
1199
|
async function fetchCallback(config, provider, body, request2, method = "POST") {
|
|
1200
|
+
const { headers } = ctx.get();
|
|
892
1201
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
|
|
893
1202
|
const req = new Request(clientUrl, {
|
|
894
1203
|
method,
|
|
895
|
-
headers
|
|
1204
|
+
headers,
|
|
896
1205
|
body
|
|
897
1206
|
});
|
|
898
1207
|
return await config.handlers.POST(req);
|
|
@@ -901,14 +1210,14 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
|
|
|
901
1210
|
// src/api/routes/auth/signout.ts
|
|
902
1211
|
var key9 = "SIGNOUT";
|
|
903
1212
|
async function route12(request2, config) {
|
|
904
|
-
let url = proxyRoutes(config)[key9];
|
|
1213
|
+
let url = proxyRoutes(config.apiUrl)[key9];
|
|
905
1214
|
const init = {
|
|
906
1215
|
method: request2.method
|
|
907
1216
|
};
|
|
908
1217
|
if (request2.method === "POST") {
|
|
909
1218
|
init.body = request2.body;
|
|
910
1219
|
const [provider] = new URL(request2.url).pathname.split("/").reverse();
|
|
911
|
-
url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
1220
|
+
url = `${proxyRoutes(config.apiUrl)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
912
1221
|
}
|
|
913
1222
|
const res = await request(url, { ...init, request: request2 }, config);
|
|
914
1223
|
return res;
|
|
@@ -918,10 +1227,11 @@ function matches12(configRoutes, request2) {
|
|
|
918
1227
|
}
|
|
919
1228
|
async function fetchSignOut(config, body) {
|
|
920
1229
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
|
|
1230
|
+
const { headers } = ctx.get();
|
|
921
1231
|
const req = new Request(clientUrl, {
|
|
922
1232
|
method: "POST",
|
|
923
1233
|
body,
|
|
924
|
-
headers
|
|
1234
|
+
headers
|
|
925
1235
|
});
|
|
926
1236
|
return await config.handlers.POST(req);
|
|
927
1237
|
}
|
|
@@ -930,7 +1240,7 @@ async function fetchSignOut(config, body) {
|
|
|
930
1240
|
var key10 = "ERROR";
|
|
931
1241
|
async function route13(req, config) {
|
|
932
1242
|
return request(
|
|
933
|
-
proxyRoutes(config)[key10],
|
|
1243
|
+
proxyRoutes(config.apiUrl)[key10],
|
|
934
1244
|
{
|
|
935
1245
|
method: req.method,
|
|
936
1246
|
request: req
|
|
@@ -946,7 +1256,7 @@ function matches13(configRoutes, request2) {
|
|
|
946
1256
|
var key11 = "VERIFY_REQUEST";
|
|
947
1257
|
async function route14(req, config) {
|
|
948
1258
|
return request(
|
|
949
|
-
proxyRoutes(config)[key11],
|
|
1259
|
+
proxyRoutes(config.apiUrl)[key11],
|
|
950
1260
|
{
|
|
951
1261
|
method: req.method,
|
|
952
1262
|
request: req
|
|
@@ -961,7 +1271,7 @@ function matches14(configRoutes, request2) {
|
|
|
961
1271
|
// src/api/routes/auth/password-reset.ts
|
|
962
1272
|
var key12 = "PASSWORD_RESET";
|
|
963
1273
|
async function route15(req, config) {
|
|
964
|
-
const url = proxyRoutes(config)[key12];
|
|
1274
|
+
const url = proxyRoutes(config.apiUrl)[key12];
|
|
965
1275
|
const res = await request(
|
|
966
1276
|
url,
|
|
967
1277
|
{
|
|
@@ -990,10 +1300,11 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
990
1300
|
if (useJson) {
|
|
991
1301
|
authParams?.set("json", "true");
|
|
992
1302
|
}
|
|
1303
|
+
const { headers } = ctx.get();
|
|
993
1304
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
|
|
994
1305
|
const init = {
|
|
995
1306
|
method,
|
|
996
|
-
headers
|
|
1307
|
+
headers
|
|
997
1308
|
};
|
|
998
1309
|
if (body && method !== "GET") {
|
|
999
1310
|
init.body = body;
|
|
@@ -1005,7 +1316,7 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
1005
1316
|
// src/api/routes/auth/verify-email.ts
|
|
1006
1317
|
var key13 = "VERIFY_EMAIL";
|
|
1007
1318
|
async function route16(req, config) {
|
|
1008
|
-
const url = proxyRoutes(config)[key13];
|
|
1319
|
+
const url = proxyRoutes(config.apiUrl)[key13];
|
|
1009
1320
|
const res = await request(
|
|
1010
1321
|
url,
|
|
1011
1322
|
{
|
|
@@ -1031,9 +1342,10 @@ function matches16(configRoutes, request2) {
|
|
|
1031
1342
|
}
|
|
1032
1343
|
async function fetchVerifyEmail(config, method, body) {
|
|
1033
1344
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
|
|
1345
|
+
const { headers } = ctx.get();
|
|
1034
1346
|
const init = {
|
|
1035
1347
|
method,
|
|
1036
|
-
headers
|
|
1348
|
+
headers
|
|
1037
1349
|
};
|
|
1038
1350
|
if (body) {
|
|
1039
1351
|
init.body = body;
|
|
@@ -1044,7 +1356,7 @@ async function fetchVerifyEmail(config, method, body) {
|
|
|
1044
1356
|
|
|
1045
1357
|
// src/api/handlers/GET.ts
|
|
1046
1358
|
function GETTER(configRoutes, config) {
|
|
1047
|
-
const { error, info, warn } = config.logger("[GET MATCHER]");
|
|
1359
|
+
const { error, info, warn: warn2 } = config.logger("[GET MATCHER]");
|
|
1048
1360
|
return async function GET7(...params) {
|
|
1049
1361
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1050
1362
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1123,78 +1435,16 @@ function GETTER(configRoutes, config) {
|
|
|
1123
1435
|
info("matches error");
|
|
1124
1436
|
return route13(req, config);
|
|
1125
1437
|
}
|
|
1126
|
-
|
|
1438
|
+
warn2(`No GET routes matched ${req.url}`);
|
|
1127
1439
|
return new Response(null, { status: 404 });
|
|
1128
1440
|
};
|
|
1129
1441
|
}
|
|
1130
1442
|
|
|
1131
|
-
// src/utils/Logger.ts
|
|
1132
|
-
var red = "\x1B[31m";
|
|
1133
|
-
var yellow = "\x1B[38;2;255;255;0m";
|
|
1134
|
-
var purple = "\x1B[38;2;200;160;255m";
|
|
1135
|
-
var orange = "\x1B[38;2;255;165;0m";
|
|
1136
|
-
var reset = "\x1B[0m";
|
|
1137
|
-
var baseLogger = (config, ...params) => ({
|
|
1138
|
-
info(message, meta) {
|
|
1139
|
-
if (config?.debug) {
|
|
1140
|
-
console.info(
|
|
1141
|
-
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
1142
|
-
""
|
|
1143
|
-
)}${reset} ${message}`,
|
|
1144
|
-
meta ? `${JSON.stringify(meta)}` : ""
|
|
1145
|
-
);
|
|
1146
|
-
}
|
|
1147
|
-
},
|
|
1148
|
-
debug(message, meta) {
|
|
1149
|
-
if (config?.debug) {
|
|
1150
|
-
console.info(
|
|
1151
|
-
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
1152
|
-
""
|
|
1153
|
-
)}${reset} ${message}`,
|
|
1154
|
-
meta ? `${JSON.stringify(meta)}` : ""
|
|
1155
|
-
);
|
|
1156
|
-
}
|
|
1157
|
-
},
|
|
1158
|
-
warn(message, meta) {
|
|
1159
|
-
if (config?.debug) {
|
|
1160
|
-
console.warn(
|
|
1161
|
-
`${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
|
|
1162
|
-
""
|
|
1163
|
-
)}${reset} ${message}`,
|
|
1164
|
-
meta ? JSON.stringify(meta) : ""
|
|
1165
|
-
);
|
|
1166
|
-
}
|
|
1167
|
-
},
|
|
1168
|
-
error(message, meta) {
|
|
1169
|
-
console.error(
|
|
1170
|
-
`${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
|
|
1171
|
-
""
|
|
1172
|
-
)}${red} ${message}`,
|
|
1173
|
-
meta ? meta : "",
|
|
1174
|
-
`${reset}`
|
|
1175
|
-
);
|
|
1176
|
-
}
|
|
1177
|
-
});
|
|
1178
|
-
function Logger(config) {
|
|
1179
|
-
return (prefixes) => {
|
|
1180
|
-
const { info, debug, warn, error } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
|
|
1181
|
-
return {
|
|
1182
|
-
info,
|
|
1183
|
-
debug,
|
|
1184
|
-
warn,
|
|
1185
|
-
error
|
|
1186
|
-
};
|
|
1187
|
-
};
|
|
1188
|
-
}
|
|
1189
|
-
function matchesLog(configRoutes, request2) {
|
|
1190
|
-
return urlMatches(request2.url, configRoutes.LOG);
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
1443
|
// src/api/routes/signup/POST.ts
|
|
1194
1444
|
async function POST5(config, init) {
|
|
1195
1445
|
init.body = init.request.body;
|
|
1196
1446
|
init.method = "POST";
|
|
1197
|
-
const url = `${apiRoutes(config).SIGNUP}`;
|
|
1447
|
+
const url = `${apiRoutes(config.apiUrl).SIGNUP}`;
|
|
1198
1448
|
return await request(url, init, config);
|
|
1199
1449
|
}
|
|
1200
1450
|
|
|
@@ -1221,9 +1471,10 @@ async function fetchSignUp(config, payload) {
|
|
|
1221
1471
|
q.set("tenantId", params.tenantId);
|
|
1222
1472
|
}
|
|
1223
1473
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
|
|
1474
|
+
const { headers } = ctx.get();
|
|
1224
1475
|
const req = new Request(clientUrl, {
|
|
1225
1476
|
method: "POST",
|
|
1226
|
-
headers
|
|
1477
|
+
headers,
|
|
1227
1478
|
body
|
|
1228
1479
|
});
|
|
1229
1480
|
return await config.handlers.POST(req);
|
|
@@ -1231,7 +1482,7 @@ async function fetchSignUp(config, payload) {
|
|
|
1231
1482
|
|
|
1232
1483
|
// src/api/handlers/POST.ts
|
|
1233
1484
|
function POSTER(configRoutes, config) {
|
|
1234
|
-
const { info, warn, error } = config.logger("[POST MATCHER]");
|
|
1485
|
+
const { info, warn: warn2, error } = config.logger("[POST MATCHER]");
|
|
1235
1486
|
return async function POST6(...params) {
|
|
1236
1487
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1237
1488
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1267,10 +1518,6 @@ function POSTER(configRoutes, config) {
|
|
|
1267
1518
|
info("matches signup");
|
|
1268
1519
|
return route17(req, config);
|
|
1269
1520
|
}
|
|
1270
|
-
if (matches2(configRoutes, req)) {
|
|
1271
|
-
info("matches users");
|
|
1272
|
-
return route2(req, config);
|
|
1273
|
-
}
|
|
1274
1521
|
if (matches6(configRoutes, req)) {
|
|
1275
1522
|
info("matches tenants");
|
|
1276
1523
|
return route6(req, config);
|
|
@@ -1307,7 +1554,7 @@ function POSTER(configRoutes, config) {
|
|
|
1307
1554
|
info("matches verify-email");
|
|
1308
1555
|
return route16(req, config);
|
|
1309
1556
|
}
|
|
1310
|
-
|
|
1557
|
+
warn2(`No POST routes matched ${req.url}`);
|
|
1311
1558
|
return new Response(null, { status: 404 });
|
|
1312
1559
|
};
|
|
1313
1560
|
}
|
|
@@ -1316,10 +1563,8 @@ function POSTER(configRoutes, config) {
|
|
|
1316
1563
|
async function DELETE3(config, init) {
|
|
1317
1564
|
const yurl = new URL(init.request.url);
|
|
1318
1565
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1319
|
-
config.tenantId = tenantId;
|
|
1320
|
-
config.userId = userId;
|
|
1321
1566
|
init.method = "DELETE";
|
|
1322
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1567
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1323
1568
|
return await request(url, init, config);
|
|
1324
1569
|
}
|
|
1325
1570
|
|
|
@@ -1327,10 +1572,8 @@ async function DELETE3(config, init) {
|
|
|
1327
1572
|
async function PUT5(config, init) {
|
|
1328
1573
|
const yurl = new URL(init.request.url);
|
|
1329
1574
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1330
|
-
config.tenantId = tenantId;
|
|
1331
|
-
config.userId = userId;
|
|
1332
1575
|
init.method = "PUT";
|
|
1333
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1576
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1334
1577
|
return await request(url, init, config);
|
|
1335
1578
|
}
|
|
1336
1579
|
|
|
@@ -1368,22 +1611,24 @@ function matches18(configRoutes, request2) {
|
|
|
1368
1611
|
return urlMatches(request2.url, route20);
|
|
1369
1612
|
}
|
|
1370
1613
|
async function fetchTenantUser(config, method) {
|
|
1371
|
-
|
|
1614
|
+
const { headers, tenantId, userId } = ctx.get();
|
|
1615
|
+
const action = method === "PUT" ? "add" : "delete";
|
|
1616
|
+
if (!tenantId) {
|
|
1372
1617
|
throw new Error(
|
|
1373
|
-
|
|
1618
|
+
`Unable to ${action} user to the tenant, the tenantId context is missing. Use nile.withContext({ tenantId })`
|
|
1374
1619
|
);
|
|
1375
1620
|
}
|
|
1376
|
-
if (!
|
|
1621
|
+
if (!userId) {
|
|
1377
1622
|
throw new Error(
|
|
1378
|
-
|
|
1623
|
+
`Unable to ${action} user to tenant. The userId context is missing. Use nile.withContext({ userId })`
|
|
1379
1624
|
);
|
|
1380
1625
|
}
|
|
1381
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
|
|
1382
|
-
"{
|
|
1383
|
-
|
|
1384
|
-
)
|
|
1626
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace("{tenantId}", tenantId).replace(
|
|
1627
|
+
"{userId}",
|
|
1628
|
+
userId
|
|
1629
|
+
)}/link`;
|
|
1385
1630
|
const req = new Request(clientUrl, {
|
|
1386
|
-
headers
|
|
1631
|
+
headers,
|
|
1387
1632
|
method
|
|
1388
1633
|
});
|
|
1389
1634
|
return await config.handlers[method](req);
|
|
@@ -1397,7 +1642,7 @@ async function DELETE4(config, init) {
|
|
|
1397
1642
|
return new Response(null, { status: 404 });
|
|
1398
1643
|
}
|
|
1399
1644
|
init.method = "DELETE";
|
|
1400
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
|
|
1645
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}/${inviteId}`;
|
|
1401
1646
|
return await request(url, init, config);
|
|
1402
1647
|
}
|
|
1403
1648
|
|
|
@@ -1420,7 +1665,7 @@ function matches19(configRoutes, request2) {
|
|
|
1420
1665
|
|
|
1421
1666
|
// src/api/handlers/DELETE.ts
|
|
1422
1667
|
function DELETER(configRoutes, config) {
|
|
1423
|
-
const { error, info, warn } = config.logger("[DELETE MATCHER]");
|
|
1668
|
+
const { error, info, warn: warn2 } = config.logger("[DELETE MATCHER]");
|
|
1424
1669
|
return async function DELETE5(...params) {
|
|
1425
1670
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1426
1671
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1451,14 +1696,14 @@ function DELETER(configRoutes, config) {
|
|
|
1451
1696
|
info("matches me");
|
|
1452
1697
|
return route(req, config);
|
|
1453
1698
|
}
|
|
1454
|
-
|
|
1699
|
+
warn2("No DELETE routes matched");
|
|
1455
1700
|
return new Response(null, { status: 404 });
|
|
1456
1701
|
};
|
|
1457
1702
|
}
|
|
1458
1703
|
|
|
1459
1704
|
// src/api/handlers/PUT.ts
|
|
1460
1705
|
function PUTER(configRoutes, config) {
|
|
1461
|
-
const { error, info, warn } = config.logger("[PUT MATCHER]");
|
|
1706
|
+
const { error, info, warn: warn2 } = config.logger("[PUT MATCHER]");
|
|
1462
1707
|
return async function PUT6(...params) {
|
|
1463
1708
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1464
1709
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1485,10 +1730,6 @@ function PUTER(configRoutes, config) {
|
|
|
1485
1730
|
info("matches tenant users");
|
|
1486
1731
|
return route3(req, config);
|
|
1487
1732
|
}
|
|
1488
|
-
if (matches2(configRoutes, req)) {
|
|
1489
|
-
info("matches users");
|
|
1490
|
-
return route2(req, config);
|
|
1491
|
-
}
|
|
1492
1733
|
if (matches(configRoutes, req)) {
|
|
1493
1734
|
info("matches me");
|
|
1494
1735
|
return route(req, config);
|
|
@@ -1501,7 +1742,7 @@ function PUTER(configRoutes, config) {
|
|
|
1501
1742
|
info("matches reset password");
|
|
1502
1743
|
return route15(req, config);
|
|
1503
1744
|
}
|
|
1504
|
-
|
|
1745
|
+
warn2("No PUT routes matched");
|
|
1505
1746
|
return new Response(null, { status: 404 });
|
|
1506
1747
|
};
|
|
1507
1748
|
}
|
|
@@ -1705,18 +1946,7 @@ var Config = class {
|
|
|
1705
1946
|
extensionCtx;
|
|
1706
1947
|
extensions;
|
|
1707
1948
|
logger;
|
|
1708
|
-
|
|
1709
|
-
* Stores the set tenant id from Server for use in sub classes
|
|
1710
|
-
*/
|
|
1711
|
-
tenantId;
|
|
1712
|
-
/**
|
|
1713
|
-
* Stores the set user id from Server for use in sub classes
|
|
1714
|
-
*/
|
|
1715
|
-
userId;
|
|
1716
|
-
/**
|
|
1717
|
-
* Stores the headers to be used in `fetch` calls
|
|
1718
|
-
*/
|
|
1719
|
-
headers;
|
|
1949
|
+
context;
|
|
1720
1950
|
/**
|
|
1721
1951
|
* The nile-auth url
|
|
1722
1952
|
*/
|
|
@@ -1767,11 +1997,12 @@ var Config = class {
|
|
|
1767
1997
|
if (databaseName) {
|
|
1768
1998
|
this.db.database = databaseName;
|
|
1769
1999
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
2000
|
+
this.context = {
|
|
2001
|
+
tenantId: config?.tenantId,
|
|
2002
|
+
userId: config?.userId,
|
|
2003
|
+
headers: config?.headers ? new Headers(config.headers) : new Headers(),
|
|
2004
|
+
preserveHeaders: false
|
|
2005
|
+
};
|
|
1775
2006
|
this.routes = {
|
|
1776
2007
|
...appRoutes(config?.routePrefix),
|
|
1777
2008
|
...config?.routes
|
|
@@ -1814,8 +2045,6 @@ var Config = class {
|
|
|
1814
2045
|
],
|
|
1815
2046
|
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
1816
2047
|
};
|
|
1817
|
-
this.tenantId = config?.tenantId;
|
|
1818
|
-
this.userId = config?.userId;
|
|
1819
2048
|
}
|
|
1820
2049
|
};
|
|
1821
2050
|
|
|
@@ -1882,7 +2111,15 @@ function createProxyForPool(pool, config) {
|
|
|
1882
2111
|
}
|
|
1883
2112
|
const caller = target[property];
|
|
1884
2113
|
return function query(...args) {
|
|
1885
|
-
|
|
2114
|
+
let log = "[QUERY]";
|
|
2115
|
+
const { userId, tenantId } = config.context;
|
|
2116
|
+
if (tenantId) {
|
|
2117
|
+
log = `${log}[TENANT:${tenantId}]`;
|
|
2118
|
+
}
|
|
2119
|
+
if (userId) {
|
|
2120
|
+
log = `${log}[USER:${userId}]`;
|
|
2121
|
+
}
|
|
2122
|
+
info(log, ...args);
|
|
1886
2123
|
const called = caller.apply(this, args);
|
|
1887
2124
|
return called;
|
|
1888
2125
|
};
|
|
@@ -1901,7 +2138,7 @@ var NileDatabase = class {
|
|
|
1901
2138
|
config;
|
|
1902
2139
|
timer;
|
|
1903
2140
|
constructor(config, id) {
|
|
1904
|
-
const { warn, info, debug } = config.logger("[NileInstance]");
|
|
2141
|
+
const { warn: warn2, info, debug } = config.logger("[NileInstance]");
|
|
1905
2142
|
this.id = id;
|
|
1906
2143
|
const poolConfig = {
|
|
1907
2144
|
min: 0,
|
|
@@ -1917,7 +2154,7 @@ var NileDatabase = class {
|
|
|
1917
2154
|
debug(`Connection pool config ${JSON.stringify(cloned)}`);
|
|
1918
2155
|
this.pool = createProxyForPool(new pg__default.default.Pool(remaining), this.config);
|
|
1919
2156
|
if (typeof afterCreate === "function") {
|
|
1920
|
-
|
|
2157
|
+
warn2(
|
|
1921
2158
|
"Providing an pool configuration will stop automatic tenant context setting."
|
|
1922
2159
|
);
|
|
1923
2160
|
}
|
|
@@ -1983,7 +2220,7 @@ var NileDatabase = class {
|
|
|
1983
2220
|
};
|
|
1984
2221
|
var NileInstance_default = NileDatabase;
|
|
1985
2222
|
function makeAfterCreate(config, id) {
|
|
1986
|
-
const { error, warn, debug } = config.logger("[afterCreate]");
|
|
2223
|
+
const { error, warn: warn2, debug } = config.logger("[afterCreate]");
|
|
1987
2224
|
return (conn, done) => {
|
|
1988
2225
|
conn.on("error", function errorHandler(e) {
|
|
1989
2226
|
error(`Connection ${id} was terminated by server`, {
|
|
@@ -1992,13 +2229,15 @@ function makeAfterCreate(config, id) {
|
|
|
1992
2229
|
});
|
|
1993
2230
|
done(e, conn);
|
|
1994
2231
|
});
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2232
|
+
const tenantId = config.context.tenantId;
|
|
2233
|
+
const userId = config.context.userId;
|
|
2234
|
+
if (tenantId) {
|
|
2235
|
+
const query = [`SET nile.tenant_id = '${tenantId}'`];
|
|
2236
|
+
if (userId) {
|
|
2237
|
+
if (!tenantId) {
|
|
2238
|
+
warn2("A user id cannot be set in context without a tenant id");
|
|
2000
2239
|
}
|
|
2001
|
-
query.push(`SET nile.user_id = '${
|
|
2240
|
+
query.push(`SET nile.user_id = '${userId}'`);
|
|
2002
2241
|
}
|
|
2003
2242
|
conn.query(query.join(";"), function(err) {
|
|
2004
2243
|
if (err) {
|
|
@@ -2011,11 +2250,11 @@ function makeAfterCreate(config, id) {
|
|
|
2011
2250
|
});
|
|
2012
2251
|
} else {
|
|
2013
2252
|
if (query.length === 1) {
|
|
2014
|
-
debug(`connection context set: tenantId=${
|
|
2253
|
+
debug(`connection context set: tenantId=${tenantId}`);
|
|
2015
2254
|
}
|
|
2016
2255
|
if (query.length === 2) {
|
|
2017
2256
|
debug(
|
|
2018
|
-
`connection context set: tenantId=${
|
|
2257
|
+
`connection context set: tenantId=${tenantId} userId=${userId}`
|
|
2019
2258
|
);
|
|
2020
2259
|
}
|
|
2021
2260
|
}
|
|
@@ -2047,19 +2286,19 @@ var DBManager = class {
|
|
|
2047
2286
|
watchEvictPool(this.poolWatcherFn);
|
|
2048
2287
|
}
|
|
2049
2288
|
poolWatcher = (config) => (id) => {
|
|
2050
|
-
const { info, warn } = Logger(config)("[DBManager]");
|
|
2289
|
+
const { info, warn: warn2 } = Logger(config)("[DBManager]");
|
|
2051
2290
|
if (id && this.connections.has(id)) {
|
|
2052
2291
|
info(`Removing ${id} from db connection pool.`);
|
|
2053
2292
|
const connection = this.connections.get(id);
|
|
2054
2293
|
connection?.shutdown();
|
|
2055
2294
|
this.connections.delete(id);
|
|
2056
2295
|
} else {
|
|
2057
|
-
|
|
2296
|
+
warn2(`missed eviction of ${id}`);
|
|
2058
2297
|
}
|
|
2059
2298
|
};
|
|
2060
2299
|
getConnection = (config) => {
|
|
2061
2300
|
const { info } = Logger(config)("[DBManager]");
|
|
2062
|
-
const id = this.makeId(config.tenantId, config.userId);
|
|
2301
|
+
const id = this.makeId(config.context.tenantId, config.context.userId);
|
|
2063
2302
|
const existing = this.connections.get(id);
|
|
2064
2303
|
info(`# of instances: ${this.connections.size}`);
|
|
2065
2304
|
if (existing) {
|
|
@@ -2067,7 +2306,7 @@ var DBManager = class {
|
|
|
2067
2306
|
existing.startTimeout();
|
|
2068
2307
|
return existing.pool;
|
|
2069
2308
|
}
|
|
2070
|
-
const newOne = new NileInstance_default(
|
|
2309
|
+
const newOne = new NileInstance_default(config, id);
|
|
2071
2310
|
this.connections.set(id, newOne);
|
|
2072
2311
|
info(`created new ${id}`);
|
|
2073
2312
|
info(`# of instances: ${this.connections.size}`);
|
|
@@ -2102,33 +2341,39 @@ var Auth = class {
|
|
|
2102
2341
|
this.#logger = config.logger("[auth]");
|
|
2103
2342
|
}
|
|
2104
2343
|
async getSession(rawResponse = false) {
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
try {
|
|
2110
|
-
const session = await res.clone().json();
|
|
2111
|
-
if (Object.keys(session).length === 0) {
|
|
2112
|
-
return void 0;
|
|
2344
|
+
return withNileContext(this.#config, async () => {
|
|
2345
|
+
const res = await fetchSession(this.#config);
|
|
2346
|
+
if (rawResponse) {
|
|
2347
|
+
return res;
|
|
2113
2348
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2349
|
+
try {
|
|
2350
|
+
const session = await res.clone().json();
|
|
2351
|
+
if (Object.keys(session).length === 0) {
|
|
2352
|
+
return void 0;
|
|
2353
|
+
}
|
|
2354
|
+
return session;
|
|
2355
|
+
} catch {
|
|
2356
|
+
return res;
|
|
2357
|
+
}
|
|
2358
|
+
});
|
|
2118
2359
|
}
|
|
2119
2360
|
async getCsrf(rawResponse = false) {
|
|
2120
|
-
return
|
|
2361
|
+
return withNileContext(this.#config, async () => {
|
|
2362
|
+
return await obtainCsrf(this.#config, rawResponse);
|
|
2363
|
+
});
|
|
2121
2364
|
}
|
|
2122
2365
|
async listProviders(rawResponse = false) {
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2366
|
+
return withNileContext(this.#config, async () => {
|
|
2367
|
+
const res = await fetchProviders(this.#config);
|
|
2368
|
+
if (rawResponse) {
|
|
2369
|
+
return res;
|
|
2370
|
+
}
|
|
2371
|
+
try {
|
|
2372
|
+
return await res.clone().json();
|
|
2373
|
+
} catch {
|
|
2374
|
+
return res;
|
|
2375
|
+
}
|
|
2376
|
+
});
|
|
2132
2377
|
}
|
|
2133
2378
|
/**
|
|
2134
2379
|
* Sign the current user out by calling `/api/auth/signout`.
|
|
@@ -2137,73 +2382,79 @@ var Auth = class {
|
|
|
2137
2382
|
* from the internal configuration once the request completes.
|
|
2138
2383
|
*/
|
|
2139
2384
|
async signOut() {
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2385
|
+
return withNileContext(this.#config, async () => {
|
|
2386
|
+
const csrfRes = await this.getCsrf();
|
|
2387
|
+
if (!("csrfToken" in csrfRes)) {
|
|
2388
|
+
throw new Error("Unable to obtain CSRF token. Sign out failed.");
|
|
2389
|
+
}
|
|
2390
|
+
const body = JSON.stringify({
|
|
2391
|
+
csrfToken: csrfRes.csrfToken,
|
|
2392
|
+
json: true
|
|
2393
|
+
});
|
|
2394
|
+
const res = await fetchSignOut(this.#config, body);
|
|
2395
|
+
updateHeaders(new Headers({}));
|
|
2396
|
+
ctx.set({ headers: null });
|
|
2397
|
+
return res;
|
|
2147
2398
|
});
|
|
2148
|
-
const res = await fetchSignOut(this.#config, body);
|
|
2149
|
-
updateHeaders(new Headers({}));
|
|
2150
|
-
this.#config.headers = new Headers();
|
|
2151
|
-
return res;
|
|
2152
2399
|
}
|
|
2153
2400
|
async signUp(payload, rawResponse) {
|
|
2154
|
-
this.#config
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
csrfToken
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2401
|
+
return withNileContext(this.#config, async () => {
|
|
2402
|
+
ctx.set({ headers: null });
|
|
2403
|
+
const { email, password, ...params } = payload;
|
|
2404
|
+
if (!email || !password) {
|
|
2405
|
+
throw new Error(
|
|
2406
|
+
"Server side sign up requires a user email and password."
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2409
|
+
const providers = await this.listProviders();
|
|
2410
|
+
const { credentials } = providers ?? {};
|
|
2411
|
+
if (!credentials) {
|
|
2412
|
+
throw new Error(
|
|
2413
|
+
"Unable to obtain credential provider. Aborting server side sign up."
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2417
|
+
let csrfToken;
|
|
2418
|
+
if ("csrfToken" in csrf) {
|
|
2419
|
+
csrfToken = csrf.csrfToken;
|
|
2420
|
+
} else {
|
|
2421
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2422
|
+
}
|
|
2423
|
+
const body = JSON.stringify({
|
|
2424
|
+
email,
|
|
2425
|
+
password,
|
|
2426
|
+
csrfToken,
|
|
2427
|
+
callbackUrl: credentials.callbackUrl
|
|
2428
|
+
});
|
|
2429
|
+
const res = await fetchSignUp(this.#config, { body, params });
|
|
2430
|
+
if (res.status > 299) {
|
|
2431
|
+
this.#logger.error(await res.clone().text());
|
|
2432
|
+
return void 0;
|
|
2433
|
+
}
|
|
2434
|
+
const token = parseToken(res.headers);
|
|
2435
|
+
if (!token) {
|
|
2436
|
+
throw new Error("Server side sign up failed. Session token not found");
|
|
2437
|
+
}
|
|
2438
|
+
const { headers } = ctx.get();
|
|
2439
|
+
headers?.append("cookie", token);
|
|
2440
|
+
ctx.set({ headers });
|
|
2441
|
+
updateHeaders(headers);
|
|
2442
|
+
if (rawResponse) {
|
|
2443
|
+
return res;
|
|
2444
|
+
}
|
|
2445
|
+
try {
|
|
2446
|
+
const json = await res.clone().json();
|
|
2447
|
+
if (json && typeof json === "object" && "tenants" in json) {
|
|
2448
|
+
const tenantId = json.tenants[0];
|
|
2449
|
+
if (tenantId) {
|
|
2450
|
+
updateTenantId(tenantId);
|
|
2451
|
+
}
|
|
2201
2452
|
}
|
|
2453
|
+
return json;
|
|
2454
|
+
} catch {
|
|
2455
|
+
return res;
|
|
2202
2456
|
}
|
|
2203
|
-
|
|
2204
|
-
} catch {
|
|
2205
|
-
return res;
|
|
2206
|
-
}
|
|
2457
|
+
});
|
|
2207
2458
|
}
|
|
2208
2459
|
/**
|
|
2209
2460
|
* Request a password reset email.
|
|
@@ -2213,34 +2464,34 @@ var Auth = class {
|
|
|
2213
2464
|
* which is returned as a {@link Response} object.
|
|
2214
2465
|
*/
|
|
2215
2466
|
async forgotPassword(req) {
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2467
|
+
return withNileContext(this.#config, async () => {
|
|
2468
|
+
let email = "";
|
|
2469
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2470
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2471
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2472
|
+
if ("email" in req) {
|
|
2473
|
+
email = req.email;
|
|
2474
|
+
}
|
|
2475
|
+
if ("callbackUrl" in req) {
|
|
2476
|
+
callbackUrl = fQUrl(req.callbackUrl ?? "", this.#config);
|
|
2477
|
+
}
|
|
2478
|
+
if ("redirectUrl" in req) {
|
|
2479
|
+
redirectUrl = fQUrl(req.redirectUrl ?? "", this.#config);
|
|
2480
|
+
}
|
|
2481
|
+
const body = JSON.stringify({
|
|
2482
|
+
email,
|
|
2483
|
+
redirectUrl,
|
|
2484
|
+
callbackUrl
|
|
2485
|
+
});
|
|
2486
|
+
const data = await fetchResetPassword(
|
|
2487
|
+
this.#config,
|
|
2488
|
+
"POST",
|
|
2489
|
+
body,
|
|
2490
|
+
new URLSearchParams(),
|
|
2491
|
+
false
|
|
2492
|
+
);
|
|
2493
|
+
return data;
|
|
2235
2494
|
});
|
|
2236
|
-
const data = await fetchResetPassword(
|
|
2237
|
-
this.#config,
|
|
2238
|
-
"POST",
|
|
2239
|
-
body,
|
|
2240
|
-
new URLSearchParams(),
|
|
2241
|
-
false
|
|
2242
|
-
);
|
|
2243
|
-
return data;
|
|
2244
2495
|
}
|
|
2245
2496
|
/**
|
|
2246
2497
|
* Complete a password reset.
|
|
@@ -2253,93 +2504,98 @@ var Auth = class {
|
|
|
2253
2504
|
* containing the necessary fields.
|
|
2254
2505
|
*/
|
|
2255
2506
|
async resetPassword(req) {
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2507
|
+
return withNileContext(this.#config, async () => {
|
|
2508
|
+
let email = "";
|
|
2509
|
+
let password = "";
|
|
2510
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2511
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2512
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2513
|
+
if (req instanceof Request) {
|
|
2514
|
+
const body2 = await req.json();
|
|
2515
|
+
email = body2.email;
|
|
2516
|
+
password = body2.password;
|
|
2517
|
+
const cbFromHeaders = parseCallback(req.headers);
|
|
2518
|
+
if (cbFromHeaders) {
|
|
2519
|
+
callbackUrl = cbFromHeaders;
|
|
2520
|
+
}
|
|
2521
|
+
if (body2.callbackUrl) {
|
|
2522
|
+
callbackUrl = body2.callbackUrl;
|
|
2523
|
+
}
|
|
2524
|
+
if (body2.redirectUrl) {
|
|
2525
|
+
redirectUrl = body2.redirectUrl;
|
|
2526
|
+
}
|
|
2527
|
+
} else {
|
|
2528
|
+
if ("email" in req) {
|
|
2529
|
+
email = req.email;
|
|
2530
|
+
}
|
|
2531
|
+
if ("password" in req) {
|
|
2532
|
+
password = req.password;
|
|
2533
|
+
}
|
|
2534
|
+
if ("callbackUrl" in req) {
|
|
2535
|
+
callbackUrl = req.callbackUrl ? req.callbackUrl : null;
|
|
2536
|
+
}
|
|
2537
|
+
if ("redirectUrl" in req) {
|
|
2538
|
+
redirectUrl = req.redirectUrl ? req.redirectUrl : null;
|
|
2539
|
+
}
|
|
2274
2540
|
}
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
email
|
|
2541
|
+
await this.getCsrf();
|
|
2542
|
+
const body = JSON.stringify({
|
|
2543
|
+
email,
|
|
2544
|
+
password,
|
|
2545
|
+
redirectUrl,
|
|
2546
|
+
callbackUrl
|
|
2547
|
+
});
|
|
2548
|
+
let urlWithParams;
|
|
2549
|
+
try {
|
|
2550
|
+
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
2551
|
+
const cloned = data.clone();
|
|
2552
|
+
if (data.status === 400) {
|
|
2553
|
+
const text = await cloned.text();
|
|
2554
|
+
this.#logger.error(text);
|
|
2555
|
+
return data;
|
|
2556
|
+
}
|
|
2557
|
+
const { url } = await data.json();
|
|
2558
|
+
urlWithParams = url;
|
|
2559
|
+
} catch {
|
|
2278
2560
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2561
|
+
let token;
|
|
2562
|
+
try {
|
|
2563
|
+
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2564
|
+
const answer = await fetchResetPassword(
|
|
2565
|
+
this.#config,
|
|
2566
|
+
"GET",
|
|
2567
|
+
null,
|
|
2568
|
+
worthyParams
|
|
2569
|
+
);
|
|
2570
|
+
token = parseResetToken(answer.headers);
|
|
2571
|
+
} catch {
|
|
2572
|
+
this.#logger.warn(
|
|
2573
|
+
"Unable to parse reset password url. Password not reset."
|
|
2574
|
+
);
|
|
2281
2575
|
}
|
|
2282
|
-
|
|
2283
|
-
|
|
2576
|
+
const { headers } = ctx.get();
|
|
2577
|
+
const cookie = headers?.get("cookie")?.split("; ");
|
|
2578
|
+
if (token) {
|
|
2579
|
+
cookie?.push(token);
|
|
2580
|
+
} else {
|
|
2581
|
+
throw new Error(
|
|
2582
|
+
"Unable to reset password, reset token is missing from response"
|
|
2583
|
+
);
|
|
2284
2584
|
}
|
|
2285
|
-
if (
|
|
2286
|
-
|
|
2585
|
+
if (cookie) {
|
|
2586
|
+
headers?.set("cookie", cookie?.join("; "));
|
|
2587
|
+
ctx.set({
|
|
2588
|
+
headers
|
|
2589
|
+
});
|
|
2287
2590
|
}
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
});
|
|
2296
|
-
let urlWithParams;
|
|
2297
|
-
try {
|
|
2298
|
-
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
2299
|
-
const cloned = data.clone();
|
|
2300
|
-
if (data.status === 400) {
|
|
2301
|
-
const text = await cloned.text();
|
|
2302
|
-
this.#logger.error(text);
|
|
2303
|
-
return data;
|
|
2304
|
-
}
|
|
2305
|
-
const { url } = await data.json();
|
|
2306
|
-
urlWithParams = url;
|
|
2307
|
-
} catch {
|
|
2308
|
-
}
|
|
2309
|
-
let token;
|
|
2310
|
-
try {
|
|
2311
|
-
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2312
|
-
const answer = await fetchResetPassword(
|
|
2313
|
-
this.#config,
|
|
2314
|
-
"GET",
|
|
2315
|
-
null,
|
|
2316
|
-
worthyParams
|
|
2317
|
-
);
|
|
2318
|
-
token = parseResetToken(answer.headers);
|
|
2319
|
-
} catch {
|
|
2320
|
-
this.#logger.warn(
|
|
2321
|
-
"Unable to parse reset password url. Password not reset."
|
|
2322
|
-
);
|
|
2323
|
-
}
|
|
2324
|
-
const cookie = this.#config.headers.get("cookie")?.split("; ");
|
|
2325
|
-
if (token) {
|
|
2326
|
-
cookie?.push(token);
|
|
2327
|
-
} else {
|
|
2328
|
-
throw new Error(
|
|
2329
|
-
"Unable to reset password, reset token is missing from response"
|
|
2330
|
-
);
|
|
2331
|
-
}
|
|
2332
|
-
this.#config.headers = new Headers({
|
|
2333
|
-
...this.#config.headers,
|
|
2334
|
-
cookie: cookie?.join("; ")
|
|
2591
|
+
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2592
|
+
cookie?.pop();
|
|
2593
|
+
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2594
|
+
cleaned.push(String(parseToken(res.headers)));
|
|
2595
|
+
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2596
|
+
updateHeaders(updatedHeaders);
|
|
2597
|
+
return res;
|
|
2335
2598
|
});
|
|
2336
|
-
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2337
|
-
cookie?.pop();
|
|
2338
|
-
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2339
|
-
cleaned.push(String(parseToken(res.headers)));
|
|
2340
|
-
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2341
|
-
updateHeaders(updatedHeaders);
|
|
2342
|
-
return res;
|
|
2343
2599
|
}
|
|
2344
2600
|
/**
|
|
2345
2601
|
* Low level helper used by {@link signIn} to complete provider flows.
|
|
@@ -2349,7 +2605,9 @@ var Auth = class {
|
|
|
2349
2605
|
*/
|
|
2350
2606
|
async callback(provider, body) {
|
|
2351
2607
|
if (body instanceof Request) {
|
|
2352
|
-
|
|
2608
|
+
ctx.set({
|
|
2609
|
+
headers: body.headers
|
|
2610
|
+
});
|
|
2353
2611
|
return await fetchCallback(
|
|
2354
2612
|
this.#config,
|
|
2355
2613
|
provider,
|
|
@@ -2361,112 +2619,115 @@ var Auth = class {
|
|
|
2361
2619
|
return await fetchCallback(this.#config, provider, body);
|
|
2362
2620
|
}
|
|
2363
2621
|
async signIn(provider, payload, rawResponse) {
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2622
|
+
return withNileContext(this.#config, async () => {
|
|
2623
|
+
if (payload instanceof Request) {
|
|
2624
|
+
const body2 = new URLSearchParams(await payload.text());
|
|
2625
|
+
const origin = new URL(payload.url).origin;
|
|
2626
|
+
const payloadUrl = body2?.get("callbackUrl");
|
|
2627
|
+
const csrfToken2 = body2?.get("csrfToken");
|
|
2628
|
+
const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
|
|
2629
|
+
if (!csrfToken2) {
|
|
2630
|
+
throw new Error(
|
|
2631
|
+
"CSRF token in missing from request. Request it by the client before calling sign in"
|
|
2632
|
+
);
|
|
2633
|
+
}
|
|
2634
|
+
const updatedHeaders = new Headers(payload.headers);
|
|
2635
|
+
updatedHeaders.set("Content-Type", "application/x-www-form-urlencoded");
|
|
2636
|
+
ctx.set({ headers: updatedHeaders });
|
|
2637
|
+
const params = new URLSearchParams({
|
|
2638
|
+
csrfToken: csrfToken2,
|
|
2639
|
+
json: String(true)
|
|
2640
|
+
});
|
|
2641
|
+
if (payloadUrl) {
|
|
2642
|
+
params.set("callbackUrl", callbackUrl);
|
|
2643
|
+
}
|
|
2644
|
+
return await fetchSignIn(this.#config, provider, params);
|
|
2645
|
+
}
|
|
2646
|
+
ctx.set({ headers: null });
|
|
2647
|
+
const { info, error } = this.#logger;
|
|
2648
|
+
const providers = await this.listProviders();
|
|
2649
|
+
info("Obtaining csrf");
|
|
2650
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2651
|
+
let csrfToken;
|
|
2652
|
+
if ("csrfToken" in csrf) {
|
|
2653
|
+
csrfToken = csrf.csrfToken;
|
|
2654
|
+
} else {
|
|
2655
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2656
|
+
}
|
|
2657
|
+
const { credentials } = providers ?? {};
|
|
2658
|
+
if (!credentials) {
|
|
2371
2659
|
throw new Error(
|
|
2372
|
-
"
|
|
2660
|
+
"Unable to obtain credential provider. Aborting server side sign in."
|
|
2373
2661
|
);
|
|
2374
2662
|
}
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2663
|
+
const { email, password } = payload ?? {};
|
|
2664
|
+
if (provider === "email" && (!email || !password)) {
|
|
2665
|
+
throw new Error(
|
|
2666
|
+
"Server side sign in requires a user email and password."
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
info(`Obtaining providers for ${email}`);
|
|
2670
|
+
info(`Attempting sign in with email ${email}`);
|
|
2671
|
+
if (!email) {
|
|
2672
|
+
throw new Error("Email missing from payload, unable to sign in");
|
|
2673
|
+
}
|
|
2674
|
+
const body = JSON.stringify({
|
|
2675
|
+
email,
|
|
2676
|
+
password,
|
|
2677
|
+
csrfToken,
|
|
2678
|
+
callbackUrl: credentials.callbackUrl
|
|
2383
2679
|
});
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
"Unable to obtain
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
);
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
const possibleError = signInRes?.headers.get("location");
|
|
2430
|
-
if (possibleError) {
|
|
2431
|
-
let urlError;
|
|
2680
|
+
const signInRes = await this.callback(provider, body);
|
|
2681
|
+
const authCookie = signInRes?.headers.get("set-cookie");
|
|
2682
|
+
if (!authCookie) {
|
|
2683
|
+
throw new Error("authentication failed");
|
|
2684
|
+
}
|
|
2685
|
+
const token = parseToken(signInRes?.headers);
|
|
2686
|
+
const possibleError = signInRes?.headers.get("location");
|
|
2687
|
+
if (possibleError) {
|
|
2688
|
+
let urlError;
|
|
2689
|
+
try {
|
|
2690
|
+
urlError = new URL(possibleError).searchParams.get("error");
|
|
2691
|
+
} catch {
|
|
2692
|
+
}
|
|
2693
|
+
if (urlError) {
|
|
2694
|
+
error("Unable to log user in", { error: urlError });
|
|
2695
|
+
return new Response(urlError, { status: signInRes.status });
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
if (!token) {
|
|
2699
|
+
error("Unable to obtain auth token", {
|
|
2700
|
+
authCookie,
|
|
2701
|
+
signInRes
|
|
2702
|
+
});
|
|
2703
|
+
throw new Error("Server login failed");
|
|
2704
|
+
}
|
|
2705
|
+
info("Server sign in successful", { authCookie });
|
|
2706
|
+
const setCookie = signInRes.headers.get("set-cookie");
|
|
2707
|
+
const { headers } = ctx.get();
|
|
2708
|
+
if (setCookie) {
|
|
2709
|
+
const cookie = [
|
|
2710
|
+
parseCSRF(headers),
|
|
2711
|
+
parseCallback(signInRes.headers),
|
|
2712
|
+
parseToken(signInRes.headers)
|
|
2713
|
+
].filter(Boolean).join("; ");
|
|
2714
|
+
const uHeaders = new Headers({ cookie });
|
|
2715
|
+
updateHeaders(uHeaders);
|
|
2716
|
+
ctx.set({ headers: uHeaders, preserveHeaders: true });
|
|
2717
|
+
} else {
|
|
2718
|
+
error("Unable to set context after sign in", {
|
|
2719
|
+
headers: signInRes.headers
|
|
2720
|
+
});
|
|
2721
|
+
}
|
|
2722
|
+
if (rawResponse) {
|
|
2723
|
+
return signInRes;
|
|
2724
|
+
}
|
|
2432
2725
|
try {
|
|
2433
|
-
|
|
2726
|
+
return await signInRes.clone().json();
|
|
2434
2727
|
} catch {
|
|
2728
|
+
return signInRes;
|
|
2435
2729
|
}
|
|
2436
|
-
|
|
2437
|
-
error("Unable to log user in", { error: urlError });
|
|
2438
|
-
return new Response(urlError, { status: signInRes.status });
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
if (!token) {
|
|
2442
|
-
error("Unable to obtain auth token", {
|
|
2443
|
-
authCookie,
|
|
2444
|
-
signInRes
|
|
2445
|
-
});
|
|
2446
|
-
throw new Error("Server login failed");
|
|
2447
|
-
}
|
|
2448
|
-
info("Server sign in successful", { authCookie });
|
|
2449
|
-
const setCookie = signInRes.headers.get("set-cookie");
|
|
2450
|
-
if (setCookie) {
|
|
2451
|
-
const cookie = [
|
|
2452
|
-
parseCSRF(this.#config.headers),
|
|
2453
|
-
parseCallback(signInRes.headers),
|
|
2454
|
-
parseToken(signInRes.headers)
|
|
2455
|
-
].filter(Boolean).join("; ");
|
|
2456
|
-
updateHeaders(new Headers({ cookie }));
|
|
2457
|
-
} else {
|
|
2458
|
-
error("Unable to set context after sign in", {
|
|
2459
|
-
headers: signInRes.headers
|
|
2460
|
-
});
|
|
2461
|
-
}
|
|
2462
|
-
if (rawResponse) {
|
|
2463
|
-
return signInRes;
|
|
2464
|
-
}
|
|
2465
|
-
try {
|
|
2466
|
-
return await signInRes.clone().json();
|
|
2467
|
-
} catch {
|
|
2468
|
-
return signInRes;
|
|
2469
|
-
}
|
|
2730
|
+
});
|
|
2470
2731
|
}
|
|
2471
2732
|
};
|
|
2472
2733
|
function parseCSRF(headers) {
|
|
@@ -2513,25 +2774,56 @@ function parseResetToken(headers) {
|
|
|
2513
2774
|
const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
|
|
2514
2775
|
return token;
|
|
2515
2776
|
}
|
|
2516
|
-
function
|
|
2777
|
+
function parseTenantId(headers) {
|
|
2778
|
+
let authCookie = headers?.get("set-cookie");
|
|
2779
|
+
if (!authCookie) {
|
|
2780
|
+
authCookie = headers?.get("cookie");
|
|
2781
|
+
}
|
|
2782
|
+
if (!authCookie) {
|
|
2783
|
+
return void 0;
|
|
2784
|
+
}
|
|
2785
|
+
const [, token] = /((__Secure-)?nile\.tenant-id=[^;]+)/.exec(authCookie) ?? [];
|
|
2786
|
+
if (token) {
|
|
2787
|
+
const [, tenantId] = token.split("=");
|
|
2788
|
+
return tenantId;
|
|
2789
|
+
}
|
|
2790
|
+
return null;
|
|
2791
|
+
}
|
|
2792
|
+
function defaultCallbackUrl(config) {
|
|
2517
2793
|
let cb = null;
|
|
2518
2794
|
let redirect = null;
|
|
2519
|
-
const
|
|
2795
|
+
const { headers } = ctx.get();
|
|
2796
|
+
const fallbackCb = parseCallback(headers);
|
|
2520
2797
|
if (fallbackCb) {
|
|
2521
2798
|
const [, value] = fallbackCb.split("=");
|
|
2522
2799
|
cb = decodeURIComponent(value);
|
|
2523
2800
|
if (value) {
|
|
2524
|
-
redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2801
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2525
2802
|
}
|
|
2526
2803
|
}
|
|
2527
2804
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
2528
2805
|
}
|
|
2806
|
+
function fQUrl(path, config) {
|
|
2807
|
+
if (path.startsWith("/")) {
|
|
2808
|
+
const { callbackUrl } = defaultCallbackUrl(config);
|
|
2809
|
+
if (callbackUrl) {
|
|
2810
|
+
const { origin } = new URL(callbackUrl);
|
|
2811
|
+
return `${origin}${path}`;
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
try {
|
|
2815
|
+
new URL(path);
|
|
2816
|
+
} catch {
|
|
2817
|
+
throw new Error("An invalid URL has been passed.");
|
|
2818
|
+
}
|
|
2819
|
+
return path;
|
|
2820
|
+
}
|
|
2529
2821
|
|
|
2530
2822
|
// src/auth/obtainCsrf.ts
|
|
2531
2823
|
async function obtainCsrf(config, rawResponse = false) {
|
|
2824
|
+
const { headers } = ctx.get();
|
|
2532
2825
|
const res = await fetchCsrf(config);
|
|
2533
2826
|
const csrfCook = parseCSRF(res.headers);
|
|
2534
|
-
const h = new Headers();
|
|
2535
2827
|
if (csrfCook) {
|
|
2536
2828
|
const [, value] = csrfCook.split("=");
|
|
2537
2829
|
const [token] = decodeURIComponent(value).split("|");
|
|
@@ -2542,29 +2834,27 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2542
2834
|
parseCallback(res.headers),
|
|
2543
2835
|
parseToken(res.headers)
|
|
2544
2836
|
].filter(Boolean).join("; ");
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
updateHeaders(
|
|
2837
|
+
headers.set("cookie", cookie);
|
|
2838
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2839
|
+
updateHeaders(headers);
|
|
2548
2840
|
}
|
|
2549
2841
|
if (!rawResponse) {
|
|
2550
2842
|
return { csrfToken: token };
|
|
2551
2843
|
}
|
|
2552
2844
|
} else {
|
|
2553
|
-
const existingCookie =
|
|
2845
|
+
const existingCookie = headers.get("cookie");
|
|
2554
2846
|
const cookieParts = [];
|
|
2555
2847
|
if (existingCookie) {
|
|
2556
|
-
cookieParts.push(
|
|
2557
|
-
parseToken(config.headers),
|
|
2558
|
-
parseCallback(config.headers)
|
|
2559
|
-
);
|
|
2848
|
+
cookieParts.push(parseToken(headers), parseCallback(headers));
|
|
2560
2849
|
}
|
|
2561
2850
|
if (csrfCook) {
|
|
2562
2851
|
cookieParts.push(csrfCook);
|
|
2563
2852
|
} else {
|
|
2564
|
-
cookieParts.push(parseCSRF(
|
|
2853
|
+
cookieParts.push(parseCSRF(headers));
|
|
2565
2854
|
}
|
|
2566
2855
|
const cookie = cookieParts.filter(Boolean).join("; ");
|
|
2567
|
-
|
|
2856
|
+
headers.set("cookie", cookie);
|
|
2857
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2568
2858
|
updateHeaders(new Headers({ cookie }));
|
|
2569
2859
|
}
|
|
2570
2860
|
if (rawResponse) {
|
|
@@ -2577,6 +2867,22 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2577
2867
|
}
|
|
2578
2868
|
}
|
|
2579
2869
|
|
|
2870
|
+
// src/utils/qualifyDomain.ts
|
|
2871
|
+
function fQUrl2(callbackUrl, path) {
|
|
2872
|
+
if (path.startsWith("/")) {
|
|
2873
|
+
if (callbackUrl) {
|
|
2874
|
+
const { origin } = new URL(callbackUrl);
|
|
2875
|
+
return `${origin}${path}`;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
try {
|
|
2879
|
+
new URL(path);
|
|
2880
|
+
} catch {
|
|
2881
|
+
throw new Error("An invalid URL has been passed.");
|
|
2882
|
+
}
|
|
2883
|
+
return path;
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2580
2886
|
// src/users/index.ts
|
|
2581
2887
|
var Users = class {
|
|
2582
2888
|
#config;
|
|
@@ -2599,15 +2905,17 @@ var Users = class {
|
|
|
2599
2905
|
* @param [rawResponse] - When `true`, return the raw {@link Response}.
|
|
2600
2906
|
*/
|
|
2601
2907
|
async updateSelf(req, rawResponse) {
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2908
|
+
return withNileContext(this.#config, async () => {
|
|
2909
|
+
const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
|
|
2910
|
+
if (rawResponse) {
|
|
2911
|
+
return res;
|
|
2912
|
+
}
|
|
2913
|
+
try {
|
|
2914
|
+
return await res?.clone().json();
|
|
2915
|
+
} catch {
|
|
2916
|
+
return res;
|
|
2917
|
+
}
|
|
2918
|
+
});
|
|
2611
2919
|
}
|
|
2612
2920
|
/**
|
|
2613
2921
|
* Remove the current user using `DELETE /api/me`.
|
|
@@ -2617,59 +2925,73 @@ var Users = class {
|
|
|
2617
2925
|
* `packages/server/src/api/routes/me/index.ts` under `removeSelf`.
|
|
2618
2926
|
*/
|
|
2619
2927
|
async removeSelf() {
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2928
|
+
return withNileContext(this.#config, async () => {
|
|
2929
|
+
const me = await this.getSelf();
|
|
2930
|
+
if ("id" in me) {
|
|
2931
|
+
const userId = me.id;
|
|
2932
|
+
ctx.set({ userId });
|
|
2933
|
+
}
|
|
2934
|
+
const res = await fetchMe(this.#config, "DELETE");
|
|
2935
|
+
updateHeaders(new Headers());
|
|
2936
|
+
return res;
|
|
2937
|
+
});
|
|
2627
2938
|
}
|
|
2628
2939
|
async getSelf(rawResponse) {
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2940
|
+
return withNileContext(this.#config, async () => {
|
|
2941
|
+
const res = await fetchMe(this.#config);
|
|
2942
|
+
if (rawResponse) {
|
|
2943
|
+
return res;
|
|
2944
|
+
}
|
|
2945
|
+
try {
|
|
2946
|
+
return await res?.clone().json();
|
|
2947
|
+
} catch {
|
|
2948
|
+
return res;
|
|
2949
|
+
}
|
|
2950
|
+
});
|
|
2638
2951
|
}
|
|
2639
2952
|
async verifySelf(options, rawResponse = false) {
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
if (!bypassEmail) {
|
|
2652
|
-
let message = "Unable to verify email.";
|
|
2653
|
-
if (e instanceof Error) {
|
|
2654
|
-
message = e.message;
|
|
2953
|
+
return withNileContext(this.#config, async () => {
|
|
2954
|
+
const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
|
|
2955
|
+
const callbackUrl = fQUrl2(
|
|
2956
|
+
defaultCallbackUrl2().callbackUrl,
|
|
2957
|
+
typeof options === "object" ? String(options.callbackUrl) : "/"
|
|
2958
|
+
);
|
|
2959
|
+
let res;
|
|
2960
|
+
try {
|
|
2961
|
+
const me = await this.getSelf();
|
|
2962
|
+
if (me instanceof Response) {
|
|
2963
|
+
return me;
|
|
2655
2964
|
}
|
|
2656
|
-
this.#
|
|
2657
|
-
|
|
2965
|
+
res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
|
|
2966
|
+
return res;
|
|
2967
|
+
} catch (e) {
|
|
2968
|
+
if (!bypassEmail) {
|
|
2969
|
+
let message = "Unable to verify email.";
|
|
2970
|
+
if (e instanceof Error) {
|
|
2971
|
+
message = e.message;
|
|
2972
|
+
}
|
|
2973
|
+
this.#logger?.error(
|
|
2974
|
+
`${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
|
|
2975
|
+
);
|
|
2976
|
+
res = new Response(message, { status: 400 });
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
if (bypassEmail) {
|
|
2980
|
+
this.#logger?.info(
|
|
2981
|
+
"bypassing email requirements for email verification"
|
|
2658
2982
|
);
|
|
2659
|
-
res =
|
|
2983
|
+
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2660
2984
|
}
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
this.#logger?.info("bypassing email requirements for email verification");
|
|
2664
|
-
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2665
|
-
}
|
|
2666
|
-
return res;
|
|
2985
|
+
return res;
|
|
2986
|
+
});
|
|
2667
2987
|
}
|
|
2668
2988
|
};
|
|
2669
2989
|
async function verifyEmailAddress(config, user, callback) {
|
|
2670
|
-
|
|
2990
|
+
const { headers } = ctx.get();
|
|
2991
|
+
headers?.set("content-type", "application/x-www-form-urlencoded");
|
|
2992
|
+
ctx.set({ headers });
|
|
2671
2993
|
const { csrfToken } = await obtainCsrf(config);
|
|
2672
|
-
const defaults = defaultCallbackUrl2(
|
|
2994
|
+
const defaults = defaultCallbackUrl2();
|
|
2673
2995
|
const callbackUrl = callback ?? String(defaults.callbackUrl);
|
|
2674
2996
|
const res = await fetchVerifyEmail(
|
|
2675
2997
|
config,
|
|
@@ -2685,9 +3007,10 @@ async function verifyEmailAddress(config, user, callback) {
|
|
|
2685
3007
|
}
|
|
2686
3008
|
return res;
|
|
2687
3009
|
}
|
|
2688
|
-
function defaultCallbackUrl2(
|
|
3010
|
+
function defaultCallbackUrl2() {
|
|
2689
3011
|
let cb = null;
|
|
2690
|
-
const
|
|
3012
|
+
const { headers } = ctx.get();
|
|
3013
|
+
const fallbackCb = parseCallback(headers);
|
|
2691
3014
|
if (fallbackCb) {
|
|
2692
3015
|
const [, value] = fallbackCb.split("=");
|
|
2693
3016
|
cb = decodeURIComponent(value);
|
|
@@ -2707,24 +3030,26 @@ var Tenants = class {
|
|
|
2707
3030
|
* `createTenant` operation definition.
|
|
2708
3031
|
*/
|
|
2709
3032
|
async create(req, rawResponse) {
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
3033
|
+
return withNileContext(this.#config, async () => {
|
|
3034
|
+
let res;
|
|
3035
|
+
if (typeof req === "string") {
|
|
3036
|
+
res = await fetchTenants(
|
|
3037
|
+
this.#config,
|
|
3038
|
+
"POST",
|
|
3039
|
+
JSON.stringify({ name: req })
|
|
3040
|
+
);
|
|
3041
|
+
} else if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3042
|
+
res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
|
|
3043
|
+
}
|
|
3044
|
+
if (rawResponse) {
|
|
3045
|
+
return res;
|
|
3046
|
+
}
|
|
3047
|
+
try {
|
|
3048
|
+
return await res?.clone().json();
|
|
3049
|
+
} catch {
|
|
3050
|
+
return res;
|
|
3051
|
+
}
|
|
3052
|
+
});
|
|
2728
3053
|
}
|
|
2729
3054
|
/**
|
|
2730
3055
|
* Remove a tenant via `DELETE /api/tenants/{tenantId}`.
|
|
@@ -2732,14 +3057,16 @@ var Tenants = class {
|
|
|
2732
3057
|
* @param req - The tenant to remove or context containing the id.
|
|
2733
3058
|
*/
|
|
2734
3059
|
async delete(req) {
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
3060
|
+
return withNileContext(this.#config, async () => {
|
|
3061
|
+
if (typeof req === "string") {
|
|
3062
|
+
ctx.set({ tenantId: req });
|
|
3063
|
+
}
|
|
3064
|
+
if (typeof req === "object" && "id" in req) {
|
|
3065
|
+
ctx.set({ tenantId: req.id });
|
|
3066
|
+
}
|
|
3067
|
+
const res = await fetchTenant(this.#config, "DELETE");
|
|
3068
|
+
return res;
|
|
3069
|
+
});
|
|
2743
3070
|
}
|
|
2744
3071
|
/**
|
|
2745
3072
|
* Fetch details for a tenant using `GET /api/tenants/{tenantId}`.
|
|
@@ -2748,53 +3075,63 @@ var Tenants = class {
|
|
|
2748
3075
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2749
3076
|
*/
|
|
2750
3077
|
async get(req, rawResponse) {
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
3078
|
+
return withNileContext(this.#config, async () => {
|
|
3079
|
+
if (typeof req === "string") {
|
|
3080
|
+
ctx.set({ tenantId: req });
|
|
3081
|
+
} else if (typeof req === "object" && "id" in req) {
|
|
3082
|
+
ctx.set({ tenantId: req.id });
|
|
3083
|
+
}
|
|
3084
|
+
const res = await fetchTenant(this.#config, "GET");
|
|
3085
|
+
if (rawResponse === true || req === true) {
|
|
3086
|
+
return res;
|
|
3087
|
+
}
|
|
3088
|
+
try {
|
|
3089
|
+
return await res?.clone().json();
|
|
3090
|
+
} catch {
|
|
3091
|
+
return res;
|
|
3092
|
+
}
|
|
3093
|
+
});
|
|
2765
3094
|
}
|
|
2766
3095
|
async update(req, rawResponse) {
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
3096
|
+
return withNileContext(this.#config, async () => {
|
|
3097
|
+
let res;
|
|
3098
|
+
if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3099
|
+
const { id, ...remaining } = req;
|
|
3100
|
+
if (id) {
|
|
3101
|
+
ctx.set({ tenantId: id });
|
|
3102
|
+
}
|
|
3103
|
+
res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
|
|
2772
3104
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
}
|
|
3105
|
+
if (rawResponse) {
|
|
3106
|
+
return res;
|
|
3107
|
+
}
|
|
3108
|
+
try {
|
|
3109
|
+
return await res?.clone().json();
|
|
3110
|
+
} catch {
|
|
3111
|
+
return res;
|
|
3112
|
+
}
|
|
3113
|
+
});
|
|
2783
3114
|
}
|
|
2784
3115
|
/**
|
|
2785
3116
|
* List tenants for the current user via `GET /api/tenants`.
|
|
2786
3117
|
* See `packages/server/src/api/routes/tenants/GET.ts` for details.
|
|
2787
3118
|
*/
|
|
2788
3119
|
async list(req) {
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
3120
|
+
return withNileContext(
|
|
3121
|
+
this.#config,
|
|
3122
|
+
async () => {
|
|
3123
|
+
const res = await fetchTenantsByUser(this.#config);
|
|
3124
|
+
if (req === true) {
|
|
3125
|
+
return res;
|
|
3126
|
+
}
|
|
3127
|
+
try {
|
|
3128
|
+
return await res?.clone().json();
|
|
3129
|
+
} catch {
|
|
3130
|
+
return res;
|
|
3131
|
+
}
|
|
3132
|
+
},
|
|
3133
|
+
"listTenants"
|
|
3134
|
+
);
|
|
2798
3135
|
}
|
|
2799
3136
|
/**
|
|
2800
3137
|
* Leave the current tenant using `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2802,29 +3139,33 @@ var Tenants = class {
|
|
|
2802
3139
|
* @param [req] - Optionally specify the tenant id to leave.
|
|
2803
3140
|
*/
|
|
2804
3141
|
async leaveTenant(req) {
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
3142
|
+
return withNileContext(this.#config, async () => {
|
|
3143
|
+
const me = await fetchMe(this.#config);
|
|
3144
|
+
try {
|
|
3145
|
+
const json = await me.json();
|
|
3146
|
+
if ("id" in json) {
|
|
3147
|
+
ctx.set({ userId: json.id, preserveHeaders: true });
|
|
3148
|
+
}
|
|
3149
|
+
} catch {
|
|
2810
3150
|
}
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
this.#
|
|
2817
|
-
}
|
|
2818
|
-
return await fetchTenantUser(this.#config, "DELETE");
|
|
3151
|
+
if (typeof req === "string") {
|
|
3152
|
+
ctx.set({ tenantId: req, preserveHeaders: true });
|
|
3153
|
+
} else {
|
|
3154
|
+
this.#handleContext(req);
|
|
3155
|
+
}
|
|
3156
|
+
return await fetchTenantUser(this.#config, "DELETE");
|
|
3157
|
+
});
|
|
2819
3158
|
}
|
|
2820
3159
|
async addMember(req, rawResponse) {
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
3160
|
+
return withNileContext(this.#config, async () => {
|
|
3161
|
+
if (typeof req === "string") {
|
|
3162
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3163
|
+
} else {
|
|
3164
|
+
this.#handleContext(req);
|
|
3165
|
+
}
|
|
3166
|
+
const res = await fetchTenantUser(this.#config, "PUT");
|
|
3167
|
+
return responseHandler(res, rawResponse);
|
|
3168
|
+
});
|
|
2828
3169
|
}
|
|
2829
3170
|
/**
|
|
2830
3171
|
* Remove a user from a tenant with `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2833,57 +3174,83 @@ var Tenants = class {
|
|
|
2833
3174
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2834
3175
|
*/
|
|
2835
3176
|
async removeMember(req, rawResponse) {
|
|
2836
|
-
this.#
|
|
2837
|
-
|
|
2838
|
-
|
|
3177
|
+
return withNileContext(this.#config, async () => {
|
|
3178
|
+
this.#handleContext(req);
|
|
3179
|
+
if (typeof req === "string") {
|
|
3180
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3181
|
+
}
|
|
3182
|
+
const res = await fetchTenantUser(this.#config, "DELETE");
|
|
3183
|
+
return responseHandler(res, rawResponse);
|
|
3184
|
+
});
|
|
2839
3185
|
}
|
|
2840
3186
|
async users(req, rawResponse) {
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
3187
|
+
return withNileContext(
|
|
3188
|
+
this.#config,
|
|
3189
|
+
async () => {
|
|
3190
|
+
this.#handleContext(req);
|
|
3191
|
+
const res = await fetchTenantUsers(this.#config, "GET");
|
|
3192
|
+
return responseHandler(
|
|
3193
|
+
res,
|
|
3194
|
+
rawResponse || typeof req === "boolean" && req
|
|
3195
|
+
);
|
|
3196
|
+
},
|
|
3197
|
+
"users"
|
|
2846
3198
|
);
|
|
2847
3199
|
}
|
|
2848
3200
|
/**
|
|
2849
3201
|
* List invites for the current tenant via `GET /api/tenants/{tenantId}/invites`.
|
|
2850
3202
|
*/
|
|
2851
3203
|
async invites() {
|
|
2852
|
-
|
|
2853
|
-
|
|
3204
|
+
return withNileContext(
|
|
3205
|
+
this.#config,
|
|
3206
|
+
async () => {
|
|
3207
|
+
const res = await fetchInvites(this.#config);
|
|
3208
|
+
return responseHandler(res);
|
|
3209
|
+
},
|
|
3210
|
+
"invites"
|
|
3211
|
+
);
|
|
2854
3212
|
}
|
|
2855
3213
|
async invite(req, rawResponse) {
|
|
2856
|
-
|
|
2857
|
-
const defaults = defaultCallbackUrl3(this.#config);
|
|
2858
|
-
let identifier = req;
|
|
2859
|
-
let callbackUrl = defaults.callbackUrl;
|
|
2860
|
-
let redirectUrl = defaults.redirectUrl;
|
|
2861
|
-
if (typeof req === "object") {
|
|
2862
|
-
if ("email" in req) {
|
|
2863
|
-
identifier = req.email;
|
|
2864
|
-
}
|
|
2865
|
-
if ("callbackUrl" in req) {
|
|
2866
|
-
callbackUrl = req.callbackUrl ? req.callbackUrl : "";
|
|
2867
|
-
}
|
|
2868
|
-
if ("redirectUrl" in req) {
|
|
2869
|
-
redirectUrl = req.redirectUrl ? req.redirectUrl : "";
|
|
2870
|
-
}
|
|
2871
|
-
}
|
|
2872
|
-
this.#config.headers.set(
|
|
2873
|
-
"Content-Type",
|
|
2874
|
-
"application/x-www-form-urlencoded"
|
|
2875
|
-
);
|
|
2876
|
-
const res = await fetchInvite(
|
|
3214
|
+
return withNileContext(
|
|
2877
3215
|
this.#config,
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
3216
|
+
async () => {
|
|
3217
|
+
await runExtensionContext(this.#config);
|
|
3218
|
+
const { csrfToken } = await obtainCsrf(
|
|
3219
|
+
this.#config
|
|
3220
|
+
);
|
|
3221
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3222
|
+
let identifier = req;
|
|
3223
|
+
let callbackUrl = defaults.callbackUrl;
|
|
3224
|
+
let redirectUrl = defaults.redirectUrl;
|
|
3225
|
+
if (typeof req === "object") {
|
|
3226
|
+
if ("email" in req) {
|
|
3227
|
+
identifier = req.email;
|
|
3228
|
+
}
|
|
3229
|
+
const { callbackUrl: cbUrl } = defaultCallbackUrl3(this.#config);
|
|
3230
|
+
if ("callbackUrl" in req) {
|
|
3231
|
+
callbackUrl = fQUrl2(cbUrl, req.callbackUrl ?? "/");
|
|
3232
|
+
}
|
|
3233
|
+
if ("redirectUrl" in req) {
|
|
3234
|
+
redirectUrl = fQUrl2(cbUrl, req.redirectUrl ?? "/");
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
const { headers } = ctx.get();
|
|
3238
|
+
headers?.set("Content-Type", "application/x-www-form-urlencoded");
|
|
3239
|
+
ctx.set({ headers });
|
|
3240
|
+
const res = await fetchInvite(
|
|
3241
|
+
this.#config,
|
|
3242
|
+
"POST",
|
|
3243
|
+
new URLSearchParams({
|
|
3244
|
+
identifier,
|
|
3245
|
+
csrfToken,
|
|
3246
|
+
callbackUrl,
|
|
3247
|
+
redirectUrl
|
|
3248
|
+
}).toString()
|
|
3249
|
+
);
|
|
3250
|
+
return responseHandler(res, rawResponse);
|
|
3251
|
+
},
|
|
3252
|
+
"invites"
|
|
2885
3253
|
);
|
|
2886
|
-
return responseHandler(res, rawResponse);
|
|
2887
3254
|
}
|
|
2888
3255
|
/**
|
|
2889
3256
|
* Accept an invite using `PUT /api/tenants/{tenantId}/invite`.
|
|
@@ -2892,22 +3259,24 @@ var Tenants = class {
|
|
|
2892
3259
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2893
3260
|
*/
|
|
2894
3261
|
async acceptInvite(req, rawResponse) {
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
3262
|
+
return withNileContext(this.#config, async () => {
|
|
3263
|
+
if (!req) {
|
|
3264
|
+
throw new Error("The identifier and token are required.");
|
|
3265
|
+
}
|
|
3266
|
+
const { identifier, token } = req;
|
|
3267
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3268
|
+
const callbackUrl = String(defaults.callbackUrl);
|
|
3269
|
+
const res = await fetchInvite(
|
|
3270
|
+
this.#config,
|
|
3271
|
+
"PUT",
|
|
3272
|
+
new URLSearchParams({
|
|
3273
|
+
identifier,
|
|
3274
|
+
token,
|
|
3275
|
+
callbackUrl
|
|
3276
|
+
}).toString()
|
|
3277
|
+
);
|
|
3278
|
+
return responseHandler(res, rawResponse);
|
|
3279
|
+
});
|
|
2911
3280
|
}
|
|
2912
3281
|
/**
|
|
2913
3282
|
* Delete a pending invite using `DELETE /api/tenants/{tenantId}/invite/{inviteId}`.
|
|
@@ -2915,25 +3284,27 @@ var Tenants = class {
|
|
|
2915
3284
|
* @param req - Identifier of the invite to remove.
|
|
2916
3285
|
*/
|
|
2917
3286
|
async deleteInvite(req) {
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
3287
|
+
return withNileContext(this.#config, async () => {
|
|
3288
|
+
let id = "";
|
|
3289
|
+
if (typeof req === "object") {
|
|
3290
|
+
id = req.id;
|
|
3291
|
+
} else {
|
|
3292
|
+
id = req;
|
|
3293
|
+
}
|
|
3294
|
+
if (!id) {
|
|
3295
|
+
throw new Error("An invite id is required.");
|
|
3296
|
+
}
|
|
3297
|
+
const res = await fetchInvite(this.#config, "DELETE", id);
|
|
3298
|
+
return responseHandler(res, true);
|
|
3299
|
+
});
|
|
2929
3300
|
}
|
|
2930
3301
|
#handleContext(req) {
|
|
2931
3302
|
if (typeof req === "object") {
|
|
2932
3303
|
if ("tenantId" in req) {
|
|
2933
|
-
|
|
3304
|
+
ctx.set({ tenantId: req.tenantId, preserveHeaders: true });
|
|
2934
3305
|
}
|
|
2935
3306
|
if ("userId" in req) {
|
|
2936
|
-
|
|
3307
|
+
ctx.set({ userId: req.userId, preserveHeaders: true });
|
|
2937
3308
|
}
|
|
2938
3309
|
}
|
|
2939
3310
|
}
|
|
@@ -2951,15 +3322,13 @@ async function responseHandler(res, rawResponse) {
|
|
|
2951
3322
|
function defaultCallbackUrl3(config) {
|
|
2952
3323
|
let cb = null;
|
|
2953
3324
|
let redirect = null;
|
|
2954
|
-
const
|
|
3325
|
+
const { headers, tenantId } = ctx.get();
|
|
3326
|
+
const fallbackCb = parseCallback(headers);
|
|
2955
3327
|
if (fallbackCb) {
|
|
2956
3328
|
const [, value] = fallbackCb.split("=");
|
|
2957
3329
|
cb = decodeURIComponent(value);
|
|
2958
3330
|
if (value) {
|
|
2959
|
-
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
|
|
2960
|
-
"{tenantId}",
|
|
2961
|
-
String(config.tenantId)
|
|
2962
|
-
)}`;
|
|
3331
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", String(tenantId))}`;
|
|
2963
3332
|
}
|
|
2964
3333
|
}
|
|
2965
3334
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
@@ -3026,97 +3395,6 @@ function updateConfig(response, config) {
|
|
|
3026
3395
|
};
|
|
3027
3396
|
}
|
|
3028
3397
|
|
|
3029
|
-
// src/api/utils/extensions.ts
|
|
3030
|
-
function getRequestConfig(params) {
|
|
3031
|
-
if (typeof params[1] === "object") {
|
|
3032
|
-
return params[1];
|
|
3033
|
-
}
|
|
3034
|
-
return {};
|
|
3035
|
-
}
|
|
3036
|
-
function bindRunExtensions(instance) {
|
|
3037
|
-
return async function runExtensions(toRun, config, params, _init) {
|
|
3038
|
-
const { debug } = config.logger("[EXTENSIONS]");
|
|
3039
|
-
const extensionConfig = getRequestConfig(
|
|
3040
|
-
Array.isArray(params) ? params : [null, params]
|
|
3041
|
-
);
|
|
3042
|
-
if (config.extensions) {
|
|
3043
|
-
for (const create2 of config.extensions) {
|
|
3044
|
-
if (typeof create2 !== "function") {
|
|
3045
|
-
continue;
|
|
3046
|
-
}
|
|
3047
|
-
const ext = create2(instance);
|
|
3048
|
-
if (extensionConfig.disableExtensions?.includes(ext.id)) {
|
|
3049
|
-
continue;
|
|
3050
|
-
}
|
|
3051
|
-
if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
|
|
3052
|
-
const result = await ext.onHandleRequest(
|
|
3053
|
-
...Array.isArray(params) ? params : [params]
|
|
3054
|
-
);
|
|
3055
|
-
debug(`${ext.id ?? create2.name} ran onHandleRequest`);
|
|
3056
|
-
if (result != null) {
|
|
3057
|
-
return result;
|
|
3058
|
-
}
|
|
3059
|
-
}
|
|
3060
|
-
const [param] = Array.isArray(params) ? params : [params];
|
|
3061
|
-
if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
|
|
3062
|
-
const previousContext = instance.getContext();
|
|
3063
|
-
if (previousContext.preserveHeaders) {
|
|
3064
|
-
instance.setContext({ preserveHeaders: false });
|
|
3065
|
-
}
|
|
3066
|
-
if (!_init) {
|
|
3067
|
-
continue;
|
|
3068
|
-
}
|
|
3069
|
-
await ext.onRequest(_init.request);
|
|
3070
|
-
const updatedContext = instance.getContext();
|
|
3071
|
-
if (updatedContext?.headers) {
|
|
3072
|
-
const cookie = updatedContext.headers.get("cookie");
|
|
3073
|
-
if (cookie && param.headers) {
|
|
3074
|
-
param.headers.set(
|
|
3075
|
-
"cookie",
|
|
3076
|
-
mergeCookies(
|
|
3077
|
-
previousContext.preserveHeaders ? previousContext.headers?.get("cookie") : null,
|
|
3078
|
-
updatedContext.headers.get("cookie")
|
|
3079
|
-
)
|
|
3080
|
-
);
|
|
3081
|
-
}
|
|
3082
|
-
if (updatedContext.tenantId && param.headers) {
|
|
3083
|
-
param.headers.set(
|
|
3084
|
-
TENANT_COOKIE,
|
|
3085
|
-
String(updatedContext.headers.get(TENANT_COOKIE))
|
|
3086
|
-
);
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
debug(`${ext.id ?? create2.name} ran onRequest`);
|
|
3090
|
-
}
|
|
3091
|
-
if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
|
|
3092
|
-
const result = await ext.onResponse(param);
|
|
3093
|
-
debug(`${ext.id ?? create2.name} ran onResponse`);
|
|
3094
|
-
if (result != null) {
|
|
3095
|
-
return result;
|
|
3096
|
-
}
|
|
3097
|
-
}
|
|
3098
|
-
}
|
|
3099
|
-
}
|
|
3100
|
-
return void 0;
|
|
3101
|
-
};
|
|
3102
|
-
}
|
|
3103
|
-
function buildExtensionConfig(instance) {
|
|
3104
|
-
return {
|
|
3105
|
-
runExtensions: bindRunExtensions(instance)
|
|
3106
|
-
};
|
|
3107
|
-
}
|
|
3108
|
-
function mergeCookies(...cookieStrings) {
|
|
3109
|
-
const cookieMap = /* @__PURE__ */ new Map();
|
|
3110
|
-
for (const str of cookieStrings) {
|
|
3111
|
-
if (!str) continue;
|
|
3112
|
-
for (const part of str.split(";")) {
|
|
3113
|
-
const [key17, value] = part.split("=").map((s) => s.trim());
|
|
3114
|
-
if (key17 && value) cookieMap.set(key17, value);
|
|
3115
|
-
}
|
|
3116
|
-
}
|
|
3117
|
-
return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
|
|
3118
|
-
}
|
|
3119
|
-
|
|
3120
3398
|
// src/Server.ts
|
|
3121
3399
|
var Server = class {
|
|
3122
3400
|
users;
|
|
@@ -3125,35 +3403,38 @@ var Server = class {
|
|
|
3125
3403
|
#config;
|
|
3126
3404
|
#handlers;
|
|
3127
3405
|
#manager;
|
|
3128
|
-
#headers;
|
|
3129
|
-
#preserveHeaders;
|
|
3406
|
+
// #headers: undefined | Headers;
|
|
3407
|
+
// #preserveHeaders: boolean;
|
|
3130
3408
|
constructor(config) {
|
|
3131
3409
|
this.#config = new Config({
|
|
3132
3410
|
...config,
|
|
3133
3411
|
extensionCtx: buildExtensionConfig(this)
|
|
3134
3412
|
});
|
|
3135
3413
|
watchTenantId((tenantId) => {
|
|
3136
|
-
if (tenantId !== this.#config.tenantId) {
|
|
3137
|
-
this.#config.tenantId = tenantId;
|
|
3414
|
+
if (tenantId !== this.#config.context.tenantId) {
|
|
3415
|
+
this.#config.context.tenantId = String(tenantId);
|
|
3138
3416
|
this.#reset();
|
|
3139
3417
|
}
|
|
3140
3418
|
});
|
|
3141
3419
|
watchUserId((userId) => {
|
|
3142
|
-
if (userId !== this.#config.userId) {
|
|
3143
|
-
this.#config.userId = userId;
|
|
3420
|
+
if (userId !== this.#config.context.userId) {
|
|
3421
|
+
this.#config.context.userId = String(userId);
|
|
3144
3422
|
this.#reset();
|
|
3145
3423
|
}
|
|
3146
3424
|
});
|
|
3147
3425
|
watchHeaders((headers) => {
|
|
3148
|
-
|
|
3149
|
-
|
|
3426
|
+
if (headers) {
|
|
3427
|
+
this.#config.context.headers = new Headers(headers);
|
|
3428
|
+
this.#config.context.preserveHeaders = true;
|
|
3429
|
+
this.#reset();
|
|
3430
|
+
}
|
|
3150
3431
|
});
|
|
3151
3432
|
this.#handlers = {
|
|
3152
3433
|
...this.#config.handlers,
|
|
3153
3434
|
withContext: handlersWithContext(this.#config)
|
|
3154
3435
|
};
|
|
3155
|
-
this.#preserveHeaders = config?.preserveHeaders ?? false;
|
|
3156
|
-
this.#config.tenantId = getTenantId({ config: this.#config });
|
|
3436
|
+
this.#config.context.preserveHeaders = config?.preserveHeaders ?? false;
|
|
3437
|
+
this.#config.context.tenantId = getTenantId({ config: this.#config });
|
|
3157
3438
|
this.#manager = new DBManager(this.#config);
|
|
3158
3439
|
this.#handleHeaders(config);
|
|
3159
3440
|
this.users = new Users(this.#config);
|
|
@@ -3208,21 +3489,6 @@ var Server = class {
|
|
|
3208
3489
|
}
|
|
3209
3490
|
};
|
|
3210
3491
|
}
|
|
3211
|
-
/**
|
|
3212
|
-
* A convenience function that applies a config and ensures whatever was passed is set properly
|
|
3213
|
-
*/
|
|
3214
|
-
getInstance(config, req) {
|
|
3215
|
-
const _config = { ...this.#config, ...config };
|
|
3216
|
-
const updatedConfig = new Config(_config);
|
|
3217
|
-
this.#config = new Config(updatedConfig);
|
|
3218
|
-
this.#config.tenantId = config.tenantId;
|
|
3219
|
-
this.#config.userId = config.userId;
|
|
3220
|
-
if (req) {
|
|
3221
|
-
this.setContext(req);
|
|
3222
|
-
}
|
|
3223
|
-
this.#reset();
|
|
3224
|
-
return this;
|
|
3225
|
-
}
|
|
3226
3492
|
get handlers() {
|
|
3227
3493
|
return this.#handlers;
|
|
3228
3494
|
}
|
|
@@ -3232,98 +3498,30 @@ var Server = class {
|
|
|
3232
3498
|
set paths(paths) {
|
|
3233
3499
|
this.#config.paths = paths;
|
|
3234
3500
|
}
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
*/
|
|
3242
|
-
setContext = (req, ...remaining) => {
|
|
3243
|
-
let ok = false;
|
|
3244
|
-
if (req && typeof req === "object" && "tenantId" in req) {
|
|
3245
|
-
ok = true;
|
|
3246
|
-
this.#config.tenantId = req.tenantId;
|
|
3247
|
-
}
|
|
3248
|
-
if (req && typeof req === "object" && "userId" in req) {
|
|
3249
|
-
ok = true;
|
|
3250
|
-
this.#config.userId = req.userId;
|
|
3251
|
-
}
|
|
3252
|
-
if (req && typeof req === "object" && "preserveHeaders" in req) {
|
|
3253
|
-
ok = true;
|
|
3254
|
-
this.#preserveHeaders = Boolean(req.preserveHeaders);
|
|
3255
|
-
}
|
|
3256
|
-
let atLeastOne = false;
|
|
3257
|
-
if (this.#config?.extensions) {
|
|
3258
|
-
for (const create2 of this.#config.extensions) {
|
|
3259
|
-
if (typeof create2 !== "function") {
|
|
3260
|
-
continue;
|
|
3261
|
-
}
|
|
3262
|
-
const ext = create2(this);
|
|
3263
|
-
if (typeof ext.onSetContext === "function") {
|
|
3264
|
-
if (req) {
|
|
3265
|
-
ext.onSetContext(req, ...remaining);
|
|
3266
|
-
atLeastOne = true;
|
|
3267
|
-
} else {
|
|
3268
|
-
this.#config.logger("extension").warn("attempted to call onSetContext without a value");
|
|
3269
|
-
}
|
|
3270
|
-
}
|
|
3271
|
-
}
|
|
3272
|
-
}
|
|
3273
|
-
if (atLeastOne) {
|
|
3274
|
-
return;
|
|
3275
|
-
}
|
|
3276
|
-
try {
|
|
3277
|
-
if (req instanceof Headers) {
|
|
3278
|
-
this.#handleHeaders(req);
|
|
3279
|
-
this.#reset();
|
|
3280
|
-
return;
|
|
3281
|
-
} else if (req instanceof Request) {
|
|
3282
|
-
this.#handleHeaders(new Headers(req.headers));
|
|
3283
|
-
this.#reset();
|
|
3284
|
-
return;
|
|
3285
|
-
}
|
|
3286
|
-
} catch {
|
|
3501
|
+
async withContext(context, fn) {
|
|
3502
|
+
const { ddl, ...ctx2 } = context ?? defaultContext;
|
|
3503
|
+
this.#config.context = { ...ctx2 };
|
|
3504
|
+
const preserve = (context && "preserveHeaders" in context && context.preserveHeaders) ?? true;
|
|
3505
|
+
if (preserve) {
|
|
3506
|
+
this.#config.context = { ...this.getContext(), ...context };
|
|
3287
3507
|
}
|
|
3288
|
-
if (
|
|
3289
|
-
|
|
3508
|
+
if (ddl) {
|
|
3509
|
+
delete this.#config.context.tenantId;
|
|
3510
|
+
delete this.#config.context.userId;
|
|
3290
3511
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
if (headers) {
|
|
3295
|
-
this.#handleHeaders(headers);
|
|
3296
|
-
this.#reset();
|
|
3297
|
-
return;
|
|
3298
|
-
}
|
|
3299
|
-
} catch {
|
|
3512
|
+
return withNileContext(this.#config, async () => {
|
|
3513
|
+
if (fn) {
|
|
3514
|
+
return fn(this);
|
|
3300
3515
|
}
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
};
|
|
3516
|
+
return this;
|
|
3517
|
+
});
|
|
3518
|
+
}
|
|
3519
|
+
/**
|
|
3520
|
+
*
|
|
3521
|
+
* @returns the last used (basically global) context object, useful for debugging or making your own context
|
|
3522
|
+
*/
|
|
3309
3523
|
getContext() {
|
|
3310
|
-
|
|
3311
|
-
for (const create2 of this.#config.extensions) {
|
|
3312
|
-
if (typeof create2 !== "function") {
|
|
3313
|
-
continue;
|
|
3314
|
-
}
|
|
3315
|
-
const ext = create2(this);
|
|
3316
|
-
if (typeof ext.onGetContext === "function") {
|
|
3317
|
-
return ext.onGetContext();
|
|
3318
|
-
}
|
|
3319
|
-
}
|
|
3320
|
-
}
|
|
3321
|
-
return {
|
|
3322
|
-
headers: this.#headers,
|
|
3323
|
-
userId: this.#config?.userId,
|
|
3324
|
-
tenantId: this.#config?.tenantId,
|
|
3325
|
-
preserveHeaders: this.#preserveHeaders
|
|
3326
|
-
};
|
|
3524
|
+
return ctx.getLastUsed();
|
|
3327
3525
|
}
|
|
3328
3526
|
/**
|
|
3329
3527
|
* Merge headers together
|
|
@@ -3332,16 +3530,19 @@ var Server = class {
|
|
|
3332
3530
|
#handleHeaders(config) {
|
|
3333
3531
|
const updates = [];
|
|
3334
3532
|
let headers;
|
|
3335
|
-
this.#headers = new Headers();
|
|
3533
|
+
this.#config.context.headers = new Headers();
|
|
3336
3534
|
if (config instanceof Headers) {
|
|
3337
3535
|
headers = config;
|
|
3338
3536
|
} else if (config?.headers) {
|
|
3339
3537
|
headers = config?.headers;
|
|
3340
3538
|
if (config && config.origin) {
|
|
3341
|
-
this.#headers.set(HEADER_ORIGIN, config.origin);
|
|
3539
|
+
this.#config.context.headers.set(HEADER_ORIGIN, config.origin);
|
|
3342
3540
|
}
|
|
3343
3541
|
if (config && config.secureCookies != null) {
|
|
3344
|
-
this.#headers.set(
|
|
3542
|
+
this.#config.context.headers.set(
|
|
3543
|
+
HEADER_SECURE_COOKIES,
|
|
3544
|
+
String(config.secureCookies)
|
|
3545
|
+
);
|
|
3345
3546
|
}
|
|
3346
3547
|
}
|
|
3347
3548
|
if (headers instanceof Headers) {
|
|
@@ -3354,8 +3555,7 @@ var Server = class {
|
|
|
3354
3555
|
}
|
|
3355
3556
|
}
|
|
3356
3557
|
const merged = {};
|
|
3357
|
-
this.#config.
|
|
3358
|
-
this.#headers?.forEach((value, key17) => {
|
|
3558
|
+
this.#config.context.headers?.forEach((value, key17) => {
|
|
3359
3559
|
if (key17.toLowerCase() !== "cookie") {
|
|
3360
3560
|
merged[key17.toLowerCase()] = value;
|
|
3361
3561
|
}
|
|
@@ -3364,16 +3564,14 @@ var Server = class {
|
|
|
3364
3564
|
merged[key17] = value;
|
|
3365
3565
|
}
|
|
3366
3566
|
for (const [key17, value] of Object.entries(merged)) {
|
|
3367
|
-
this.#headers.set(key17, value);
|
|
3567
|
+
this.#config.context.headers.set(key17, value);
|
|
3368
3568
|
}
|
|
3369
3569
|
this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
|
|
3370
|
-
this.#config.headers = this.#headers;
|
|
3371
3570
|
}
|
|
3372
3571
|
/**
|
|
3373
3572
|
* Allow some internal mutations to reset our config + headers
|
|
3374
3573
|
*/
|
|
3375
3574
|
#reset = () => {
|
|
3376
|
-
this.#config.headers = this.#headers ?? new Headers();
|
|
3377
3575
|
this.#config.extensionCtx = buildExtensionConfig(this);
|
|
3378
3576
|
this.users = new Users(this.#config);
|
|
3379
3577
|
this.tenants = new Tenants(this.#config);
|
|
@@ -3400,6 +3598,7 @@ exports.USER_COOKIE = USER_COOKIE;
|
|
|
3400
3598
|
exports.parseCSRF = parseCSRF;
|
|
3401
3599
|
exports.parseCallback = parseCallback;
|
|
3402
3600
|
exports.parseResetToken = parseResetToken;
|
|
3601
|
+
exports.parseTenantId = parseTenantId;
|
|
3403
3602
|
exports.parseToken = parseToken;
|
|
3404
3603
|
//# sourceMappingURL=index.js.map
|
|
3405
3604
|
//# sourceMappingURL=index.js.map
|