@niledatabase/server 5.0.0-alpha.25 → 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.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
1
2
|
import 'dotenv/config';
|
|
2
3
|
import pg from 'pg';
|
|
3
4
|
|
|
@@ -6,6 +7,7 @@ var ExtensionState = /* @__PURE__ */ ((ExtensionState2) => {
|
|
|
6
7
|
ExtensionState2["onHandleRequest"] = "onHandleRequest";
|
|
7
8
|
ExtensionState2["onRequest"] = "onRequest";
|
|
8
9
|
ExtensionState2["onResponse"] = "onResponse";
|
|
10
|
+
ExtensionState2["withContext"] = "withContext";
|
|
9
11
|
return ExtensionState2;
|
|
10
12
|
})(ExtensionState || {});
|
|
11
13
|
var APIErrorErrorCodeEnum = {
|
|
@@ -63,21 +65,18 @@ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
|
|
|
63
65
|
INVITE: `${prefix}${"/tenants/{tenantId}/invite" /* INVITE */}`,
|
|
64
66
|
LOG: `${prefix}/_log`
|
|
65
67
|
});
|
|
66
|
-
var apiRoutes = (
|
|
67
|
-
ME: makeRestUrl(
|
|
68
|
-
USERS: (qp) => makeRestUrl(
|
|
69
|
-
USER: (userId) => makeRestUrl(
|
|
70
|
-
TENANTS: makeRestUrl(
|
|
71
|
-
TENANT: (tenantId) => makeRestUrl(
|
|
72
|
-
SIGNUP: makeRestUrl(
|
|
73
|
-
TENANT_USERS: (tenantId) => makeRestUrl(
|
|
74
|
-
INVITES: (tenantId) => makeRestUrl(
|
|
75
|
-
INVITE: (tenantId) => makeRestUrl(
|
|
76
|
-
TENANT_USER: makeRestUrl(
|
|
77
|
-
|
|
78
|
-
`/tenants/${config.tenantId}/users/${config.userId}`
|
|
79
|
-
),
|
|
80
|
-
USER_TENANTS: (userId) => makeRestUrl(config, `/users/${userId}/tenants`)
|
|
68
|
+
var apiRoutes = (apiUrl) => ({
|
|
69
|
+
ME: makeRestUrl(apiUrl, "/me"),
|
|
70
|
+
USERS: (qp) => makeRestUrl(apiUrl, "/users", qp),
|
|
71
|
+
USER: (userId) => makeRestUrl(apiUrl, `/users/${userId}`),
|
|
72
|
+
TENANTS: makeRestUrl(apiUrl, "/tenants"),
|
|
73
|
+
TENANT: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}`),
|
|
74
|
+
SIGNUP: makeRestUrl(apiUrl, "/signup"),
|
|
75
|
+
TENANT_USERS: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users`),
|
|
76
|
+
INVITES: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invites`),
|
|
77
|
+
INVITE: (tenantId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/invite`),
|
|
78
|
+
TENANT_USER: (tenantId, userId) => makeRestUrl(apiUrl, `/tenants/${tenantId}/users/${userId}`),
|
|
79
|
+
USER_TENANTS: (userId) => makeRestUrl(apiUrl, `/users/${userId}/tenants`)
|
|
81
80
|
});
|
|
82
81
|
var proxyRoutes = (config) => ({
|
|
83
82
|
SIGNIN: makeRestUrl(config, "/auth/signin" /* SIGNIN */),
|
|
@@ -101,8 +100,8 @@ function filterNullUndefined(obj) {
|
|
|
101
100
|
)
|
|
102
101
|
);
|
|
103
102
|
}
|
|
104
|
-
function makeRestUrl(
|
|
105
|
-
const url =
|
|
103
|
+
function makeRestUrl(apiUrl, path, qp) {
|
|
104
|
+
const url = apiUrl || NILEDB_API_URL;
|
|
106
105
|
if (!url) {
|
|
107
106
|
throw new Error(
|
|
108
107
|
"An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?"
|
|
@@ -259,10 +258,290 @@ async function auth(req, config) {
|
|
|
259
258
|
}
|
|
260
259
|
}
|
|
261
260
|
|
|
261
|
+
// src/utils/Logger.ts
|
|
262
|
+
var red = "\x1B[31m";
|
|
263
|
+
var yellow = "\x1B[38;2;255;255;0m";
|
|
264
|
+
var purple = "\x1B[38;2;200;160;255m";
|
|
265
|
+
var orange = "\x1B[38;2;255;165;0m";
|
|
266
|
+
var reset = "\x1B[0m";
|
|
267
|
+
var baseLogger = (config, ...params) => ({
|
|
268
|
+
silly(message, meta) {
|
|
269
|
+
if (config?.debug && process.env.LOG_LEVEL === "silly") {
|
|
270
|
+
console.log(
|
|
271
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
272
|
+
""
|
|
273
|
+
)}${reset} ${message}`,
|
|
274
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
info(message, meta) {
|
|
279
|
+
if (config?.debug) {
|
|
280
|
+
console.info(
|
|
281
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
282
|
+
""
|
|
283
|
+
)}${reset} ${message}`,
|
|
284
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
debug(message, meta) {
|
|
289
|
+
if (config?.debug) {
|
|
290
|
+
console.log(
|
|
291
|
+
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
292
|
+
""
|
|
293
|
+
)}${reset} ${message}`,
|
|
294
|
+
meta ? `${JSON.stringify(meta)}` : ""
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
warn(message, meta) {
|
|
299
|
+
if (config?.debug) {
|
|
300
|
+
console.warn(
|
|
301
|
+
`${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
|
|
302
|
+
""
|
|
303
|
+
)}${reset} ${message}`,
|
|
304
|
+
meta ? JSON.stringify(meta) : ""
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
error(message, meta) {
|
|
309
|
+
console.error(
|
|
310
|
+
`${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
|
|
311
|
+
""
|
|
312
|
+
)}${red} ${message}`,
|
|
313
|
+
meta ? meta : "",
|
|
314
|
+
`${reset}`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
function Logger(config) {
|
|
319
|
+
return (prefixes) => {
|
|
320
|
+
const { info, debug, warn: warn2, error, silly: silly2 } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
|
|
321
|
+
return {
|
|
322
|
+
info,
|
|
323
|
+
debug,
|
|
324
|
+
warn: warn2,
|
|
325
|
+
error,
|
|
326
|
+
silly: silly2
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function matchesLog(configRoutes, request2) {
|
|
331
|
+
return urlMatches(request2.url, configRoutes.LOG);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/api/utils/extensions.ts
|
|
335
|
+
function getRequestConfig(params) {
|
|
336
|
+
if (typeof params[1] === "object") {
|
|
337
|
+
return params[1];
|
|
338
|
+
}
|
|
339
|
+
return {};
|
|
340
|
+
}
|
|
341
|
+
function bindRunExtensions(instance) {
|
|
342
|
+
return async function runExtensions(toRun, config, params, _init) {
|
|
343
|
+
const { debug } = config.logger("[EXTENSIONS]");
|
|
344
|
+
const extensionConfig = getRequestConfig(
|
|
345
|
+
Array.isArray(params) ? params : [null, params]
|
|
346
|
+
);
|
|
347
|
+
if (config.extensions) {
|
|
348
|
+
for (const create2 of config.extensions) {
|
|
349
|
+
if (typeof create2 !== "function") {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const ext = create2(instance);
|
|
353
|
+
if (extensionConfig.disableExtensions?.includes(ext.id)) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (ext.withContext && toRun === "withContext" /* withContext */) {
|
|
357
|
+
await ext.withContext(ctx);
|
|
358
|
+
}
|
|
359
|
+
if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
|
|
360
|
+
const result = await ext.onHandleRequest(
|
|
361
|
+
Array.isArray(params) ? params : [params]
|
|
362
|
+
);
|
|
363
|
+
debug(`${ext.id ?? create2.name} ran onHandleRequest`);
|
|
364
|
+
if (result != null) {
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const [param] = Array.isArray(params) ? params : [params];
|
|
369
|
+
if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
|
|
370
|
+
const { ...previousContext } = ctx.get();
|
|
371
|
+
const preserveHeaders = previousContext.preserveHeaders;
|
|
372
|
+
if (preserveHeaders) {
|
|
373
|
+
ctx.set({ preserveHeaders: false });
|
|
374
|
+
}
|
|
375
|
+
if (!_init) {
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
const previousHeaders = new Headers(previousContext.headers);
|
|
379
|
+
await ext.onRequest(_init.request, ctx);
|
|
380
|
+
const updatedContext = ctx.get();
|
|
381
|
+
if (updatedContext?.headers) {
|
|
382
|
+
const cookie = updatedContext.headers.get("cookie");
|
|
383
|
+
if (cookie && param.headers) {
|
|
384
|
+
const updatedCookies = mergeCookies(
|
|
385
|
+
preserveHeaders ? previousHeaders?.get("cookie") : null,
|
|
386
|
+
updatedContext.headers.get("cookie")
|
|
387
|
+
);
|
|
388
|
+
param.headers.set("cookie", updatedCookies);
|
|
389
|
+
}
|
|
390
|
+
if (updatedContext.tenantId && param.headers) {
|
|
391
|
+
param.headers.set(
|
|
392
|
+
TENANT_COOKIE,
|
|
393
|
+
String(updatedContext.headers.get(TENANT_COOKIE))
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
ctx.set({ headers: param.headers });
|
|
397
|
+
}
|
|
398
|
+
debug(`${ext.id ?? create2.name} ran onRequest`);
|
|
399
|
+
}
|
|
400
|
+
if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
|
|
401
|
+
const result = await ext.onResponse(param, ctx);
|
|
402
|
+
debug(`${ext.id ?? create2.name} ran onResponse`);
|
|
403
|
+
if (result != null) {
|
|
404
|
+
return result;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return void 0;
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function buildExtensionConfig(instance) {
|
|
413
|
+
return {
|
|
414
|
+
runExtensions: bindRunExtensions(instance)
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
function mergeCookies(...cookieStrings) {
|
|
418
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
419
|
+
for (const str of cookieStrings) {
|
|
420
|
+
if (!str) continue;
|
|
421
|
+
for (const part of str.split(";")) {
|
|
422
|
+
const [key17, value] = part.split("=").map((s) => s.trim());
|
|
423
|
+
if (key17 && value) cookieMap.set(key17, value);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
|
|
427
|
+
}
|
|
428
|
+
async function runExtensionContext(config) {
|
|
429
|
+
await config?.extensionCtx?.runExtensions("withContext" /* withContext */, config);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/api/utils/request-context.ts
|
|
433
|
+
var { warn, silly } = Logger({ debug: true })("[REQUEST CONTEXT]");
|
|
434
|
+
var storage = new AsyncLocalStorage();
|
|
435
|
+
var defaultContext = {
|
|
436
|
+
headers: new Headers(),
|
|
437
|
+
tenantId: void 0,
|
|
438
|
+
userId: void 0,
|
|
439
|
+
preserveHeaders: false
|
|
440
|
+
};
|
|
441
|
+
var lastUsedContext = defaultContext;
|
|
442
|
+
var ctx = {
|
|
443
|
+
run(ctx2, fn) {
|
|
444
|
+
const merged = {
|
|
445
|
+
...defaultContext,
|
|
446
|
+
...ctx2,
|
|
447
|
+
headers: ctx2.headers instanceof Headers ? ctx2.headers : new Headers(ctx2.headers)
|
|
448
|
+
};
|
|
449
|
+
lastUsedContext = merged;
|
|
450
|
+
return storage.run(merged, fn);
|
|
451
|
+
},
|
|
452
|
+
get: () => {
|
|
453
|
+
const ctx2 = storage.getStore();
|
|
454
|
+
if (!ctx2) {
|
|
455
|
+
return { ...defaultContext };
|
|
456
|
+
}
|
|
457
|
+
silly(`[GET] ${serializeContext(ctx2)}`);
|
|
458
|
+
return ctx2;
|
|
459
|
+
},
|
|
460
|
+
/**
|
|
461
|
+
* This is a mirror of Server.getContext, but only for requests. We keep only the request
|
|
462
|
+
* information around, everything else is :above_my_pay_grade:
|
|
463
|
+
* @param partial A partial context to override
|
|
464
|
+
*/
|
|
465
|
+
set: (partial) => {
|
|
466
|
+
const store = storage.getStore();
|
|
467
|
+
if (!store) {
|
|
468
|
+
warn("ctx.set() called outside of ctx.run(). This will not persist.");
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
if (partial.headers === null) {
|
|
472
|
+
store.headers = new Headers();
|
|
473
|
+
} else if (partial.headers && store.headers instanceof Headers) {
|
|
474
|
+
for (const [k, v] of new Headers(partial.headers).entries()) {
|
|
475
|
+
store.headers.set(k, v);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if ("tenantId" in partial)
|
|
479
|
+
store.tenantId = partial.tenantId ?? store.tenantId;
|
|
480
|
+
if ("userId" in partial) store.userId = partial.userId ?? store.userId;
|
|
481
|
+
if ("preserveHeaders" in partial)
|
|
482
|
+
store.preserveHeaders = Boolean(partial.preserveHeaders);
|
|
483
|
+
silly(`[SET] ${serializeContext(store)}`);
|
|
484
|
+
lastUsedContext = { ...store };
|
|
485
|
+
},
|
|
486
|
+
// for convenience only
|
|
487
|
+
getLastUsed: () => lastUsedContext
|
|
488
|
+
};
|
|
489
|
+
function withNileContext(config, fn, name = "unknown") {
|
|
490
|
+
const initialContext = config.context;
|
|
491
|
+
const existing = ctx.get();
|
|
492
|
+
const mergedHeaders = new Headers(existing.headers);
|
|
493
|
+
if (initialContext instanceof Request) {
|
|
494
|
+
initialContext.headers.forEach((value, key17) => {
|
|
495
|
+
mergedHeaders.set(key17, value);
|
|
496
|
+
});
|
|
497
|
+
const context2 = {
|
|
498
|
+
headers: mergedHeaders,
|
|
499
|
+
tenantId: existing.tenantId,
|
|
500
|
+
userId: existing.userId,
|
|
501
|
+
preserveHeaders: existing.preserveHeaders ?? false
|
|
502
|
+
};
|
|
503
|
+
silly(`${name} [INITIAL - Request] ${serializeContext(context2)}`);
|
|
504
|
+
return ctx.run(context2, fn);
|
|
505
|
+
}
|
|
506
|
+
if (initialContext.headers) {
|
|
507
|
+
const incoming = initialContext.headers instanceof Headers ? initialContext.headers : new Headers(initialContext.headers);
|
|
508
|
+
incoming.forEach((value, key17) => {
|
|
509
|
+
mergedHeaders.set(key17, value);
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
const tenantId = "tenantId" in initialContext && initialContext.tenantId;
|
|
513
|
+
const userId = "userId" in initialContext && initialContext.userId;
|
|
514
|
+
const preserveHeaders = "preserveHeaders" in initialContext && initialContext.preserveHeaders;
|
|
515
|
+
const context = {
|
|
516
|
+
headers: mergedHeaders,
|
|
517
|
+
tenantId: tenantId ? tenantId : existing.tenantId,
|
|
518
|
+
userId: userId ? userId : existing.userId,
|
|
519
|
+
preserveHeaders: preserveHeaders ? preserveHeaders : existing.preserveHeaders ?? false
|
|
520
|
+
};
|
|
521
|
+
silly(`${name} [INITIAL - Partial<Context>] ${serializeContext(context)}`);
|
|
522
|
+
return ctx.run(context, async () => {
|
|
523
|
+
await runExtensionContext(config);
|
|
524
|
+
return fn();
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
function serializeContext(context) {
|
|
528
|
+
const headers = {};
|
|
529
|
+
const rawHeaders = new Headers(context.headers);
|
|
530
|
+
rawHeaders.forEach((value, key17) => {
|
|
531
|
+
headers[key17] = value;
|
|
532
|
+
});
|
|
533
|
+
return JSON.stringify({
|
|
534
|
+
headers,
|
|
535
|
+
tenantId: context.tenantId,
|
|
536
|
+
userId: context.userId,
|
|
537
|
+
preserveHeaders: context.preserveHeaders
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
|
|
262
541
|
// src/api/routes/me/index.ts
|
|
263
542
|
var key = "ME";
|
|
264
543
|
async function route(request2, config) {
|
|
265
|
-
const url = apiRoutes(config)[key];
|
|
544
|
+
const url = apiRoutes(config.apiUrl)[key];
|
|
266
545
|
if (request2.method === "GET") {
|
|
267
546
|
return await GET(url, { request: request2 }, config);
|
|
268
547
|
}
|
|
@@ -283,8 +562,9 @@ function matches(configRoutes, request2) {
|
|
|
283
562
|
}
|
|
284
563
|
async function fetchMe(config, method, body) {
|
|
285
564
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
|
|
565
|
+
const { headers } = ctx.get();
|
|
286
566
|
const init = {
|
|
287
|
-
headers
|
|
567
|
+
headers,
|
|
288
568
|
method: method ?? "GET"
|
|
289
569
|
};
|
|
290
570
|
if (method === "PUT") {
|
|
@@ -336,9 +616,9 @@ function getTokenFromCookie(headers, cookieKey) {
|
|
|
336
616
|
return _cookies[cookieKey];
|
|
337
617
|
}
|
|
338
618
|
}
|
|
339
|
-
function getTenantFromHttp(headers,
|
|
619
|
+
function getTenantFromHttp(headers, context) {
|
|
340
620
|
const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
|
|
341
|
-
return cookieTenant ? cookieTenant :
|
|
621
|
+
return cookieTenant ? cookieTenant : context?.tenantId;
|
|
342
622
|
}
|
|
343
623
|
|
|
344
624
|
// src/api/routes/users/POST.ts
|
|
@@ -348,8 +628,11 @@ async function POST(config, init) {
|
|
|
348
628
|
const yurl = new URL(init.request.url);
|
|
349
629
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
350
630
|
const newTenantName = yurl.searchParams.get("newTenantName");
|
|
351
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers
|
|
352
|
-
const url = apiRoutes(config).USERS({
|
|
631
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
632
|
+
const url = apiRoutes(config.apiUrl).USERS({
|
|
633
|
+
tenantId: tenant,
|
|
634
|
+
newTenantName
|
|
635
|
+
});
|
|
353
636
|
return await request(url, init, config);
|
|
354
637
|
}
|
|
355
638
|
|
|
@@ -357,13 +640,13 @@ async function POST(config, init) {
|
|
|
357
640
|
async function GET2(config, init, log) {
|
|
358
641
|
const yurl = new URL(init.request.url);
|
|
359
642
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
360
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
|
|
643
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config.context);
|
|
361
644
|
if (!tenant) {
|
|
362
645
|
log("[GET] No tenant id provided.");
|
|
363
646
|
return new Response(null, { status: 404 });
|
|
364
647
|
}
|
|
365
648
|
init.method = "GET";
|
|
366
|
-
const url = apiRoutes(config).TENANT_USERS(tenant);
|
|
649
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenant);
|
|
367
650
|
return await request(url, init, config);
|
|
368
651
|
}
|
|
369
652
|
|
|
@@ -372,7 +655,7 @@ async function PUT2(config, init) {
|
|
|
372
655
|
init.body = init.request.body;
|
|
373
656
|
init.method = "PUT";
|
|
374
657
|
const [userId] = new URL(init.request.url).pathname.split("/").reverse();
|
|
375
|
-
const url = apiRoutes(config).USER(userId);
|
|
658
|
+
const url = apiRoutes(config.apiUrl).USER(userId);
|
|
376
659
|
return await request(url, init, config);
|
|
377
660
|
}
|
|
378
661
|
|
|
@@ -399,7 +682,7 @@ function matches2(configRoutes, request2) {
|
|
|
399
682
|
async function GET3(config, init) {
|
|
400
683
|
const yurl = new URL(init.request.url);
|
|
401
684
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
402
|
-
const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
|
|
685
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USERS(tenantId)}`;
|
|
403
686
|
return await request(url, init, config);
|
|
404
687
|
}
|
|
405
688
|
|
|
@@ -413,7 +696,7 @@ async function POST2(config, init) {
|
|
|
413
696
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
414
697
|
init.body = JSON.stringify({ email: session.email });
|
|
415
698
|
init.method = "POST";
|
|
416
|
-
const url = apiRoutes(config).TENANT_USERS(tenantId);
|
|
699
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenantId);
|
|
417
700
|
return await request(url, init, config);
|
|
418
701
|
}
|
|
419
702
|
|
|
@@ -447,12 +730,13 @@ function matches3(configRoutes, request2) {
|
|
|
447
730
|
}
|
|
448
731
|
async function fetchTenantUsers(config, method, payload) {
|
|
449
732
|
const { body, params } = {};
|
|
450
|
-
|
|
733
|
+
const { tenantId, headers } = ctx.get();
|
|
734
|
+
if (!tenantId) {
|
|
451
735
|
throw new Error(
|
|
452
736
|
"Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
453
737
|
);
|
|
454
738
|
}
|
|
455
|
-
if (!isUUID(
|
|
739
|
+
if (!isUUID(tenantId)) {
|
|
456
740
|
config.logger("fetchTenantUsers").warn(
|
|
457
741
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
458
742
|
);
|
|
@@ -464,14 +748,11 @@ async function fetchTenantUsers(config, method, payload) {
|
|
|
464
748
|
if (params?.tenantId) {
|
|
465
749
|
q.set("tenantId", params.tenantId);
|
|
466
750
|
}
|
|
467
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
|
|
468
|
-
"{tenantId}",
|
|
469
|
-
config.tenantId
|
|
470
|
-
)}`;
|
|
751
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace("{tenantId}", tenantId)}`;
|
|
471
752
|
const m = method;
|
|
472
753
|
const init = {
|
|
473
754
|
method: m,
|
|
474
|
-
headers
|
|
755
|
+
headers
|
|
475
756
|
};
|
|
476
757
|
const req = new Request(clientUrl, init);
|
|
477
758
|
return await config.handlers[m](req);
|
|
@@ -488,7 +769,7 @@ async function PUT3(config, init) {
|
|
|
488
769
|
init.body = new URLSearchParams(yurl.searchParams).toString();
|
|
489
770
|
}
|
|
490
771
|
init.method = "PUT";
|
|
491
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
772
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
492
773
|
const res = await request(url, init, config);
|
|
493
774
|
const location = res?.headers?.get("location");
|
|
494
775
|
if (location) {
|
|
@@ -512,7 +793,7 @@ async function POST3(config, init) {
|
|
|
512
793
|
}
|
|
513
794
|
init.method = "POST";
|
|
514
795
|
init.body = init.request.body;
|
|
515
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
796
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
516
797
|
return await request(url, init, config);
|
|
517
798
|
}
|
|
518
799
|
|
|
@@ -538,21 +819,22 @@ function matches4(configRoutes, request2) {
|
|
|
538
819
|
return urlMatches(request2.url, route20);
|
|
539
820
|
}
|
|
540
821
|
async function fetchInvite(config, method, body) {
|
|
541
|
-
|
|
822
|
+
const { headers, tenantId } = ctx.get();
|
|
823
|
+
if (!tenantId) {
|
|
542
824
|
throw new Error(
|
|
543
825
|
"Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
544
826
|
);
|
|
545
827
|
}
|
|
546
|
-
if (!isUUID(
|
|
828
|
+
if (!isUUID(tenantId)) {
|
|
547
829
|
config.logger("fetchInvite").warn(
|
|
548
830
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
549
831
|
);
|
|
550
832
|
}
|
|
551
|
-
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}",
|
|
833
|
+
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", tenantId)}`;
|
|
552
834
|
const m = method ?? "GET";
|
|
553
835
|
const init = {
|
|
554
836
|
method: m,
|
|
555
|
-
headers
|
|
837
|
+
headers
|
|
556
838
|
};
|
|
557
839
|
if (method === "POST" || method === "PUT") {
|
|
558
840
|
init.body = body;
|
|
@@ -572,7 +854,7 @@ async function GET4(config, init) {
|
|
|
572
854
|
return new Response(null, { status: 404 });
|
|
573
855
|
}
|
|
574
856
|
init.method = "GET";
|
|
575
|
-
const url = `${apiRoutes(config).INVITES(tenantId)}`;
|
|
857
|
+
const url = `${apiRoutes(config.apiUrl).INVITES(tenantId)}`;
|
|
576
858
|
return await request(url, init, config);
|
|
577
859
|
}
|
|
578
860
|
|
|
@@ -593,29 +875,29 @@ function matches5(configRoutes, request2) {
|
|
|
593
875
|
return url.pathname.endsWith(route20);
|
|
594
876
|
}
|
|
595
877
|
async function fetchInvites(config) {
|
|
596
|
-
|
|
878
|
+
const { tenantId, headers } = ctx.get();
|
|
879
|
+
if (!tenantId) {
|
|
597
880
|
throw new Error(
|
|
598
881
|
"Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
599
882
|
);
|
|
600
883
|
}
|
|
601
|
-
if (!isUUID(
|
|
884
|
+
if (!isUUID(tenantId)) {
|
|
602
885
|
config.logger("fetchInvites").warn(
|
|
603
886
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
604
887
|
);
|
|
605
888
|
}
|
|
606
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}",
|
|
607
|
-
const req = new Request(clientUrl, { headers
|
|
889
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", tenantId)}`;
|
|
890
|
+
const req = new Request(clientUrl, { headers });
|
|
608
891
|
return await config.handlers.GET(req);
|
|
609
892
|
}
|
|
610
893
|
|
|
611
894
|
// src/api/routes/tenants/GET.ts
|
|
612
895
|
async function GET5(config, session, init) {
|
|
613
|
-
let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
|
|
896
|
+
let url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.id)}`;
|
|
614
897
|
if (typeof session === "object" && "user" in session && session.user) {
|
|
615
|
-
url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
|
|
898
|
+
url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.user.id)}`;
|
|
616
899
|
}
|
|
617
|
-
|
|
618
|
-
return res;
|
|
900
|
+
return await request(url, init, config);
|
|
619
901
|
}
|
|
620
902
|
|
|
621
903
|
// src/api/routes/tenants/[tenantId]/GET.ts
|
|
@@ -627,7 +909,7 @@ async function GET6(config, init, log) {
|
|
|
627
909
|
return new Response(null, { status: 404 });
|
|
628
910
|
}
|
|
629
911
|
init.method = "GET";
|
|
630
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
912
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
631
913
|
return await request(url, init, config);
|
|
632
914
|
}
|
|
633
915
|
|
|
@@ -639,7 +921,7 @@ async function DELETE2(config, init) {
|
|
|
639
921
|
return new Response(null, { status: 404 });
|
|
640
922
|
}
|
|
641
923
|
init.method = "DELETE";
|
|
642
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
924
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
643
925
|
return await request(url, init, config);
|
|
644
926
|
}
|
|
645
927
|
|
|
@@ -652,7 +934,7 @@ async function PUT4(config, init) {
|
|
|
652
934
|
}
|
|
653
935
|
init.body = init.request.body;
|
|
654
936
|
init.method = "PUT";
|
|
655
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
937
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
656
938
|
return await request(url, init, config);
|
|
657
939
|
}
|
|
658
940
|
|
|
@@ -660,7 +942,7 @@ async function PUT4(config, init) {
|
|
|
660
942
|
async function POST4(config, init) {
|
|
661
943
|
init.body = init.request.body;
|
|
662
944
|
init.method = "POST";
|
|
663
|
-
const url = `${apiRoutes(config).TENANTS}`;
|
|
945
|
+
const url = `${apiRoutes(config.apiUrl).TENANTS}`;
|
|
664
946
|
return await request(url, init, config);
|
|
665
947
|
}
|
|
666
948
|
|
|
@@ -694,10 +976,11 @@ function matches6(configRoutes, request2) {
|
|
|
694
976
|
return urlMatches(request2.url, configRoutes[key6]);
|
|
695
977
|
}
|
|
696
978
|
async function fetchTenants(config, method, body) {
|
|
979
|
+
const { headers } = ctx.get();
|
|
697
980
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
698
981
|
const init = {
|
|
699
982
|
method,
|
|
700
|
-
headers
|
|
983
|
+
headers
|
|
701
984
|
};
|
|
702
985
|
{
|
|
703
986
|
init.body = body;
|
|
@@ -706,21 +989,22 @@ async function fetchTenants(config, method, body) {
|
|
|
706
989
|
return await config.handlers.POST(req);
|
|
707
990
|
}
|
|
708
991
|
async function fetchTenant(config, method, body) {
|
|
709
|
-
|
|
992
|
+
const { headers, tenantId } = ctx.get();
|
|
993
|
+
if (!tenantId) {
|
|
710
994
|
throw new Error(
|
|
711
995
|
"Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
712
996
|
);
|
|
713
997
|
}
|
|
714
|
-
if (!isUUID(
|
|
998
|
+
if (!isUUID(tenantId)) {
|
|
715
999
|
config.logger("fetch tenant").warn(
|
|
716
1000
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
717
1001
|
);
|
|
718
1002
|
}
|
|
719
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}",
|
|
1003
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", tenantId)}`;
|
|
720
1004
|
const m = method ?? "GET";
|
|
721
1005
|
const init = {
|
|
722
1006
|
method: m,
|
|
723
|
-
headers
|
|
1007
|
+
headers
|
|
724
1008
|
};
|
|
725
1009
|
if (m === "PUT") {
|
|
726
1010
|
init.body = body;
|
|
@@ -729,32 +1013,33 @@ async function fetchTenant(config, method, body) {
|
|
|
729
1013
|
return await config.handlers[m](req);
|
|
730
1014
|
}
|
|
731
1015
|
async function fetchTenantsByUser(config) {
|
|
732
|
-
const { warn } = config.logger("fetchTenantsByUser");
|
|
733
|
-
|
|
734
|
-
|
|
1016
|
+
const { warn: warn2 } = config.logger(" fetchTenantsByUser ");
|
|
1017
|
+
const { userId, headers } = ctx.get();
|
|
1018
|
+
if (!userId) {
|
|
1019
|
+
warn2(
|
|
735
1020
|
"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."
|
|
736
1021
|
);
|
|
737
|
-
} else if (!isUUID(
|
|
738
|
-
|
|
1022
|
+
} else if (!isUUID(userId)) {
|
|
1023
|
+
warn2(
|
|
739
1024
|
"nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
740
1025
|
);
|
|
741
1026
|
}
|
|
742
1027
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
743
|
-
const req = new Request(clientUrl, { headers
|
|
1028
|
+
const req = new Request(clientUrl, { headers });
|
|
744
1029
|
return await config.handlers.GET(req);
|
|
745
1030
|
}
|
|
746
1031
|
|
|
747
1032
|
// src/api/routes/auth/signin.ts
|
|
748
1033
|
var key7 = "SIGNIN";
|
|
749
1034
|
async function route7(req, config) {
|
|
750
|
-
let url = proxyRoutes(config)[key7];
|
|
1035
|
+
let url = proxyRoutes(config.apiUrl)[key7];
|
|
751
1036
|
const init = {
|
|
752
1037
|
method: req.method,
|
|
753
1038
|
headers: req.headers
|
|
754
1039
|
};
|
|
755
1040
|
if (req.method === "POST") {
|
|
756
1041
|
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
757
|
-
url = `${proxyRoutes(config)[key7]}/${provider}`;
|
|
1042
|
+
url = `${proxyRoutes(config.apiUrl)[key7]}/${provider}`;
|
|
758
1043
|
}
|
|
759
1044
|
const passThroughUrl = new URL(req.url);
|
|
760
1045
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
@@ -767,10 +1052,11 @@ function matches7(configRoutes, request2) {
|
|
|
767
1052
|
}
|
|
768
1053
|
async function fetchSignIn(config, provider, body) {
|
|
769
1054
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
|
|
1055
|
+
const { headers } = ctx.get();
|
|
770
1056
|
const req = new Request(clientUrl, {
|
|
771
1057
|
method: "POST",
|
|
772
|
-
|
|
773
|
-
|
|
1058
|
+
body,
|
|
1059
|
+
headers
|
|
774
1060
|
});
|
|
775
1061
|
return await config.handlers.POST(req);
|
|
776
1062
|
}
|
|
@@ -778,7 +1064,7 @@ async function fetchSignIn(config, provider, body) {
|
|
|
778
1064
|
// src/api/routes/auth/session.ts
|
|
779
1065
|
async function route8(req, config) {
|
|
780
1066
|
return request(
|
|
781
|
-
proxyRoutes(config).SESSION,
|
|
1067
|
+
proxyRoutes(config.apiUrl).SESSION,
|
|
782
1068
|
{
|
|
783
1069
|
method: req.method,
|
|
784
1070
|
request: req
|
|
@@ -791,9 +1077,10 @@ function matches8(configRoutes, request2) {
|
|
|
791
1077
|
}
|
|
792
1078
|
async function fetchSession(config) {
|
|
793
1079
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
|
|
1080
|
+
const { headers } = ctx.get();
|
|
794
1081
|
const req = new Request(clientUrl, {
|
|
795
1082
|
method: "GET",
|
|
796
|
-
headers
|
|
1083
|
+
headers
|
|
797
1084
|
});
|
|
798
1085
|
return await config.handlers.GET(req);
|
|
799
1086
|
}
|
|
@@ -801,7 +1088,7 @@ async function fetchSession(config) {
|
|
|
801
1088
|
// src/api/routes/auth/providers.ts
|
|
802
1089
|
async function route9(req, config) {
|
|
803
1090
|
return request(
|
|
804
|
-
proxyRoutes(config).PROVIDERS,
|
|
1091
|
+
proxyRoutes(config.apiUrl).PROVIDERS,
|
|
805
1092
|
{
|
|
806
1093
|
method: req.method,
|
|
807
1094
|
request: req
|
|
@@ -814,9 +1101,10 @@ function matches9(configRoutes, request2) {
|
|
|
814
1101
|
}
|
|
815
1102
|
async function fetchProviders(config) {
|
|
816
1103
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
|
|
1104
|
+
const { headers } = ctx.get();
|
|
817
1105
|
const req = new Request(clientUrl, {
|
|
818
1106
|
method: "GET",
|
|
819
|
-
headers
|
|
1107
|
+
headers
|
|
820
1108
|
});
|
|
821
1109
|
return await config.handlers.GET(req);
|
|
822
1110
|
}
|
|
@@ -824,7 +1112,7 @@ async function fetchProviders(config) {
|
|
|
824
1112
|
// src/api/routes/auth/csrf.ts
|
|
825
1113
|
async function route10(req, config) {
|
|
826
1114
|
return request(
|
|
827
|
-
proxyRoutes(config).CSRF,
|
|
1115
|
+
proxyRoutes(config.apiUrl).CSRF,
|
|
828
1116
|
{
|
|
829
1117
|
method: req.method,
|
|
830
1118
|
request: req
|
|
@@ -837,9 +1125,10 @@ function matches10(configRoutes, request2) {
|
|
|
837
1125
|
}
|
|
838
1126
|
async function fetchCsrf(config) {
|
|
839
1127
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
|
|
1128
|
+
const { headers } = ctx.get();
|
|
840
1129
|
const req = new Request(clientUrl, {
|
|
841
1130
|
method: "GET",
|
|
842
|
-
headers
|
|
1131
|
+
headers
|
|
843
1132
|
});
|
|
844
1133
|
return await config.handlers.GET(req);
|
|
845
1134
|
}
|
|
@@ -852,7 +1141,7 @@ async function route11(req, config) {
|
|
|
852
1141
|
try {
|
|
853
1142
|
const passThroughUrl = new URL(req.url);
|
|
854
1143
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
855
|
-
const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
1144
|
+
const url = `${proxyRoutes(config.apiUrl)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
856
1145
|
const res = await request(
|
|
857
1146
|
url,
|
|
858
1147
|
{
|
|
@@ -883,10 +1172,11 @@ function matches11(configRoutes, request2) {
|
|
|
883
1172
|
return urlMatches(request2.url, configRoutes.CALLBACK);
|
|
884
1173
|
}
|
|
885
1174
|
async function fetchCallback(config, provider, body, request2, method = "POST") {
|
|
1175
|
+
const { headers } = ctx.get();
|
|
886
1176
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
|
|
887
1177
|
const req = new Request(clientUrl, {
|
|
888
1178
|
method,
|
|
889
|
-
headers
|
|
1179
|
+
headers,
|
|
890
1180
|
body
|
|
891
1181
|
});
|
|
892
1182
|
return await config.handlers.POST(req);
|
|
@@ -895,14 +1185,14 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
|
|
|
895
1185
|
// src/api/routes/auth/signout.ts
|
|
896
1186
|
var key9 = "SIGNOUT";
|
|
897
1187
|
async function route12(request2, config) {
|
|
898
|
-
let url = proxyRoutes(config)[key9];
|
|
1188
|
+
let url = proxyRoutes(config.apiUrl)[key9];
|
|
899
1189
|
const init = {
|
|
900
1190
|
method: request2.method
|
|
901
1191
|
};
|
|
902
1192
|
if (request2.method === "POST") {
|
|
903
1193
|
init.body = request2.body;
|
|
904
1194
|
const [provider] = new URL(request2.url).pathname.split("/").reverse();
|
|
905
|
-
url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
1195
|
+
url = `${proxyRoutes(config.apiUrl)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
906
1196
|
}
|
|
907
1197
|
const res = await request(url, { ...init, request: request2 }, config);
|
|
908
1198
|
return res;
|
|
@@ -912,10 +1202,11 @@ function matches12(configRoutes, request2) {
|
|
|
912
1202
|
}
|
|
913
1203
|
async function fetchSignOut(config, body) {
|
|
914
1204
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
|
|
1205
|
+
const { headers } = ctx.get();
|
|
915
1206
|
const req = new Request(clientUrl, {
|
|
916
1207
|
method: "POST",
|
|
917
1208
|
body,
|
|
918
|
-
headers
|
|
1209
|
+
headers
|
|
919
1210
|
});
|
|
920
1211
|
return await config.handlers.POST(req);
|
|
921
1212
|
}
|
|
@@ -924,7 +1215,7 @@ async function fetchSignOut(config, body) {
|
|
|
924
1215
|
var key10 = "ERROR";
|
|
925
1216
|
async function route13(req, config) {
|
|
926
1217
|
return request(
|
|
927
|
-
proxyRoutes(config)[key10],
|
|
1218
|
+
proxyRoutes(config.apiUrl)[key10],
|
|
928
1219
|
{
|
|
929
1220
|
method: req.method,
|
|
930
1221
|
request: req
|
|
@@ -940,7 +1231,7 @@ function matches13(configRoutes, request2) {
|
|
|
940
1231
|
var key11 = "VERIFY_REQUEST";
|
|
941
1232
|
async function route14(req, config) {
|
|
942
1233
|
return request(
|
|
943
|
-
proxyRoutes(config)[key11],
|
|
1234
|
+
proxyRoutes(config.apiUrl)[key11],
|
|
944
1235
|
{
|
|
945
1236
|
method: req.method,
|
|
946
1237
|
request: req
|
|
@@ -955,7 +1246,7 @@ function matches14(configRoutes, request2) {
|
|
|
955
1246
|
// src/api/routes/auth/password-reset.ts
|
|
956
1247
|
var key12 = "PASSWORD_RESET";
|
|
957
1248
|
async function route15(req, config) {
|
|
958
|
-
const url = proxyRoutes(config)[key12];
|
|
1249
|
+
const url = proxyRoutes(config.apiUrl)[key12];
|
|
959
1250
|
const res = await request(
|
|
960
1251
|
url,
|
|
961
1252
|
{
|
|
@@ -984,10 +1275,11 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
984
1275
|
if (useJson) {
|
|
985
1276
|
authParams?.set("json", "true");
|
|
986
1277
|
}
|
|
1278
|
+
const { headers } = ctx.get();
|
|
987
1279
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
|
|
988
1280
|
const init = {
|
|
989
1281
|
method,
|
|
990
|
-
headers
|
|
1282
|
+
headers
|
|
991
1283
|
};
|
|
992
1284
|
if (body && method !== "GET") {
|
|
993
1285
|
init.body = body;
|
|
@@ -999,7 +1291,7 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
999
1291
|
// src/api/routes/auth/verify-email.ts
|
|
1000
1292
|
var key13 = "VERIFY_EMAIL";
|
|
1001
1293
|
async function route16(req, config) {
|
|
1002
|
-
const url = proxyRoutes(config)[key13];
|
|
1294
|
+
const url = proxyRoutes(config.apiUrl)[key13];
|
|
1003
1295
|
const res = await request(
|
|
1004
1296
|
url,
|
|
1005
1297
|
{
|
|
@@ -1025,9 +1317,10 @@ function matches16(configRoutes, request2) {
|
|
|
1025
1317
|
}
|
|
1026
1318
|
async function fetchVerifyEmail(config, method, body) {
|
|
1027
1319
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
|
|
1320
|
+
const { headers } = ctx.get();
|
|
1028
1321
|
const init = {
|
|
1029
1322
|
method,
|
|
1030
|
-
headers
|
|
1323
|
+
headers
|
|
1031
1324
|
};
|
|
1032
1325
|
if (body) {
|
|
1033
1326
|
init.body = body;
|
|
@@ -1038,7 +1331,7 @@ async function fetchVerifyEmail(config, method, body) {
|
|
|
1038
1331
|
|
|
1039
1332
|
// src/api/handlers/GET.ts
|
|
1040
1333
|
function GETTER(configRoutes, config) {
|
|
1041
|
-
const { error, info, warn } = config.logger("[GET MATCHER]");
|
|
1334
|
+
const { error, info, warn: warn2 } = config.logger("[GET MATCHER]");
|
|
1042
1335
|
return async function GET7(...params) {
|
|
1043
1336
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1044
1337
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1117,78 +1410,16 @@ function GETTER(configRoutes, config) {
|
|
|
1117
1410
|
info("matches error");
|
|
1118
1411
|
return route13(req, config);
|
|
1119
1412
|
}
|
|
1120
|
-
|
|
1413
|
+
warn2(`No GET routes matched ${req.url}`);
|
|
1121
1414
|
return new Response(null, { status: 404 });
|
|
1122
1415
|
};
|
|
1123
1416
|
}
|
|
1124
1417
|
|
|
1125
|
-
// src/utils/Logger.ts
|
|
1126
|
-
var red = "\x1B[31m";
|
|
1127
|
-
var yellow = "\x1B[38;2;255;255;0m";
|
|
1128
|
-
var purple = "\x1B[38;2;200;160;255m";
|
|
1129
|
-
var orange = "\x1B[38;2;255;165;0m";
|
|
1130
|
-
var reset = "\x1B[0m";
|
|
1131
|
-
var baseLogger = (config, ...params) => ({
|
|
1132
|
-
info(message, meta) {
|
|
1133
|
-
if (config?.debug) {
|
|
1134
|
-
console.info(
|
|
1135
|
-
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
1136
|
-
""
|
|
1137
|
-
)}${reset} ${message}`,
|
|
1138
|
-
meta ? `${JSON.stringify(meta)}` : ""
|
|
1139
|
-
);
|
|
1140
|
-
}
|
|
1141
|
-
},
|
|
1142
|
-
debug(message, meta) {
|
|
1143
|
-
if (config?.debug) {
|
|
1144
|
-
console.info(
|
|
1145
|
-
`${orange}[niledb]${reset}${purple}[DEBUG]${reset}${params.join(
|
|
1146
|
-
""
|
|
1147
|
-
)}${reset} ${message}`,
|
|
1148
|
-
meta ? `${JSON.stringify(meta)}` : ""
|
|
1149
|
-
);
|
|
1150
|
-
}
|
|
1151
|
-
},
|
|
1152
|
-
warn(message, meta) {
|
|
1153
|
-
if (config?.debug) {
|
|
1154
|
-
console.warn(
|
|
1155
|
-
`${orange}[niledb]${reset}${yellow}[WARN]${reset}${params.join(
|
|
1156
|
-
""
|
|
1157
|
-
)}${reset} ${message}`,
|
|
1158
|
-
meta ? JSON.stringify(meta) : ""
|
|
1159
|
-
);
|
|
1160
|
-
}
|
|
1161
|
-
},
|
|
1162
|
-
error(message, meta) {
|
|
1163
|
-
console.error(
|
|
1164
|
-
`${orange}[niledb]${reset}${red}[ERROR]${reset}${params.join(
|
|
1165
|
-
""
|
|
1166
|
-
)}${red} ${message}`,
|
|
1167
|
-
meta ? meta : "",
|
|
1168
|
-
`${reset}`
|
|
1169
|
-
);
|
|
1170
|
-
}
|
|
1171
|
-
});
|
|
1172
|
-
function Logger(config) {
|
|
1173
|
-
return (prefixes) => {
|
|
1174
|
-
const { info, debug, warn, error } = config && typeof config?.logger === "function" ? config.logger(prefixes) : baseLogger(config, prefixes);
|
|
1175
|
-
return {
|
|
1176
|
-
info,
|
|
1177
|
-
debug,
|
|
1178
|
-
warn,
|
|
1179
|
-
error
|
|
1180
|
-
};
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
function matchesLog(configRoutes, request2) {
|
|
1184
|
-
return urlMatches(request2.url, configRoutes.LOG);
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
1418
|
// src/api/routes/signup/POST.ts
|
|
1188
1419
|
async function POST5(config, init) {
|
|
1189
1420
|
init.body = init.request.body;
|
|
1190
1421
|
init.method = "POST";
|
|
1191
|
-
const url = `${apiRoutes(config).SIGNUP}`;
|
|
1422
|
+
const url = `${apiRoutes(config.apiUrl).SIGNUP}`;
|
|
1192
1423
|
return await request(url, init, config);
|
|
1193
1424
|
}
|
|
1194
1425
|
|
|
@@ -1215,9 +1446,10 @@ async function fetchSignUp(config, payload) {
|
|
|
1215
1446
|
q.set("tenantId", params.tenantId);
|
|
1216
1447
|
}
|
|
1217
1448
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
|
|
1449
|
+
const { headers } = ctx.get();
|
|
1218
1450
|
const req = new Request(clientUrl, {
|
|
1219
1451
|
method: "POST",
|
|
1220
|
-
headers
|
|
1452
|
+
headers,
|
|
1221
1453
|
body
|
|
1222
1454
|
});
|
|
1223
1455
|
return await config.handlers.POST(req);
|
|
@@ -1225,7 +1457,7 @@ async function fetchSignUp(config, payload) {
|
|
|
1225
1457
|
|
|
1226
1458
|
// src/api/handlers/POST.ts
|
|
1227
1459
|
function POSTER(configRoutes, config) {
|
|
1228
|
-
const { info, warn, error } = config.logger("[POST MATCHER]");
|
|
1460
|
+
const { info, warn: warn2, error } = config.logger("[POST MATCHER]");
|
|
1229
1461
|
return async function POST6(...params) {
|
|
1230
1462
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1231
1463
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1261,10 +1493,6 @@ function POSTER(configRoutes, config) {
|
|
|
1261
1493
|
info("matches signup");
|
|
1262
1494
|
return route17(req, config);
|
|
1263
1495
|
}
|
|
1264
|
-
if (matches2(configRoutes, req)) {
|
|
1265
|
-
info("matches users");
|
|
1266
|
-
return route2(req, config);
|
|
1267
|
-
}
|
|
1268
1496
|
if (matches6(configRoutes, req)) {
|
|
1269
1497
|
info("matches tenants");
|
|
1270
1498
|
return route6(req, config);
|
|
@@ -1301,7 +1529,7 @@ function POSTER(configRoutes, config) {
|
|
|
1301
1529
|
info("matches verify-email");
|
|
1302
1530
|
return route16(req, config);
|
|
1303
1531
|
}
|
|
1304
|
-
|
|
1532
|
+
warn2(`No POST routes matched ${req.url}`);
|
|
1305
1533
|
return new Response(null, { status: 404 });
|
|
1306
1534
|
};
|
|
1307
1535
|
}
|
|
@@ -1310,10 +1538,8 @@ function POSTER(configRoutes, config) {
|
|
|
1310
1538
|
async function DELETE3(config, init) {
|
|
1311
1539
|
const yurl = new URL(init.request.url);
|
|
1312
1540
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1313
|
-
config.tenantId = tenantId;
|
|
1314
|
-
config.userId = userId;
|
|
1315
1541
|
init.method = "DELETE";
|
|
1316
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1542
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1317
1543
|
return await request(url, init, config);
|
|
1318
1544
|
}
|
|
1319
1545
|
|
|
@@ -1321,10 +1547,8 @@ async function DELETE3(config, init) {
|
|
|
1321
1547
|
async function PUT5(config, init) {
|
|
1322
1548
|
const yurl = new URL(init.request.url);
|
|
1323
1549
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1324
|
-
config.tenantId = tenantId;
|
|
1325
|
-
config.userId = userId;
|
|
1326
1550
|
init.method = "PUT";
|
|
1327
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1551
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1328
1552
|
return await request(url, init, config);
|
|
1329
1553
|
}
|
|
1330
1554
|
|
|
@@ -1362,22 +1586,24 @@ function matches18(configRoutes, request2) {
|
|
|
1362
1586
|
return urlMatches(request2.url, route20);
|
|
1363
1587
|
}
|
|
1364
1588
|
async function fetchTenantUser(config, method) {
|
|
1365
|
-
|
|
1589
|
+
const { headers, tenantId, userId } = ctx.get();
|
|
1590
|
+
const action = method === "PUT" ? "add" : "delete";
|
|
1591
|
+
if (!tenantId) {
|
|
1366
1592
|
throw new Error(
|
|
1367
|
-
|
|
1593
|
+
`Unable to ${action} user to the tenant, the tenantId context is missing. Use nile.withContext({ tenantId })`
|
|
1368
1594
|
);
|
|
1369
1595
|
}
|
|
1370
|
-
if (!
|
|
1596
|
+
if (!userId) {
|
|
1371
1597
|
throw new Error(
|
|
1372
|
-
|
|
1598
|
+
`Unable to ${action} user to tenant. The userId context is missing. Use nile.withContext({ userId })`
|
|
1373
1599
|
);
|
|
1374
1600
|
}
|
|
1375
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
|
|
1376
|
-
"{
|
|
1377
|
-
|
|
1378
|
-
)
|
|
1601
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace("{tenantId}", tenantId).replace(
|
|
1602
|
+
"{userId}",
|
|
1603
|
+
userId
|
|
1604
|
+
)}/link`;
|
|
1379
1605
|
const req = new Request(clientUrl, {
|
|
1380
|
-
headers
|
|
1606
|
+
headers,
|
|
1381
1607
|
method
|
|
1382
1608
|
});
|
|
1383
1609
|
return await config.handlers[method](req);
|
|
@@ -1391,7 +1617,7 @@ async function DELETE4(config, init) {
|
|
|
1391
1617
|
return new Response(null, { status: 404 });
|
|
1392
1618
|
}
|
|
1393
1619
|
init.method = "DELETE";
|
|
1394
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
|
|
1620
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}/${inviteId}`;
|
|
1395
1621
|
return await request(url, init, config);
|
|
1396
1622
|
}
|
|
1397
1623
|
|
|
@@ -1414,7 +1640,7 @@ function matches19(configRoutes, request2) {
|
|
|
1414
1640
|
|
|
1415
1641
|
// src/api/handlers/DELETE.ts
|
|
1416
1642
|
function DELETER(configRoutes, config) {
|
|
1417
|
-
const { error, info, warn } = config.logger("[DELETE MATCHER]");
|
|
1643
|
+
const { error, info, warn: warn2 } = config.logger("[DELETE MATCHER]");
|
|
1418
1644
|
return async function DELETE5(...params) {
|
|
1419
1645
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1420
1646
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1445,14 +1671,14 @@ function DELETER(configRoutes, config) {
|
|
|
1445
1671
|
info("matches me");
|
|
1446
1672
|
return route(req, config);
|
|
1447
1673
|
}
|
|
1448
|
-
|
|
1674
|
+
warn2("No DELETE routes matched");
|
|
1449
1675
|
return new Response(null, { status: 404 });
|
|
1450
1676
|
};
|
|
1451
1677
|
}
|
|
1452
1678
|
|
|
1453
1679
|
// src/api/handlers/PUT.ts
|
|
1454
1680
|
function PUTER(configRoutes, config) {
|
|
1455
|
-
const { error, info, warn } = config.logger("[PUT MATCHER]");
|
|
1681
|
+
const { error, info, warn: warn2 } = config.logger("[PUT MATCHER]");
|
|
1456
1682
|
return async function PUT6(...params) {
|
|
1457
1683
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1458
1684
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1479,10 +1705,6 @@ function PUTER(configRoutes, config) {
|
|
|
1479
1705
|
info("matches tenant users");
|
|
1480
1706
|
return route3(req, config);
|
|
1481
1707
|
}
|
|
1482
|
-
if (matches2(configRoutes, req)) {
|
|
1483
|
-
info("matches users");
|
|
1484
|
-
return route2(req, config);
|
|
1485
|
-
}
|
|
1486
1708
|
if (matches(configRoutes, req)) {
|
|
1487
1709
|
info("matches me");
|
|
1488
1710
|
return route(req, config);
|
|
@@ -1495,7 +1717,7 @@ function PUTER(configRoutes, config) {
|
|
|
1495
1717
|
info("matches reset password");
|
|
1496
1718
|
return route15(req, config);
|
|
1497
1719
|
}
|
|
1498
|
-
|
|
1720
|
+
warn2("No PUT routes matched");
|
|
1499
1721
|
return new Response(null, { status: 404 });
|
|
1500
1722
|
};
|
|
1501
1723
|
}
|
|
@@ -1699,25 +1921,14 @@ var Config = class {
|
|
|
1699
1921
|
extensionCtx;
|
|
1700
1922
|
extensions;
|
|
1701
1923
|
logger;
|
|
1924
|
+
context;
|
|
1702
1925
|
/**
|
|
1703
|
-
*
|
|
1926
|
+
* The nile-auth url
|
|
1704
1927
|
*/
|
|
1705
|
-
|
|
1928
|
+
apiUrl;
|
|
1929
|
+
origin;
|
|
1706
1930
|
/**
|
|
1707
|
-
*
|
|
1708
|
-
*/
|
|
1709
|
-
userId;
|
|
1710
|
-
/**
|
|
1711
|
-
* Stores the headers to be used in `fetch` calls
|
|
1712
|
-
*/
|
|
1713
|
-
headers;
|
|
1714
|
-
/**
|
|
1715
|
-
* The nile-auth url
|
|
1716
|
-
*/
|
|
1717
|
-
apiUrl;
|
|
1718
|
-
origin;
|
|
1719
|
-
/**
|
|
1720
|
-
* important for separating the `origin` config value from a default in order to make requests
|
|
1931
|
+
* important for separating the `origin` config value from a default in order to make requests
|
|
1721
1932
|
*/
|
|
1722
1933
|
serverOrigin;
|
|
1723
1934
|
debug;
|
|
@@ -1761,11 +1972,12 @@ var Config = class {
|
|
|
1761
1972
|
if (databaseName) {
|
|
1762
1973
|
this.db.database = databaseName;
|
|
1763
1974
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1975
|
+
this.context = {
|
|
1976
|
+
tenantId: config?.tenantId,
|
|
1977
|
+
userId: config?.userId,
|
|
1978
|
+
headers: config?.headers ? new Headers(config.headers) : new Headers(),
|
|
1979
|
+
preserveHeaders: false
|
|
1980
|
+
};
|
|
1769
1981
|
this.routes = {
|
|
1770
1982
|
...appRoutes(config?.routePrefix),
|
|
1771
1983
|
...config?.routes
|
|
@@ -1808,8 +2020,6 @@ var Config = class {
|
|
|
1808
2020
|
],
|
|
1809
2021
|
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
1810
2022
|
};
|
|
1811
|
-
this.tenantId = config?.tenantId;
|
|
1812
|
-
this.userId = config?.userId;
|
|
1813
2023
|
}
|
|
1814
2024
|
};
|
|
1815
2025
|
|
|
@@ -1876,7 +2086,15 @@ function createProxyForPool(pool, config) {
|
|
|
1876
2086
|
}
|
|
1877
2087
|
const caller = target[property];
|
|
1878
2088
|
return function query(...args) {
|
|
1879
|
-
|
|
2089
|
+
let log = "[QUERY]";
|
|
2090
|
+
const { userId, tenantId } = config.context;
|
|
2091
|
+
if (tenantId) {
|
|
2092
|
+
log = `${log}[TENANT:${tenantId}]`;
|
|
2093
|
+
}
|
|
2094
|
+
if (userId) {
|
|
2095
|
+
log = `${log}[USER:${userId}]`;
|
|
2096
|
+
}
|
|
2097
|
+
info(log, ...args);
|
|
1880
2098
|
const called = caller.apply(this, args);
|
|
1881
2099
|
return called;
|
|
1882
2100
|
};
|
|
@@ -1895,7 +2113,7 @@ var NileDatabase = class {
|
|
|
1895
2113
|
config;
|
|
1896
2114
|
timer;
|
|
1897
2115
|
constructor(config, id) {
|
|
1898
|
-
const { warn, info, debug } = config.logger("[NileInstance]");
|
|
2116
|
+
const { warn: warn2, info, debug } = config.logger("[NileInstance]");
|
|
1899
2117
|
this.id = id;
|
|
1900
2118
|
const poolConfig = {
|
|
1901
2119
|
min: 0,
|
|
@@ -1911,7 +2129,7 @@ var NileDatabase = class {
|
|
|
1911
2129
|
debug(`Connection pool config ${JSON.stringify(cloned)}`);
|
|
1912
2130
|
this.pool = createProxyForPool(new pg.Pool(remaining), this.config);
|
|
1913
2131
|
if (typeof afterCreate === "function") {
|
|
1914
|
-
|
|
2132
|
+
warn2(
|
|
1915
2133
|
"Providing an pool configuration will stop automatic tenant context setting."
|
|
1916
2134
|
);
|
|
1917
2135
|
}
|
|
@@ -1977,7 +2195,7 @@ var NileDatabase = class {
|
|
|
1977
2195
|
};
|
|
1978
2196
|
var NileInstance_default = NileDatabase;
|
|
1979
2197
|
function makeAfterCreate(config, id) {
|
|
1980
|
-
const { error, warn, debug } = config.logger("[afterCreate]");
|
|
2198
|
+
const { error, warn: warn2, debug } = config.logger("[afterCreate]");
|
|
1981
2199
|
return (conn, done) => {
|
|
1982
2200
|
conn.on("error", function errorHandler(e) {
|
|
1983
2201
|
error(`Connection ${id} was terminated by server`, {
|
|
@@ -1986,13 +2204,15 @@ function makeAfterCreate(config, id) {
|
|
|
1986
2204
|
});
|
|
1987
2205
|
done(e, conn);
|
|
1988
2206
|
});
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2207
|
+
const tenantId = config.context.tenantId;
|
|
2208
|
+
const userId = config.context.userId;
|
|
2209
|
+
if (tenantId) {
|
|
2210
|
+
const query = [`SET nile.tenant_id = '${tenantId}'`];
|
|
2211
|
+
if (userId) {
|
|
2212
|
+
if (!tenantId) {
|
|
2213
|
+
warn2("A user id cannot be set in context without a tenant id");
|
|
1994
2214
|
}
|
|
1995
|
-
query.push(`SET nile.user_id = '${
|
|
2215
|
+
query.push(`SET nile.user_id = '${userId}'`);
|
|
1996
2216
|
}
|
|
1997
2217
|
conn.query(query.join(";"), function(err) {
|
|
1998
2218
|
if (err) {
|
|
@@ -2005,11 +2225,11 @@ function makeAfterCreate(config, id) {
|
|
|
2005
2225
|
});
|
|
2006
2226
|
} else {
|
|
2007
2227
|
if (query.length === 1) {
|
|
2008
|
-
debug(`connection context set: tenantId=${
|
|
2228
|
+
debug(`connection context set: tenantId=${tenantId}`);
|
|
2009
2229
|
}
|
|
2010
2230
|
if (query.length === 2) {
|
|
2011
2231
|
debug(
|
|
2012
|
-
`connection context set: tenantId=${
|
|
2232
|
+
`connection context set: tenantId=${tenantId} userId=${userId}`
|
|
2013
2233
|
);
|
|
2014
2234
|
}
|
|
2015
2235
|
}
|
|
@@ -2041,19 +2261,19 @@ var DBManager = class {
|
|
|
2041
2261
|
watchEvictPool(this.poolWatcherFn);
|
|
2042
2262
|
}
|
|
2043
2263
|
poolWatcher = (config) => (id) => {
|
|
2044
|
-
const { info, warn } = Logger(config)("[DBManager]");
|
|
2264
|
+
const { info, warn: warn2 } = Logger(config)("[DBManager]");
|
|
2045
2265
|
if (id && this.connections.has(id)) {
|
|
2046
2266
|
info(`Removing ${id} from db connection pool.`);
|
|
2047
2267
|
const connection = this.connections.get(id);
|
|
2048
2268
|
connection?.shutdown();
|
|
2049
2269
|
this.connections.delete(id);
|
|
2050
2270
|
} else {
|
|
2051
|
-
|
|
2271
|
+
warn2(`missed eviction of ${id}`);
|
|
2052
2272
|
}
|
|
2053
2273
|
};
|
|
2054
2274
|
getConnection = (config) => {
|
|
2055
2275
|
const { info } = Logger(config)("[DBManager]");
|
|
2056
|
-
const id = this.makeId(config.tenantId, config.userId);
|
|
2276
|
+
const id = this.makeId(config.context.tenantId, config.context.userId);
|
|
2057
2277
|
const existing = this.connections.get(id);
|
|
2058
2278
|
info(`# of instances: ${this.connections.size}`);
|
|
2059
2279
|
if (existing) {
|
|
@@ -2061,7 +2281,7 @@ var DBManager = class {
|
|
|
2061
2281
|
existing.startTimeout();
|
|
2062
2282
|
return existing.pool;
|
|
2063
2283
|
}
|
|
2064
|
-
const newOne = new NileInstance_default(
|
|
2284
|
+
const newOne = new NileInstance_default(config, id);
|
|
2065
2285
|
this.connections.set(id, newOne);
|
|
2066
2286
|
info(`created new ${id}`);
|
|
2067
2287
|
info(`# of instances: ${this.connections.size}`);
|
|
@@ -2096,33 +2316,39 @@ var Auth = class {
|
|
|
2096
2316
|
this.#logger = config.logger("[auth]");
|
|
2097
2317
|
}
|
|
2098
2318
|
async getSession(rawResponse = false) {
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
try {
|
|
2104
|
-
const session = await res.clone().json();
|
|
2105
|
-
if (Object.keys(session).length === 0) {
|
|
2106
|
-
return void 0;
|
|
2319
|
+
return withNileContext(this.#config, async () => {
|
|
2320
|
+
const res = await fetchSession(this.#config);
|
|
2321
|
+
if (rawResponse) {
|
|
2322
|
+
return res;
|
|
2107
2323
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2324
|
+
try {
|
|
2325
|
+
const session = await res.clone().json();
|
|
2326
|
+
if (Object.keys(session).length === 0) {
|
|
2327
|
+
return void 0;
|
|
2328
|
+
}
|
|
2329
|
+
return session;
|
|
2330
|
+
} catch {
|
|
2331
|
+
return res;
|
|
2332
|
+
}
|
|
2333
|
+
});
|
|
2112
2334
|
}
|
|
2113
2335
|
async getCsrf(rawResponse = false) {
|
|
2114
|
-
return
|
|
2336
|
+
return withNileContext(this.#config, async () => {
|
|
2337
|
+
return await obtainCsrf(this.#config, rawResponse);
|
|
2338
|
+
});
|
|
2115
2339
|
}
|
|
2116
2340
|
async listProviders(rawResponse = false) {
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2341
|
+
return withNileContext(this.#config, async () => {
|
|
2342
|
+
const res = await fetchProviders(this.#config);
|
|
2343
|
+
if (rawResponse) {
|
|
2344
|
+
return res;
|
|
2345
|
+
}
|
|
2346
|
+
try {
|
|
2347
|
+
return await res.clone().json();
|
|
2348
|
+
} catch {
|
|
2349
|
+
return res;
|
|
2350
|
+
}
|
|
2351
|
+
});
|
|
2126
2352
|
}
|
|
2127
2353
|
/**
|
|
2128
2354
|
* Sign the current user out by calling `/api/auth/signout`.
|
|
@@ -2131,73 +2357,79 @@ var Auth = class {
|
|
|
2131
2357
|
* from the internal configuration once the request completes.
|
|
2132
2358
|
*/
|
|
2133
2359
|
async signOut() {
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2360
|
+
return withNileContext(this.#config, async () => {
|
|
2361
|
+
const csrfRes = await this.getCsrf();
|
|
2362
|
+
if (!("csrfToken" in csrfRes)) {
|
|
2363
|
+
throw new Error("Unable to obtain CSRF token. Sign out failed.");
|
|
2364
|
+
}
|
|
2365
|
+
const body = JSON.stringify({
|
|
2366
|
+
csrfToken: csrfRes.csrfToken,
|
|
2367
|
+
json: true
|
|
2368
|
+
});
|
|
2369
|
+
const res = await fetchSignOut(this.#config, body);
|
|
2370
|
+
updateHeaders(new Headers({}));
|
|
2371
|
+
ctx.set({ headers: null });
|
|
2372
|
+
return res;
|
|
2141
2373
|
});
|
|
2142
|
-
const res = await fetchSignOut(this.#config, body);
|
|
2143
|
-
updateHeaders(new Headers({}));
|
|
2144
|
-
this.#config.headers = new Headers();
|
|
2145
|
-
return res;
|
|
2146
2374
|
}
|
|
2147
2375
|
async signUp(payload, rawResponse) {
|
|
2148
|
-
this.#config
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
csrfToken
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2376
|
+
return withNileContext(this.#config, async () => {
|
|
2377
|
+
ctx.set({ headers: null });
|
|
2378
|
+
const { email, password, ...params } = payload;
|
|
2379
|
+
if (!email || !password) {
|
|
2380
|
+
throw new Error(
|
|
2381
|
+
"Server side sign up requires a user email and password."
|
|
2382
|
+
);
|
|
2383
|
+
}
|
|
2384
|
+
const providers = await this.listProviders();
|
|
2385
|
+
const { credentials } = providers ?? {};
|
|
2386
|
+
if (!credentials) {
|
|
2387
|
+
throw new Error(
|
|
2388
|
+
"Unable to obtain credential provider. Aborting server side sign up."
|
|
2389
|
+
);
|
|
2390
|
+
}
|
|
2391
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2392
|
+
let csrfToken;
|
|
2393
|
+
if ("csrfToken" in csrf) {
|
|
2394
|
+
csrfToken = csrf.csrfToken;
|
|
2395
|
+
} else {
|
|
2396
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2397
|
+
}
|
|
2398
|
+
const body = JSON.stringify({
|
|
2399
|
+
email,
|
|
2400
|
+
password,
|
|
2401
|
+
csrfToken,
|
|
2402
|
+
callbackUrl: credentials.callbackUrl
|
|
2403
|
+
});
|
|
2404
|
+
const res = await fetchSignUp(this.#config, { body, params });
|
|
2405
|
+
if (res.status > 299) {
|
|
2406
|
+
this.#logger.error(await res.clone().text());
|
|
2407
|
+
return void 0;
|
|
2408
|
+
}
|
|
2409
|
+
const token = parseToken(res.headers);
|
|
2410
|
+
if (!token) {
|
|
2411
|
+
throw new Error("Server side sign up failed. Session token not found");
|
|
2412
|
+
}
|
|
2413
|
+
const { headers } = ctx.get();
|
|
2414
|
+
headers?.append("cookie", token);
|
|
2415
|
+
ctx.set({ headers });
|
|
2416
|
+
updateHeaders(headers);
|
|
2417
|
+
if (rawResponse) {
|
|
2418
|
+
return res;
|
|
2419
|
+
}
|
|
2420
|
+
try {
|
|
2421
|
+
const json = await res.clone().json();
|
|
2422
|
+
if (json && typeof json === "object" && "tenants" in json) {
|
|
2423
|
+
const tenantId = json.tenants[0];
|
|
2424
|
+
if (tenantId) {
|
|
2425
|
+
updateTenantId(tenantId);
|
|
2426
|
+
}
|
|
2195
2427
|
}
|
|
2428
|
+
return json;
|
|
2429
|
+
} catch {
|
|
2430
|
+
return res;
|
|
2196
2431
|
}
|
|
2197
|
-
|
|
2198
|
-
} catch {
|
|
2199
|
-
return res;
|
|
2200
|
-
}
|
|
2432
|
+
});
|
|
2201
2433
|
}
|
|
2202
2434
|
/**
|
|
2203
2435
|
* Request a password reset email.
|
|
@@ -2207,34 +2439,34 @@ var Auth = class {
|
|
|
2207
2439
|
* which is returned as a {@link Response} object.
|
|
2208
2440
|
*/
|
|
2209
2441
|
async forgotPassword(req) {
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2442
|
+
return withNileContext(this.#config, async () => {
|
|
2443
|
+
let email = "";
|
|
2444
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2445
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2446
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2447
|
+
if ("email" in req) {
|
|
2448
|
+
email = req.email;
|
|
2449
|
+
}
|
|
2450
|
+
if ("callbackUrl" in req) {
|
|
2451
|
+
callbackUrl = fQUrl(req.callbackUrl ?? "", this.#config);
|
|
2452
|
+
}
|
|
2453
|
+
if ("redirectUrl" in req) {
|
|
2454
|
+
redirectUrl = fQUrl(req.redirectUrl ?? "", this.#config);
|
|
2455
|
+
}
|
|
2456
|
+
const body = JSON.stringify({
|
|
2457
|
+
email,
|
|
2458
|
+
redirectUrl,
|
|
2459
|
+
callbackUrl
|
|
2460
|
+
});
|
|
2461
|
+
const data = await fetchResetPassword(
|
|
2462
|
+
this.#config,
|
|
2463
|
+
"POST",
|
|
2464
|
+
body,
|
|
2465
|
+
new URLSearchParams(),
|
|
2466
|
+
false
|
|
2467
|
+
);
|
|
2468
|
+
return data;
|
|
2229
2469
|
});
|
|
2230
|
-
const data = await fetchResetPassword(
|
|
2231
|
-
this.#config,
|
|
2232
|
-
"POST",
|
|
2233
|
-
body,
|
|
2234
|
-
new URLSearchParams(),
|
|
2235
|
-
false
|
|
2236
|
-
);
|
|
2237
|
-
return data;
|
|
2238
2470
|
}
|
|
2239
2471
|
/**
|
|
2240
2472
|
* Complete a password reset.
|
|
@@ -2247,93 +2479,98 @@ var Auth = class {
|
|
|
2247
2479
|
* containing the necessary fields.
|
|
2248
2480
|
*/
|
|
2249
2481
|
async resetPassword(req) {
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2482
|
+
return withNileContext(this.#config, async () => {
|
|
2483
|
+
let email = "";
|
|
2484
|
+
let password = "";
|
|
2485
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2486
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2487
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2488
|
+
if (req instanceof Request) {
|
|
2489
|
+
const body2 = await req.json();
|
|
2490
|
+
email = body2.email;
|
|
2491
|
+
password = body2.password;
|
|
2492
|
+
const cbFromHeaders = parseCallback(req.headers);
|
|
2493
|
+
if (cbFromHeaders) {
|
|
2494
|
+
callbackUrl = cbFromHeaders;
|
|
2495
|
+
}
|
|
2496
|
+
if (body2.callbackUrl) {
|
|
2497
|
+
callbackUrl = body2.callbackUrl;
|
|
2498
|
+
}
|
|
2499
|
+
if (body2.redirectUrl) {
|
|
2500
|
+
redirectUrl = body2.redirectUrl;
|
|
2501
|
+
}
|
|
2502
|
+
} else {
|
|
2503
|
+
if ("email" in req) {
|
|
2504
|
+
email = req.email;
|
|
2505
|
+
}
|
|
2506
|
+
if ("password" in req) {
|
|
2507
|
+
password = req.password;
|
|
2508
|
+
}
|
|
2509
|
+
if ("callbackUrl" in req) {
|
|
2510
|
+
callbackUrl = req.callbackUrl ? req.callbackUrl : null;
|
|
2511
|
+
}
|
|
2512
|
+
if ("redirectUrl" in req) {
|
|
2513
|
+
redirectUrl = req.redirectUrl ? req.redirectUrl : null;
|
|
2514
|
+
}
|
|
2268
2515
|
}
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
email
|
|
2516
|
+
await this.getCsrf();
|
|
2517
|
+
const body = JSON.stringify({
|
|
2518
|
+
email,
|
|
2519
|
+
password,
|
|
2520
|
+
redirectUrl,
|
|
2521
|
+
callbackUrl
|
|
2522
|
+
});
|
|
2523
|
+
let urlWithParams;
|
|
2524
|
+
try {
|
|
2525
|
+
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
2526
|
+
const cloned = data.clone();
|
|
2527
|
+
if (data.status === 400) {
|
|
2528
|
+
const text = await cloned.text();
|
|
2529
|
+
this.#logger.error(text);
|
|
2530
|
+
return data;
|
|
2531
|
+
}
|
|
2532
|
+
const { url } = await data.json();
|
|
2533
|
+
urlWithParams = url;
|
|
2534
|
+
} catch {
|
|
2272
2535
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2536
|
+
let token;
|
|
2537
|
+
try {
|
|
2538
|
+
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2539
|
+
const answer = await fetchResetPassword(
|
|
2540
|
+
this.#config,
|
|
2541
|
+
"GET",
|
|
2542
|
+
null,
|
|
2543
|
+
worthyParams
|
|
2544
|
+
);
|
|
2545
|
+
token = parseResetToken(answer.headers);
|
|
2546
|
+
} catch {
|
|
2547
|
+
this.#logger.warn(
|
|
2548
|
+
"Unable to parse reset password url. Password not reset."
|
|
2549
|
+
);
|
|
2275
2550
|
}
|
|
2276
|
-
|
|
2277
|
-
|
|
2551
|
+
const { headers } = ctx.get();
|
|
2552
|
+
const cookie = headers?.get("cookie")?.split("; ");
|
|
2553
|
+
if (token) {
|
|
2554
|
+
cookie?.push(token);
|
|
2555
|
+
} else {
|
|
2556
|
+
throw new Error(
|
|
2557
|
+
"Unable to reset password, reset token is missing from response"
|
|
2558
|
+
);
|
|
2278
2559
|
}
|
|
2279
|
-
if (
|
|
2280
|
-
|
|
2560
|
+
if (cookie) {
|
|
2561
|
+
headers?.set("cookie", cookie?.join("; "));
|
|
2562
|
+
ctx.set({
|
|
2563
|
+
headers
|
|
2564
|
+
});
|
|
2281
2565
|
}
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
});
|
|
2290
|
-
let urlWithParams;
|
|
2291
|
-
try {
|
|
2292
|
-
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
2293
|
-
const cloned = data.clone();
|
|
2294
|
-
if (data.status === 400) {
|
|
2295
|
-
const text = await cloned.text();
|
|
2296
|
-
this.#logger.error(text);
|
|
2297
|
-
return data;
|
|
2298
|
-
}
|
|
2299
|
-
const { url } = await data.json();
|
|
2300
|
-
urlWithParams = url;
|
|
2301
|
-
} catch {
|
|
2302
|
-
}
|
|
2303
|
-
let token;
|
|
2304
|
-
try {
|
|
2305
|
-
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2306
|
-
const answer = await fetchResetPassword(
|
|
2307
|
-
this.#config,
|
|
2308
|
-
"GET",
|
|
2309
|
-
null,
|
|
2310
|
-
worthyParams
|
|
2311
|
-
);
|
|
2312
|
-
token = parseResetToken(answer.headers);
|
|
2313
|
-
} catch {
|
|
2314
|
-
this.#logger.warn(
|
|
2315
|
-
"Unable to parse reset password url. Password not reset."
|
|
2316
|
-
);
|
|
2317
|
-
}
|
|
2318
|
-
const cookie = this.#config.headers.get("cookie")?.split("; ");
|
|
2319
|
-
if (token) {
|
|
2320
|
-
cookie?.push(token);
|
|
2321
|
-
} else {
|
|
2322
|
-
throw new Error(
|
|
2323
|
-
"Unable to reset password, reset token is missing from response"
|
|
2324
|
-
);
|
|
2325
|
-
}
|
|
2326
|
-
this.#config.headers = new Headers({
|
|
2327
|
-
...this.#config.headers,
|
|
2328
|
-
cookie: cookie?.join("; ")
|
|
2566
|
+
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2567
|
+
cookie?.pop();
|
|
2568
|
+
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2569
|
+
cleaned.push(String(parseToken(res.headers)));
|
|
2570
|
+
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2571
|
+
updateHeaders(updatedHeaders);
|
|
2572
|
+
return res;
|
|
2329
2573
|
});
|
|
2330
|
-
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2331
|
-
cookie?.pop();
|
|
2332
|
-
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2333
|
-
cleaned.push(String(parseToken(res.headers)));
|
|
2334
|
-
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2335
|
-
updateHeaders(updatedHeaders);
|
|
2336
|
-
return res;
|
|
2337
2574
|
}
|
|
2338
2575
|
/**
|
|
2339
2576
|
* Low level helper used by {@link signIn} to complete provider flows.
|
|
@@ -2343,7 +2580,9 @@ var Auth = class {
|
|
|
2343
2580
|
*/
|
|
2344
2581
|
async callback(provider, body) {
|
|
2345
2582
|
if (body instanceof Request) {
|
|
2346
|
-
|
|
2583
|
+
ctx.set({
|
|
2584
|
+
headers: body.headers
|
|
2585
|
+
});
|
|
2347
2586
|
return await fetchCallback(
|
|
2348
2587
|
this.#config,
|
|
2349
2588
|
provider,
|
|
@@ -2355,112 +2594,115 @@ var Auth = class {
|
|
|
2355
2594
|
return await fetchCallback(this.#config, provider, body);
|
|
2356
2595
|
}
|
|
2357
2596
|
async signIn(provider, payload, rawResponse) {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2597
|
+
return withNileContext(this.#config, async () => {
|
|
2598
|
+
if (payload instanceof Request) {
|
|
2599
|
+
const body2 = new URLSearchParams(await payload.text());
|
|
2600
|
+
const origin = new URL(payload.url).origin;
|
|
2601
|
+
const payloadUrl = body2?.get("callbackUrl");
|
|
2602
|
+
const csrfToken2 = body2?.get("csrfToken");
|
|
2603
|
+
const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
|
|
2604
|
+
if (!csrfToken2) {
|
|
2605
|
+
throw new Error(
|
|
2606
|
+
"CSRF token in missing from request. Request it by the client before calling sign in"
|
|
2607
|
+
);
|
|
2608
|
+
}
|
|
2609
|
+
const updatedHeaders = new Headers(payload.headers);
|
|
2610
|
+
updatedHeaders.set("Content-Type", "application/x-www-form-urlencoded");
|
|
2611
|
+
ctx.set({ headers: updatedHeaders });
|
|
2612
|
+
const params = new URLSearchParams({
|
|
2613
|
+
csrfToken: csrfToken2,
|
|
2614
|
+
json: String(true)
|
|
2615
|
+
});
|
|
2616
|
+
if (payloadUrl) {
|
|
2617
|
+
params.set("callbackUrl", callbackUrl);
|
|
2618
|
+
}
|
|
2619
|
+
return await fetchSignIn(this.#config, provider, params);
|
|
2620
|
+
}
|
|
2621
|
+
ctx.set({ headers: null });
|
|
2622
|
+
const { info, error } = this.#logger;
|
|
2623
|
+
const providers = await this.listProviders();
|
|
2624
|
+
info("Obtaining csrf");
|
|
2625
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2626
|
+
let csrfToken;
|
|
2627
|
+
if ("csrfToken" in csrf) {
|
|
2628
|
+
csrfToken = csrf.csrfToken;
|
|
2629
|
+
} else {
|
|
2630
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2631
|
+
}
|
|
2632
|
+
const { credentials } = providers ?? {};
|
|
2633
|
+
if (!credentials) {
|
|
2365
2634
|
throw new Error(
|
|
2366
|
-
"
|
|
2635
|
+
"Unable to obtain credential provider. Aborting server side sign in."
|
|
2367
2636
|
);
|
|
2368
2637
|
}
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2638
|
+
const { email, password } = payload ?? {};
|
|
2639
|
+
if (provider === "email" && (!email || !password)) {
|
|
2640
|
+
throw new Error(
|
|
2641
|
+
"Server side sign in requires a user email and password."
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
info(`Obtaining providers for ${email}`);
|
|
2645
|
+
info(`Attempting sign in with email ${email}`);
|
|
2646
|
+
if (!email) {
|
|
2647
|
+
throw new Error("Email missing from payload, unable to sign in");
|
|
2648
|
+
}
|
|
2649
|
+
const body = JSON.stringify({
|
|
2650
|
+
email,
|
|
2651
|
+
password,
|
|
2652
|
+
csrfToken,
|
|
2653
|
+
callbackUrl: credentials.callbackUrl
|
|
2377
2654
|
});
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
"Unable to obtain
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
);
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
const possibleError = signInRes?.headers.get("location");
|
|
2424
|
-
if (possibleError) {
|
|
2425
|
-
let urlError;
|
|
2655
|
+
const signInRes = await this.callback(provider, body);
|
|
2656
|
+
const authCookie = signInRes?.headers.get("set-cookie");
|
|
2657
|
+
if (!authCookie) {
|
|
2658
|
+
throw new Error("authentication failed");
|
|
2659
|
+
}
|
|
2660
|
+
const token = parseToken(signInRes?.headers);
|
|
2661
|
+
const possibleError = signInRes?.headers.get("location");
|
|
2662
|
+
if (possibleError) {
|
|
2663
|
+
let urlError;
|
|
2664
|
+
try {
|
|
2665
|
+
urlError = new URL(possibleError).searchParams.get("error");
|
|
2666
|
+
} catch {
|
|
2667
|
+
}
|
|
2668
|
+
if (urlError) {
|
|
2669
|
+
error("Unable to log user in", { error: urlError });
|
|
2670
|
+
return new Response(urlError, { status: signInRes.status });
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
if (!token) {
|
|
2674
|
+
error("Unable to obtain auth token", {
|
|
2675
|
+
authCookie,
|
|
2676
|
+
signInRes
|
|
2677
|
+
});
|
|
2678
|
+
throw new Error("Server login failed");
|
|
2679
|
+
}
|
|
2680
|
+
info("Server sign in successful", { authCookie });
|
|
2681
|
+
const setCookie = signInRes.headers.get("set-cookie");
|
|
2682
|
+
const { headers } = ctx.get();
|
|
2683
|
+
if (setCookie) {
|
|
2684
|
+
const cookie = [
|
|
2685
|
+
parseCSRF(headers),
|
|
2686
|
+
parseCallback(signInRes.headers),
|
|
2687
|
+
parseToken(signInRes.headers)
|
|
2688
|
+
].filter(Boolean).join("; ");
|
|
2689
|
+
const uHeaders = new Headers({ cookie });
|
|
2690
|
+
updateHeaders(uHeaders);
|
|
2691
|
+
ctx.set({ headers: uHeaders });
|
|
2692
|
+
} else {
|
|
2693
|
+
error("Unable to set context after sign in", {
|
|
2694
|
+
headers: signInRes.headers
|
|
2695
|
+
});
|
|
2696
|
+
}
|
|
2697
|
+
if (rawResponse) {
|
|
2698
|
+
return signInRes;
|
|
2699
|
+
}
|
|
2426
2700
|
try {
|
|
2427
|
-
|
|
2701
|
+
return await signInRes.clone().json();
|
|
2428
2702
|
} catch {
|
|
2703
|
+
return signInRes;
|
|
2429
2704
|
}
|
|
2430
|
-
|
|
2431
|
-
error("Unable to log user in", { error: urlError });
|
|
2432
|
-
return new Response(urlError, { status: signInRes.status });
|
|
2433
|
-
}
|
|
2434
|
-
}
|
|
2435
|
-
if (!token) {
|
|
2436
|
-
error("Unable to obtain auth token", {
|
|
2437
|
-
authCookie,
|
|
2438
|
-
signInRes
|
|
2439
|
-
});
|
|
2440
|
-
throw new Error("Server login failed");
|
|
2441
|
-
}
|
|
2442
|
-
info("Server sign in successful", { authCookie });
|
|
2443
|
-
const setCookie = signInRes.headers.get("set-cookie");
|
|
2444
|
-
if (setCookie) {
|
|
2445
|
-
const cookie = [
|
|
2446
|
-
parseCSRF(this.#config.headers),
|
|
2447
|
-
parseCallback(signInRes.headers),
|
|
2448
|
-
parseToken(signInRes.headers)
|
|
2449
|
-
].filter(Boolean).join("; ");
|
|
2450
|
-
updateHeaders(new Headers({ cookie }));
|
|
2451
|
-
} else {
|
|
2452
|
-
error("Unable to set context after sign in", {
|
|
2453
|
-
headers: signInRes.headers
|
|
2454
|
-
});
|
|
2455
|
-
}
|
|
2456
|
-
if (rawResponse) {
|
|
2457
|
-
return signInRes;
|
|
2458
|
-
}
|
|
2459
|
-
try {
|
|
2460
|
-
return await signInRes.clone().json();
|
|
2461
|
-
} catch {
|
|
2462
|
-
return signInRes;
|
|
2463
|
-
}
|
|
2705
|
+
});
|
|
2464
2706
|
}
|
|
2465
2707
|
};
|
|
2466
2708
|
function parseCSRF(headers) {
|
|
@@ -2507,25 +2749,56 @@ function parseResetToken(headers) {
|
|
|
2507
2749
|
const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
|
|
2508
2750
|
return token;
|
|
2509
2751
|
}
|
|
2510
|
-
function
|
|
2752
|
+
function parseTenantId(headers) {
|
|
2753
|
+
let authCookie = headers?.get("set-cookie");
|
|
2754
|
+
if (!authCookie) {
|
|
2755
|
+
authCookie = headers?.get("cookie");
|
|
2756
|
+
}
|
|
2757
|
+
if (!authCookie) {
|
|
2758
|
+
return void 0;
|
|
2759
|
+
}
|
|
2760
|
+
const [, token] = /((__Secure-)?nile\.tenant-id=[^;]+)/.exec(authCookie) ?? [];
|
|
2761
|
+
if (token) {
|
|
2762
|
+
const [, tenantId] = token.split("=");
|
|
2763
|
+
return tenantId;
|
|
2764
|
+
}
|
|
2765
|
+
return null;
|
|
2766
|
+
}
|
|
2767
|
+
function defaultCallbackUrl(config) {
|
|
2511
2768
|
let cb = null;
|
|
2512
2769
|
let redirect = null;
|
|
2513
|
-
const
|
|
2770
|
+
const { headers } = ctx.get();
|
|
2771
|
+
const fallbackCb = parseCallback(headers);
|
|
2514
2772
|
if (fallbackCb) {
|
|
2515
2773
|
const [, value] = fallbackCb.split("=");
|
|
2516
2774
|
cb = decodeURIComponent(value);
|
|
2517
2775
|
if (value) {
|
|
2518
|
-
redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2776
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2519
2777
|
}
|
|
2520
2778
|
}
|
|
2521
2779
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
2522
2780
|
}
|
|
2781
|
+
function fQUrl(path, config) {
|
|
2782
|
+
if (path.startsWith("/")) {
|
|
2783
|
+
const { callbackUrl } = defaultCallbackUrl(config);
|
|
2784
|
+
if (callbackUrl) {
|
|
2785
|
+
const { origin } = new URL(callbackUrl);
|
|
2786
|
+
return `${origin}${path}`;
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
try {
|
|
2790
|
+
new URL(path);
|
|
2791
|
+
} catch {
|
|
2792
|
+
throw new Error("An invalid URL has been passed.");
|
|
2793
|
+
}
|
|
2794
|
+
return path;
|
|
2795
|
+
}
|
|
2523
2796
|
|
|
2524
2797
|
// src/auth/obtainCsrf.ts
|
|
2525
2798
|
async function obtainCsrf(config, rawResponse = false) {
|
|
2799
|
+
const { headers } = ctx.get();
|
|
2526
2800
|
const res = await fetchCsrf(config);
|
|
2527
2801
|
const csrfCook = parseCSRF(res.headers);
|
|
2528
|
-
const h = new Headers();
|
|
2529
2802
|
if (csrfCook) {
|
|
2530
2803
|
const [, value] = csrfCook.split("=");
|
|
2531
2804
|
const [token] = decodeURIComponent(value).split("|");
|
|
@@ -2536,29 +2809,27 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2536
2809
|
parseCallback(res.headers),
|
|
2537
2810
|
parseToken(res.headers)
|
|
2538
2811
|
].filter(Boolean).join("; ");
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
updateHeaders(
|
|
2812
|
+
headers.set("cookie", cookie);
|
|
2813
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2814
|
+
updateHeaders(headers);
|
|
2542
2815
|
}
|
|
2543
2816
|
if (!rawResponse) {
|
|
2544
2817
|
return { csrfToken: token };
|
|
2545
2818
|
}
|
|
2546
2819
|
} else {
|
|
2547
|
-
const existingCookie =
|
|
2820
|
+
const existingCookie = headers.get("cookie");
|
|
2548
2821
|
const cookieParts = [];
|
|
2549
2822
|
if (existingCookie) {
|
|
2550
|
-
cookieParts.push(
|
|
2551
|
-
parseToken(config.headers),
|
|
2552
|
-
parseCallback(config.headers)
|
|
2553
|
-
);
|
|
2823
|
+
cookieParts.push(parseToken(headers), parseCallback(headers));
|
|
2554
2824
|
}
|
|
2555
2825
|
if (csrfCook) {
|
|
2556
2826
|
cookieParts.push(csrfCook);
|
|
2557
2827
|
} else {
|
|
2558
|
-
cookieParts.push(parseCSRF(
|
|
2828
|
+
cookieParts.push(parseCSRF(headers));
|
|
2559
2829
|
}
|
|
2560
2830
|
const cookie = cookieParts.filter(Boolean).join("; ");
|
|
2561
|
-
|
|
2831
|
+
headers.set("cookie", cookie);
|
|
2832
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2562
2833
|
updateHeaders(new Headers({ cookie }));
|
|
2563
2834
|
}
|
|
2564
2835
|
if (rawResponse) {
|
|
@@ -2593,15 +2864,17 @@ var Users = class {
|
|
|
2593
2864
|
* @param [rawResponse] - When `true`, return the raw {@link Response}.
|
|
2594
2865
|
*/
|
|
2595
2866
|
async updateSelf(req, rawResponse) {
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2867
|
+
return withNileContext(this.#config, async () => {
|
|
2868
|
+
const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
|
|
2869
|
+
if (rawResponse) {
|
|
2870
|
+
return res;
|
|
2871
|
+
}
|
|
2872
|
+
try {
|
|
2873
|
+
return await res?.clone().json();
|
|
2874
|
+
} catch {
|
|
2875
|
+
return res;
|
|
2876
|
+
}
|
|
2877
|
+
});
|
|
2605
2878
|
}
|
|
2606
2879
|
/**
|
|
2607
2880
|
* Remove the current user using `DELETE /api/me`.
|
|
@@ -2611,59 +2884,70 @@ var Users = class {
|
|
|
2611
2884
|
* `packages/server/src/api/routes/me/index.ts` under `removeSelf`.
|
|
2612
2885
|
*/
|
|
2613
2886
|
async removeSelf() {
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2887
|
+
return withNileContext(this.#config, async () => {
|
|
2888
|
+
const me = await this.getSelf();
|
|
2889
|
+
if ("id" in me) {
|
|
2890
|
+
const userId = me.id;
|
|
2891
|
+
ctx.set({ userId });
|
|
2892
|
+
}
|
|
2893
|
+
const res = await fetchMe(this.#config, "DELETE");
|
|
2894
|
+
updateHeaders(new Headers());
|
|
2895
|
+
return res;
|
|
2896
|
+
});
|
|
2621
2897
|
}
|
|
2622
2898
|
async getSelf(rawResponse) {
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2899
|
+
return withNileContext(this.#config, async () => {
|
|
2900
|
+
const res = await fetchMe(this.#config);
|
|
2901
|
+
if (rawResponse) {
|
|
2902
|
+
return res;
|
|
2903
|
+
}
|
|
2904
|
+
try {
|
|
2905
|
+
return await res?.clone().json();
|
|
2906
|
+
} catch {
|
|
2907
|
+
return res;
|
|
2908
|
+
}
|
|
2909
|
+
});
|
|
2632
2910
|
}
|
|
2633
2911
|
async verifySelf(options, rawResponse = false) {
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2912
|
+
return withNileContext(this.#config, async () => {
|
|
2913
|
+
const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
|
|
2914
|
+
const callbackUrl = typeof options === "object" ? options.callbackUrl : defaultCallbackUrl2().callbackUrl;
|
|
2915
|
+
let res;
|
|
2916
|
+
try {
|
|
2917
|
+
const me = await this.getSelf();
|
|
2918
|
+
if (me instanceof Response) {
|
|
2919
|
+
return me;
|
|
2920
|
+
}
|
|
2921
|
+
res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
|
|
2922
|
+
return res;
|
|
2923
|
+
} catch (e) {
|
|
2924
|
+
if (!bypassEmail) {
|
|
2925
|
+
let message = "Unable to verify email.";
|
|
2926
|
+
if (e instanceof Error) {
|
|
2927
|
+
message = e.message;
|
|
2928
|
+
}
|
|
2929
|
+
this.#logger?.error(
|
|
2930
|
+
`${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
|
|
2931
|
+
);
|
|
2932
|
+
res = new Response(message, { status: 400 });
|
|
2649
2933
|
}
|
|
2650
|
-
|
|
2651
|
-
|
|
2934
|
+
}
|
|
2935
|
+
if (bypassEmail) {
|
|
2936
|
+
this.#logger?.info(
|
|
2937
|
+
"bypassing email requirements for email verification"
|
|
2652
2938
|
);
|
|
2653
|
-
res =
|
|
2939
|
+
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2654
2940
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
this.#logger?.info("bypassing email requirements for email verification");
|
|
2658
|
-
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2659
|
-
}
|
|
2660
|
-
return res;
|
|
2941
|
+
return res;
|
|
2942
|
+
});
|
|
2661
2943
|
}
|
|
2662
2944
|
};
|
|
2663
2945
|
async function verifyEmailAddress(config, user, callback) {
|
|
2664
|
-
|
|
2946
|
+
const { headers } = ctx.get();
|
|
2947
|
+
headers?.set("content-type", "application/x-www-form-urlencoded");
|
|
2948
|
+
ctx.set({ headers });
|
|
2665
2949
|
const { csrfToken } = await obtainCsrf(config);
|
|
2666
|
-
const defaults = defaultCallbackUrl2(
|
|
2950
|
+
const defaults = defaultCallbackUrl2();
|
|
2667
2951
|
const callbackUrl = callback ?? String(defaults.callbackUrl);
|
|
2668
2952
|
const res = await fetchVerifyEmail(
|
|
2669
2953
|
config,
|
|
@@ -2679,9 +2963,10 @@ async function verifyEmailAddress(config, user, callback) {
|
|
|
2679
2963
|
}
|
|
2680
2964
|
return res;
|
|
2681
2965
|
}
|
|
2682
|
-
function defaultCallbackUrl2(
|
|
2966
|
+
function defaultCallbackUrl2() {
|
|
2683
2967
|
let cb = null;
|
|
2684
|
-
const
|
|
2968
|
+
const { headers } = ctx.get();
|
|
2969
|
+
const fallbackCb = parseCallback(headers);
|
|
2685
2970
|
if (fallbackCb) {
|
|
2686
2971
|
const [, value] = fallbackCb.split("=");
|
|
2687
2972
|
cb = decodeURIComponent(value);
|
|
@@ -2701,24 +2986,26 @@ var Tenants = class {
|
|
|
2701
2986
|
* `createTenant` operation definition.
|
|
2702
2987
|
*/
|
|
2703
2988
|
async create(req, rawResponse) {
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2989
|
+
return withNileContext(this.#config, async () => {
|
|
2990
|
+
let res;
|
|
2991
|
+
if (typeof req === "string") {
|
|
2992
|
+
res = await fetchTenants(
|
|
2993
|
+
this.#config,
|
|
2994
|
+
"POST",
|
|
2995
|
+
JSON.stringify({ name: req })
|
|
2996
|
+
);
|
|
2997
|
+
} else if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
2998
|
+
res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
|
|
2999
|
+
}
|
|
3000
|
+
if (rawResponse) {
|
|
3001
|
+
return res;
|
|
3002
|
+
}
|
|
3003
|
+
try {
|
|
3004
|
+
return await res?.clone().json();
|
|
3005
|
+
} catch {
|
|
3006
|
+
return res;
|
|
3007
|
+
}
|
|
3008
|
+
});
|
|
2722
3009
|
}
|
|
2723
3010
|
/**
|
|
2724
3011
|
* Remove a tenant via `DELETE /api/tenants/{tenantId}`.
|
|
@@ -2726,14 +3013,16 @@ var Tenants = class {
|
|
|
2726
3013
|
* @param req - The tenant to remove or context containing the id.
|
|
2727
3014
|
*/
|
|
2728
3015
|
async delete(req) {
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
3016
|
+
return withNileContext(this.#config, async () => {
|
|
3017
|
+
if (typeof req === "string") {
|
|
3018
|
+
ctx.set({ tenantId: req });
|
|
3019
|
+
}
|
|
3020
|
+
if (typeof req === "object" && "id" in req) {
|
|
3021
|
+
ctx.set({ tenantId: req.id });
|
|
3022
|
+
}
|
|
3023
|
+
const res = await fetchTenant(this.#config, "DELETE");
|
|
3024
|
+
return res;
|
|
3025
|
+
});
|
|
2737
3026
|
}
|
|
2738
3027
|
/**
|
|
2739
3028
|
* Fetch details for a tenant using `GET /api/tenants/{tenantId}`.
|
|
@@ -2742,53 +3031,63 @@ var Tenants = class {
|
|
|
2742
3031
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2743
3032
|
*/
|
|
2744
3033
|
async get(req, rawResponse) {
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
3034
|
+
return withNileContext(this.#config, async () => {
|
|
3035
|
+
if (typeof req === "string") {
|
|
3036
|
+
ctx.set({ tenantId: req });
|
|
3037
|
+
} else if (typeof req === "object" && "id" in req) {
|
|
3038
|
+
ctx.set({ tenantId: req.id });
|
|
3039
|
+
}
|
|
3040
|
+
const res = await fetchTenant(this.#config, "GET");
|
|
3041
|
+
if (rawResponse === true || req === true) {
|
|
3042
|
+
return res;
|
|
3043
|
+
}
|
|
3044
|
+
try {
|
|
3045
|
+
return await res?.clone().json();
|
|
3046
|
+
} catch {
|
|
3047
|
+
return res;
|
|
3048
|
+
}
|
|
3049
|
+
});
|
|
2759
3050
|
}
|
|
2760
3051
|
async update(req, rawResponse) {
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
3052
|
+
return withNileContext(this.#config, async () => {
|
|
3053
|
+
let res;
|
|
3054
|
+
if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3055
|
+
const { id, ...remaining } = req;
|
|
3056
|
+
if (id) {
|
|
3057
|
+
ctx.set({ tenantId: id });
|
|
3058
|
+
}
|
|
3059
|
+
res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
|
|
2766
3060
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
}
|
|
3061
|
+
if (rawResponse) {
|
|
3062
|
+
return res;
|
|
3063
|
+
}
|
|
3064
|
+
try {
|
|
3065
|
+
return await res?.clone().json();
|
|
3066
|
+
} catch {
|
|
3067
|
+
return res;
|
|
3068
|
+
}
|
|
3069
|
+
});
|
|
2777
3070
|
}
|
|
2778
3071
|
/**
|
|
2779
3072
|
* List tenants for the current user via `GET /api/tenants`.
|
|
2780
3073
|
* See `packages/server/src/api/routes/tenants/GET.ts` for details.
|
|
2781
3074
|
*/
|
|
2782
3075
|
async list(req) {
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
3076
|
+
return withNileContext(
|
|
3077
|
+
this.#config,
|
|
3078
|
+
async () => {
|
|
3079
|
+
const res = await fetchTenantsByUser(this.#config);
|
|
3080
|
+
if (req === true) {
|
|
3081
|
+
return res;
|
|
3082
|
+
}
|
|
3083
|
+
try {
|
|
3084
|
+
return await res?.clone().json();
|
|
3085
|
+
} catch {
|
|
3086
|
+
return res;
|
|
3087
|
+
}
|
|
3088
|
+
},
|
|
3089
|
+
"listTenants"
|
|
3090
|
+
);
|
|
2792
3091
|
}
|
|
2793
3092
|
/**
|
|
2794
3093
|
* Leave the current tenant using `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2796,29 +3095,33 @@ var Tenants = class {
|
|
|
2796
3095
|
* @param [req] - Optionally specify the tenant id to leave.
|
|
2797
3096
|
*/
|
|
2798
3097
|
async leaveTenant(req) {
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
3098
|
+
return withNileContext(this.#config, async () => {
|
|
3099
|
+
const me = await fetchMe(this.#config);
|
|
3100
|
+
try {
|
|
3101
|
+
const json = await me.json();
|
|
3102
|
+
if ("id" in json) {
|
|
3103
|
+
ctx.set({ userId: json.id, preserveHeaders: true });
|
|
3104
|
+
}
|
|
3105
|
+
} catch {
|
|
2804
3106
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
this.#
|
|
2811
|
-
}
|
|
2812
|
-
return await fetchTenantUser(this.#config, "DELETE");
|
|
3107
|
+
if (typeof req === "string") {
|
|
3108
|
+
ctx.set({ tenantId: req, preserveHeaders: true });
|
|
3109
|
+
} else {
|
|
3110
|
+
this.#handleContext(req);
|
|
3111
|
+
}
|
|
3112
|
+
return await fetchTenantUser(this.#config, "DELETE");
|
|
3113
|
+
});
|
|
2813
3114
|
}
|
|
2814
3115
|
async addMember(req, rawResponse) {
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
3116
|
+
return withNileContext(this.#config, async () => {
|
|
3117
|
+
if (typeof req === "string") {
|
|
3118
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3119
|
+
} else {
|
|
3120
|
+
this.#handleContext(req);
|
|
3121
|
+
}
|
|
3122
|
+
const res = await fetchTenantUser(this.#config, "PUT");
|
|
3123
|
+
return responseHandler(res, rawResponse);
|
|
3124
|
+
});
|
|
2822
3125
|
}
|
|
2823
3126
|
/**
|
|
2824
3127
|
* Remove a user from a tenant with `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2827,57 +3130,82 @@ var Tenants = class {
|
|
|
2827
3130
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2828
3131
|
*/
|
|
2829
3132
|
async removeMember(req, rawResponse) {
|
|
2830
|
-
this.#
|
|
2831
|
-
|
|
2832
|
-
|
|
3133
|
+
return withNileContext(this.#config, async () => {
|
|
3134
|
+
this.#handleContext(req);
|
|
3135
|
+
if (typeof req === "string") {
|
|
3136
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3137
|
+
}
|
|
3138
|
+
const res = await fetchTenantUser(this.#config, "DELETE");
|
|
3139
|
+
return responseHandler(res, rawResponse);
|
|
3140
|
+
});
|
|
2833
3141
|
}
|
|
2834
3142
|
async users(req, rawResponse) {
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
3143
|
+
return withNileContext(
|
|
3144
|
+
this.#config,
|
|
3145
|
+
async () => {
|
|
3146
|
+
this.#handleContext(req);
|
|
3147
|
+
const res = await fetchTenantUsers(this.#config, "GET");
|
|
3148
|
+
return responseHandler(
|
|
3149
|
+
res,
|
|
3150
|
+
rawResponse || typeof req === "boolean" && req
|
|
3151
|
+
);
|
|
3152
|
+
},
|
|
3153
|
+
"users"
|
|
2840
3154
|
);
|
|
2841
3155
|
}
|
|
2842
3156
|
/**
|
|
2843
3157
|
* List invites for the current tenant via `GET /api/tenants/{tenantId}/invites`.
|
|
2844
3158
|
*/
|
|
2845
3159
|
async invites() {
|
|
2846
|
-
|
|
2847
|
-
|
|
3160
|
+
return withNileContext(
|
|
3161
|
+
this.#config,
|
|
3162
|
+
async () => {
|
|
3163
|
+
const res = await fetchInvites(this.#config);
|
|
3164
|
+
return responseHandler(res);
|
|
3165
|
+
},
|
|
3166
|
+
"invites"
|
|
3167
|
+
);
|
|
2848
3168
|
}
|
|
2849
3169
|
async invite(req, rawResponse) {
|
|
2850
|
-
|
|
2851
|
-
const defaults = defaultCallbackUrl3(this.#config);
|
|
2852
|
-
let identifier = req;
|
|
2853
|
-
let callbackUrl = defaults.callbackUrl;
|
|
2854
|
-
let redirectUrl = defaults.redirectUrl;
|
|
2855
|
-
if (typeof req === "object") {
|
|
2856
|
-
if ("email" in req) {
|
|
2857
|
-
identifier = req.email;
|
|
2858
|
-
}
|
|
2859
|
-
if ("callbackUrl" in req) {
|
|
2860
|
-
callbackUrl = req.callbackUrl ? req.callbackUrl : "";
|
|
2861
|
-
}
|
|
2862
|
-
if ("redirectUrl" in req) {
|
|
2863
|
-
redirectUrl = req.redirectUrl ? req.redirectUrl : "";
|
|
2864
|
-
}
|
|
2865
|
-
}
|
|
2866
|
-
this.#config.headers.set(
|
|
2867
|
-
"Content-Type",
|
|
2868
|
-
"application/x-www-form-urlencoded"
|
|
2869
|
-
);
|
|
2870
|
-
const res = await fetchInvite(
|
|
3170
|
+
return withNileContext(
|
|
2871
3171
|
this.#config,
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3172
|
+
async () => {
|
|
3173
|
+
await runExtensionContext(this.#config);
|
|
3174
|
+
const { csrfToken } = await obtainCsrf(
|
|
3175
|
+
this.#config
|
|
3176
|
+
);
|
|
3177
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3178
|
+
let identifier = req;
|
|
3179
|
+
let callbackUrl = defaults.callbackUrl;
|
|
3180
|
+
let redirectUrl = defaults.redirectUrl;
|
|
3181
|
+
if (typeof req === "object") {
|
|
3182
|
+
if ("email" in req) {
|
|
3183
|
+
identifier = req.email;
|
|
3184
|
+
}
|
|
3185
|
+
if ("callbackUrl" in req) {
|
|
3186
|
+
callbackUrl = fQUrl2(req.callbackUrl ?? "", this.#config);
|
|
3187
|
+
}
|
|
3188
|
+
if ("redirectUrl" in req) {
|
|
3189
|
+
redirectUrl = fQUrl2(req.redirectUrl ?? "", this.#config);
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
const { headers } = ctx.get();
|
|
3193
|
+
headers?.set("Content-Type", "application/x-www-form-urlencoded");
|
|
3194
|
+
ctx.set({ headers });
|
|
3195
|
+
const res = await fetchInvite(
|
|
3196
|
+
this.#config,
|
|
3197
|
+
"POST",
|
|
3198
|
+
new URLSearchParams({
|
|
3199
|
+
identifier,
|
|
3200
|
+
csrfToken,
|
|
3201
|
+
callbackUrl,
|
|
3202
|
+
redirectUrl
|
|
3203
|
+
}).toString()
|
|
3204
|
+
);
|
|
3205
|
+
return responseHandler(res, rawResponse);
|
|
3206
|
+
},
|
|
3207
|
+
"invites"
|
|
2879
3208
|
);
|
|
2880
|
-
return responseHandler(res, rawResponse);
|
|
2881
3209
|
}
|
|
2882
3210
|
/**
|
|
2883
3211
|
* Accept an invite using `PUT /api/tenants/{tenantId}/invite`.
|
|
@@ -2886,22 +3214,24 @@ var Tenants = class {
|
|
|
2886
3214
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2887
3215
|
*/
|
|
2888
3216
|
async acceptInvite(req, rawResponse) {
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
3217
|
+
return withNileContext(this.#config, async () => {
|
|
3218
|
+
if (!req) {
|
|
3219
|
+
throw new Error("The identifier and token are required.");
|
|
3220
|
+
}
|
|
3221
|
+
const { identifier, token } = req;
|
|
3222
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3223
|
+
const callbackUrl = String(defaults.callbackUrl);
|
|
3224
|
+
const res = await fetchInvite(
|
|
3225
|
+
this.#config,
|
|
3226
|
+
"PUT",
|
|
3227
|
+
new URLSearchParams({
|
|
3228
|
+
identifier,
|
|
3229
|
+
token,
|
|
3230
|
+
callbackUrl
|
|
3231
|
+
}).toString()
|
|
3232
|
+
);
|
|
3233
|
+
return responseHandler(res, rawResponse);
|
|
3234
|
+
});
|
|
2905
3235
|
}
|
|
2906
3236
|
/**
|
|
2907
3237
|
* Delete a pending invite using `DELETE /api/tenants/{tenantId}/invite/{inviteId}`.
|
|
@@ -2909,25 +3239,27 @@ var Tenants = class {
|
|
|
2909
3239
|
* @param req - Identifier of the invite to remove.
|
|
2910
3240
|
*/
|
|
2911
3241
|
async deleteInvite(req) {
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
3242
|
+
return withNileContext(this.#config, async () => {
|
|
3243
|
+
let id = "";
|
|
3244
|
+
if (typeof req === "object") {
|
|
3245
|
+
id = req.id;
|
|
3246
|
+
} else {
|
|
3247
|
+
id = req;
|
|
3248
|
+
}
|
|
3249
|
+
if (!id) {
|
|
3250
|
+
throw new Error("An invite id is required.");
|
|
3251
|
+
}
|
|
3252
|
+
const res = await fetchInvite(this.#config, "DELETE", id);
|
|
3253
|
+
return responseHandler(res, true);
|
|
3254
|
+
});
|
|
2923
3255
|
}
|
|
2924
3256
|
#handleContext(req) {
|
|
2925
3257
|
if (typeof req === "object") {
|
|
2926
3258
|
if ("tenantId" in req) {
|
|
2927
|
-
|
|
3259
|
+
ctx.set({ tenantId: req.tenantId, preserveHeaders: true });
|
|
2928
3260
|
}
|
|
2929
3261
|
if ("userId" in req) {
|
|
2930
|
-
|
|
3262
|
+
ctx.set({ userId: req.userId, preserveHeaders: true });
|
|
2931
3263
|
}
|
|
2932
3264
|
}
|
|
2933
3265
|
}
|
|
@@ -2945,19 +3277,32 @@ async function responseHandler(res, rawResponse) {
|
|
|
2945
3277
|
function defaultCallbackUrl3(config) {
|
|
2946
3278
|
let cb = null;
|
|
2947
3279
|
let redirect = null;
|
|
2948
|
-
const
|
|
3280
|
+
const { headers, tenantId } = ctx.get();
|
|
3281
|
+
const fallbackCb = parseCallback(headers);
|
|
2949
3282
|
if (fallbackCb) {
|
|
2950
3283
|
const [, value] = fallbackCb.split("=");
|
|
2951
3284
|
cb = decodeURIComponent(value);
|
|
2952
3285
|
if (value) {
|
|
2953
|
-
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
|
|
2954
|
-
"{tenantId}",
|
|
2955
|
-
String(config.tenantId)
|
|
2956
|
-
)}`;
|
|
3286
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", String(tenantId))}`;
|
|
2957
3287
|
}
|
|
2958
3288
|
}
|
|
2959
3289
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
2960
3290
|
}
|
|
3291
|
+
function fQUrl2(path, config) {
|
|
3292
|
+
if (path.startsWith("/")) {
|
|
3293
|
+
const { callbackUrl } = defaultCallbackUrl3(config);
|
|
3294
|
+
if (callbackUrl) {
|
|
3295
|
+
const { origin } = new URL(callbackUrl);
|
|
3296
|
+
return `${origin}${path}`;
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
try {
|
|
3300
|
+
new URL(path);
|
|
3301
|
+
} catch {
|
|
3302
|
+
throw new Error("An invalid URL has been passed.");
|
|
3303
|
+
}
|
|
3304
|
+
return path;
|
|
3305
|
+
}
|
|
2961
3306
|
|
|
2962
3307
|
// src/api/handlers/withContext/index.ts
|
|
2963
3308
|
function handlersWithContext(config) {
|
|
@@ -3020,97 +3365,6 @@ function updateConfig(response, config) {
|
|
|
3020
3365
|
};
|
|
3021
3366
|
}
|
|
3022
3367
|
|
|
3023
|
-
// src/api/utils/extensions.ts
|
|
3024
|
-
function getRequestConfig(params) {
|
|
3025
|
-
if (typeof params[1] === "object") {
|
|
3026
|
-
return params[1];
|
|
3027
|
-
}
|
|
3028
|
-
return {};
|
|
3029
|
-
}
|
|
3030
|
-
function bindRunExtensions(instance) {
|
|
3031
|
-
return async function runExtensions(toRun, config, params, _init) {
|
|
3032
|
-
const { debug } = config.logger("[EXTENSIONS]");
|
|
3033
|
-
const extensionConfig = getRequestConfig(
|
|
3034
|
-
Array.isArray(params) ? params : [null, params]
|
|
3035
|
-
);
|
|
3036
|
-
if (config.extensions) {
|
|
3037
|
-
for (const create2 of config.extensions) {
|
|
3038
|
-
if (typeof create2 !== "function") {
|
|
3039
|
-
continue;
|
|
3040
|
-
}
|
|
3041
|
-
const ext = create2(instance);
|
|
3042
|
-
if (extensionConfig.disableExtensions?.includes(ext.id)) {
|
|
3043
|
-
continue;
|
|
3044
|
-
}
|
|
3045
|
-
if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
|
|
3046
|
-
const result = await ext.onHandleRequest(
|
|
3047
|
-
...Array.isArray(params) ? params : [params]
|
|
3048
|
-
);
|
|
3049
|
-
debug(`${ext.id ?? create2.name} ran onHandleRequest`);
|
|
3050
|
-
if (result != null) {
|
|
3051
|
-
return result;
|
|
3052
|
-
}
|
|
3053
|
-
}
|
|
3054
|
-
const [param] = Array.isArray(params) ? params : [params];
|
|
3055
|
-
if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
|
|
3056
|
-
const previousContext = instance.getContext();
|
|
3057
|
-
if (previousContext.preserveHeaders) {
|
|
3058
|
-
instance.setContext({ preserveHeaders: false });
|
|
3059
|
-
}
|
|
3060
|
-
if (!_init) {
|
|
3061
|
-
continue;
|
|
3062
|
-
}
|
|
3063
|
-
await ext.onRequest(_init.request);
|
|
3064
|
-
const updatedContext = instance.getContext();
|
|
3065
|
-
if (updatedContext?.headers) {
|
|
3066
|
-
const cookie = updatedContext.headers.get("cookie");
|
|
3067
|
-
if (cookie && param.headers) {
|
|
3068
|
-
param.headers.set(
|
|
3069
|
-
"cookie",
|
|
3070
|
-
mergeCookies(
|
|
3071
|
-
previousContext.preserveHeaders ? previousContext.headers?.get("cookie") : null,
|
|
3072
|
-
updatedContext.headers.get("cookie")
|
|
3073
|
-
)
|
|
3074
|
-
);
|
|
3075
|
-
}
|
|
3076
|
-
if (updatedContext.tenantId && param.headers) {
|
|
3077
|
-
param.headers.set(
|
|
3078
|
-
TENANT_COOKIE,
|
|
3079
|
-
String(updatedContext.headers.get(TENANT_COOKIE))
|
|
3080
|
-
);
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
3083
|
-
debug(`${ext.id ?? create2.name} ran onRequest`);
|
|
3084
|
-
}
|
|
3085
|
-
if (ext.onResponse && toRun === "onResponse" /* onResponse */) {
|
|
3086
|
-
const result = await ext.onResponse(param);
|
|
3087
|
-
debug(`${ext.id ?? create2.name} ran onResponse`);
|
|
3088
|
-
if (result != null) {
|
|
3089
|
-
return result;
|
|
3090
|
-
}
|
|
3091
|
-
}
|
|
3092
|
-
}
|
|
3093
|
-
}
|
|
3094
|
-
return void 0;
|
|
3095
|
-
};
|
|
3096
|
-
}
|
|
3097
|
-
function buildExtensionConfig(instance) {
|
|
3098
|
-
return {
|
|
3099
|
-
runExtensions: bindRunExtensions(instance)
|
|
3100
|
-
};
|
|
3101
|
-
}
|
|
3102
|
-
function mergeCookies(...cookieStrings) {
|
|
3103
|
-
const cookieMap = /* @__PURE__ */ new Map();
|
|
3104
|
-
for (const str of cookieStrings) {
|
|
3105
|
-
if (!str) continue;
|
|
3106
|
-
for (const part of str.split(";")) {
|
|
3107
|
-
const [key17, value] = part.split("=").map((s) => s.trim());
|
|
3108
|
-
if (key17 && value) cookieMap.set(key17, value);
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
return [...cookieMap.entries()].map(([k, v]) => `${k}=${v}`).join("; ");
|
|
3112
|
-
}
|
|
3113
|
-
|
|
3114
3368
|
// src/Server.ts
|
|
3115
3369
|
var Server = class {
|
|
3116
3370
|
users;
|
|
@@ -3119,35 +3373,37 @@ var Server = class {
|
|
|
3119
3373
|
#config;
|
|
3120
3374
|
#handlers;
|
|
3121
3375
|
#manager;
|
|
3122
|
-
#headers;
|
|
3123
|
-
#preserveHeaders;
|
|
3376
|
+
// #headers: undefined | Headers;
|
|
3377
|
+
// #preserveHeaders: boolean;
|
|
3124
3378
|
constructor(config) {
|
|
3125
3379
|
this.#config = new Config({
|
|
3126
3380
|
...config,
|
|
3127
3381
|
extensionCtx: buildExtensionConfig(this)
|
|
3128
3382
|
});
|
|
3129
3383
|
watchTenantId((tenantId) => {
|
|
3130
|
-
if (tenantId !== this.#config.tenantId) {
|
|
3131
|
-
this.#config.tenantId = tenantId;
|
|
3384
|
+
if (tenantId !== this.#config.context.tenantId) {
|
|
3385
|
+
this.#config.context.tenantId = String(tenantId);
|
|
3132
3386
|
this.#reset();
|
|
3133
3387
|
}
|
|
3134
3388
|
});
|
|
3135
3389
|
watchUserId((userId) => {
|
|
3136
|
-
if (userId !== this.#config.userId) {
|
|
3137
|
-
this.#config.userId = userId;
|
|
3390
|
+
if (userId !== this.#config.context.userId) {
|
|
3391
|
+
this.#config.context.userId = String(userId);
|
|
3138
3392
|
this.#reset();
|
|
3139
3393
|
}
|
|
3140
3394
|
});
|
|
3141
3395
|
watchHeaders((headers) => {
|
|
3142
|
-
|
|
3143
|
-
|
|
3396
|
+
if (headers) {
|
|
3397
|
+
this.#config.context.headers = new Headers(headers);
|
|
3398
|
+
this.#reset();
|
|
3399
|
+
}
|
|
3144
3400
|
});
|
|
3145
3401
|
this.#handlers = {
|
|
3146
3402
|
...this.#config.handlers,
|
|
3147
3403
|
withContext: handlersWithContext(this.#config)
|
|
3148
3404
|
};
|
|
3149
|
-
this.#preserveHeaders = config?.preserveHeaders ?? false;
|
|
3150
|
-
this.#config.tenantId = getTenantId({ config: this.#config });
|
|
3405
|
+
this.#config.context.preserveHeaders = config?.preserveHeaders ?? false;
|
|
3406
|
+
this.#config.context.tenantId = getTenantId({ config: this.#config });
|
|
3151
3407
|
this.#manager = new DBManager(this.#config);
|
|
3152
3408
|
this.#handleHeaders(config);
|
|
3153
3409
|
this.users = new Users(this.#config);
|
|
@@ -3202,21 +3458,6 @@ var Server = class {
|
|
|
3202
3458
|
}
|
|
3203
3459
|
};
|
|
3204
3460
|
}
|
|
3205
|
-
/**
|
|
3206
|
-
* A convenience function that applies a config and ensures whatever was passed is set properly
|
|
3207
|
-
*/
|
|
3208
|
-
getInstance(config, req) {
|
|
3209
|
-
const _config = { ...this.#config, ...config };
|
|
3210
|
-
const updatedConfig = new Config(_config);
|
|
3211
|
-
this.#config = new Config(updatedConfig);
|
|
3212
|
-
this.#config.tenantId = config.tenantId;
|
|
3213
|
-
this.#config.userId = config.userId;
|
|
3214
|
-
if (req) {
|
|
3215
|
-
this.setContext(req);
|
|
3216
|
-
}
|
|
3217
|
-
this.#reset();
|
|
3218
|
-
return this;
|
|
3219
|
-
}
|
|
3220
3461
|
get handlers() {
|
|
3221
3462
|
return this.#handlers;
|
|
3222
3463
|
}
|
|
@@ -3226,98 +3467,30 @@ var Server = class {
|
|
|
3226
3467
|
set paths(paths) {
|
|
3227
3468
|
this.#config.paths = paths;
|
|
3228
3469
|
}
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
*/
|
|
3236
|
-
setContext = (req, ...remaining) => {
|
|
3237
|
-
let ok = false;
|
|
3238
|
-
if (req && typeof req === "object" && "tenantId" in req) {
|
|
3239
|
-
ok = true;
|
|
3240
|
-
this.#config.tenantId = req.tenantId;
|
|
3241
|
-
}
|
|
3242
|
-
if (req && typeof req === "object" && "userId" in req) {
|
|
3243
|
-
ok = true;
|
|
3244
|
-
this.#config.userId = req.userId;
|
|
3245
|
-
}
|
|
3246
|
-
if (req && typeof req === "object" && "preserveHeaders" in req) {
|
|
3247
|
-
ok = true;
|
|
3248
|
-
this.#preserveHeaders = Boolean(req.preserveHeaders);
|
|
3249
|
-
}
|
|
3250
|
-
let atLeastOne = false;
|
|
3251
|
-
if (this.#config?.extensions) {
|
|
3252
|
-
for (const create2 of this.#config.extensions) {
|
|
3253
|
-
if (typeof create2 !== "function") {
|
|
3254
|
-
continue;
|
|
3255
|
-
}
|
|
3256
|
-
const ext = create2(this);
|
|
3257
|
-
if (typeof ext.onSetContext === "function") {
|
|
3258
|
-
if (req) {
|
|
3259
|
-
ext.onSetContext(req, ...remaining);
|
|
3260
|
-
atLeastOne = true;
|
|
3261
|
-
} else {
|
|
3262
|
-
this.#config.logger("extension").warn("attempted to call onSetContext without a value");
|
|
3263
|
-
}
|
|
3264
|
-
}
|
|
3265
|
-
}
|
|
3266
|
-
}
|
|
3267
|
-
if (atLeastOne) {
|
|
3268
|
-
return;
|
|
3269
|
-
}
|
|
3270
|
-
try {
|
|
3271
|
-
if (req instanceof Headers) {
|
|
3272
|
-
this.#handleHeaders(req);
|
|
3273
|
-
this.#reset();
|
|
3274
|
-
return;
|
|
3275
|
-
} else if (req instanceof Request) {
|
|
3276
|
-
this.#handleHeaders(new Headers(req.headers));
|
|
3277
|
-
this.#reset();
|
|
3278
|
-
return;
|
|
3279
|
-
}
|
|
3280
|
-
} catch {
|
|
3470
|
+
async withContext(context, fn) {
|
|
3471
|
+
const { ddl, ...ctx2 } = context ?? defaultContext;
|
|
3472
|
+
this.#config.context = { ...ctx2 };
|
|
3473
|
+
const preserve = (context && "preserveHeaders" in context && context.preserveHeaders) ?? true;
|
|
3474
|
+
if (preserve) {
|
|
3475
|
+
this.#config.context = { ...this.getContext(), ...context };
|
|
3281
3476
|
}
|
|
3282
|
-
if (
|
|
3283
|
-
|
|
3477
|
+
if (ddl) {
|
|
3478
|
+
delete this.#config.context.tenantId;
|
|
3479
|
+
delete this.#config.context.userId;
|
|
3284
3480
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
if (headers) {
|
|
3289
|
-
this.#handleHeaders(headers);
|
|
3290
|
-
this.#reset();
|
|
3291
|
-
return;
|
|
3292
|
-
}
|
|
3293
|
-
} catch {
|
|
3481
|
+
return withNileContext(this.#config, async () => {
|
|
3482
|
+
if (fn) {
|
|
3483
|
+
return fn(this);
|
|
3294
3484
|
}
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
};
|
|
3485
|
+
return this;
|
|
3486
|
+
});
|
|
3487
|
+
}
|
|
3488
|
+
/**
|
|
3489
|
+
*
|
|
3490
|
+
* @returns the last used (basically global) context object, useful for debugging or making your own context
|
|
3491
|
+
*/
|
|
3303
3492
|
getContext() {
|
|
3304
|
-
|
|
3305
|
-
for (const create2 of this.#config.extensions) {
|
|
3306
|
-
if (typeof create2 !== "function") {
|
|
3307
|
-
continue;
|
|
3308
|
-
}
|
|
3309
|
-
const ext = create2(this);
|
|
3310
|
-
if (typeof ext.onGetContext === "function") {
|
|
3311
|
-
return ext.onGetContext();
|
|
3312
|
-
}
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3315
|
-
return {
|
|
3316
|
-
headers: this.#headers,
|
|
3317
|
-
userId: this.#config?.userId,
|
|
3318
|
-
tenantId: this.#config?.tenantId,
|
|
3319
|
-
preserveHeaders: this.#preserveHeaders
|
|
3320
|
-
};
|
|
3493
|
+
return ctx.getLastUsed();
|
|
3321
3494
|
}
|
|
3322
3495
|
/**
|
|
3323
3496
|
* Merge headers together
|
|
@@ -3326,16 +3499,19 @@ var Server = class {
|
|
|
3326
3499
|
#handleHeaders(config) {
|
|
3327
3500
|
const updates = [];
|
|
3328
3501
|
let headers;
|
|
3329
|
-
this.#headers = new Headers();
|
|
3502
|
+
this.#config.context.headers = new Headers();
|
|
3330
3503
|
if (config instanceof Headers) {
|
|
3331
3504
|
headers = config;
|
|
3332
3505
|
} else if (config?.headers) {
|
|
3333
3506
|
headers = config?.headers;
|
|
3334
3507
|
if (config && config.origin) {
|
|
3335
|
-
this.#headers.set(HEADER_ORIGIN, config.origin);
|
|
3508
|
+
this.#config.context.headers.set(HEADER_ORIGIN, config.origin);
|
|
3336
3509
|
}
|
|
3337
3510
|
if (config && config.secureCookies != null) {
|
|
3338
|
-
this.#headers.set(
|
|
3511
|
+
this.#config.context.headers.set(
|
|
3512
|
+
HEADER_SECURE_COOKIES,
|
|
3513
|
+
String(config.secureCookies)
|
|
3514
|
+
);
|
|
3339
3515
|
}
|
|
3340
3516
|
}
|
|
3341
3517
|
if (headers instanceof Headers) {
|
|
@@ -3348,8 +3524,7 @@ var Server = class {
|
|
|
3348
3524
|
}
|
|
3349
3525
|
}
|
|
3350
3526
|
const merged = {};
|
|
3351
|
-
this.#config.
|
|
3352
|
-
this.#headers?.forEach((value, key17) => {
|
|
3527
|
+
this.#config.context.headers?.forEach((value, key17) => {
|
|
3353
3528
|
if (key17.toLowerCase() !== "cookie") {
|
|
3354
3529
|
merged[key17.toLowerCase()] = value;
|
|
3355
3530
|
}
|
|
@@ -3358,16 +3533,14 @@ var Server = class {
|
|
|
3358
3533
|
merged[key17] = value;
|
|
3359
3534
|
}
|
|
3360
3535
|
for (const [key17, value] of Object.entries(merged)) {
|
|
3361
|
-
this.#headers.set(key17, value);
|
|
3536
|
+
this.#config.context.headers.set(key17, value);
|
|
3362
3537
|
}
|
|
3363
3538
|
this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
|
|
3364
|
-
this.#config.headers = this.#headers;
|
|
3365
3539
|
}
|
|
3366
3540
|
/**
|
|
3367
3541
|
* Allow some internal mutations to reset our config + headers
|
|
3368
3542
|
*/
|
|
3369
3543
|
#reset = () => {
|
|
3370
|
-
this.#config.headers = this.#headers ?? new Headers();
|
|
3371
3544
|
this.#config.extensionCtx = buildExtensionConfig(this);
|
|
3372
3545
|
this.users = new Users(this.#config);
|
|
3373
3546
|
this.tenants = new Tenants(this.#config);
|
|
@@ -3382,6 +3555,6 @@ function create(config) {
|
|
|
3382
3555
|
return server;
|
|
3383
3556
|
}
|
|
3384
3557
|
|
|
3385
|
-
export { APIErrorErrorCodeEnum, ExtensionState, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseResetToken, parseToken };
|
|
3558
|
+
export { APIErrorErrorCodeEnum, ExtensionState, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseResetToken, parseTenantId, parseToken };
|
|
3386
3559
|
//# sourceMappingURL=index.mjs.map
|
|
3387
3560
|
//# sourceMappingURL=index.mjs.map
|