@niledatabase/server 5.0.0-alpha.26 → 5.0.0-alpha.27
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 +1123 -949
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1123 -950
- 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,290 @@ 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 [k, v] of new Headers(partial.headers).entries()) {
|
|
481
|
+
store.headers.set(k, v);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if ("tenantId" in partial)
|
|
485
|
+
store.tenantId = partial.tenantId ?? store.tenantId;
|
|
486
|
+
if ("userId" in partial) store.userId = partial.userId ?? store.userId;
|
|
487
|
+
if ("preserveHeaders" in partial)
|
|
488
|
+
store.preserveHeaders = Boolean(partial.preserveHeaders);
|
|
489
|
+
silly(`[SET] ${serializeContext(store)}`);
|
|
490
|
+
lastUsedContext = { ...store };
|
|
491
|
+
},
|
|
492
|
+
// for convenience only
|
|
493
|
+
getLastUsed: () => lastUsedContext
|
|
494
|
+
};
|
|
495
|
+
function withNileContext(config, fn, name = "unknown") {
|
|
496
|
+
const initialContext = config.context;
|
|
497
|
+
const existing = ctx.get();
|
|
498
|
+
const mergedHeaders = new Headers(existing.headers);
|
|
499
|
+
if (initialContext instanceof Request) {
|
|
500
|
+
initialContext.headers.forEach((value, key17) => {
|
|
501
|
+
mergedHeaders.set(key17, value);
|
|
502
|
+
});
|
|
503
|
+
const context2 = {
|
|
504
|
+
headers: mergedHeaders,
|
|
505
|
+
tenantId: existing.tenantId,
|
|
506
|
+
userId: existing.userId,
|
|
507
|
+
preserveHeaders: existing.preserveHeaders ?? false
|
|
508
|
+
};
|
|
509
|
+
silly(`${name} [INITIAL - Request] ${serializeContext(context2)}`);
|
|
510
|
+
return ctx.run(context2, fn);
|
|
511
|
+
}
|
|
512
|
+
if (initialContext.headers) {
|
|
513
|
+
const incoming = initialContext.headers instanceof Headers ? initialContext.headers : new Headers(initialContext.headers);
|
|
514
|
+
incoming.forEach((value, key17) => {
|
|
515
|
+
mergedHeaders.set(key17, value);
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
const tenantId = "tenantId" in initialContext && initialContext.tenantId;
|
|
519
|
+
const userId = "userId" in initialContext && initialContext.userId;
|
|
520
|
+
const preserveHeaders = "preserveHeaders" in initialContext && initialContext.preserveHeaders;
|
|
521
|
+
const context = {
|
|
522
|
+
headers: mergedHeaders,
|
|
523
|
+
tenantId: tenantId ? tenantId : existing.tenantId,
|
|
524
|
+
userId: userId ? userId : existing.userId,
|
|
525
|
+
preserveHeaders: preserveHeaders ? preserveHeaders : existing.preserveHeaders ?? false
|
|
526
|
+
};
|
|
527
|
+
silly(`${name} [INITIAL - Partial<Context>] ${serializeContext(context)}`);
|
|
528
|
+
return ctx.run(context, async () => {
|
|
529
|
+
await runExtensionContext(config);
|
|
530
|
+
return fn();
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
function serializeContext(context) {
|
|
534
|
+
const headers = {};
|
|
535
|
+
const rawHeaders = new Headers(context.headers);
|
|
536
|
+
rawHeaders.forEach((value, key17) => {
|
|
537
|
+
headers[key17] = value;
|
|
538
|
+
});
|
|
539
|
+
return JSON.stringify({
|
|
540
|
+
headers,
|
|
541
|
+
tenantId: context.tenantId,
|
|
542
|
+
userId: context.userId,
|
|
543
|
+
preserveHeaders: context.preserveHeaders
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
268
547
|
// src/api/routes/me/index.ts
|
|
269
548
|
var key = "ME";
|
|
270
549
|
async function route(request2, config) {
|
|
271
|
-
const url = apiRoutes(config)[key];
|
|
550
|
+
const url = apiRoutes(config.apiUrl)[key];
|
|
272
551
|
if (request2.method === "GET") {
|
|
273
552
|
return await GET(url, { request: request2 }, config);
|
|
274
553
|
}
|
|
@@ -289,8 +568,9 @@ function matches(configRoutes, request2) {
|
|
|
289
568
|
}
|
|
290
569
|
async function fetchMe(config, method, body) {
|
|
291
570
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
|
|
571
|
+
const { headers } = ctx.get();
|
|
292
572
|
const init = {
|
|
293
|
-
headers
|
|
573
|
+
headers,
|
|
294
574
|
method: method ?? "GET"
|
|
295
575
|
};
|
|
296
576
|
if (method === "PUT") {
|
|
@@ -342,9 +622,9 @@ function getTokenFromCookie(headers, cookieKey) {
|
|
|
342
622
|
return _cookies[cookieKey];
|
|
343
623
|
}
|
|
344
624
|
}
|
|
345
|
-
function getTenantFromHttp(headers,
|
|
625
|
+
function getTenantFromHttp(headers, context) {
|
|
346
626
|
const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
|
|
347
|
-
return cookieTenant ? cookieTenant :
|
|
627
|
+
return cookieTenant ? cookieTenant : context?.tenantId;
|
|
348
628
|
}
|
|
349
629
|
|
|
350
630
|
// src/api/routes/users/POST.ts
|
|
@@ -354,8 +634,11 @@ async function POST(config, init) {
|
|
|
354
634
|
const yurl = new URL(init.request.url);
|
|
355
635
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
356
636
|
const newTenantName = yurl.searchParams.get("newTenantName");
|
|
357
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers
|
|
358
|
-
const url = apiRoutes(config).USERS({
|
|
637
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
638
|
+
const url = apiRoutes(config.apiUrl).USERS({
|
|
639
|
+
tenantId: tenant,
|
|
640
|
+
newTenantName
|
|
641
|
+
});
|
|
359
642
|
return await request(url, init, config);
|
|
360
643
|
}
|
|
361
644
|
|
|
@@ -363,13 +646,13 @@ async function POST(config, init) {
|
|
|
363
646
|
async function GET2(config, init, log) {
|
|
364
647
|
const yurl = new URL(init.request.url);
|
|
365
648
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
366
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
|
|
649
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config.context);
|
|
367
650
|
if (!tenant) {
|
|
368
651
|
log("[GET] No tenant id provided.");
|
|
369
652
|
return new Response(null, { status: 404 });
|
|
370
653
|
}
|
|
371
654
|
init.method = "GET";
|
|
372
|
-
const url = apiRoutes(config).TENANT_USERS(tenant);
|
|
655
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenant);
|
|
373
656
|
return await request(url, init, config);
|
|
374
657
|
}
|
|
375
658
|
|
|
@@ -378,7 +661,7 @@ async function PUT2(config, init) {
|
|
|
378
661
|
init.body = init.request.body;
|
|
379
662
|
init.method = "PUT";
|
|
380
663
|
const [userId] = new URL(init.request.url).pathname.split("/").reverse();
|
|
381
|
-
const url = apiRoutes(config).USER(userId);
|
|
664
|
+
const url = apiRoutes(config.apiUrl).USER(userId);
|
|
382
665
|
return await request(url, init, config);
|
|
383
666
|
}
|
|
384
667
|
|
|
@@ -405,7 +688,7 @@ function matches2(configRoutes, request2) {
|
|
|
405
688
|
async function GET3(config, init) {
|
|
406
689
|
const yurl = new URL(init.request.url);
|
|
407
690
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
408
|
-
const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
|
|
691
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USERS(tenantId)}`;
|
|
409
692
|
return await request(url, init, config);
|
|
410
693
|
}
|
|
411
694
|
|
|
@@ -419,7 +702,7 @@ async function POST2(config, init) {
|
|
|
419
702
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
420
703
|
init.body = JSON.stringify({ email: session.email });
|
|
421
704
|
init.method = "POST";
|
|
422
|
-
const url = apiRoutes(config).TENANT_USERS(tenantId);
|
|
705
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenantId);
|
|
423
706
|
return await request(url, init, config);
|
|
424
707
|
}
|
|
425
708
|
|
|
@@ -453,12 +736,13 @@ function matches3(configRoutes, request2) {
|
|
|
453
736
|
}
|
|
454
737
|
async function fetchTenantUsers(config, method, payload) {
|
|
455
738
|
const { body, params } = {};
|
|
456
|
-
|
|
739
|
+
const { tenantId, headers } = ctx.get();
|
|
740
|
+
if (!tenantId) {
|
|
457
741
|
throw new Error(
|
|
458
742
|
"Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
459
743
|
);
|
|
460
744
|
}
|
|
461
|
-
if (!isUUID(
|
|
745
|
+
if (!isUUID(tenantId)) {
|
|
462
746
|
config.logger("fetchTenantUsers").warn(
|
|
463
747
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
464
748
|
);
|
|
@@ -470,14 +754,11 @@ async function fetchTenantUsers(config, method, payload) {
|
|
|
470
754
|
if (params?.tenantId) {
|
|
471
755
|
q.set("tenantId", params.tenantId);
|
|
472
756
|
}
|
|
473
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
|
|
474
|
-
"{tenantId}",
|
|
475
|
-
config.tenantId
|
|
476
|
-
)}`;
|
|
757
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace("{tenantId}", tenantId)}`;
|
|
477
758
|
const m = method;
|
|
478
759
|
const init = {
|
|
479
760
|
method: m,
|
|
480
|
-
headers
|
|
761
|
+
headers
|
|
481
762
|
};
|
|
482
763
|
const req = new Request(clientUrl, init);
|
|
483
764
|
return await config.handlers[m](req);
|
|
@@ -494,7 +775,7 @@ async function PUT3(config, init) {
|
|
|
494
775
|
init.body = new URLSearchParams(yurl.searchParams).toString();
|
|
495
776
|
}
|
|
496
777
|
init.method = "PUT";
|
|
497
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
778
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
498
779
|
const res = await request(url, init, config);
|
|
499
780
|
const location = res?.headers?.get("location");
|
|
500
781
|
if (location) {
|
|
@@ -518,7 +799,7 @@ async function POST3(config, init) {
|
|
|
518
799
|
}
|
|
519
800
|
init.method = "POST";
|
|
520
801
|
init.body = init.request.body;
|
|
521
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
802
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
522
803
|
return await request(url, init, config);
|
|
523
804
|
}
|
|
524
805
|
|
|
@@ -544,21 +825,22 @@ function matches4(configRoutes, request2) {
|
|
|
544
825
|
return urlMatches(request2.url, route20);
|
|
545
826
|
}
|
|
546
827
|
async function fetchInvite(config, method, body) {
|
|
547
|
-
|
|
828
|
+
const { headers, tenantId } = ctx.get();
|
|
829
|
+
if (!tenantId) {
|
|
548
830
|
throw new Error(
|
|
549
831
|
"Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
550
832
|
);
|
|
551
833
|
}
|
|
552
|
-
if (!isUUID(
|
|
834
|
+
if (!isUUID(tenantId)) {
|
|
553
835
|
config.logger("fetchInvite").warn(
|
|
554
836
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
555
837
|
);
|
|
556
838
|
}
|
|
557
|
-
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}",
|
|
839
|
+
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", tenantId)}`;
|
|
558
840
|
const m = method ?? "GET";
|
|
559
841
|
const init = {
|
|
560
842
|
method: m,
|
|
561
|
-
headers
|
|
843
|
+
headers
|
|
562
844
|
};
|
|
563
845
|
if (method === "POST" || method === "PUT") {
|
|
564
846
|
init.body = body;
|
|
@@ -578,7 +860,7 @@ async function GET4(config, init) {
|
|
|
578
860
|
return new Response(null, { status: 404 });
|
|
579
861
|
}
|
|
580
862
|
init.method = "GET";
|
|
581
|
-
const url = `${apiRoutes(config).INVITES(tenantId)}`;
|
|
863
|
+
const url = `${apiRoutes(config.apiUrl).INVITES(tenantId)}`;
|
|
582
864
|
return await request(url, init, config);
|
|
583
865
|
}
|
|
584
866
|
|
|
@@ -599,29 +881,29 @@ function matches5(configRoutes, request2) {
|
|
|
599
881
|
return url.pathname.endsWith(route20);
|
|
600
882
|
}
|
|
601
883
|
async function fetchInvites(config) {
|
|
602
|
-
|
|
884
|
+
const { tenantId, headers } = ctx.get();
|
|
885
|
+
if (!tenantId) {
|
|
603
886
|
throw new Error(
|
|
604
887
|
"Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
605
888
|
);
|
|
606
889
|
}
|
|
607
|
-
if (!isUUID(
|
|
890
|
+
if (!isUUID(tenantId)) {
|
|
608
891
|
config.logger("fetchInvites").warn(
|
|
609
892
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
610
893
|
);
|
|
611
894
|
}
|
|
612
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}",
|
|
613
|
-
const req = new Request(clientUrl, { headers
|
|
895
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", tenantId)}`;
|
|
896
|
+
const req = new Request(clientUrl, { headers });
|
|
614
897
|
return await config.handlers.GET(req);
|
|
615
898
|
}
|
|
616
899
|
|
|
617
900
|
// src/api/routes/tenants/GET.ts
|
|
618
901
|
async function GET5(config, session, init) {
|
|
619
|
-
let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
|
|
902
|
+
let url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.id)}`;
|
|
620
903
|
if (typeof session === "object" && "user" in session && session.user) {
|
|
621
|
-
url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
|
|
904
|
+
url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.user.id)}`;
|
|
622
905
|
}
|
|
623
|
-
|
|
624
|
-
return res;
|
|
906
|
+
return await request(url, init, config);
|
|
625
907
|
}
|
|
626
908
|
|
|
627
909
|
// src/api/routes/tenants/[tenantId]/GET.ts
|
|
@@ -633,7 +915,7 @@ async function GET6(config, init, log) {
|
|
|
633
915
|
return new Response(null, { status: 404 });
|
|
634
916
|
}
|
|
635
917
|
init.method = "GET";
|
|
636
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
918
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
637
919
|
return await request(url, init, config);
|
|
638
920
|
}
|
|
639
921
|
|
|
@@ -645,7 +927,7 @@ async function DELETE2(config, init) {
|
|
|
645
927
|
return new Response(null, { status: 404 });
|
|
646
928
|
}
|
|
647
929
|
init.method = "DELETE";
|
|
648
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
930
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
649
931
|
return await request(url, init, config);
|
|
650
932
|
}
|
|
651
933
|
|
|
@@ -658,7 +940,7 @@ async function PUT4(config, init) {
|
|
|
658
940
|
}
|
|
659
941
|
init.body = init.request.body;
|
|
660
942
|
init.method = "PUT";
|
|
661
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
943
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
662
944
|
return await request(url, init, config);
|
|
663
945
|
}
|
|
664
946
|
|
|
@@ -666,7 +948,7 @@ async function PUT4(config, init) {
|
|
|
666
948
|
async function POST4(config, init) {
|
|
667
949
|
init.body = init.request.body;
|
|
668
950
|
init.method = "POST";
|
|
669
|
-
const url = `${apiRoutes(config).TENANTS}`;
|
|
951
|
+
const url = `${apiRoutes(config.apiUrl).TENANTS}`;
|
|
670
952
|
return await request(url, init, config);
|
|
671
953
|
}
|
|
672
954
|
|
|
@@ -700,10 +982,11 @@ function matches6(configRoutes, request2) {
|
|
|
700
982
|
return urlMatches(request2.url, configRoutes[key6]);
|
|
701
983
|
}
|
|
702
984
|
async function fetchTenants(config, method, body) {
|
|
985
|
+
const { headers } = ctx.get();
|
|
703
986
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
704
987
|
const init = {
|
|
705
988
|
method,
|
|
706
|
-
headers
|
|
989
|
+
headers
|
|
707
990
|
};
|
|
708
991
|
{
|
|
709
992
|
init.body = body;
|
|
@@ -712,21 +995,22 @@ async function fetchTenants(config, method, body) {
|
|
|
712
995
|
return await config.handlers.POST(req);
|
|
713
996
|
}
|
|
714
997
|
async function fetchTenant(config, method, body) {
|
|
715
|
-
|
|
998
|
+
const { headers, tenantId } = ctx.get();
|
|
999
|
+
if (!tenantId) {
|
|
716
1000
|
throw new Error(
|
|
717
1001
|
"Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
718
1002
|
);
|
|
719
1003
|
}
|
|
720
|
-
if (!isUUID(
|
|
1004
|
+
if (!isUUID(tenantId)) {
|
|
721
1005
|
config.logger("fetch tenant").warn(
|
|
722
1006
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
723
1007
|
);
|
|
724
1008
|
}
|
|
725
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}",
|
|
1009
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", tenantId)}`;
|
|
726
1010
|
const m = method ?? "GET";
|
|
727
1011
|
const init = {
|
|
728
1012
|
method: m,
|
|
729
|
-
headers
|
|
1013
|
+
headers
|
|
730
1014
|
};
|
|
731
1015
|
if (m === "PUT") {
|
|
732
1016
|
init.body = body;
|
|
@@ -735,32 +1019,33 @@ async function fetchTenant(config, method, body) {
|
|
|
735
1019
|
return await config.handlers[m](req);
|
|
736
1020
|
}
|
|
737
1021
|
async function fetchTenantsByUser(config) {
|
|
738
|
-
const { warn } = config.logger("fetchTenantsByUser");
|
|
739
|
-
|
|
740
|
-
|
|
1022
|
+
const { warn: warn2 } = config.logger(" fetchTenantsByUser ");
|
|
1023
|
+
const { userId, headers } = ctx.get();
|
|
1024
|
+
if (!userId) {
|
|
1025
|
+
warn2(
|
|
741
1026
|
"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
1027
|
);
|
|
743
|
-
} else if (!isUUID(
|
|
744
|
-
|
|
1028
|
+
} else if (!isUUID(userId)) {
|
|
1029
|
+
warn2(
|
|
745
1030
|
"nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
746
1031
|
);
|
|
747
1032
|
}
|
|
748
1033
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
749
|
-
const req = new Request(clientUrl, { headers
|
|
1034
|
+
const req = new Request(clientUrl, { headers });
|
|
750
1035
|
return await config.handlers.GET(req);
|
|
751
1036
|
}
|
|
752
1037
|
|
|
753
1038
|
// src/api/routes/auth/signin.ts
|
|
754
1039
|
var key7 = "SIGNIN";
|
|
755
1040
|
async function route7(req, config) {
|
|
756
|
-
let url = proxyRoutes(config)[key7];
|
|
1041
|
+
let url = proxyRoutes(config.apiUrl)[key7];
|
|
757
1042
|
const init = {
|
|
758
1043
|
method: req.method,
|
|
759
1044
|
headers: req.headers
|
|
760
1045
|
};
|
|
761
1046
|
if (req.method === "POST") {
|
|
762
1047
|
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
763
|
-
url = `${proxyRoutes(config)[key7]}/${provider}`;
|
|
1048
|
+
url = `${proxyRoutes(config.apiUrl)[key7]}/${provider}`;
|
|
764
1049
|
}
|
|
765
1050
|
const passThroughUrl = new URL(req.url);
|
|
766
1051
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
@@ -773,10 +1058,11 @@ function matches7(configRoutes, request2) {
|
|
|
773
1058
|
}
|
|
774
1059
|
async function fetchSignIn(config, provider, body) {
|
|
775
1060
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
|
|
1061
|
+
const { headers } = ctx.get();
|
|
776
1062
|
const req = new Request(clientUrl, {
|
|
777
1063
|
method: "POST",
|
|
778
|
-
|
|
779
|
-
|
|
1064
|
+
body,
|
|
1065
|
+
headers
|
|
780
1066
|
});
|
|
781
1067
|
return await config.handlers.POST(req);
|
|
782
1068
|
}
|
|
@@ -784,7 +1070,7 @@ async function fetchSignIn(config, provider, body) {
|
|
|
784
1070
|
// src/api/routes/auth/session.ts
|
|
785
1071
|
async function route8(req, config) {
|
|
786
1072
|
return request(
|
|
787
|
-
proxyRoutes(config).SESSION,
|
|
1073
|
+
proxyRoutes(config.apiUrl).SESSION,
|
|
788
1074
|
{
|
|
789
1075
|
method: req.method,
|
|
790
1076
|
request: req
|
|
@@ -797,9 +1083,10 @@ function matches8(configRoutes, request2) {
|
|
|
797
1083
|
}
|
|
798
1084
|
async function fetchSession(config) {
|
|
799
1085
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
|
|
1086
|
+
const { headers } = ctx.get();
|
|
800
1087
|
const req = new Request(clientUrl, {
|
|
801
1088
|
method: "GET",
|
|
802
|
-
headers
|
|
1089
|
+
headers
|
|
803
1090
|
});
|
|
804
1091
|
return await config.handlers.GET(req);
|
|
805
1092
|
}
|
|
@@ -807,7 +1094,7 @@ async function fetchSession(config) {
|
|
|
807
1094
|
// src/api/routes/auth/providers.ts
|
|
808
1095
|
async function route9(req, config) {
|
|
809
1096
|
return request(
|
|
810
|
-
proxyRoutes(config).PROVIDERS,
|
|
1097
|
+
proxyRoutes(config.apiUrl).PROVIDERS,
|
|
811
1098
|
{
|
|
812
1099
|
method: req.method,
|
|
813
1100
|
request: req
|
|
@@ -820,9 +1107,10 @@ function matches9(configRoutes, request2) {
|
|
|
820
1107
|
}
|
|
821
1108
|
async function fetchProviders(config) {
|
|
822
1109
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
|
|
1110
|
+
const { headers } = ctx.get();
|
|
823
1111
|
const req = new Request(clientUrl, {
|
|
824
1112
|
method: "GET",
|
|
825
|
-
headers
|
|
1113
|
+
headers
|
|
826
1114
|
});
|
|
827
1115
|
return await config.handlers.GET(req);
|
|
828
1116
|
}
|
|
@@ -830,7 +1118,7 @@ async function fetchProviders(config) {
|
|
|
830
1118
|
// src/api/routes/auth/csrf.ts
|
|
831
1119
|
async function route10(req, config) {
|
|
832
1120
|
return request(
|
|
833
|
-
proxyRoutes(config).CSRF,
|
|
1121
|
+
proxyRoutes(config.apiUrl).CSRF,
|
|
834
1122
|
{
|
|
835
1123
|
method: req.method,
|
|
836
1124
|
request: req
|
|
@@ -843,9 +1131,10 @@ function matches10(configRoutes, request2) {
|
|
|
843
1131
|
}
|
|
844
1132
|
async function fetchCsrf(config) {
|
|
845
1133
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
|
|
1134
|
+
const { headers } = ctx.get();
|
|
846
1135
|
const req = new Request(clientUrl, {
|
|
847
1136
|
method: "GET",
|
|
848
|
-
headers
|
|
1137
|
+
headers
|
|
849
1138
|
});
|
|
850
1139
|
return await config.handlers.GET(req);
|
|
851
1140
|
}
|
|
@@ -858,7 +1147,7 @@ async function route11(req, config) {
|
|
|
858
1147
|
try {
|
|
859
1148
|
const passThroughUrl = new URL(req.url);
|
|
860
1149
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
861
|
-
const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
1150
|
+
const url = `${proxyRoutes(config.apiUrl)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
862
1151
|
const res = await request(
|
|
863
1152
|
url,
|
|
864
1153
|
{
|
|
@@ -889,10 +1178,11 @@ function matches11(configRoutes, request2) {
|
|
|
889
1178
|
return urlMatches(request2.url, configRoutes.CALLBACK);
|
|
890
1179
|
}
|
|
891
1180
|
async function fetchCallback(config, provider, body, request2, method = "POST") {
|
|
1181
|
+
const { headers } = ctx.get();
|
|
892
1182
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
|
|
893
1183
|
const req = new Request(clientUrl, {
|
|
894
1184
|
method,
|
|
895
|
-
headers
|
|
1185
|
+
headers,
|
|
896
1186
|
body
|
|
897
1187
|
});
|
|
898
1188
|
return await config.handlers.POST(req);
|
|
@@ -901,14 +1191,14 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
|
|
|
901
1191
|
// src/api/routes/auth/signout.ts
|
|
902
1192
|
var key9 = "SIGNOUT";
|
|
903
1193
|
async function route12(request2, config) {
|
|
904
|
-
let url = proxyRoutes(config)[key9];
|
|
1194
|
+
let url = proxyRoutes(config.apiUrl)[key9];
|
|
905
1195
|
const init = {
|
|
906
1196
|
method: request2.method
|
|
907
1197
|
};
|
|
908
1198
|
if (request2.method === "POST") {
|
|
909
1199
|
init.body = request2.body;
|
|
910
1200
|
const [provider] = new URL(request2.url).pathname.split("/").reverse();
|
|
911
|
-
url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
1201
|
+
url = `${proxyRoutes(config.apiUrl)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
912
1202
|
}
|
|
913
1203
|
const res = await request(url, { ...init, request: request2 }, config);
|
|
914
1204
|
return res;
|
|
@@ -918,10 +1208,11 @@ function matches12(configRoutes, request2) {
|
|
|
918
1208
|
}
|
|
919
1209
|
async function fetchSignOut(config, body) {
|
|
920
1210
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
|
|
1211
|
+
const { headers } = ctx.get();
|
|
921
1212
|
const req = new Request(clientUrl, {
|
|
922
1213
|
method: "POST",
|
|
923
1214
|
body,
|
|
924
|
-
headers
|
|
1215
|
+
headers
|
|
925
1216
|
});
|
|
926
1217
|
return await config.handlers.POST(req);
|
|
927
1218
|
}
|
|
@@ -930,7 +1221,7 @@ async function fetchSignOut(config, body) {
|
|
|
930
1221
|
var key10 = "ERROR";
|
|
931
1222
|
async function route13(req, config) {
|
|
932
1223
|
return request(
|
|
933
|
-
proxyRoutes(config)[key10],
|
|
1224
|
+
proxyRoutes(config.apiUrl)[key10],
|
|
934
1225
|
{
|
|
935
1226
|
method: req.method,
|
|
936
1227
|
request: req
|
|
@@ -946,7 +1237,7 @@ function matches13(configRoutes, request2) {
|
|
|
946
1237
|
var key11 = "VERIFY_REQUEST";
|
|
947
1238
|
async function route14(req, config) {
|
|
948
1239
|
return request(
|
|
949
|
-
proxyRoutes(config)[key11],
|
|
1240
|
+
proxyRoutes(config.apiUrl)[key11],
|
|
950
1241
|
{
|
|
951
1242
|
method: req.method,
|
|
952
1243
|
request: req
|
|
@@ -961,7 +1252,7 @@ function matches14(configRoutes, request2) {
|
|
|
961
1252
|
// src/api/routes/auth/password-reset.ts
|
|
962
1253
|
var key12 = "PASSWORD_RESET";
|
|
963
1254
|
async function route15(req, config) {
|
|
964
|
-
const url = proxyRoutes(config)[key12];
|
|
1255
|
+
const url = proxyRoutes(config.apiUrl)[key12];
|
|
965
1256
|
const res = await request(
|
|
966
1257
|
url,
|
|
967
1258
|
{
|
|
@@ -990,10 +1281,11 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
990
1281
|
if (useJson) {
|
|
991
1282
|
authParams?.set("json", "true");
|
|
992
1283
|
}
|
|
1284
|
+
const { headers } = ctx.get();
|
|
993
1285
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
|
|
994
1286
|
const init = {
|
|
995
1287
|
method,
|
|
996
|
-
headers
|
|
1288
|
+
headers
|
|
997
1289
|
};
|
|
998
1290
|
if (body && method !== "GET") {
|
|
999
1291
|
init.body = body;
|
|
@@ -1005,7 +1297,7 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
1005
1297
|
// src/api/routes/auth/verify-email.ts
|
|
1006
1298
|
var key13 = "VERIFY_EMAIL";
|
|
1007
1299
|
async function route16(req, config) {
|
|
1008
|
-
const url = proxyRoutes(config)[key13];
|
|
1300
|
+
const url = proxyRoutes(config.apiUrl)[key13];
|
|
1009
1301
|
const res = await request(
|
|
1010
1302
|
url,
|
|
1011
1303
|
{
|
|
@@ -1031,9 +1323,10 @@ function matches16(configRoutes, request2) {
|
|
|
1031
1323
|
}
|
|
1032
1324
|
async function fetchVerifyEmail(config, method, body) {
|
|
1033
1325
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
|
|
1326
|
+
const { headers } = ctx.get();
|
|
1034
1327
|
const init = {
|
|
1035
1328
|
method,
|
|
1036
|
-
headers
|
|
1329
|
+
headers
|
|
1037
1330
|
};
|
|
1038
1331
|
if (body) {
|
|
1039
1332
|
init.body = body;
|
|
@@ -1044,7 +1337,7 @@ async function fetchVerifyEmail(config, method, body) {
|
|
|
1044
1337
|
|
|
1045
1338
|
// src/api/handlers/GET.ts
|
|
1046
1339
|
function GETTER(configRoutes, config) {
|
|
1047
|
-
const { error, info, warn } = config.logger("[GET MATCHER]");
|
|
1340
|
+
const { error, info, warn: warn2 } = config.logger("[GET MATCHER]");
|
|
1048
1341
|
return async function GET7(...params) {
|
|
1049
1342
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1050
1343
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1123,78 +1416,16 @@ function GETTER(configRoutes, config) {
|
|
|
1123
1416
|
info("matches error");
|
|
1124
1417
|
return route13(req, config);
|
|
1125
1418
|
}
|
|
1126
|
-
|
|
1419
|
+
warn2(`No GET routes matched ${req.url}`);
|
|
1127
1420
|
return new Response(null, { status: 404 });
|
|
1128
1421
|
};
|
|
1129
1422
|
}
|
|
1130
1423
|
|
|
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
1424
|
// src/api/routes/signup/POST.ts
|
|
1194
1425
|
async function POST5(config, init) {
|
|
1195
1426
|
init.body = init.request.body;
|
|
1196
1427
|
init.method = "POST";
|
|
1197
|
-
const url = `${apiRoutes(config).SIGNUP}`;
|
|
1428
|
+
const url = `${apiRoutes(config.apiUrl).SIGNUP}`;
|
|
1198
1429
|
return await request(url, init, config);
|
|
1199
1430
|
}
|
|
1200
1431
|
|
|
@@ -1221,9 +1452,10 @@ async function fetchSignUp(config, payload) {
|
|
|
1221
1452
|
q.set("tenantId", params.tenantId);
|
|
1222
1453
|
}
|
|
1223
1454
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
|
|
1455
|
+
const { headers } = ctx.get();
|
|
1224
1456
|
const req = new Request(clientUrl, {
|
|
1225
1457
|
method: "POST",
|
|
1226
|
-
headers
|
|
1458
|
+
headers,
|
|
1227
1459
|
body
|
|
1228
1460
|
});
|
|
1229
1461
|
return await config.handlers.POST(req);
|
|
@@ -1231,7 +1463,7 @@ async function fetchSignUp(config, payload) {
|
|
|
1231
1463
|
|
|
1232
1464
|
// src/api/handlers/POST.ts
|
|
1233
1465
|
function POSTER(configRoutes, config) {
|
|
1234
|
-
const { info, warn, error } = config.logger("[POST MATCHER]");
|
|
1466
|
+
const { info, warn: warn2, error } = config.logger("[POST MATCHER]");
|
|
1235
1467
|
return async function POST6(...params) {
|
|
1236
1468
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1237
1469
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1267,10 +1499,6 @@ function POSTER(configRoutes, config) {
|
|
|
1267
1499
|
info("matches signup");
|
|
1268
1500
|
return route17(req, config);
|
|
1269
1501
|
}
|
|
1270
|
-
if (matches2(configRoutes, req)) {
|
|
1271
|
-
info("matches users");
|
|
1272
|
-
return route2(req, config);
|
|
1273
|
-
}
|
|
1274
1502
|
if (matches6(configRoutes, req)) {
|
|
1275
1503
|
info("matches tenants");
|
|
1276
1504
|
return route6(req, config);
|
|
@@ -1307,7 +1535,7 @@ function POSTER(configRoutes, config) {
|
|
|
1307
1535
|
info("matches verify-email");
|
|
1308
1536
|
return route16(req, config);
|
|
1309
1537
|
}
|
|
1310
|
-
|
|
1538
|
+
warn2(`No POST routes matched ${req.url}`);
|
|
1311
1539
|
return new Response(null, { status: 404 });
|
|
1312
1540
|
};
|
|
1313
1541
|
}
|
|
@@ -1316,10 +1544,8 @@ function POSTER(configRoutes, config) {
|
|
|
1316
1544
|
async function DELETE3(config, init) {
|
|
1317
1545
|
const yurl = new URL(init.request.url);
|
|
1318
1546
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1319
|
-
config.tenantId = tenantId;
|
|
1320
|
-
config.userId = userId;
|
|
1321
1547
|
init.method = "DELETE";
|
|
1322
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1548
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1323
1549
|
return await request(url, init, config);
|
|
1324
1550
|
}
|
|
1325
1551
|
|
|
@@ -1327,10 +1553,8 @@ async function DELETE3(config, init) {
|
|
|
1327
1553
|
async function PUT5(config, init) {
|
|
1328
1554
|
const yurl = new URL(init.request.url);
|
|
1329
1555
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1330
|
-
config.tenantId = tenantId;
|
|
1331
|
-
config.userId = userId;
|
|
1332
1556
|
init.method = "PUT";
|
|
1333
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1557
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1334
1558
|
return await request(url, init, config);
|
|
1335
1559
|
}
|
|
1336
1560
|
|
|
@@ -1368,22 +1592,24 @@ function matches18(configRoutes, request2) {
|
|
|
1368
1592
|
return urlMatches(request2.url, route20);
|
|
1369
1593
|
}
|
|
1370
1594
|
async function fetchTenantUser(config, method) {
|
|
1371
|
-
|
|
1595
|
+
const { headers, tenantId, userId } = ctx.get();
|
|
1596
|
+
const action = method === "PUT" ? "add" : "delete";
|
|
1597
|
+
if (!tenantId) {
|
|
1372
1598
|
throw new Error(
|
|
1373
|
-
|
|
1599
|
+
`Unable to ${action} user to the tenant, the tenantId context is missing. Use nile.withContext({ tenantId })`
|
|
1374
1600
|
);
|
|
1375
1601
|
}
|
|
1376
|
-
if (!
|
|
1602
|
+
if (!userId) {
|
|
1377
1603
|
throw new Error(
|
|
1378
|
-
|
|
1604
|
+
`Unable to ${action} user to tenant. The userId context is missing. Use nile.withContext({ userId })`
|
|
1379
1605
|
);
|
|
1380
1606
|
}
|
|
1381
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
|
|
1382
|
-
"{
|
|
1383
|
-
|
|
1384
|
-
)
|
|
1607
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace("{tenantId}", tenantId).replace(
|
|
1608
|
+
"{userId}",
|
|
1609
|
+
userId
|
|
1610
|
+
)}/link`;
|
|
1385
1611
|
const req = new Request(clientUrl, {
|
|
1386
|
-
headers
|
|
1612
|
+
headers,
|
|
1387
1613
|
method
|
|
1388
1614
|
});
|
|
1389
1615
|
return await config.handlers[method](req);
|
|
@@ -1397,7 +1623,7 @@ async function DELETE4(config, init) {
|
|
|
1397
1623
|
return new Response(null, { status: 404 });
|
|
1398
1624
|
}
|
|
1399
1625
|
init.method = "DELETE";
|
|
1400
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
|
|
1626
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}/${inviteId}`;
|
|
1401
1627
|
return await request(url, init, config);
|
|
1402
1628
|
}
|
|
1403
1629
|
|
|
@@ -1420,7 +1646,7 @@ function matches19(configRoutes, request2) {
|
|
|
1420
1646
|
|
|
1421
1647
|
// src/api/handlers/DELETE.ts
|
|
1422
1648
|
function DELETER(configRoutes, config) {
|
|
1423
|
-
const { error, info, warn } = config.logger("[DELETE MATCHER]");
|
|
1649
|
+
const { error, info, warn: warn2 } = config.logger("[DELETE MATCHER]");
|
|
1424
1650
|
return async function DELETE5(...params) {
|
|
1425
1651
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1426
1652
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1451,14 +1677,14 @@ function DELETER(configRoutes, config) {
|
|
|
1451
1677
|
info("matches me");
|
|
1452
1678
|
return route(req, config);
|
|
1453
1679
|
}
|
|
1454
|
-
|
|
1680
|
+
warn2("No DELETE routes matched");
|
|
1455
1681
|
return new Response(null, { status: 404 });
|
|
1456
1682
|
};
|
|
1457
1683
|
}
|
|
1458
1684
|
|
|
1459
1685
|
// src/api/handlers/PUT.ts
|
|
1460
1686
|
function PUTER(configRoutes, config) {
|
|
1461
|
-
const { error, info, warn } = config.logger("[PUT MATCHER]");
|
|
1687
|
+
const { error, info, warn: warn2 } = config.logger("[PUT MATCHER]");
|
|
1462
1688
|
return async function PUT6(...params) {
|
|
1463
1689
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1464
1690
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1485,10 +1711,6 @@ function PUTER(configRoutes, config) {
|
|
|
1485
1711
|
info("matches tenant users");
|
|
1486
1712
|
return route3(req, config);
|
|
1487
1713
|
}
|
|
1488
|
-
if (matches2(configRoutes, req)) {
|
|
1489
|
-
info("matches users");
|
|
1490
|
-
return route2(req, config);
|
|
1491
|
-
}
|
|
1492
1714
|
if (matches(configRoutes, req)) {
|
|
1493
1715
|
info("matches me");
|
|
1494
1716
|
return route(req, config);
|
|
@@ -1501,7 +1723,7 @@ function PUTER(configRoutes, config) {
|
|
|
1501
1723
|
info("matches reset password");
|
|
1502
1724
|
return route15(req, config);
|
|
1503
1725
|
}
|
|
1504
|
-
|
|
1726
|
+
warn2("No PUT routes matched");
|
|
1505
1727
|
return new Response(null, { status: 404 });
|
|
1506
1728
|
};
|
|
1507
1729
|
}
|
|
@@ -1705,25 +1927,14 @@ var Config = class {
|
|
|
1705
1927
|
extensionCtx;
|
|
1706
1928
|
extensions;
|
|
1707
1929
|
logger;
|
|
1930
|
+
context;
|
|
1708
1931
|
/**
|
|
1709
|
-
*
|
|
1932
|
+
* The nile-auth url
|
|
1710
1933
|
*/
|
|
1711
|
-
|
|
1934
|
+
apiUrl;
|
|
1935
|
+
origin;
|
|
1712
1936
|
/**
|
|
1713
|
-
*
|
|
1714
|
-
*/
|
|
1715
|
-
userId;
|
|
1716
|
-
/**
|
|
1717
|
-
* Stores the headers to be used in `fetch` calls
|
|
1718
|
-
*/
|
|
1719
|
-
headers;
|
|
1720
|
-
/**
|
|
1721
|
-
* The nile-auth url
|
|
1722
|
-
*/
|
|
1723
|
-
apiUrl;
|
|
1724
|
-
origin;
|
|
1725
|
-
/**
|
|
1726
|
-
* important for separating the `origin` config value from a default in order to make requests
|
|
1937
|
+
* important for separating the `origin` config value from a default in order to make requests
|
|
1727
1938
|
*/
|
|
1728
1939
|
serverOrigin;
|
|
1729
1940
|
debug;
|
|
@@ -1767,11 +1978,12 @@ var Config = class {
|
|
|
1767
1978
|
if (databaseName) {
|
|
1768
1979
|
this.db.database = databaseName;
|
|
1769
1980
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1981
|
+
this.context = {
|
|
1982
|
+
tenantId: config?.tenantId,
|
|
1983
|
+
userId: config?.userId,
|
|
1984
|
+
headers: config?.headers ? new Headers(config.headers) : new Headers(),
|
|
1985
|
+
preserveHeaders: false
|
|
1986
|
+
};
|
|
1775
1987
|
this.routes = {
|
|
1776
1988
|
...appRoutes(config?.routePrefix),
|
|
1777
1989
|
...config?.routes
|
|
@@ -1814,8 +2026,6 @@ var Config = class {
|
|
|
1814
2026
|
],
|
|
1815
2027
|
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
1816
2028
|
};
|
|
1817
|
-
this.tenantId = config?.tenantId;
|
|
1818
|
-
this.userId = config?.userId;
|
|
1819
2029
|
}
|
|
1820
2030
|
};
|
|
1821
2031
|
|
|
@@ -1882,7 +2092,15 @@ function createProxyForPool(pool, config) {
|
|
|
1882
2092
|
}
|
|
1883
2093
|
const caller = target[property];
|
|
1884
2094
|
return function query(...args) {
|
|
1885
|
-
|
|
2095
|
+
let log = "[QUERY]";
|
|
2096
|
+
const { userId, tenantId } = config.context;
|
|
2097
|
+
if (tenantId) {
|
|
2098
|
+
log = `${log}[TENANT:${tenantId}]`;
|
|
2099
|
+
}
|
|
2100
|
+
if (userId) {
|
|
2101
|
+
log = `${log}[USER:${userId}]`;
|
|
2102
|
+
}
|
|
2103
|
+
info(log, ...args);
|
|
1886
2104
|
const called = caller.apply(this, args);
|
|
1887
2105
|
return called;
|
|
1888
2106
|
};
|
|
@@ -1901,7 +2119,7 @@ var NileDatabase = class {
|
|
|
1901
2119
|
config;
|
|
1902
2120
|
timer;
|
|
1903
2121
|
constructor(config, id) {
|
|
1904
|
-
const { warn, info, debug } = config.logger("[NileInstance]");
|
|
2122
|
+
const { warn: warn2, info, debug } = config.logger("[NileInstance]");
|
|
1905
2123
|
this.id = id;
|
|
1906
2124
|
const poolConfig = {
|
|
1907
2125
|
min: 0,
|
|
@@ -1917,7 +2135,7 @@ var NileDatabase = class {
|
|
|
1917
2135
|
debug(`Connection pool config ${JSON.stringify(cloned)}`);
|
|
1918
2136
|
this.pool = createProxyForPool(new pg__default.default.Pool(remaining), this.config);
|
|
1919
2137
|
if (typeof afterCreate === "function") {
|
|
1920
|
-
|
|
2138
|
+
warn2(
|
|
1921
2139
|
"Providing an pool configuration will stop automatic tenant context setting."
|
|
1922
2140
|
);
|
|
1923
2141
|
}
|
|
@@ -1983,7 +2201,7 @@ var NileDatabase = class {
|
|
|
1983
2201
|
};
|
|
1984
2202
|
var NileInstance_default = NileDatabase;
|
|
1985
2203
|
function makeAfterCreate(config, id) {
|
|
1986
|
-
const { error, warn, debug } = config.logger("[afterCreate]");
|
|
2204
|
+
const { error, warn: warn2, debug } = config.logger("[afterCreate]");
|
|
1987
2205
|
return (conn, done) => {
|
|
1988
2206
|
conn.on("error", function errorHandler(e) {
|
|
1989
2207
|
error(`Connection ${id} was terminated by server`, {
|
|
@@ -1992,13 +2210,15 @@ function makeAfterCreate(config, id) {
|
|
|
1992
2210
|
});
|
|
1993
2211
|
done(e, conn);
|
|
1994
2212
|
});
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2213
|
+
const tenantId = config.context.tenantId;
|
|
2214
|
+
const userId = config.context.userId;
|
|
2215
|
+
if (tenantId) {
|
|
2216
|
+
const query = [`SET nile.tenant_id = '${tenantId}'`];
|
|
2217
|
+
if (userId) {
|
|
2218
|
+
if (!tenantId) {
|
|
2219
|
+
warn2("A user id cannot be set in context without a tenant id");
|
|
2000
2220
|
}
|
|
2001
|
-
query.push(`SET nile.user_id = '${
|
|
2221
|
+
query.push(`SET nile.user_id = '${userId}'`);
|
|
2002
2222
|
}
|
|
2003
2223
|
conn.query(query.join(";"), function(err) {
|
|
2004
2224
|
if (err) {
|
|
@@ -2011,11 +2231,11 @@ function makeAfterCreate(config, id) {
|
|
|
2011
2231
|
});
|
|
2012
2232
|
} else {
|
|
2013
2233
|
if (query.length === 1) {
|
|
2014
|
-
debug(`connection context set: tenantId=${
|
|
2234
|
+
debug(`connection context set: tenantId=${tenantId}`);
|
|
2015
2235
|
}
|
|
2016
2236
|
if (query.length === 2) {
|
|
2017
2237
|
debug(
|
|
2018
|
-
`connection context set: tenantId=${
|
|
2238
|
+
`connection context set: tenantId=${tenantId} userId=${userId}`
|
|
2019
2239
|
);
|
|
2020
2240
|
}
|
|
2021
2241
|
}
|
|
@@ -2047,19 +2267,19 @@ var DBManager = class {
|
|
|
2047
2267
|
watchEvictPool(this.poolWatcherFn);
|
|
2048
2268
|
}
|
|
2049
2269
|
poolWatcher = (config) => (id) => {
|
|
2050
|
-
const { info, warn } = Logger(config)("[DBManager]");
|
|
2270
|
+
const { info, warn: warn2 } = Logger(config)("[DBManager]");
|
|
2051
2271
|
if (id && this.connections.has(id)) {
|
|
2052
2272
|
info(`Removing ${id} from db connection pool.`);
|
|
2053
2273
|
const connection = this.connections.get(id);
|
|
2054
2274
|
connection?.shutdown();
|
|
2055
2275
|
this.connections.delete(id);
|
|
2056
2276
|
} else {
|
|
2057
|
-
|
|
2277
|
+
warn2(`missed eviction of ${id}`);
|
|
2058
2278
|
}
|
|
2059
2279
|
};
|
|
2060
2280
|
getConnection = (config) => {
|
|
2061
2281
|
const { info } = Logger(config)("[DBManager]");
|
|
2062
|
-
const id = this.makeId(config.tenantId, config.userId);
|
|
2282
|
+
const id = this.makeId(config.context.tenantId, config.context.userId);
|
|
2063
2283
|
const existing = this.connections.get(id);
|
|
2064
2284
|
info(`# of instances: ${this.connections.size}`);
|
|
2065
2285
|
if (existing) {
|
|
@@ -2067,7 +2287,7 @@ var DBManager = class {
|
|
|
2067
2287
|
existing.startTimeout();
|
|
2068
2288
|
return existing.pool;
|
|
2069
2289
|
}
|
|
2070
|
-
const newOne = new NileInstance_default(
|
|
2290
|
+
const newOne = new NileInstance_default(config, id);
|
|
2071
2291
|
this.connections.set(id, newOne);
|
|
2072
2292
|
info(`created new ${id}`);
|
|
2073
2293
|
info(`# of instances: ${this.connections.size}`);
|
|
@@ -2102,33 +2322,39 @@ var Auth = class {
|
|
|
2102
2322
|
this.#logger = config.logger("[auth]");
|
|
2103
2323
|
}
|
|
2104
2324
|
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;
|
|
2325
|
+
return withNileContext(this.#config, async () => {
|
|
2326
|
+
const res = await fetchSession(this.#config);
|
|
2327
|
+
if (rawResponse) {
|
|
2328
|
+
return res;
|
|
2113
2329
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2330
|
+
try {
|
|
2331
|
+
const session = await res.clone().json();
|
|
2332
|
+
if (Object.keys(session).length === 0) {
|
|
2333
|
+
return void 0;
|
|
2334
|
+
}
|
|
2335
|
+
return session;
|
|
2336
|
+
} catch {
|
|
2337
|
+
return res;
|
|
2338
|
+
}
|
|
2339
|
+
});
|
|
2118
2340
|
}
|
|
2119
2341
|
async getCsrf(rawResponse = false) {
|
|
2120
|
-
return
|
|
2342
|
+
return withNileContext(this.#config, async () => {
|
|
2343
|
+
return await obtainCsrf(this.#config, rawResponse);
|
|
2344
|
+
});
|
|
2121
2345
|
}
|
|
2122
2346
|
async listProviders(rawResponse = false) {
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2347
|
+
return withNileContext(this.#config, async () => {
|
|
2348
|
+
const res = await fetchProviders(this.#config);
|
|
2349
|
+
if (rawResponse) {
|
|
2350
|
+
return res;
|
|
2351
|
+
}
|
|
2352
|
+
try {
|
|
2353
|
+
return await res.clone().json();
|
|
2354
|
+
} catch {
|
|
2355
|
+
return res;
|
|
2356
|
+
}
|
|
2357
|
+
});
|
|
2132
2358
|
}
|
|
2133
2359
|
/**
|
|
2134
2360
|
* Sign the current user out by calling `/api/auth/signout`.
|
|
@@ -2137,73 +2363,79 @@ var Auth = class {
|
|
|
2137
2363
|
* from the internal configuration once the request completes.
|
|
2138
2364
|
*/
|
|
2139
2365
|
async signOut() {
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2366
|
+
return withNileContext(this.#config, async () => {
|
|
2367
|
+
const csrfRes = await this.getCsrf();
|
|
2368
|
+
if (!("csrfToken" in csrfRes)) {
|
|
2369
|
+
throw new Error("Unable to obtain CSRF token. Sign out failed.");
|
|
2370
|
+
}
|
|
2371
|
+
const body = JSON.stringify({
|
|
2372
|
+
csrfToken: csrfRes.csrfToken,
|
|
2373
|
+
json: true
|
|
2374
|
+
});
|
|
2375
|
+
const res = await fetchSignOut(this.#config, body);
|
|
2376
|
+
updateHeaders(new Headers({}));
|
|
2377
|
+
ctx.set({ headers: null });
|
|
2378
|
+
return res;
|
|
2147
2379
|
});
|
|
2148
|
-
const res = await fetchSignOut(this.#config, body);
|
|
2149
|
-
updateHeaders(new Headers({}));
|
|
2150
|
-
this.#config.headers = new Headers();
|
|
2151
|
-
return res;
|
|
2152
2380
|
}
|
|
2153
2381
|
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
|
-
|
|
2382
|
+
return withNileContext(this.#config, async () => {
|
|
2383
|
+
ctx.set({ headers: null });
|
|
2384
|
+
const { email, password, ...params } = payload;
|
|
2385
|
+
if (!email || !password) {
|
|
2386
|
+
throw new Error(
|
|
2387
|
+
"Server side sign up requires a user email and password."
|
|
2388
|
+
);
|
|
2389
|
+
}
|
|
2390
|
+
const providers = await this.listProviders();
|
|
2391
|
+
const { credentials } = providers ?? {};
|
|
2392
|
+
if (!credentials) {
|
|
2393
|
+
throw new Error(
|
|
2394
|
+
"Unable to obtain credential provider. Aborting server side sign up."
|
|
2395
|
+
);
|
|
2396
|
+
}
|
|
2397
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2398
|
+
let csrfToken;
|
|
2399
|
+
if ("csrfToken" in csrf) {
|
|
2400
|
+
csrfToken = csrf.csrfToken;
|
|
2401
|
+
} else {
|
|
2402
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2403
|
+
}
|
|
2404
|
+
const body = JSON.stringify({
|
|
2405
|
+
email,
|
|
2406
|
+
password,
|
|
2407
|
+
csrfToken,
|
|
2408
|
+
callbackUrl: credentials.callbackUrl
|
|
2409
|
+
});
|
|
2410
|
+
const res = await fetchSignUp(this.#config, { body, params });
|
|
2411
|
+
if (res.status > 299) {
|
|
2412
|
+
this.#logger.error(await res.clone().text());
|
|
2413
|
+
return void 0;
|
|
2414
|
+
}
|
|
2415
|
+
const token = parseToken(res.headers);
|
|
2416
|
+
if (!token) {
|
|
2417
|
+
throw new Error("Server side sign up failed. Session token not found");
|
|
2418
|
+
}
|
|
2419
|
+
const { headers } = ctx.get();
|
|
2420
|
+
headers?.append("cookie", token);
|
|
2421
|
+
ctx.set({ headers });
|
|
2422
|
+
updateHeaders(headers);
|
|
2423
|
+
if (rawResponse) {
|
|
2424
|
+
return res;
|
|
2425
|
+
}
|
|
2426
|
+
try {
|
|
2427
|
+
const json = await res.clone().json();
|
|
2428
|
+
if (json && typeof json === "object" && "tenants" in json) {
|
|
2429
|
+
const tenantId = json.tenants[0];
|
|
2430
|
+
if (tenantId) {
|
|
2431
|
+
updateTenantId(tenantId);
|
|
2432
|
+
}
|
|
2201
2433
|
}
|
|
2434
|
+
return json;
|
|
2435
|
+
} catch {
|
|
2436
|
+
return res;
|
|
2202
2437
|
}
|
|
2203
|
-
|
|
2204
|
-
} catch {
|
|
2205
|
-
return res;
|
|
2206
|
-
}
|
|
2438
|
+
});
|
|
2207
2439
|
}
|
|
2208
2440
|
/**
|
|
2209
2441
|
* Request a password reset email.
|
|
@@ -2213,34 +2445,34 @@ var Auth = class {
|
|
|
2213
2445
|
* which is returned as a {@link Response} object.
|
|
2214
2446
|
*/
|
|
2215
2447
|
async forgotPassword(req) {
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2448
|
+
return withNileContext(this.#config, async () => {
|
|
2449
|
+
let email = "";
|
|
2450
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2451
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2452
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2453
|
+
if ("email" in req) {
|
|
2454
|
+
email = req.email;
|
|
2455
|
+
}
|
|
2456
|
+
if ("callbackUrl" in req) {
|
|
2457
|
+
callbackUrl = fQUrl(req.callbackUrl ?? "", this.#config);
|
|
2458
|
+
}
|
|
2459
|
+
if ("redirectUrl" in req) {
|
|
2460
|
+
redirectUrl = fQUrl(req.redirectUrl ?? "", this.#config);
|
|
2461
|
+
}
|
|
2462
|
+
const body = JSON.stringify({
|
|
2463
|
+
email,
|
|
2464
|
+
redirectUrl,
|
|
2465
|
+
callbackUrl
|
|
2466
|
+
});
|
|
2467
|
+
const data = await fetchResetPassword(
|
|
2468
|
+
this.#config,
|
|
2469
|
+
"POST",
|
|
2470
|
+
body,
|
|
2471
|
+
new URLSearchParams(),
|
|
2472
|
+
false
|
|
2473
|
+
);
|
|
2474
|
+
return data;
|
|
2235
2475
|
});
|
|
2236
|
-
const data = await fetchResetPassword(
|
|
2237
|
-
this.#config,
|
|
2238
|
-
"POST",
|
|
2239
|
-
body,
|
|
2240
|
-
new URLSearchParams(),
|
|
2241
|
-
false
|
|
2242
|
-
);
|
|
2243
|
-
return data;
|
|
2244
2476
|
}
|
|
2245
2477
|
/**
|
|
2246
2478
|
* Complete a password reset.
|
|
@@ -2253,93 +2485,98 @@ var Auth = class {
|
|
|
2253
2485
|
* containing the necessary fields.
|
|
2254
2486
|
*/
|
|
2255
2487
|
async resetPassword(req) {
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2488
|
+
return withNileContext(this.#config, async () => {
|
|
2489
|
+
let email = "";
|
|
2490
|
+
let password = "";
|
|
2491
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2492
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2493
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2494
|
+
if (req instanceof Request) {
|
|
2495
|
+
const body2 = await req.json();
|
|
2496
|
+
email = body2.email;
|
|
2497
|
+
password = body2.password;
|
|
2498
|
+
const cbFromHeaders = parseCallback(req.headers);
|
|
2499
|
+
if (cbFromHeaders) {
|
|
2500
|
+
callbackUrl = cbFromHeaders;
|
|
2501
|
+
}
|
|
2502
|
+
if (body2.callbackUrl) {
|
|
2503
|
+
callbackUrl = body2.callbackUrl;
|
|
2504
|
+
}
|
|
2505
|
+
if (body2.redirectUrl) {
|
|
2506
|
+
redirectUrl = body2.redirectUrl;
|
|
2507
|
+
}
|
|
2508
|
+
} else {
|
|
2509
|
+
if ("email" in req) {
|
|
2510
|
+
email = req.email;
|
|
2511
|
+
}
|
|
2512
|
+
if ("password" in req) {
|
|
2513
|
+
password = req.password;
|
|
2514
|
+
}
|
|
2515
|
+
if ("callbackUrl" in req) {
|
|
2516
|
+
callbackUrl = req.callbackUrl ? req.callbackUrl : null;
|
|
2517
|
+
}
|
|
2518
|
+
if ("redirectUrl" in req) {
|
|
2519
|
+
redirectUrl = req.redirectUrl ? req.redirectUrl : null;
|
|
2520
|
+
}
|
|
2274
2521
|
}
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
email
|
|
2522
|
+
await this.getCsrf();
|
|
2523
|
+
const body = JSON.stringify({
|
|
2524
|
+
email,
|
|
2525
|
+
password,
|
|
2526
|
+
redirectUrl,
|
|
2527
|
+
callbackUrl
|
|
2528
|
+
});
|
|
2529
|
+
let urlWithParams;
|
|
2530
|
+
try {
|
|
2531
|
+
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
2532
|
+
const cloned = data.clone();
|
|
2533
|
+
if (data.status === 400) {
|
|
2534
|
+
const text = await cloned.text();
|
|
2535
|
+
this.#logger.error(text);
|
|
2536
|
+
return data;
|
|
2537
|
+
}
|
|
2538
|
+
const { url } = await data.json();
|
|
2539
|
+
urlWithParams = url;
|
|
2540
|
+
} catch {
|
|
2278
2541
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2542
|
+
let token;
|
|
2543
|
+
try {
|
|
2544
|
+
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2545
|
+
const answer = await fetchResetPassword(
|
|
2546
|
+
this.#config,
|
|
2547
|
+
"GET",
|
|
2548
|
+
null,
|
|
2549
|
+
worthyParams
|
|
2550
|
+
);
|
|
2551
|
+
token = parseResetToken(answer.headers);
|
|
2552
|
+
} catch {
|
|
2553
|
+
this.#logger.warn(
|
|
2554
|
+
"Unable to parse reset password url. Password not reset."
|
|
2555
|
+
);
|
|
2281
2556
|
}
|
|
2282
|
-
|
|
2283
|
-
|
|
2557
|
+
const { headers } = ctx.get();
|
|
2558
|
+
const cookie = headers?.get("cookie")?.split("; ");
|
|
2559
|
+
if (token) {
|
|
2560
|
+
cookie?.push(token);
|
|
2561
|
+
} else {
|
|
2562
|
+
throw new Error(
|
|
2563
|
+
"Unable to reset password, reset token is missing from response"
|
|
2564
|
+
);
|
|
2284
2565
|
}
|
|
2285
|
-
if (
|
|
2286
|
-
|
|
2566
|
+
if (cookie) {
|
|
2567
|
+
headers?.set("cookie", cookie?.join("; "));
|
|
2568
|
+
ctx.set({
|
|
2569
|
+
headers
|
|
2570
|
+
});
|
|
2287
2571
|
}
|
|
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("; ")
|
|
2572
|
+
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2573
|
+
cookie?.pop();
|
|
2574
|
+
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2575
|
+
cleaned.push(String(parseToken(res.headers)));
|
|
2576
|
+
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2577
|
+
updateHeaders(updatedHeaders);
|
|
2578
|
+
return res;
|
|
2335
2579
|
});
|
|
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
2580
|
}
|
|
2344
2581
|
/**
|
|
2345
2582
|
* Low level helper used by {@link signIn} to complete provider flows.
|
|
@@ -2349,7 +2586,9 @@ var Auth = class {
|
|
|
2349
2586
|
*/
|
|
2350
2587
|
async callback(provider, body) {
|
|
2351
2588
|
if (body instanceof Request) {
|
|
2352
|
-
|
|
2589
|
+
ctx.set({
|
|
2590
|
+
headers: body.headers
|
|
2591
|
+
});
|
|
2353
2592
|
return await fetchCallback(
|
|
2354
2593
|
this.#config,
|
|
2355
2594
|
provider,
|
|
@@ -2361,112 +2600,115 @@ var Auth = class {
|
|
|
2361
2600
|
return await fetchCallback(this.#config, provider, body);
|
|
2362
2601
|
}
|
|
2363
2602
|
async signIn(provider, payload, rawResponse) {
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2603
|
+
return withNileContext(this.#config, async () => {
|
|
2604
|
+
if (payload instanceof Request) {
|
|
2605
|
+
const body2 = new URLSearchParams(await payload.text());
|
|
2606
|
+
const origin = new URL(payload.url).origin;
|
|
2607
|
+
const payloadUrl = body2?.get("callbackUrl");
|
|
2608
|
+
const csrfToken2 = body2?.get("csrfToken");
|
|
2609
|
+
const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
|
|
2610
|
+
if (!csrfToken2) {
|
|
2611
|
+
throw new Error(
|
|
2612
|
+
"CSRF token in missing from request. Request it by the client before calling sign in"
|
|
2613
|
+
);
|
|
2614
|
+
}
|
|
2615
|
+
const updatedHeaders = new Headers(payload.headers);
|
|
2616
|
+
updatedHeaders.set("Content-Type", "application/x-www-form-urlencoded");
|
|
2617
|
+
ctx.set({ headers: updatedHeaders });
|
|
2618
|
+
const params = new URLSearchParams({
|
|
2619
|
+
csrfToken: csrfToken2,
|
|
2620
|
+
json: String(true)
|
|
2621
|
+
});
|
|
2622
|
+
if (payloadUrl) {
|
|
2623
|
+
params.set("callbackUrl", callbackUrl);
|
|
2624
|
+
}
|
|
2625
|
+
return await fetchSignIn(this.#config, provider, params);
|
|
2626
|
+
}
|
|
2627
|
+
ctx.set({ headers: null });
|
|
2628
|
+
const { info, error } = this.#logger;
|
|
2629
|
+
const providers = await this.listProviders();
|
|
2630
|
+
info("Obtaining csrf");
|
|
2631
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2632
|
+
let csrfToken;
|
|
2633
|
+
if ("csrfToken" in csrf) {
|
|
2634
|
+
csrfToken = csrf.csrfToken;
|
|
2635
|
+
} else {
|
|
2636
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2637
|
+
}
|
|
2638
|
+
const { credentials } = providers ?? {};
|
|
2639
|
+
if (!credentials) {
|
|
2371
2640
|
throw new Error(
|
|
2372
|
-
"
|
|
2641
|
+
"Unable to obtain credential provider. Aborting server side sign in."
|
|
2373
2642
|
);
|
|
2374
2643
|
}
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2644
|
+
const { email, password } = payload ?? {};
|
|
2645
|
+
if (provider === "email" && (!email || !password)) {
|
|
2646
|
+
throw new Error(
|
|
2647
|
+
"Server side sign in requires a user email and password."
|
|
2648
|
+
);
|
|
2649
|
+
}
|
|
2650
|
+
info(`Obtaining providers for ${email}`);
|
|
2651
|
+
info(`Attempting sign in with email ${email}`);
|
|
2652
|
+
if (!email) {
|
|
2653
|
+
throw new Error("Email missing from payload, unable to sign in");
|
|
2654
|
+
}
|
|
2655
|
+
const body = JSON.stringify({
|
|
2656
|
+
email,
|
|
2657
|
+
password,
|
|
2658
|
+
csrfToken,
|
|
2659
|
+
callbackUrl: credentials.callbackUrl
|
|
2383
2660
|
});
|
|
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;
|
|
2661
|
+
const signInRes = await this.callback(provider, body);
|
|
2662
|
+
const authCookie = signInRes?.headers.get("set-cookie");
|
|
2663
|
+
if (!authCookie) {
|
|
2664
|
+
throw new Error("authentication failed");
|
|
2665
|
+
}
|
|
2666
|
+
const token = parseToken(signInRes?.headers);
|
|
2667
|
+
const possibleError = signInRes?.headers.get("location");
|
|
2668
|
+
if (possibleError) {
|
|
2669
|
+
let urlError;
|
|
2670
|
+
try {
|
|
2671
|
+
urlError = new URL(possibleError).searchParams.get("error");
|
|
2672
|
+
} catch {
|
|
2673
|
+
}
|
|
2674
|
+
if (urlError) {
|
|
2675
|
+
error("Unable to log user in", { error: urlError });
|
|
2676
|
+
return new Response(urlError, { status: signInRes.status });
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
if (!token) {
|
|
2680
|
+
error("Unable to obtain auth token", {
|
|
2681
|
+
authCookie,
|
|
2682
|
+
signInRes
|
|
2683
|
+
});
|
|
2684
|
+
throw new Error("Server login failed");
|
|
2685
|
+
}
|
|
2686
|
+
info("Server sign in successful", { authCookie });
|
|
2687
|
+
const setCookie = signInRes.headers.get("set-cookie");
|
|
2688
|
+
const { headers } = ctx.get();
|
|
2689
|
+
if (setCookie) {
|
|
2690
|
+
const cookie = [
|
|
2691
|
+
parseCSRF(headers),
|
|
2692
|
+
parseCallback(signInRes.headers),
|
|
2693
|
+
parseToken(signInRes.headers)
|
|
2694
|
+
].filter(Boolean).join("; ");
|
|
2695
|
+
const uHeaders = new Headers({ cookie });
|
|
2696
|
+
updateHeaders(uHeaders);
|
|
2697
|
+
ctx.set({ headers: uHeaders });
|
|
2698
|
+
} else {
|
|
2699
|
+
error("Unable to set context after sign in", {
|
|
2700
|
+
headers: signInRes.headers
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
if (rawResponse) {
|
|
2704
|
+
return signInRes;
|
|
2705
|
+
}
|
|
2432
2706
|
try {
|
|
2433
|
-
|
|
2707
|
+
return await signInRes.clone().json();
|
|
2434
2708
|
} catch {
|
|
2709
|
+
return signInRes;
|
|
2435
2710
|
}
|
|
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
|
-
}
|
|
2711
|
+
});
|
|
2470
2712
|
}
|
|
2471
2713
|
};
|
|
2472
2714
|
function parseCSRF(headers) {
|
|
@@ -2513,25 +2755,56 @@ function parseResetToken(headers) {
|
|
|
2513
2755
|
const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
|
|
2514
2756
|
return token;
|
|
2515
2757
|
}
|
|
2516
|
-
function
|
|
2758
|
+
function parseTenantId(headers) {
|
|
2759
|
+
let authCookie = headers?.get("set-cookie");
|
|
2760
|
+
if (!authCookie) {
|
|
2761
|
+
authCookie = headers?.get("cookie");
|
|
2762
|
+
}
|
|
2763
|
+
if (!authCookie) {
|
|
2764
|
+
return void 0;
|
|
2765
|
+
}
|
|
2766
|
+
const [, token] = /((__Secure-)?nile\.tenant-id=[^;]+)/.exec(authCookie) ?? [];
|
|
2767
|
+
if (token) {
|
|
2768
|
+
const [, tenantId] = token.split("=");
|
|
2769
|
+
return tenantId;
|
|
2770
|
+
}
|
|
2771
|
+
return null;
|
|
2772
|
+
}
|
|
2773
|
+
function defaultCallbackUrl(config) {
|
|
2517
2774
|
let cb = null;
|
|
2518
2775
|
let redirect = null;
|
|
2519
|
-
const
|
|
2776
|
+
const { headers } = ctx.get();
|
|
2777
|
+
const fallbackCb = parseCallback(headers);
|
|
2520
2778
|
if (fallbackCb) {
|
|
2521
2779
|
const [, value] = fallbackCb.split("=");
|
|
2522
2780
|
cb = decodeURIComponent(value);
|
|
2523
2781
|
if (value) {
|
|
2524
|
-
redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2782
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2525
2783
|
}
|
|
2526
2784
|
}
|
|
2527
2785
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
2528
2786
|
}
|
|
2787
|
+
function fQUrl(path, config) {
|
|
2788
|
+
if (path.startsWith("/")) {
|
|
2789
|
+
const { callbackUrl } = defaultCallbackUrl(config);
|
|
2790
|
+
if (callbackUrl) {
|
|
2791
|
+
const { origin } = new URL(callbackUrl);
|
|
2792
|
+
return `${origin}${path}`;
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
try {
|
|
2796
|
+
new URL(path);
|
|
2797
|
+
} catch {
|
|
2798
|
+
throw new Error("An invalid URL has been passed.");
|
|
2799
|
+
}
|
|
2800
|
+
return path;
|
|
2801
|
+
}
|
|
2529
2802
|
|
|
2530
2803
|
// src/auth/obtainCsrf.ts
|
|
2531
2804
|
async function obtainCsrf(config, rawResponse = false) {
|
|
2805
|
+
const { headers } = ctx.get();
|
|
2532
2806
|
const res = await fetchCsrf(config);
|
|
2533
2807
|
const csrfCook = parseCSRF(res.headers);
|
|
2534
|
-
const h = new Headers();
|
|
2535
2808
|
if (csrfCook) {
|
|
2536
2809
|
const [, value] = csrfCook.split("=");
|
|
2537
2810
|
const [token] = decodeURIComponent(value).split("|");
|
|
@@ -2542,29 +2815,27 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2542
2815
|
parseCallback(res.headers),
|
|
2543
2816
|
parseToken(res.headers)
|
|
2544
2817
|
].filter(Boolean).join("; ");
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
updateHeaders(
|
|
2818
|
+
headers.set("cookie", cookie);
|
|
2819
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2820
|
+
updateHeaders(headers);
|
|
2548
2821
|
}
|
|
2549
2822
|
if (!rawResponse) {
|
|
2550
2823
|
return { csrfToken: token };
|
|
2551
2824
|
}
|
|
2552
2825
|
} else {
|
|
2553
|
-
const existingCookie =
|
|
2826
|
+
const existingCookie = headers.get("cookie");
|
|
2554
2827
|
const cookieParts = [];
|
|
2555
2828
|
if (existingCookie) {
|
|
2556
|
-
cookieParts.push(
|
|
2557
|
-
parseToken(config.headers),
|
|
2558
|
-
parseCallback(config.headers)
|
|
2559
|
-
);
|
|
2829
|
+
cookieParts.push(parseToken(headers), parseCallback(headers));
|
|
2560
2830
|
}
|
|
2561
2831
|
if (csrfCook) {
|
|
2562
2832
|
cookieParts.push(csrfCook);
|
|
2563
2833
|
} else {
|
|
2564
|
-
cookieParts.push(parseCSRF(
|
|
2834
|
+
cookieParts.push(parseCSRF(headers));
|
|
2565
2835
|
}
|
|
2566
2836
|
const cookie = cookieParts.filter(Boolean).join("; ");
|
|
2567
|
-
|
|
2837
|
+
headers.set("cookie", cookie);
|
|
2838
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2568
2839
|
updateHeaders(new Headers({ cookie }));
|
|
2569
2840
|
}
|
|
2570
2841
|
if (rawResponse) {
|
|
@@ -2599,15 +2870,17 @@ var Users = class {
|
|
|
2599
2870
|
* @param [rawResponse] - When `true`, return the raw {@link Response}.
|
|
2600
2871
|
*/
|
|
2601
2872
|
async updateSelf(req, rawResponse) {
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2873
|
+
return withNileContext(this.#config, async () => {
|
|
2874
|
+
const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
|
|
2875
|
+
if (rawResponse) {
|
|
2876
|
+
return res;
|
|
2877
|
+
}
|
|
2878
|
+
try {
|
|
2879
|
+
return await res?.clone().json();
|
|
2880
|
+
} catch {
|
|
2881
|
+
return res;
|
|
2882
|
+
}
|
|
2883
|
+
});
|
|
2611
2884
|
}
|
|
2612
2885
|
/**
|
|
2613
2886
|
* Remove the current user using `DELETE /api/me`.
|
|
@@ -2617,59 +2890,70 @@ var Users = class {
|
|
|
2617
2890
|
* `packages/server/src/api/routes/me/index.ts` under `removeSelf`.
|
|
2618
2891
|
*/
|
|
2619
2892
|
async removeSelf() {
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2893
|
+
return withNileContext(this.#config, async () => {
|
|
2894
|
+
const me = await this.getSelf();
|
|
2895
|
+
if ("id" in me) {
|
|
2896
|
+
const userId = me.id;
|
|
2897
|
+
ctx.set({ userId });
|
|
2898
|
+
}
|
|
2899
|
+
const res = await fetchMe(this.#config, "DELETE");
|
|
2900
|
+
updateHeaders(new Headers());
|
|
2901
|
+
return res;
|
|
2902
|
+
});
|
|
2627
2903
|
}
|
|
2628
2904
|
async getSelf(rawResponse) {
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2905
|
+
return withNileContext(this.#config, async () => {
|
|
2906
|
+
const res = await fetchMe(this.#config);
|
|
2907
|
+
if (rawResponse) {
|
|
2908
|
+
return res;
|
|
2909
|
+
}
|
|
2910
|
+
try {
|
|
2911
|
+
return await res?.clone().json();
|
|
2912
|
+
} catch {
|
|
2913
|
+
return res;
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2638
2916
|
}
|
|
2639
2917
|
async verifySelf(options, rawResponse = false) {
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2918
|
+
return withNileContext(this.#config, async () => {
|
|
2919
|
+
const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
|
|
2920
|
+
const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2().callbackUrl;
|
|
2921
|
+
let res;
|
|
2922
|
+
try {
|
|
2923
|
+
const me = await this.getSelf();
|
|
2924
|
+
if (me instanceof Response) {
|
|
2925
|
+
return me;
|
|
2926
|
+
}
|
|
2927
|
+
res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
|
|
2928
|
+
return res;
|
|
2929
|
+
} catch (e) {
|
|
2930
|
+
if (!bypassEmail) {
|
|
2931
|
+
let message = "Unable to verify email.";
|
|
2932
|
+
if (e instanceof Error) {
|
|
2933
|
+
message = e.message;
|
|
2934
|
+
}
|
|
2935
|
+
this.#logger?.error(
|
|
2936
|
+
`${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
|
|
2937
|
+
);
|
|
2938
|
+
res = new Response(message, { status: 400 });
|
|
2655
2939
|
}
|
|
2656
|
-
|
|
2657
|
-
|
|
2940
|
+
}
|
|
2941
|
+
if (bypassEmail) {
|
|
2942
|
+
this.#logger?.info(
|
|
2943
|
+
"bypassing email requirements for email verification"
|
|
2658
2944
|
);
|
|
2659
|
-
res =
|
|
2945
|
+
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2660
2946
|
}
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
this.#logger?.info("bypassing email requirements for email verification");
|
|
2664
|
-
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2665
|
-
}
|
|
2666
|
-
return res;
|
|
2947
|
+
return res;
|
|
2948
|
+
});
|
|
2667
2949
|
}
|
|
2668
2950
|
};
|
|
2669
2951
|
async function verifyEmailAddress(config, user, callback) {
|
|
2670
|
-
|
|
2952
|
+
const { headers } = ctx.get();
|
|
2953
|
+
headers?.set("content-type", "application/x-www-form-urlencoded");
|
|
2954
|
+
ctx.set({ headers });
|
|
2671
2955
|
const { csrfToken } = await obtainCsrf(config);
|
|
2672
|
-
const defaults = defaultCallbackUrl2(
|
|
2956
|
+
const defaults = defaultCallbackUrl2();
|
|
2673
2957
|
const callbackUrl = callback ?? String(defaults.callbackUrl);
|
|
2674
2958
|
const res = await fetchVerifyEmail(
|
|
2675
2959
|
config,
|
|
@@ -2685,9 +2969,10 @@ async function verifyEmailAddress(config, user, callback) {
|
|
|
2685
2969
|
}
|
|
2686
2970
|
return res;
|
|
2687
2971
|
}
|
|
2688
|
-
function defaultCallbackUrl2(
|
|
2972
|
+
function defaultCallbackUrl2() {
|
|
2689
2973
|
let cb = null;
|
|
2690
|
-
const
|
|
2974
|
+
const { headers } = ctx.get();
|
|
2975
|
+
const fallbackCb = parseCallback(headers);
|
|
2691
2976
|
if (fallbackCb) {
|
|
2692
2977
|
const [, value] = fallbackCb.split("=");
|
|
2693
2978
|
cb = decodeURIComponent(value);
|
|
@@ -2707,24 +2992,26 @@ var Tenants = class {
|
|
|
2707
2992
|
* `createTenant` operation definition.
|
|
2708
2993
|
*/
|
|
2709
2994
|
async create(req, rawResponse) {
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2995
|
+
return withNileContext(this.#config, async () => {
|
|
2996
|
+
let res;
|
|
2997
|
+
if (typeof req === "string") {
|
|
2998
|
+
res = await fetchTenants(
|
|
2999
|
+
this.#config,
|
|
3000
|
+
"POST",
|
|
3001
|
+
JSON.stringify({ name: req })
|
|
3002
|
+
);
|
|
3003
|
+
} else if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3004
|
+
res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
|
|
3005
|
+
}
|
|
3006
|
+
if (rawResponse) {
|
|
3007
|
+
return res;
|
|
3008
|
+
}
|
|
3009
|
+
try {
|
|
3010
|
+
return await res?.clone().json();
|
|
3011
|
+
} catch {
|
|
3012
|
+
return res;
|
|
3013
|
+
}
|
|
3014
|
+
});
|
|
2728
3015
|
}
|
|
2729
3016
|
/**
|
|
2730
3017
|
* Remove a tenant via `DELETE /api/tenants/{tenantId}`.
|
|
@@ -2732,14 +3019,16 @@ var Tenants = class {
|
|
|
2732
3019
|
* @param req - The tenant to remove or context containing the id.
|
|
2733
3020
|
*/
|
|
2734
3021
|
async delete(req) {
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
3022
|
+
return withNileContext(this.#config, async () => {
|
|
3023
|
+
if (typeof req === "string") {
|
|
3024
|
+
ctx.set({ tenantId: req });
|
|
3025
|
+
}
|
|
3026
|
+
if (typeof req === "object" && "id" in req) {
|
|
3027
|
+
ctx.set({ tenantId: req.id });
|
|
3028
|
+
}
|
|
3029
|
+
const res = await fetchTenant(this.#config, "DELETE");
|
|
3030
|
+
return res;
|
|
3031
|
+
});
|
|
2743
3032
|
}
|
|
2744
3033
|
/**
|
|
2745
3034
|
* Fetch details for a tenant using `GET /api/tenants/{tenantId}`.
|
|
@@ -2748,53 +3037,63 @@ var Tenants = class {
|
|
|
2748
3037
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2749
3038
|
*/
|
|
2750
3039
|
async get(req, rawResponse) {
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
3040
|
+
return withNileContext(this.#config, async () => {
|
|
3041
|
+
if (typeof req === "string") {
|
|
3042
|
+
ctx.set({ tenantId: req });
|
|
3043
|
+
} else if (typeof req === "object" && "id" in req) {
|
|
3044
|
+
ctx.set({ tenantId: req.id });
|
|
3045
|
+
}
|
|
3046
|
+
const res = await fetchTenant(this.#config, "GET");
|
|
3047
|
+
if (rawResponse === true || req === true) {
|
|
3048
|
+
return res;
|
|
3049
|
+
}
|
|
3050
|
+
try {
|
|
3051
|
+
return await res?.clone().json();
|
|
3052
|
+
} catch {
|
|
3053
|
+
return res;
|
|
3054
|
+
}
|
|
3055
|
+
});
|
|
2765
3056
|
}
|
|
2766
3057
|
async update(req, rawResponse) {
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
3058
|
+
return withNileContext(this.#config, async () => {
|
|
3059
|
+
let res;
|
|
3060
|
+
if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3061
|
+
const { id, ...remaining } = req;
|
|
3062
|
+
if (id) {
|
|
3063
|
+
ctx.set({ tenantId: id });
|
|
3064
|
+
}
|
|
3065
|
+
res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
|
|
2772
3066
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
}
|
|
3067
|
+
if (rawResponse) {
|
|
3068
|
+
return res;
|
|
3069
|
+
}
|
|
3070
|
+
try {
|
|
3071
|
+
return await res?.clone().json();
|
|
3072
|
+
} catch {
|
|
3073
|
+
return res;
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
2783
3076
|
}
|
|
2784
3077
|
/**
|
|
2785
3078
|
* List tenants for the current user via `GET /api/tenants`.
|
|
2786
3079
|
* See `packages/server/src/api/routes/tenants/GET.ts` for details.
|
|
2787
3080
|
*/
|
|
2788
3081
|
async list(req) {
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
3082
|
+
return withNileContext(
|
|
3083
|
+
this.#config,
|
|
3084
|
+
async () => {
|
|
3085
|
+
const res = await fetchTenantsByUser(this.#config);
|
|
3086
|
+
if (req === true) {
|
|
3087
|
+
return res;
|
|
3088
|
+
}
|
|
3089
|
+
try {
|
|
3090
|
+
return await res?.clone().json();
|
|
3091
|
+
} catch {
|
|
3092
|
+
return res;
|
|
3093
|
+
}
|
|
3094
|
+
},
|
|
3095
|
+
"listTenants"
|
|
3096
|
+
);
|
|
2798
3097
|
}
|
|
2799
3098
|
/**
|
|
2800
3099
|
* Leave the current tenant using `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2802,29 +3101,33 @@ var Tenants = class {
|
|
|
2802
3101
|
* @param [req] - Optionally specify the tenant id to leave.
|
|
2803
3102
|
*/
|
|
2804
3103
|
async leaveTenant(req) {
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
3104
|
+
return withNileContext(this.#config, async () => {
|
|
3105
|
+
const me = await fetchMe(this.#config);
|
|
3106
|
+
try {
|
|
3107
|
+
const json = await me.json();
|
|
3108
|
+
if ("id" in json) {
|
|
3109
|
+
ctx.set({ userId: json.id, preserveHeaders: true });
|
|
3110
|
+
}
|
|
3111
|
+
} catch {
|
|
2810
3112
|
}
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
this.#
|
|
2817
|
-
}
|
|
2818
|
-
return await fetchTenantUser(this.#config, "DELETE");
|
|
3113
|
+
if (typeof req === "string") {
|
|
3114
|
+
ctx.set({ tenantId: req, preserveHeaders: true });
|
|
3115
|
+
} else {
|
|
3116
|
+
this.#handleContext(req);
|
|
3117
|
+
}
|
|
3118
|
+
return await fetchTenantUser(this.#config, "DELETE");
|
|
3119
|
+
});
|
|
2819
3120
|
}
|
|
2820
3121
|
async addMember(req, rawResponse) {
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
3122
|
+
return withNileContext(this.#config, async () => {
|
|
3123
|
+
if (typeof req === "string") {
|
|
3124
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3125
|
+
} else {
|
|
3126
|
+
this.#handleContext(req);
|
|
3127
|
+
}
|
|
3128
|
+
const res = await fetchTenantUser(this.#config, "PUT");
|
|
3129
|
+
return responseHandler(res, rawResponse);
|
|
3130
|
+
});
|
|
2828
3131
|
}
|
|
2829
3132
|
/**
|
|
2830
3133
|
* Remove a user from a tenant with `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2833,57 +3136,82 @@ var Tenants = class {
|
|
|
2833
3136
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2834
3137
|
*/
|
|
2835
3138
|
async removeMember(req, rawResponse) {
|
|
2836
|
-
this.#
|
|
2837
|
-
|
|
2838
|
-
|
|
3139
|
+
return withNileContext(this.#config, async () => {
|
|
3140
|
+
this.#handleContext(req);
|
|
3141
|
+
if (typeof req === "string") {
|
|
3142
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3143
|
+
}
|
|
3144
|
+
const res = await fetchTenantUser(this.#config, "DELETE");
|
|
3145
|
+
return responseHandler(res, rawResponse);
|
|
3146
|
+
});
|
|
2839
3147
|
}
|
|
2840
3148
|
async users(req, rawResponse) {
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
3149
|
+
return withNileContext(
|
|
3150
|
+
this.#config,
|
|
3151
|
+
async () => {
|
|
3152
|
+
this.#handleContext(req);
|
|
3153
|
+
const res = await fetchTenantUsers(this.#config, "GET");
|
|
3154
|
+
return responseHandler(
|
|
3155
|
+
res,
|
|
3156
|
+
rawResponse || typeof req === "boolean" && req
|
|
3157
|
+
);
|
|
3158
|
+
},
|
|
3159
|
+
"users"
|
|
2846
3160
|
);
|
|
2847
3161
|
}
|
|
2848
3162
|
/**
|
|
2849
3163
|
* List invites for the current tenant via `GET /api/tenants/{tenantId}/invites`.
|
|
2850
3164
|
*/
|
|
2851
3165
|
async invites() {
|
|
2852
|
-
|
|
2853
|
-
|
|
3166
|
+
return withNileContext(
|
|
3167
|
+
this.#config,
|
|
3168
|
+
async () => {
|
|
3169
|
+
const res = await fetchInvites(this.#config);
|
|
3170
|
+
return responseHandler(res);
|
|
3171
|
+
},
|
|
3172
|
+
"invites"
|
|
3173
|
+
);
|
|
2854
3174
|
}
|
|
2855
3175
|
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(
|
|
3176
|
+
return withNileContext(
|
|
2877
3177
|
this.#config,
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
3178
|
+
async () => {
|
|
3179
|
+
await runExtensionContext(this.#config);
|
|
3180
|
+
const { csrfToken } = await obtainCsrf(
|
|
3181
|
+
this.#config
|
|
3182
|
+
);
|
|
3183
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3184
|
+
let identifier = req;
|
|
3185
|
+
let callbackUrl = defaults.callbackUrl;
|
|
3186
|
+
let redirectUrl = defaults.redirectUrl;
|
|
3187
|
+
if (typeof req === "object") {
|
|
3188
|
+
if ("email" in req) {
|
|
3189
|
+
identifier = req.email;
|
|
3190
|
+
}
|
|
3191
|
+
if ("callbackUrl" in req) {
|
|
3192
|
+
callbackUrl = fQUrl2(req.callbackUrl ?? "", this.#config);
|
|
3193
|
+
}
|
|
3194
|
+
if ("redirectUrl" in req) {
|
|
3195
|
+
redirectUrl = fQUrl2(req.redirectUrl ?? "", this.#config);
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
const { headers } = ctx.get();
|
|
3199
|
+
headers?.set("Content-Type", "application/x-www-form-urlencoded");
|
|
3200
|
+
ctx.set({ headers });
|
|
3201
|
+
const res = await fetchInvite(
|
|
3202
|
+
this.#config,
|
|
3203
|
+
"POST",
|
|
3204
|
+
new URLSearchParams({
|
|
3205
|
+
identifier,
|
|
3206
|
+
csrfToken,
|
|
3207
|
+
callbackUrl,
|
|
3208
|
+
redirectUrl
|
|
3209
|
+
}).toString()
|
|
3210
|
+
);
|
|
3211
|
+
return responseHandler(res, rawResponse);
|
|
3212
|
+
},
|
|
3213
|
+
"invites"
|
|
2885
3214
|
);
|
|
2886
|
-
return responseHandler(res, rawResponse);
|
|
2887
3215
|
}
|
|
2888
3216
|
/**
|
|
2889
3217
|
* Accept an invite using `PUT /api/tenants/{tenantId}/invite`.
|
|
@@ -2892,22 +3220,24 @@ var Tenants = class {
|
|
|
2892
3220
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2893
3221
|
*/
|
|
2894
3222
|
async acceptInvite(req, rawResponse) {
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
3223
|
+
return withNileContext(this.#config, async () => {
|
|
3224
|
+
if (!req) {
|
|
3225
|
+
throw new Error("The identifier and token are required.");
|
|
3226
|
+
}
|
|
3227
|
+
const { identifier, token } = req;
|
|
3228
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3229
|
+
const callbackUrl = String(defaults.callbackUrl);
|
|
3230
|
+
const res = await fetchInvite(
|
|
3231
|
+
this.#config,
|
|
3232
|
+
"PUT",
|
|
3233
|
+
new URLSearchParams({
|
|
3234
|
+
identifier,
|
|
3235
|
+
token,
|
|
3236
|
+
callbackUrl
|
|
3237
|
+
}).toString()
|
|
3238
|
+
);
|
|
3239
|
+
return responseHandler(res, rawResponse);
|
|
3240
|
+
});
|
|
2911
3241
|
}
|
|
2912
3242
|
/**
|
|
2913
3243
|
* Delete a pending invite using `DELETE /api/tenants/{tenantId}/invite/{inviteId}`.
|
|
@@ -2915,25 +3245,27 @@ var Tenants = class {
|
|
|
2915
3245
|
* @param req - Identifier of the invite to remove.
|
|
2916
3246
|
*/
|
|
2917
3247
|
async deleteInvite(req) {
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
3248
|
+
return withNileContext(this.#config, async () => {
|
|
3249
|
+
let id = "";
|
|
3250
|
+
if (typeof req === "object") {
|
|
3251
|
+
id = req.id;
|
|
3252
|
+
} else {
|
|
3253
|
+
id = req;
|
|
3254
|
+
}
|
|
3255
|
+
if (!id) {
|
|
3256
|
+
throw new Error("An invite id is required.");
|
|
3257
|
+
}
|
|
3258
|
+
const res = await fetchInvite(this.#config, "DELETE", id);
|
|
3259
|
+
return responseHandler(res, true);
|
|
3260
|
+
});
|
|
2929
3261
|
}
|
|
2930
3262
|
#handleContext(req) {
|
|
2931
3263
|
if (typeof req === "object") {
|
|
2932
3264
|
if ("tenantId" in req) {
|
|
2933
|
-
|
|
3265
|
+
ctx.set({ tenantId: req.tenantId, preserveHeaders: true });
|
|
2934
3266
|
}
|
|
2935
3267
|
if ("userId" in req) {
|
|
2936
|
-
|
|
3268
|
+
ctx.set({ userId: req.userId, preserveHeaders: true });
|
|
2937
3269
|
}
|
|
2938
3270
|
}
|
|
2939
3271
|
}
|
|
@@ -2951,19 +3283,32 @@ async function responseHandler(res, rawResponse) {
|
|
|
2951
3283
|
function defaultCallbackUrl3(config) {
|
|
2952
3284
|
let cb = null;
|
|
2953
3285
|
let redirect = null;
|
|
2954
|
-
const
|
|
3286
|
+
const { headers, tenantId } = ctx.get();
|
|
3287
|
+
const fallbackCb = parseCallback(headers);
|
|
2955
3288
|
if (fallbackCb) {
|
|
2956
3289
|
const [, value] = fallbackCb.split("=");
|
|
2957
3290
|
cb = decodeURIComponent(value);
|
|
2958
3291
|
if (value) {
|
|
2959
|
-
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
|
|
2960
|
-
"{tenantId}",
|
|
2961
|
-
String(config.tenantId)
|
|
2962
|
-
)}`;
|
|
3292
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", String(tenantId))}`;
|
|
2963
3293
|
}
|
|
2964
3294
|
}
|
|
2965
3295
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
2966
3296
|
}
|
|
3297
|
+
function fQUrl2(path, config) {
|
|
3298
|
+
if (path.startsWith("/")) {
|
|
3299
|
+
const { callbackUrl } = defaultCallbackUrl3(config);
|
|
3300
|
+
if (callbackUrl) {
|
|
3301
|
+
const { origin } = new URL(callbackUrl);
|
|
3302
|
+
return `${origin}${path}`;
|
|
3303
|
+
}
|
|
3304
|
+
}
|
|
3305
|
+
try {
|
|
3306
|
+
new URL(path);
|
|
3307
|
+
} catch {
|
|
3308
|
+
throw new Error("An invalid URL has been passed.");
|
|
3309
|
+
}
|
|
3310
|
+
return path;
|
|
3311
|
+
}
|
|
2967
3312
|
|
|
2968
3313
|
// src/api/handlers/withContext/index.ts
|
|
2969
3314
|
function handlersWithContext(config) {
|
|
@@ -3026,97 +3371,6 @@ function updateConfig(response, config) {
|
|
|
3026
3371
|
};
|
|
3027
3372
|
}
|
|
3028
3373
|
|
|
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
3374
|
// src/Server.ts
|
|
3121
3375
|
var Server = class {
|
|
3122
3376
|
users;
|
|
@@ -3125,35 +3379,37 @@ var Server = class {
|
|
|
3125
3379
|
#config;
|
|
3126
3380
|
#handlers;
|
|
3127
3381
|
#manager;
|
|
3128
|
-
#headers;
|
|
3129
|
-
#preserveHeaders;
|
|
3382
|
+
// #headers: undefined | Headers;
|
|
3383
|
+
// #preserveHeaders: boolean;
|
|
3130
3384
|
constructor(config) {
|
|
3131
3385
|
this.#config = new Config({
|
|
3132
3386
|
...config,
|
|
3133
3387
|
extensionCtx: buildExtensionConfig(this)
|
|
3134
3388
|
});
|
|
3135
3389
|
watchTenantId((tenantId) => {
|
|
3136
|
-
if (tenantId !== this.#config.tenantId) {
|
|
3137
|
-
this.#config.tenantId = tenantId;
|
|
3390
|
+
if (tenantId !== this.#config.context.tenantId) {
|
|
3391
|
+
this.#config.context.tenantId = String(tenantId);
|
|
3138
3392
|
this.#reset();
|
|
3139
3393
|
}
|
|
3140
3394
|
});
|
|
3141
3395
|
watchUserId((userId) => {
|
|
3142
|
-
if (userId !== this.#config.userId) {
|
|
3143
|
-
this.#config.userId = userId;
|
|
3396
|
+
if (userId !== this.#config.context.userId) {
|
|
3397
|
+
this.#config.context.userId = String(userId);
|
|
3144
3398
|
this.#reset();
|
|
3145
3399
|
}
|
|
3146
3400
|
});
|
|
3147
3401
|
watchHeaders((headers) => {
|
|
3148
|
-
|
|
3149
|
-
|
|
3402
|
+
if (headers) {
|
|
3403
|
+
this.#config.context.headers = new Headers(headers);
|
|
3404
|
+
this.#reset();
|
|
3405
|
+
}
|
|
3150
3406
|
});
|
|
3151
3407
|
this.#handlers = {
|
|
3152
3408
|
...this.#config.handlers,
|
|
3153
3409
|
withContext: handlersWithContext(this.#config)
|
|
3154
3410
|
};
|
|
3155
|
-
this.#preserveHeaders = config?.preserveHeaders ?? false;
|
|
3156
|
-
this.#config.tenantId = getTenantId({ config: this.#config });
|
|
3411
|
+
this.#config.context.preserveHeaders = config?.preserveHeaders ?? false;
|
|
3412
|
+
this.#config.context.tenantId = getTenantId({ config: this.#config });
|
|
3157
3413
|
this.#manager = new DBManager(this.#config);
|
|
3158
3414
|
this.#handleHeaders(config);
|
|
3159
3415
|
this.users = new Users(this.#config);
|
|
@@ -3208,21 +3464,6 @@ var Server = class {
|
|
|
3208
3464
|
}
|
|
3209
3465
|
};
|
|
3210
3466
|
}
|
|
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
3467
|
get handlers() {
|
|
3227
3468
|
return this.#handlers;
|
|
3228
3469
|
}
|
|
@@ -3232,98 +3473,30 @@ var Server = class {
|
|
|
3232
3473
|
set paths(paths) {
|
|
3233
3474
|
this.#config.paths = paths;
|
|
3234
3475
|
}
|
|
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 {
|
|
3476
|
+
async withContext(context, fn) {
|
|
3477
|
+
const { ddl, ...ctx2 } = context ?? defaultContext;
|
|
3478
|
+
this.#config.context = { ...ctx2 };
|
|
3479
|
+
const preserve = (context && "preserveHeaders" in context && context.preserveHeaders) ?? true;
|
|
3480
|
+
if (preserve) {
|
|
3481
|
+
this.#config.context = { ...this.getContext(), ...context };
|
|
3287
3482
|
}
|
|
3288
|
-
if (
|
|
3289
|
-
|
|
3483
|
+
if (ddl) {
|
|
3484
|
+
delete this.#config.context.tenantId;
|
|
3485
|
+
delete this.#config.context.userId;
|
|
3290
3486
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
if (headers) {
|
|
3295
|
-
this.#handleHeaders(headers);
|
|
3296
|
-
this.#reset();
|
|
3297
|
-
return;
|
|
3298
|
-
}
|
|
3299
|
-
} catch {
|
|
3487
|
+
return withNileContext(this.#config, async () => {
|
|
3488
|
+
if (fn) {
|
|
3489
|
+
return fn(this);
|
|
3300
3490
|
}
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
};
|
|
3491
|
+
return this;
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
/**
|
|
3495
|
+
*
|
|
3496
|
+
* @returns the last used (basically global) context object, useful for debugging or making your own context
|
|
3497
|
+
*/
|
|
3309
3498
|
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
|
-
};
|
|
3499
|
+
return ctx.getLastUsed();
|
|
3327
3500
|
}
|
|
3328
3501
|
/**
|
|
3329
3502
|
* Merge headers together
|
|
@@ -3332,16 +3505,19 @@ var Server = class {
|
|
|
3332
3505
|
#handleHeaders(config) {
|
|
3333
3506
|
const updates = [];
|
|
3334
3507
|
let headers;
|
|
3335
|
-
this.#headers = new Headers();
|
|
3508
|
+
this.#config.context.headers = new Headers();
|
|
3336
3509
|
if (config instanceof Headers) {
|
|
3337
3510
|
headers = config;
|
|
3338
3511
|
} else if (config?.headers) {
|
|
3339
3512
|
headers = config?.headers;
|
|
3340
3513
|
if (config && config.origin) {
|
|
3341
|
-
this.#headers.set(HEADER_ORIGIN, config.origin);
|
|
3514
|
+
this.#config.context.headers.set(HEADER_ORIGIN, config.origin);
|
|
3342
3515
|
}
|
|
3343
3516
|
if (config && config.secureCookies != null) {
|
|
3344
|
-
this.#headers.set(
|
|
3517
|
+
this.#config.context.headers.set(
|
|
3518
|
+
HEADER_SECURE_COOKIES,
|
|
3519
|
+
String(config.secureCookies)
|
|
3520
|
+
);
|
|
3345
3521
|
}
|
|
3346
3522
|
}
|
|
3347
3523
|
if (headers instanceof Headers) {
|
|
@@ -3354,8 +3530,7 @@ var Server = class {
|
|
|
3354
3530
|
}
|
|
3355
3531
|
}
|
|
3356
3532
|
const merged = {};
|
|
3357
|
-
this.#config.
|
|
3358
|
-
this.#headers?.forEach((value, key17) => {
|
|
3533
|
+
this.#config.context.headers?.forEach((value, key17) => {
|
|
3359
3534
|
if (key17.toLowerCase() !== "cookie") {
|
|
3360
3535
|
merged[key17.toLowerCase()] = value;
|
|
3361
3536
|
}
|
|
@@ -3364,16 +3539,14 @@ var Server = class {
|
|
|
3364
3539
|
merged[key17] = value;
|
|
3365
3540
|
}
|
|
3366
3541
|
for (const [key17, value] of Object.entries(merged)) {
|
|
3367
|
-
this.#headers.set(key17, value);
|
|
3542
|
+
this.#config.context.headers.set(key17, value);
|
|
3368
3543
|
}
|
|
3369
3544
|
this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
|
|
3370
|
-
this.#config.headers = this.#headers;
|
|
3371
3545
|
}
|
|
3372
3546
|
/**
|
|
3373
3547
|
* Allow some internal mutations to reset our config + headers
|
|
3374
3548
|
*/
|
|
3375
3549
|
#reset = () => {
|
|
3376
|
-
this.#config.headers = this.#headers ?? new Headers();
|
|
3377
3550
|
this.#config.extensionCtx = buildExtensionConfig(this);
|
|
3378
3551
|
this.users = new Users(this.#config);
|
|
3379
3552
|
this.tenants = new Tenants(this.#config);
|
|
@@ -3400,6 +3573,7 @@ exports.USER_COOKIE = USER_COOKIE;
|
|
|
3400
3573
|
exports.parseCSRF = parseCSRF;
|
|
3401
3574
|
exports.parseCallback = parseCallback;
|
|
3402
3575
|
exports.parseResetToken = parseResetToken;
|
|
3576
|
+
exports.parseTenantId = parseTenantId;
|
|
3403
3577
|
exports.parseToken = parseToken;
|
|
3404
3578
|
//# sourceMappingURL=index.js.map
|
|
3405
3579
|
//# sourceMappingURL=index.js.map
|