@niledatabase/server 5.0.0-alpha.26 → 5.0.0-alpha.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +48 -38
- package/dist/index.d.ts +48 -38
- package/dist/index.js +1144 -945
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1144 -946
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.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,309 @@ 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 [key17, value] of new Headers(partial.headers).entries()) {
|
|
475
|
+
if (key17.toLowerCase() === "cookie") {
|
|
476
|
+
const existingCookies = parseCookieHeader(
|
|
477
|
+
store.headers.get("cookie") || ""
|
|
478
|
+
);
|
|
479
|
+
const newCookies = parseCookieHeader(value);
|
|
480
|
+
const mergedCookies = { ...existingCookies, ...newCookies };
|
|
481
|
+
store.headers.set("cookie", serializeCookies(mergedCookies));
|
|
482
|
+
} else {
|
|
483
|
+
store.headers.set(key17, value);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if ("tenantId" in partial)
|
|
488
|
+
store.tenantId = partial.tenantId ?? store.tenantId;
|
|
489
|
+
if ("userId" in partial) store.userId = partial.userId ?? store.userId;
|
|
490
|
+
if ("preserveHeaders" in partial)
|
|
491
|
+
store.preserveHeaders = Boolean(partial.preserveHeaders);
|
|
492
|
+
silly(`[SET] ${serializeContext(store)}`);
|
|
493
|
+
lastUsedContext = { ...store };
|
|
494
|
+
},
|
|
495
|
+
// for convenience only
|
|
496
|
+
getLastUsed: () => lastUsedContext
|
|
497
|
+
};
|
|
498
|
+
function withNileContext(config, fn, name = "unknown") {
|
|
499
|
+
const initialContext = config.context;
|
|
500
|
+
const existing = ctx.get();
|
|
501
|
+
const mergedHeaders = new Headers(existing.headers);
|
|
502
|
+
if (initialContext instanceof Request) {
|
|
503
|
+
initialContext.headers.forEach((value, key17) => {
|
|
504
|
+
mergedHeaders.set(key17, value);
|
|
505
|
+
});
|
|
506
|
+
const context2 = {
|
|
507
|
+
headers: mergedHeaders,
|
|
508
|
+
tenantId: existing.tenantId,
|
|
509
|
+
userId: existing.userId,
|
|
510
|
+
preserveHeaders: existing.preserveHeaders ?? false
|
|
511
|
+
};
|
|
512
|
+
silly(`${name} [INITIAL - Request] ${serializeContext(context2)}`);
|
|
513
|
+
return ctx.run(context2, fn);
|
|
514
|
+
}
|
|
515
|
+
if (initialContext.headers) {
|
|
516
|
+
const incoming = initialContext.headers instanceof Headers ? initialContext.headers : new Headers(initialContext.headers);
|
|
517
|
+
incoming.forEach((value, key17) => {
|
|
518
|
+
mergedHeaders.set(key17, value);
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
const tenantId = "tenantId" in initialContext && initialContext.tenantId;
|
|
522
|
+
const userId = "userId" in initialContext && initialContext.userId;
|
|
523
|
+
const preserveHeaders = "preserveHeaders" in initialContext && initialContext.preserveHeaders;
|
|
524
|
+
const context = {
|
|
525
|
+
headers: mergedHeaders,
|
|
526
|
+
tenantId: tenantId ? tenantId : existing.tenantId,
|
|
527
|
+
userId: userId ? userId : existing.userId,
|
|
528
|
+
preserveHeaders: preserveHeaders ? preserveHeaders : existing.preserveHeaders ?? false
|
|
529
|
+
};
|
|
530
|
+
silly(`${name} [INITIAL - Partial<Context>] ${serializeContext(context)}`);
|
|
531
|
+
return ctx.run(context, async () => {
|
|
532
|
+
await runExtensionContext(config);
|
|
533
|
+
return fn();
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
function serializeContext(context) {
|
|
537
|
+
const headers = {};
|
|
538
|
+
const rawHeaders = new Headers(context.headers);
|
|
539
|
+
rawHeaders.forEach((value, key17) => {
|
|
540
|
+
headers[key17] = value;
|
|
541
|
+
});
|
|
542
|
+
return JSON.stringify({
|
|
543
|
+
headers,
|
|
544
|
+
tenantId: context.tenantId,
|
|
545
|
+
userId: context.userId,
|
|
546
|
+
preserveHeaders: context.preserveHeaders
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
function parseCookieHeader(header) {
|
|
550
|
+
return header.split(";").map((c) => c.trim()).filter(Boolean).reduce((acc, curr) => {
|
|
551
|
+
const [key17, ...val] = curr.split("=");
|
|
552
|
+
if (key17) acc[key17] = val.join("=");
|
|
553
|
+
return acc;
|
|
554
|
+
}, {});
|
|
555
|
+
}
|
|
556
|
+
function serializeCookies(cookies) {
|
|
557
|
+
return Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join("; ");
|
|
558
|
+
}
|
|
559
|
+
|
|
262
560
|
// src/api/routes/me/index.ts
|
|
263
561
|
var key = "ME";
|
|
264
562
|
async function route(request2, config) {
|
|
265
|
-
const url = apiRoutes(config)[key];
|
|
563
|
+
const url = apiRoutes(config.apiUrl)[key];
|
|
266
564
|
if (request2.method === "GET") {
|
|
267
565
|
return await GET(url, { request: request2 }, config);
|
|
268
566
|
}
|
|
@@ -283,8 +581,9 @@ function matches(configRoutes, request2) {
|
|
|
283
581
|
}
|
|
284
582
|
async function fetchMe(config, method, body) {
|
|
285
583
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
|
|
584
|
+
const { headers } = ctx.get();
|
|
286
585
|
const init = {
|
|
287
|
-
headers
|
|
586
|
+
headers,
|
|
288
587
|
method: method ?? "GET"
|
|
289
588
|
};
|
|
290
589
|
if (method === "PUT") {
|
|
@@ -336,9 +635,9 @@ function getTokenFromCookie(headers, cookieKey) {
|
|
|
336
635
|
return _cookies[cookieKey];
|
|
337
636
|
}
|
|
338
637
|
}
|
|
339
|
-
function getTenantFromHttp(headers,
|
|
638
|
+
function getTenantFromHttp(headers, context) {
|
|
340
639
|
const cookieTenant = getTokenFromCookie(headers, TENANT_COOKIE);
|
|
341
|
-
return cookieTenant ? cookieTenant :
|
|
640
|
+
return cookieTenant ? cookieTenant : context?.tenantId;
|
|
342
641
|
}
|
|
343
642
|
|
|
344
643
|
// src/api/routes/users/POST.ts
|
|
@@ -348,8 +647,11 @@ async function POST(config, init) {
|
|
|
348
647
|
const yurl = new URL(init.request.url);
|
|
349
648
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
350
649
|
const newTenantName = yurl.searchParams.get("newTenantName");
|
|
351
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers
|
|
352
|
-
const url = apiRoutes(config).USERS({
|
|
650
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
651
|
+
const url = apiRoutes(config.apiUrl).USERS({
|
|
652
|
+
tenantId: tenant,
|
|
653
|
+
newTenantName
|
|
654
|
+
});
|
|
353
655
|
return await request(url, init, config);
|
|
354
656
|
}
|
|
355
657
|
|
|
@@ -357,13 +659,13 @@ async function POST(config, init) {
|
|
|
357
659
|
async function GET2(config, init, log) {
|
|
358
660
|
const yurl = new URL(init.request.url);
|
|
359
661
|
const tenantId = yurl.searchParams.get("tenantId");
|
|
360
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config);
|
|
662
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers, config.context);
|
|
361
663
|
if (!tenant) {
|
|
362
664
|
log("[GET] No tenant id provided.");
|
|
363
665
|
return new Response(null, { status: 404 });
|
|
364
666
|
}
|
|
365
667
|
init.method = "GET";
|
|
366
|
-
const url = apiRoutes(config).TENANT_USERS(tenant);
|
|
668
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenant);
|
|
367
669
|
return await request(url, init, config);
|
|
368
670
|
}
|
|
369
671
|
|
|
@@ -372,7 +674,7 @@ async function PUT2(config, init) {
|
|
|
372
674
|
init.body = init.request.body;
|
|
373
675
|
init.method = "PUT";
|
|
374
676
|
const [userId] = new URL(init.request.url).pathname.split("/").reverse();
|
|
375
|
-
const url = apiRoutes(config).USER(userId);
|
|
677
|
+
const url = apiRoutes(config.apiUrl).USER(userId);
|
|
376
678
|
return await request(url, init, config);
|
|
377
679
|
}
|
|
378
680
|
|
|
@@ -399,7 +701,7 @@ function matches2(configRoutes, request2) {
|
|
|
399
701
|
async function GET3(config, init) {
|
|
400
702
|
const yurl = new URL(init.request.url);
|
|
401
703
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
402
|
-
const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
|
|
704
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USERS(tenantId)}`;
|
|
403
705
|
return await request(url, init, config);
|
|
404
706
|
}
|
|
405
707
|
|
|
@@ -413,7 +715,7 @@ async function POST2(config, init) {
|
|
|
413
715
|
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
414
716
|
init.body = JSON.stringify({ email: session.email });
|
|
415
717
|
init.method = "POST";
|
|
416
|
-
const url = apiRoutes(config).TENANT_USERS(tenantId);
|
|
718
|
+
const url = apiRoutes(config.apiUrl).TENANT_USERS(tenantId);
|
|
417
719
|
return await request(url, init, config);
|
|
418
720
|
}
|
|
419
721
|
|
|
@@ -447,12 +749,13 @@ function matches3(configRoutes, request2) {
|
|
|
447
749
|
}
|
|
448
750
|
async function fetchTenantUsers(config, method, payload) {
|
|
449
751
|
const { body, params } = {};
|
|
450
|
-
|
|
752
|
+
const { tenantId, headers } = ctx.get();
|
|
753
|
+
if (!tenantId) {
|
|
451
754
|
throw new Error(
|
|
452
755
|
"Unable to fetch the user's tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
453
756
|
);
|
|
454
757
|
}
|
|
455
|
-
if (!isUUID(
|
|
758
|
+
if (!isUUID(tenantId)) {
|
|
456
759
|
config.logger("fetchTenantUsers").warn(
|
|
457
760
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
458
761
|
);
|
|
@@ -464,14 +767,11 @@ async function fetchTenantUsers(config, method, payload) {
|
|
|
464
767
|
if (params?.tenantId) {
|
|
465
768
|
q.set("tenantId", params.tenantId);
|
|
466
769
|
}
|
|
467
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
|
|
468
|
-
"{tenantId}",
|
|
469
|
-
config.tenantId
|
|
470
|
-
)}`;
|
|
770
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace("{tenantId}", tenantId)}`;
|
|
471
771
|
const m = method;
|
|
472
772
|
const init = {
|
|
473
773
|
method: m,
|
|
474
|
-
headers
|
|
774
|
+
headers
|
|
475
775
|
};
|
|
476
776
|
const req = new Request(clientUrl, init);
|
|
477
777
|
return await config.handlers[m](req);
|
|
@@ -488,7 +788,7 @@ async function PUT3(config, init) {
|
|
|
488
788
|
init.body = new URLSearchParams(yurl.searchParams).toString();
|
|
489
789
|
}
|
|
490
790
|
init.method = "PUT";
|
|
491
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
791
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
492
792
|
const res = await request(url, init, config);
|
|
493
793
|
const location = res?.headers?.get("location");
|
|
494
794
|
if (location) {
|
|
@@ -512,7 +812,7 @@ async function POST3(config, init) {
|
|
|
512
812
|
}
|
|
513
813
|
init.method = "POST";
|
|
514
814
|
init.body = init.request.body;
|
|
515
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}`;
|
|
815
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}`;
|
|
516
816
|
return await request(url, init, config);
|
|
517
817
|
}
|
|
518
818
|
|
|
@@ -538,21 +838,22 @@ function matches4(configRoutes, request2) {
|
|
|
538
838
|
return urlMatches(request2.url, route20);
|
|
539
839
|
}
|
|
540
840
|
async function fetchInvite(config, method, body) {
|
|
541
|
-
|
|
841
|
+
const { headers, tenantId } = ctx.get();
|
|
842
|
+
if (!tenantId) {
|
|
542
843
|
throw new Error(
|
|
543
844
|
"Unable to fetch the invite for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
544
845
|
);
|
|
545
846
|
}
|
|
546
|
-
if (!isUUID(
|
|
847
|
+
if (!isUUID(tenantId)) {
|
|
547
848
|
config.logger("fetchInvite").warn(
|
|
548
849
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
549
850
|
);
|
|
550
851
|
}
|
|
551
|
-
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}",
|
|
852
|
+
let clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", tenantId)}`;
|
|
552
853
|
const m = method ?? "GET";
|
|
553
854
|
const init = {
|
|
554
855
|
method: m,
|
|
555
|
-
headers
|
|
856
|
+
headers
|
|
556
857
|
};
|
|
557
858
|
if (method === "POST" || method === "PUT") {
|
|
558
859
|
init.body = body;
|
|
@@ -572,7 +873,7 @@ async function GET4(config, init) {
|
|
|
572
873
|
return new Response(null, { status: 404 });
|
|
573
874
|
}
|
|
574
875
|
init.method = "GET";
|
|
575
|
-
const url = `${apiRoutes(config).INVITES(tenantId)}`;
|
|
876
|
+
const url = `${apiRoutes(config.apiUrl).INVITES(tenantId)}`;
|
|
576
877
|
return await request(url, init, config);
|
|
577
878
|
}
|
|
578
879
|
|
|
@@ -593,29 +894,29 @@ function matches5(configRoutes, request2) {
|
|
|
593
894
|
return url.pathname.endsWith(route20);
|
|
594
895
|
}
|
|
595
896
|
async function fetchInvites(config) {
|
|
596
|
-
|
|
897
|
+
const { tenantId, headers } = ctx.get();
|
|
898
|
+
if (!tenantId) {
|
|
597
899
|
throw new Error(
|
|
598
900
|
"Unable to fetch invites for the tenant, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
599
901
|
);
|
|
600
902
|
}
|
|
601
|
-
if (!isUUID(
|
|
903
|
+
if (!isUUID(tenantId)) {
|
|
602
904
|
config.logger("fetchInvites").warn(
|
|
603
905
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
604
906
|
);
|
|
605
907
|
}
|
|
606
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}",
|
|
607
|
-
const req = new Request(clientUrl, { headers
|
|
908
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/invites" /* INVITES */.replace("{tenantId}", tenantId)}`;
|
|
909
|
+
const req = new Request(clientUrl, { headers });
|
|
608
910
|
return await config.handlers.GET(req);
|
|
609
911
|
}
|
|
610
912
|
|
|
611
913
|
// src/api/routes/tenants/GET.ts
|
|
612
914
|
async function GET5(config, session, init) {
|
|
613
|
-
let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
|
|
915
|
+
let url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.id)}`;
|
|
614
916
|
if (typeof session === "object" && "user" in session && session.user) {
|
|
615
|
-
url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
|
|
917
|
+
url = `${apiRoutes(config.apiUrl).USER_TENANTS(session.user.id)}`;
|
|
616
918
|
}
|
|
617
|
-
|
|
618
|
-
return res;
|
|
919
|
+
return await request(url, init, config);
|
|
619
920
|
}
|
|
620
921
|
|
|
621
922
|
// src/api/routes/tenants/[tenantId]/GET.ts
|
|
@@ -627,7 +928,7 @@ async function GET6(config, init, log) {
|
|
|
627
928
|
return new Response(null, { status: 404 });
|
|
628
929
|
}
|
|
629
930
|
init.method = "GET";
|
|
630
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
931
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
631
932
|
return await request(url, init, config);
|
|
632
933
|
}
|
|
633
934
|
|
|
@@ -639,7 +940,7 @@ async function DELETE2(config, init) {
|
|
|
639
940
|
return new Response(null, { status: 404 });
|
|
640
941
|
}
|
|
641
942
|
init.method = "DELETE";
|
|
642
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
943
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
643
944
|
return await request(url, init, config);
|
|
644
945
|
}
|
|
645
946
|
|
|
@@ -652,7 +953,7 @@ async function PUT4(config, init) {
|
|
|
652
953
|
}
|
|
653
954
|
init.body = init.request.body;
|
|
654
955
|
init.method = "PUT";
|
|
655
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
956
|
+
const url = `${apiRoutes(config.apiUrl).TENANT(tenantId)}`;
|
|
656
957
|
return await request(url, init, config);
|
|
657
958
|
}
|
|
658
959
|
|
|
@@ -660,7 +961,7 @@ async function PUT4(config, init) {
|
|
|
660
961
|
async function POST4(config, init) {
|
|
661
962
|
init.body = init.request.body;
|
|
662
963
|
init.method = "POST";
|
|
663
|
-
const url = `${apiRoutes(config).TENANTS}`;
|
|
964
|
+
const url = `${apiRoutes(config.apiUrl).TENANTS}`;
|
|
664
965
|
return await request(url, init, config);
|
|
665
966
|
}
|
|
666
967
|
|
|
@@ -694,10 +995,11 @@ function matches6(configRoutes, request2) {
|
|
|
694
995
|
return urlMatches(request2.url, configRoutes[key6]);
|
|
695
996
|
}
|
|
696
997
|
async function fetchTenants(config, method, body) {
|
|
998
|
+
const { headers } = ctx.get();
|
|
697
999
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
698
1000
|
const init = {
|
|
699
1001
|
method,
|
|
700
|
-
headers
|
|
1002
|
+
headers
|
|
701
1003
|
};
|
|
702
1004
|
{
|
|
703
1005
|
init.body = body;
|
|
@@ -706,21 +1008,22 @@ async function fetchTenants(config, method, body) {
|
|
|
706
1008
|
return await config.handlers.POST(req);
|
|
707
1009
|
}
|
|
708
1010
|
async function fetchTenant(config, method, body) {
|
|
709
|
-
|
|
1011
|
+
const { headers, tenantId } = ctx.get();
|
|
1012
|
+
if (!tenantId) {
|
|
710
1013
|
throw new Error(
|
|
711
1014
|
"Unable to fetch tenants, the tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
712
1015
|
);
|
|
713
1016
|
}
|
|
714
|
-
if (!isUUID(
|
|
1017
|
+
if (!isUUID(tenantId)) {
|
|
715
1018
|
config.logger("fetch tenant").warn(
|
|
716
1019
|
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
717
1020
|
);
|
|
718
1021
|
}
|
|
719
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}",
|
|
1022
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", tenantId)}`;
|
|
720
1023
|
const m = method ?? "GET";
|
|
721
1024
|
const init = {
|
|
722
1025
|
method: m,
|
|
723
|
-
headers
|
|
1026
|
+
headers
|
|
724
1027
|
};
|
|
725
1028
|
if (m === "PUT") {
|
|
726
1029
|
init.body = body;
|
|
@@ -729,32 +1032,33 @@ async function fetchTenant(config, method, body) {
|
|
|
729
1032
|
return await config.handlers[m](req);
|
|
730
1033
|
}
|
|
731
1034
|
async function fetchTenantsByUser(config) {
|
|
732
|
-
const { warn } = config.logger("fetchTenantsByUser");
|
|
733
|
-
|
|
734
|
-
|
|
1035
|
+
const { warn: warn2 } = config.logger(" fetchTenantsByUser ");
|
|
1036
|
+
const { userId, headers } = ctx.get();
|
|
1037
|
+
if (!userId) {
|
|
1038
|
+
warn2(
|
|
735
1039
|
"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
1040
|
);
|
|
737
|
-
} else if (!isUUID(
|
|
738
|
-
|
|
1041
|
+
} else if (!isUUID(userId)) {
|
|
1042
|
+
warn2(
|
|
739
1043
|
"nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
740
1044
|
);
|
|
741
1045
|
}
|
|
742
1046
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
743
|
-
const req = new Request(clientUrl, { headers
|
|
1047
|
+
const req = new Request(clientUrl, { headers });
|
|
744
1048
|
return await config.handlers.GET(req);
|
|
745
1049
|
}
|
|
746
1050
|
|
|
747
1051
|
// src/api/routes/auth/signin.ts
|
|
748
1052
|
var key7 = "SIGNIN";
|
|
749
1053
|
async function route7(req, config) {
|
|
750
|
-
let url = proxyRoutes(config)[key7];
|
|
1054
|
+
let url = proxyRoutes(config.apiUrl)[key7];
|
|
751
1055
|
const init = {
|
|
752
1056
|
method: req.method,
|
|
753
1057
|
headers: req.headers
|
|
754
1058
|
};
|
|
755
1059
|
if (req.method === "POST") {
|
|
756
1060
|
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
757
|
-
url = `${proxyRoutes(config)[key7]}/${provider}`;
|
|
1061
|
+
url = `${proxyRoutes(config.apiUrl)[key7]}/${provider}`;
|
|
758
1062
|
}
|
|
759
1063
|
const passThroughUrl = new URL(req.url);
|
|
760
1064
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
@@ -767,10 +1071,11 @@ function matches7(configRoutes, request2) {
|
|
|
767
1071
|
}
|
|
768
1072
|
async function fetchSignIn(config, provider, body) {
|
|
769
1073
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
|
|
1074
|
+
const { headers } = ctx.get();
|
|
770
1075
|
const req = new Request(clientUrl, {
|
|
771
1076
|
method: "POST",
|
|
772
|
-
|
|
773
|
-
|
|
1077
|
+
body,
|
|
1078
|
+
headers
|
|
774
1079
|
});
|
|
775
1080
|
return await config.handlers.POST(req);
|
|
776
1081
|
}
|
|
@@ -778,7 +1083,7 @@ async function fetchSignIn(config, provider, body) {
|
|
|
778
1083
|
// src/api/routes/auth/session.ts
|
|
779
1084
|
async function route8(req, config) {
|
|
780
1085
|
return request(
|
|
781
|
-
proxyRoutes(config).SESSION,
|
|
1086
|
+
proxyRoutes(config.apiUrl).SESSION,
|
|
782
1087
|
{
|
|
783
1088
|
method: req.method,
|
|
784
1089
|
request: req
|
|
@@ -791,9 +1096,10 @@ function matches8(configRoutes, request2) {
|
|
|
791
1096
|
}
|
|
792
1097
|
async function fetchSession(config) {
|
|
793
1098
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
|
|
1099
|
+
const { headers } = ctx.get();
|
|
794
1100
|
const req = new Request(clientUrl, {
|
|
795
1101
|
method: "GET",
|
|
796
|
-
headers
|
|
1102
|
+
headers
|
|
797
1103
|
});
|
|
798
1104
|
return await config.handlers.GET(req);
|
|
799
1105
|
}
|
|
@@ -801,7 +1107,7 @@ async function fetchSession(config) {
|
|
|
801
1107
|
// src/api/routes/auth/providers.ts
|
|
802
1108
|
async function route9(req, config) {
|
|
803
1109
|
return request(
|
|
804
|
-
proxyRoutes(config).PROVIDERS,
|
|
1110
|
+
proxyRoutes(config.apiUrl).PROVIDERS,
|
|
805
1111
|
{
|
|
806
1112
|
method: req.method,
|
|
807
1113
|
request: req
|
|
@@ -814,9 +1120,10 @@ function matches9(configRoutes, request2) {
|
|
|
814
1120
|
}
|
|
815
1121
|
async function fetchProviders(config) {
|
|
816
1122
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
|
|
1123
|
+
const { headers } = ctx.get();
|
|
817
1124
|
const req = new Request(clientUrl, {
|
|
818
1125
|
method: "GET",
|
|
819
|
-
headers
|
|
1126
|
+
headers
|
|
820
1127
|
});
|
|
821
1128
|
return await config.handlers.GET(req);
|
|
822
1129
|
}
|
|
@@ -824,7 +1131,7 @@ async function fetchProviders(config) {
|
|
|
824
1131
|
// src/api/routes/auth/csrf.ts
|
|
825
1132
|
async function route10(req, config) {
|
|
826
1133
|
return request(
|
|
827
|
-
proxyRoutes(config).CSRF,
|
|
1134
|
+
proxyRoutes(config.apiUrl).CSRF,
|
|
828
1135
|
{
|
|
829
1136
|
method: req.method,
|
|
830
1137
|
request: req
|
|
@@ -837,9 +1144,10 @@ function matches10(configRoutes, request2) {
|
|
|
837
1144
|
}
|
|
838
1145
|
async function fetchCsrf(config) {
|
|
839
1146
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
|
|
1147
|
+
const { headers } = ctx.get();
|
|
840
1148
|
const req = new Request(clientUrl, {
|
|
841
1149
|
method: "GET",
|
|
842
|
-
headers
|
|
1150
|
+
headers
|
|
843
1151
|
});
|
|
844
1152
|
return await config.handlers.GET(req);
|
|
845
1153
|
}
|
|
@@ -852,7 +1160,7 @@ async function route11(req, config) {
|
|
|
852
1160
|
try {
|
|
853
1161
|
const passThroughUrl = new URL(req.url);
|
|
854
1162
|
const params = new URLSearchParams(passThroughUrl.search);
|
|
855
|
-
const url = `${proxyRoutes(config)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
1163
|
+
const url = `${proxyRoutes(config.apiUrl)[key8]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
856
1164
|
const res = await request(
|
|
857
1165
|
url,
|
|
858
1166
|
{
|
|
@@ -883,10 +1191,11 @@ function matches11(configRoutes, request2) {
|
|
|
883
1191
|
return urlMatches(request2.url, configRoutes.CALLBACK);
|
|
884
1192
|
}
|
|
885
1193
|
async function fetchCallback(config, provider, body, request2, method = "POST") {
|
|
1194
|
+
const { headers } = ctx.get();
|
|
886
1195
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
|
|
887
1196
|
const req = new Request(clientUrl, {
|
|
888
1197
|
method,
|
|
889
|
-
headers
|
|
1198
|
+
headers,
|
|
890
1199
|
body
|
|
891
1200
|
});
|
|
892
1201
|
return await config.handlers.POST(req);
|
|
@@ -895,14 +1204,14 @@ async function fetchCallback(config, provider, body, request2, method = "POST")
|
|
|
895
1204
|
// src/api/routes/auth/signout.ts
|
|
896
1205
|
var key9 = "SIGNOUT";
|
|
897
1206
|
async function route12(request2, config) {
|
|
898
|
-
let url = proxyRoutes(config)[key9];
|
|
1207
|
+
let url = proxyRoutes(config.apiUrl)[key9];
|
|
899
1208
|
const init = {
|
|
900
1209
|
method: request2.method
|
|
901
1210
|
};
|
|
902
1211
|
if (request2.method === "POST") {
|
|
903
1212
|
init.body = request2.body;
|
|
904
1213
|
const [provider] = new URL(request2.url).pathname.split("/").reverse();
|
|
905
|
-
url = `${proxyRoutes(config)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
1214
|
+
url = `${proxyRoutes(config.apiUrl)[key9]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
906
1215
|
}
|
|
907
1216
|
const res = await request(url, { ...init, request: request2 }, config);
|
|
908
1217
|
return res;
|
|
@@ -912,10 +1221,11 @@ function matches12(configRoutes, request2) {
|
|
|
912
1221
|
}
|
|
913
1222
|
async function fetchSignOut(config, body) {
|
|
914
1223
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
|
|
1224
|
+
const { headers } = ctx.get();
|
|
915
1225
|
const req = new Request(clientUrl, {
|
|
916
1226
|
method: "POST",
|
|
917
1227
|
body,
|
|
918
|
-
headers
|
|
1228
|
+
headers
|
|
919
1229
|
});
|
|
920
1230
|
return await config.handlers.POST(req);
|
|
921
1231
|
}
|
|
@@ -924,7 +1234,7 @@ async function fetchSignOut(config, body) {
|
|
|
924
1234
|
var key10 = "ERROR";
|
|
925
1235
|
async function route13(req, config) {
|
|
926
1236
|
return request(
|
|
927
|
-
proxyRoutes(config)[key10],
|
|
1237
|
+
proxyRoutes(config.apiUrl)[key10],
|
|
928
1238
|
{
|
|
929
1239
|
method: req.method,
|
|
930
1240
|
request: req
|
|
@@ -940,7 +1250,7 @@ function matches13(configRoutes, request2) {
|
|
|
940
1250
|
var key11 = "VERIFY_REQUEST";
|
|
941
1251
|
async function route14(req, config) {
|
|
942
1252
|
return request(
|
|
943
|
-
proxyRoutes(config)[key11],
|
|
1253
|
+
proxyRoutes(config.apiUrl)[key11],
|
|
944
1254
|
{
|
|
945
1255
|
method: req.method,
|
|
946
1256
|
request: req
|
|
@@ -955,7 +1265,7 @@ function matches14(configRoutes, request2) {
|
|
|
955
1265
|
// src/api/routes/auth/password-reset.ts
|
|
956
1266
|
var key12 = "PASSWORD_RESET";
|
|
957
1267
|
async function route15(req, config) {
|
|
958
|
-
const url = proxyRoutes(config)[key12];
|
|
1268
|
+
const url = proxyRoutes(config.apiUrl)[key12];
|
|
959
1269
|
const res = await request(
|
|
960
1270
|
url,
|
|
961
1271
|
{
|
|
@@ -984,10 +1294,11 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
984
1294
|
if (useJson) {
|
|
985
1295
|
authParams?.set("json", "true");
|
|
986
1296
|
}
|
|
1297
|
+
const { headers } = ctx.get();
|
|
987
1298
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
|
|
988
1299
|
const init = {
|
|
989
1300
|
method,
|
|
990
|
-
headers
|
|
1301
|
+
headers
|
|
991
1302
|
};
|
|
992
1303
|
if (body && method !== "GET") {
|
|
993
1304
|
init.body = body;
|
|
@@ -999,7 +1310,7 @@ async function fetchResetPassword(config, method, body, params, useJson = true)
|
|
|
999
1310
|
// src/api/routes/auth/verify-email.ts
|
|
1000
1311
|
var key13 = "VERIFY_EMAIL";
|
|
1001
1312
|
async function route16(req, config) {
|
|
1002
|
-
const url = proxyRoutes(config)[key13];
|
|
1313
|
+
const url = proxyRoutes(config.apiUrl)[key13];
|
|
1003
1314
|
const res = await request(
|
|
1004
1315
|
url,
|
|
1005
1316
|
{
|
|
@@ -1025,9 +1336,10 @@ function matches16(configRoutes, request2) {
|
|
|
1025
1336
|
}
|
|
1026
1337
|
async function fetchVerifyEmail(config, method, body) {
|
|
1027
1338
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
|
|
1339
|
+
const { headers } = ctx.get();
|
|
1028
1340
|
const init = {
|
|
1029
1341
|
method,
|
|
1030
|
-
headers
|
|
1342
|
+
headers
|
|
1031
1343
|
};
|
|
1032
1344
|
if (body) {
|
|
1033
1345
|
init.body = body;
|
|
@@ -1038,7 +1350,7 @@ async function fetchVerifyEmail(config, method, body) {
|
|
|
1038
1350
|
|
|
1039
1351
|
// src/api/handlers/GET.ts
|
|
1040
1352
|
function GETTER(configRoutes, config) {
|
|
1041
|
-
const { error, info, warn } = config.logger("[GET MATCHER]");
|
|
1353
|
+
const { error, info, warn: warn2 } = config.logger("[GET MATCHER]");
|
|
1042
1354
|
return async function GET7(...params) {
|
|
1043
1355
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1044
1356
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1117,78 +1429,16 @@ function GETTER(configRoutes, config) {
|
|
|
1117
1429
|
info("matches error");
|
|
1118
1430
|
return route13(req, config);
|
|
1119
1431
|
}
|
|
1120
|
-
|
|
1432
|
+
warn2(`No GET routes matched ${req.url}`);
|
|
1121
1433
|
return new Response(null, { status: 404 });
|
|
1122
1434
|
};
|
|
1123
1435
|
}
|
|
1124
1436
|
|
|
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
1437
|
// src/api/routes/signup/POST.ts
|
|
1188
1438
|
async function POST5(config, init) {
|
|
1189
1439
|
init.body = init.request.body;
|
|
1190
1440
|
init.method = "POST";
|
|
1191
|
-
const url = `${apiRoutes(config).SIGNUP}`;
|
|
1441
|
+
const url = `${apiRoutes(config.apiUrl).SIGNUP}`;
|
|
1192
1442
|
return await request(url, init, config);
|
|
1193
1443
|
}
|
|
1194
1444
|
|
|
@@ -1215,9 +1465,10 @@ async function fetchSignUp(config, payload) {
|
|
|
1215
1465
|
q.set("tenantId", params.tenantId);
|
|
1216
1466
|
}
|
|
1217
1467
|
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
|
|
1468
|
+
const { headers } = ctx.get();
|
|
1218
1469
|
const req = new Request(clientUrl, {
|
|
1219
1470
|
method: "POST",
|
|
1220
|
-
headers
|
|
1471
|
+
headers,
|
|
1221
1472
|
body
|
|
1222
1473
|
});
|
|
1223
1474
|
return await config.handlers.POST(req);
|
|
@@ -1225,7 +1476,7 @@ async function fetchSignUp(config, payload) {
|
|
|
1225
1476
|
|
|
1226
1477
|
// src/api/handlers/POST.ts
|
|
1227
1478
|
function POSTER(configRoutes, config) {
|
|
1228
|
-
const { info, warn, error } = config.logger("[POST MATCHER]");
|
|
1479
|
+
const { info, warn: warn2, error } = config.logger("[POST MATCHER]");
|
|
1229
1480
|
return async function POST6(...params) {
|
|
1230
1481
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1231
1482
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1261,10 +1512,6 @@ function POSTER(configRoutes, config) {
|
|
|
1261
1512
|
info("matches signup");
|
|
1262
1513
|
return route17(req, config);
|
|
1263
1514
|
}
|
|
1264
|
-
if (matches2(configRoutes, req)) {
|
|
1265
|
-
info("matches users");
|
|
1266
|
-
return route2(req, config);
|
|
1267
|
-
}
|
|
1268
1515
|
if (matches6(configRoutes, req)) {
|
|
1269
1516
|
info("matches tenants");
|
|
1270
1517
|
return route6(req, config);
|
|
@@ -1301,7 +1548,7 @@ function POSTER(configRoutes, config) {
|
|
|
1301
1548
|
info("matches verify-email");
|
|
1302
1549
|
return route16(req, config);
|
|
1303
1550
|
}
|
|
1304
|
-
|
|
1551
|
+
warn2(`No POST routes matched ${req.url}`);
|
|
1305
1552
|
return new Response(null, { status: 404 });
|
|
1306
1553
|
};
|
|
1307
1554
|
}
|
|
@@ -1310,10 +1557,8 @@ function POSTER(configRoutes, config) {
|
|
|
1310
1557
|
async function DELETE3(config, init) {
|
|
1311
1558
|
const yurl = new URL(init.request.url);
|
|
1312
1559
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1313
|
-
config.tenantId = tenantId;
|
|
1314
|
-
config.userId = userId;
|
|
1315
1560
|
init.method = "DELETE";
|
|
1316
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1561
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1317
1562
|
return await request(url, init, config);
|
|
1318
1563
|
}
|
|
1319
1564
|
|
|
@@ -1321,10 +1566,8 @@ async function DELETE3(config, init) {
|
|
|
1321
1566
|
async function PUT5(config, init) {
|
|
1322
1567
|
const yurl = new URL(init.request.url);
|
|
1323
1568
|
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1324
|
-
config.tenantId = tenantId;
|
|
1325
|
-
config.userId = userId;
|
|
1326
1569
|
init.method = "PUT";
|
|
1327
|
-
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1570
|
+
const url = `${apiRoutes(config.apiUrl).TENANT_USER(tenantId, userId)}/link`;
|
|
1328
1571
|
return await request(url, init, config);
|
|
1329
1572
|
}
|
|
1330
1573
|
|
|
@@ -1362,22 +1605,24 @@ function matches18(configRoutes, request2) {
|
|
|
1362
1605
|
return urlMatches(request2.url, route20);
|
|
1363
1606
|
}
|
|
1364
1607
|
async function fetchTenantUser(config, method) {
|
|
1365
|
-
|
|
1608
|
+
const { headers, tenantId, userId } = ctx.get();
|
|
1609
|
+
const action = method === "PUT" ? "add" : "delete";
|
|
1610
|
+
if (!tenantId) {
|
|
1366
1611
|
throw new Error(
|
|
1367
|
-
|
|
1612
|
+
`Unable to ${action} user to the tenant, the tenantId context is missing. Use nile.withContext({ tenantId })`
|
|
1368
1613
|
);
|
|
1369
1614
|
}
|
|
1370
|
-
if (!
|
|
1615
|
+
if (!userId) {
|
|
1371
1616
|
throw new Error(
|
|
1372
|
-
|
|
1617
|
+
`Unable to ${action} user to tenant. The userId context is missing. Use nile.withContext({ userId })`
|
|
1373
1618
|
);
|
|
1374
1619
|
}
|
|
1375
|
-
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
|
|
1376
|
-
"{
|
|
1377
|
-
|
|
1378
|
-
)
|
|
1620
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace("{tenantId}", tenantId).replace(
|
|
1621
|
+
"{userId}",
|
|
1622
|
+
userId
|
|
1623
|
+
)}/link`;
|
|
1379
1624
|
const req = new Request(clientUrl, {
|
|
1380
|
-
headers
|
|
1625
|
+
headers,
|
|
1381
1626
|
method
|
|
1382
1627
|
});
|
|
1383
1628
|
return await config.handlers[method](req);
|
|
@@ -1391,7 +1636,7 @@ async function DELETE4(config, init) {
|
|
|
1391
1636
|
return new Response(null, { status: 404 });
|
|
1392
1637
|
}
|
|
1393
1638
|
init.method = "DELETE";
|
|
1394
|
-
const url = `${apiRoutes(config).INVITE(tenantId)}/${inviteId}`;
|
|
1639
|
+
const url = `${apiRoutes(config.apiUrl).INVITE(tenantId)}/${inviteId}`;
|
|
1395
1640
|
return await request(url, init, config);
|
|
1396
1641
|
}
|
|
1397
1642
|
|
|
@@ -1414,7 +1659,7 @@ function matches19(configRoutes, request2) {
|
|
|
1414
1659
|
|
|
1415
1660
|
// src/api/handlers/DELETE.ts
|
|
1416
1661
|
function DELETER(configRoutes, config) {
|
|
1417
|
-
const { error, info, warn } = config.logger("[DELETE MATCHER]");
|
|
1662
|
+
const { error, info, warn: warn2 } = config.logger("[DELETE MATCHER]");
|
|
1418
1663
|
return async function DELETE5(...params) {
|
|
1419
1664
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1420
1665
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1445,14 +1690,14 @@ function DELETER(configRoutes, config) {
|
|
|
1445
1690
|
info("matches me");
|
|
1446
1691
|
return route(req, config);
|
|
1447
1692
|
}
|
|
1448
|
-
|
|
1693
|
+
warn2("No DELETE routes matched");
|
|
1449
1694
|
return new Response(null, { status: 404 });
|
|
1450
1695
|
};
|
|
1451
1696
|
}
|
|
1452
1697
|
|
|
1453
1698
|
// src/api/handlers/PUT.ts
|
|
1454
1699
|
function PUTER(configRoutes, config) {
|
|
1455
|
-
const { error, info, warn } = config.logger("[PUT MATCHER]");
|
|
1700
|
+
const { error, info, warn: warn2 } = config.logger("[PUT MATCHER]");
|
|
1456
1701
|
return async function PUT6(...params) {
|
|
1457
1702
|
const handledRequest = await config.extensionCtx?.runExtensions(
|
|
1458
1703
|
"onHandleRequest" /* onHandleRequest */,
|
|
@@ -1479,10 +1724,6 @@ function PUTER(configRoutes, config) {
|
|
|
1479
1724
|
info("matches tenant users");
|
|
1480
1725
|
return route3(req, config);
|
|
1481
1726
|
}
|
|
1482
|
-
if (matches2(configRoutes, req)) {
|
|
1483
|
-
info("matches users");
|
|
1484
|
-
return route2(req, config);
|
|
1485
|
-
}
|
|
1486
1727
|
if (matches(configRoutes, req)) {
|
|
1487
1728
|
info("matches me");
|
|
1488
1729
|
return route(req, config);
|
|
@@ -1495,7 +1736,7 @@ function PUTER(configRoutes, config) {
|
|
|
1495
1736
|
info("matches reset password");
|
|
1496
1737
|
return route15(req, config);
|
|
1497
1738
|
}
|
|
1498
|
-
|
|
1739
|
+
warn2("No PUT routes matched");
|
|
1499
1740
|
return new Response(null, { status: 404 });
|
|
1500
1741
|
};
|
|
1501
1742
|
}
|
|
@@ -1699,18 +1940,7 @@ var Config = class {
|
|
|
1699
1940
|
extensionCtx;
|
|
1700
1941
|
extensions;
|
|
1701
1942
|
logger;
|
|
1702
|
-
|
|
1703
|
-
* Stores the set tenant id from Server for use in sub classes
|
|
1704
|
-
*/
|
|
1705
|
-
tenantId;
|
|
1706
|
-
/**
|
|
1707
|
-
* Stores the set user id from Server for use in sub classes
|
|
1708
|
-
*/
|
|
1709
|
-
userId;
|
|
1710
|
-
/**
|
|
1711
|
-
* Stores the headers to be used in `fetch` calls
|
|
1712
|
-
*/
|
|
1713
|
-
headers;
|
|
1943
|
+
context;
|
|
1714
1944
|
/**
|
|
1715
1945
|
* The nile-auth url
|
|
1716
1946
|
*/
|
|
@@ -1761,11 +1991,12 @@ var Config = class {
|
|
|
1761
1991
|
if (databaseName) {
|
|
1762
1992
|
this.db.database = databaseName;
|
|
1763
1993
|
}
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1994
|
+
this.context = {
|
|
1995
|
+
tenantId: config?.tenantId,
|
|
1996
|
+
userId: config?.userId,
|
|
1997
|
+
headers: config?.headers ? new Headers(config.headers) : new Headers(),
|
|
1998
|
+
preserveHeaders: false
|
|
1999
|
+
};
|
|
1769
2000
|
this.routes = {
|
|
1770
2001
|
...appRoutes(config?.routePrefix),
|
|
1771
2002
|
...config?.routes
|
|
@@ -1808,8 +2039,6 @@ var Config = class {
|
|
|
1808
2039
|
],
|
|
1809
2040
|
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
1810
2041
|
};
|
|
1811
|
-
this.tenantId = config?.tenantId;
|
|
1812
|
-
this.userId = config?.userId;
|
|
1813
2042
|
}
|
|
1814
2043
|
};
|
|
1815
2044
|
|
|
@@ -1876,7 +2105,15 @@ function createProxyForPool(pool, config) {
|
|
|
1876
2105
|
}
|
|
1877
2106
|
const caller = target[property];
|
|
1878
2107
|
return function query(...args) {
|
|
1879
|
-
|
|
2108
|
+
let log = "[QUERY]";
|
|
2109
|
+
const { userId, tenantId } = config.context;
|
|
2110
|
+
if (tenantId) {
|
|
2111
|
+
log = `${log}[TENANT:${tenantId}]`;
|
|
2112
|
+
}
|
|
2113
|
+
if (userId) {
|
|
2114
|
+
log = `${log}[USER:${userId}]`;
|
|
2115
|
+
}
|
|
2116
|
+
info(log, ...args);
|
|
1880
2117
|
const called = caller.apply(this, args);
|
|
1881
2118
|
return called;
|
|
1882
2119
|
};
|
|
@@ -1895,7 +2132,7 @@ var NileDatabase = class {
|
|
|
1895
2132
|
config;
|
|
1896
2133
|
timer;
|
|
1897
2134
|
constructor(config, id) {
|
|
1898
|
-
const { warn, info, debug } = config.logger("[NileInstance]");
|
|
2135
|
+
const { warn: warn2, info, debug } = config.logger("[NileInstance]");
|
|
1899
2136
|
this.id = id;
|
|
1900
2137
|
const poolConfig = {
|
|
1901
2138
|
min: 0,
|
|
@@ -1911,7 +2148,7 @@ var NileDatabase = class {
|
|
|
1911
2148
|
debug(`Connection pool config ${JSON.stringify(cloned)}`);
|
|
1912
2149
|
this.pool = createProxyForPool(new pg.Pool(remaining), this.config);
|
|
1913
2150
|
if (typeof afterCreate === "function") {
|
|
1914
|
-
|
|
2151
|
+
warn2(
|
|
1915
2152
|
"Providing an pool configuration will stop automatic tenant context setting."
|
|
1916
2153
|
);
|
|
1917
2154
|
}
|
|
@@ -1977,7 +2214,7 @@ var NileDatabase = class {
|
|
|
1977
2214
|
};
|
|
1978
2215
|
var NileInstance_default = NileDatabase;
|
|
1979
2216
|
function makeAfterCreate(config, id) {
|
|
1980
|
-
const { error, warn, debug } = config.logger("[afterCreate]");
|
|
2217
|
+
const { error, warn: warn2, debug } = config.logger("[afterCreate]");
|
|
1981
2218
|
return (conn, done) => {
|
|
1982
2219
|
conn.on("error", function errorHandler(e) {
|
|
1983
2220
|
error(`Connection ${id} was terminated by server`, {
|
|
@@ -1986,13 +2223,15 @@ function makeAfterCreate(config, id) {
|
|
|
1986
2223
|
});
|
|
1987
2224
|
done(e, conn);
|
|
1988
2225
|
});
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2226
|
+
const tenantId = config.context.tenantId;
|
|
2227
|
+
const userId = config.context.userId;
|
|
2228
|
+
if (tenantId) {
|
|
2229
|
+
const query = [`SET nile.tenant_id = '${tenantId}'`];
|
|
2230
|
+
if (userId) {
|
|
2231
|
+
if (!tenantId) {
|
|
2232
|
+
warn2("A user id cannot be set in context without a tenant id");
|
|
1994
2233
|
}
|
|
1995
|
-
query.push(`SET nile.user_id = '${
|
|
2234
|
+
query.push(`SET nile.user_id = '${userId}'`);
|
|
1996
2235
|
}
|
|
1997
2236
|
conn.query(query.join(";"), function(err) {
|
|
1998
2237
|
if (err) {
|
|
@@ -2005,11 +2244,11 @@ function makeAfterCreate(config, id) {
|
|
|
2005
2244
|
});
|
|
2006
2245
|
} else {
|
|
2007
2246
|
if (query.length === 1) {
|
|
2008
|
-
debug(`connection context set: tenantId=${
|
|
2247
|
+
debug(`connection context set: tenantId=${tenantId}`);
|
|
2009
2248
|
}
|
|
2010
2249
|
if (query.length === 2) {
|
|
2011
2250
|
debug(
|
|
2012
|
-
`connection context set: tenantId=${
|
|
2251
|
+
`connection context set: tenantId=${tenantId} userId=${userId}`
|
|
2013
2252
|
);
|
|
2014
2253
|
}
|
|
2015
2254
|
}
|
|
@@ -2041,19 +2280,19 @@ var DBManager = class {
|
|
|
2041
2280
|
watchEvictPool(this.poolWatcherFn);
|
|
2042
2281
|
}
|
|
2043
2282
|
poolWatcher = (config) => (id) => {
|
|
2044
|
-
const { info, warn } = Logger(config)("[DBManager]");
|
|
2283
|
+
const { info, warn: warn2 } = Logger(config)("[DBManager]");
|
|
2045
2284
|
if (id && this.connections.has(id)) {
|
|
2046
2285
|
info(`Removing ${id} from db connection pool.`);
|
|
2047
2286
|
const connection = this.connections.get(id);
|
|
2048
2287
|
connection?.shutdown();
|
|
2049
2288
|
this.connections.delete(id);
|
|
2050
2289
|
} else {
|
|
2051
|
-
|
|
2290
|
+
warn2(`missed eviction of ${id}`);
|
|
2052
2291
|
}
|
|
2053
2292
|
};
|
|
2054
2293
|
getConnection = (config) => {
|
|
2055
2294
|
const { info } = Logger(config)("[DBManager]");
|
|
2056
|
-
const id = this.makeId(config.tenantId, config.userId);
|
|
2295
|
+
const id = this.makeId(config.context.tenantId, config.context.userId);
|
|
2057
2296
|
const existing = this.connections.get(id);
|
|
2058
2297
|
info(`# of instances: ${this.connections.size}`);
|
|
2059
2298
|
if (existing) {
|
|
@@ -2061,7 +2300,7 @@ var DBManager = class {
|
|
|
2061
2300
|
existing.startTimeout();
|
|
2062
2301
|
return existing.pool;
|
|
2063
2302
|
}
|
|
2064
|
-
const newOne = new NileInstance_default(
|
|
2303
|
+
const newOne = new NileInstance_default(config, id);
|
|
2065
2304
|
this.connections.set(id, newOne);
|
|
2066
2305
|
info(`created new ${id}`);
|
|
2067
2306
|
info(`# of instances: ${this.connections.size}`);
|
|
@@ -2096,33 +2335,39 @@ var Auth = class {
|
|
|
2096
2335
|
this.#logger = config.logger("[auth]");
|
|
2097
2336
|
}
|
|
2098
2337
|
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;
|
|
2338
|
+
return withNileContext(this.#config, async () => {
|
|
2339
|
+
const res = await fetchSession(this.#config);
|
|
2340
|
+
if (rawResponse) {
|
|
2341
|
+
return res;
|
|
2107
2342
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2343
|
+
try {
|
|
2344
|
+
const session = await res.clone().json();
|
|
2345
|
+
if (Object.keys(session).length === 0) {
|
|
2346
|
+
return void 0;
|
|
2347
|
+
}
|
|
2348
|
+
return session;
|
|
2349
|
+
} catch {
|
|
2350
|
+
return res;
|
|
2351
|
+
}
|
|
2352
|
+
});
|
|
2112
2353
|
}
|
|
2113
2354
|
async getCsrf(rawResponse = false) {
|
|
2114
|
-
return
|
|
2355
|
+
return withNileContext(this.#config, async () => {
|
|
2356
|
+
return await obtainCsrf(this.#config, rawResponse);
|
|
2357
|
+
});
|
|
2115
2358
|
}
|
|
2116
2359
|
async listProviders(rawResponse = false) {
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2360
|
+
return withNileContext(this.#config, async () => {
|
|
2361
|
+
const res = await fetchProviders(this.#config);
|
|
2362
|
+
if (rawResponse) {
|
|
2363
|
+
return res;
|
|
2364
|
+
}
|
|
2365
|
+
try {
|
|
2366
|
+
return await res.clone().json();
|
|
2367
|
+
} catch {
|
|
2368
|
+
return res;
|
|
2369
|
+
}
|
|
2370
|
+
});
|
|
2126
2371
|
}
|
|
2127
2372
|
/**
|
|
2128
2373
|
* Sign the current user out by calling `/api/auth/signout`.
|
|
@@ -2131,73 +2376,79 @@ var Auth = class {
|
|
|
2131
2376
|
* from the internal configuration once the request completes.
|
|
2132
2377
|
*/
|
|
2133
2378
|
async signOut() {
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2379
|
+
return withNileContext(this.#config, async () => {
|
|
2380
|
+
const csrfRes = await this.getCsrf();
|
|
2381
|
+
if (!("csrfToken" in csrfRes)) {
|
|
2382
|
+
throw new Error("Unable to obtain CSRF token. Sign out failed.");
|
|
2383
|
+
}
|
|
2384
|
+
const body = JSON.stringify({
|
|
2385
|
+
csrfToken: csrfRes.csrfToken,
|
|
2386
|
+
json: true
|
|
2387
|
+
});
|
|
2388
|
+
const res = await fetchSignOut(this.#config, body);
|
|
2389
|
+
updateHeaders(new Headers({}));
|
|
2390
|
+
ctx.set({ headers: null });
|
|
2391
|
+
return res;
|
|
2141
2392
|
});
|
|
2142
|
-
const res = await fetchSignOut(this.#config, body);
|
|
2143
|
-
updateHeaders(new Headers({}));
|
|
2144
|
-
this.#config.headers = new Headers();
|
|
2145
|
-
return res;
|
|
2146
2393
|
}
|
|
2147
2394
|
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
|
-
|
|
2395
|
+
return withNileContext(this.#config, async () => {
|
|
2396
|
+
ctx.set({ headers: null });
|
|
2397
|
+
const { email, password, ...params } = payload;
|
|
2398
|
+
if (!email || !password) {
|
|
2399
|
+
throw new Error(
|
|
2400
|
+
"Server side sign up requires a user email and password."
|
|
2401
|
+
);
|
|
2402
|
+
}
|
|
2403
|
+
const providers = await this.listProviders();
|
|
2404
|
+
const { credentials } = providers ?? {};
|
|
2405
|
+
if (!credentials) {
|
|
2406
|
+
throw new Error(
|
|
2407
|
+
"Unable to obtain credential provider. Aborting server side sign up."
|
|
2408
|
+
);
|
|
2409
|
+
}
|
|
2410
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2411
|
+
let csrfToken;
|
|
2412
|
+
if ("csrfToken" in csrf) {
|
|
2413
|
+
csrfToken = csrf.csrfToken;
|
|
2414
|
+
} else {
|
|
2415
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2416
|
+
}
|
|
2417
|
+
const body = JSON.stringify({
|
|
2418
|
+
email,
|
|
2419
|
+
password,
|
|
2420
|
+
csrfToken,
|
|
2421
|
+
callbackUrl: credentials.callbackUrl
|
|
2422
|
+
});
|
|
2423
|
+
const res = await fetchSignUp(this.#config, { body, params });
|
|
2424
|
+
if (res.status > 299) {
|
|
2425
|
+
this.#logger.error(await res.clone().text());
|
|
2426
|
+
return void 0;
|
|
2427
|
+
}
|
|
2428
|
+
const token = parseToken(res.headers);
|
|
2429
|
+
if (!token) {
|
|
2430
|
+
throw new Error("Server side sign up failed. Session token not found");
|
|
2431
|
+
}
|
|
2432
|
+
const { headers } = ctx.get();
|
|
2433
|
+
headers?.append("cookie", token);
|
|
2434
|
+
ctx.set({ headers });
|
|
2435
|
+
updateHeaders(headers);
|
|
2436
|
+
if (rawResponse) {
|
|
2437
|
+
return res;
|
|
2438
|
+
}
|
|
2439
|
+
try {
|
|
2440
|
+
const json = await res.clone().json();
|
|
2441
|
+
if (json && typeof json === "object" && "tenants" in json) {
|
|
2442
|
+
const tenantId = json.tenants[0];
|
|
2443
|
+
if (tenantId) {
|
|
2444
|
+
updateTenantId(tenantId);
|
|
2445
|
+
}
|
|
2195
2446
|
}
|
|
2447
|
+
return json;
|
|
2448
|
+
} catch {
|
|
2449
|
+
return res;
|
|
2196
2450
|
}
|
|
2197
|
-
|
|
2198
|
-
} catch {
|
|
2199
|
-
return res;
|
|
2200
|
-
}
|
|
2451
|
+
});
|
|
2201
2452
|
}
|
|
2202
2453
|
/**
|
|
2203
2454
|
* Request a password reset email.
|
|
@@ -2207,34 +2458,34 @@ var Auth = class {
|
|
|
2207
2458
|
* which is returned as a {@link Response} object.
|
|
2208
2459
|
*/
|
|
2209
2460
|
async forgotPassword(req) {
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2461
|
+
return withNileContext(this.#config, async () => {
|
|
2462
|
+
let email = "";
|
|
2463
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2464
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2465
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2466
|
+
if ("email" in req) {
|
|
2467
|
+
email = req.email;
|
|
2468
|
+
}
|
|
2469
|
+
if ("callbackUrl" in req) {
|
|
2470
|
+
callbackUrl = fQUrl(req.callbackUrl ?? "", this.#config);
|
|
2471
|
+
}
|
|
2472
|
+
if ("redirectUrl" in req) {
|
|
2473
|
+
redirectUrl = fQUrl(req.redirectUrl ?? "", this.#config);
|
|
2474
|
+
}
|
|
2475
|
+
const body = JSON.stringify({
|
|
2476
|
+
email,
|
|
2477
|
+
redirectUrl,
|
|
2478
|
+
callbackUrl
|
|
2479
|
+
});
|
|
2480
|
+
const data = await fetchResetPassword(
|
|
2481
|
+
this.#config,
|
|
2482
|
+
"POST",
|
|
2483
|
+
body,
|
|
2484
|
+
new URLSearchParams(),
|
|
2485
|
+
false
|
|
2486
|
+
);
|
|
2487
|
+
return data;
|
|
2229
2488
|
});
|
|
2230
|
-
const data = await fetchResetPassword(
|
|
2231
|
-
this.#config,
|
|
2232
|
-
"POST",
|
|
2233
|
-
body,
|
|
2234
|
-
new URLSearchParams(),
|
|
2235
|
-
false
|
|
2236
|
-
);
|
|
2237
|
-
return data;
|
|
2238
2489
|
}
|
|
2239
2490
|
/**
|
|
2240
2491
|
* Complete a password reset.
|
|
@@ -2247,93 +2498,98 @@ var Auth = class {
|
|
|
2247
2498
|
* containing the necessary fields.
|
|
2248
2499
|
*/
|
|
2249
2500
|
async resetPassword(req) {
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2501
|
+
return withNileContext(this.#config, async () => {
|
|
2502
|
+
let email = "";
|
|
2503
|
+
let password = "";
|
|
2504
|
+
const defaults = defaultCallbackUrl(this.#config);
|
|
2505
|
+
let callbackUrl = defaults.callbackUrl;
|
|
2506
|
+
let redirectUrl = defaults.redirectUrl;
|
|
2507
|
+
if (req instanceof Request) {
|
|
2508
|
+
const body2 = await req.json();
|
|
2509
|
+
email = body2.email;
|
|
2510
|
+
password = body2.password;
|
|
2511
|
+
const cbFromHeaders = parseCallback(req.headers);
|
|
2512
|
+
if (cbFromHeaders) {
|
|
2513
|
+
callbackUrl = cbFromHeaders;
|
|
2514
|
+
}
|
|
2515
|
+
if (body2.callbackUrl) {
|
|
2516
|
+
callbackUrl = body2.callbackUrl;
|
|
2517
|
+
}
|
|
2518
|
+
if (body2.redirectUrl) {
|
|
2519
|
+
redirectUrl = body2.redirectUrl;
|
|
2520
|
+
}
|
|
2521
|
+
} else {
|
|
2522
|
+
if ("email" in req) {
|
|
2523
|
+
email = req.email;
|
|
2524
|
+
}
|
|
2525
|
+
if ("password" in req) {
|
|
2526
|
+
password = req.password;
|
|
2527
|
+
}
|
|
2528
|
+
if ("callbackUrl" in req) {
|
|
2529
|
+
callbackUrl = req.callbackUrl ? req.callbackUrl : null;
|
|
2530
|
+
}
|
|
2531
|
+
if ("redirectUrl" in req) {
|
|
2532
|
+
redirectUrl = req.redirectUrl ? req.redirectUrl : null;
|
|
2533
|
+
}
|
|
2268
2534
|
}
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
email
|
|
2535
|
+
await this.getCsrf();
|
|
2536
|
+
const body = JSON.stringify({
|
|
2537
|
+
email,
|
|
2538
|
+
password,
|
|
2539
|
+
redirectUrl,
|
|
2540
|
+
callbackUrl
|
|
2541
|
+
});
|
|
2542
|
+
let urlWithParams;
|
|
2543
|
+
try {
|
|
2544
|
+
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
2545
|
+
const cloned = data.clone();
|
|
2546
|
+
if (data.status === 400) {
|
|
2547
|
+
const text = await cloned.text();
|
|
2548
|
+
this.#logger.error(text);
|
|
2549
|
+
return data;
|
|
2550
|
+
}
|
|
2551
|
+
const { url } = await data.json();
|
|
2552
|
+
urlWithParams = url;
|
|
2553
|
+
} catch {
|
|
2272
2554
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2555
|
+
let token;
|
|
2556
|
+
try {
|
|
2557
|
+
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2558
|
+
const answer = await fetchResetPassword(
|
|
2559
|
+
this.#config,
|
|
2560
|
+
"GET",
|
|
2561
|
+
null,
|
|
2562
|
+
worthyParams
|
|
2563
|
+
);
|
|
2564
|
+
token = parseResetToken(answer.headers);
|
|
2565
|
+
} catch {
|
|
2566
|
+
this.#logger.warn(
|
|
2567
|
+
"Unable to parse reset password url. Password not reset."
|
|
2568
|
+
);
|
|
2275
2569
|
}
|
|
2276
|
-
|
|
2277
|
-
|
|
2570
|
+
const { headers } = ctx.get();
|
|
2571
|
+
const cookie = headers?.get("cookie")?.split("; ");
|
|
2572
|
+
if (token) {
|
|
2573
|
+
cookie?.push(token);
|
|
2574
|
+
} else {
|
|
2575
|
+
throw new Error(
|
|
2576
|
+
"Unable to reset password, reset token is missing from response"
|
|
2577
|
+
);
|
|
2278
2578
|
}
|
|
2279
|
-
if (
|
|
2280
|
-
|
|
2579
|
+
if (cookie) {
|
|
2580
|
+
headers?.set("cookie", cookie?.join("; "));
|
|
2581
|
+
ctx.set({
|
|
2582
|
+
headers
|
|
2583
|
+
});
|
|
2281
2584
|
}
|
|
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("; ")
|
|
2585
|
+
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2586
|
+
cookie?.pop();
|
|
2587
|
+
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2588
|
+
cleaned.push(String(parseToken(res.headers)));
|
|
2589
|
+
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2590
|
+
updateHeaders(updatedHeaders);
|
|
2591
|
+
return res;
|
|
2329
2592
|
});
|
|
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
2593
|
}
|
|
2338
2594
|
/**
|
|
2339
2595
|
* Low level helper used by {@link signIn} to complete provider flows.
|
|
@@ -2343,7 +2599,9 @@ var Auth = class {
|
|
|
2343
2599
|
*/
|
|
2344
2600
|
async callback(provider, body) {
|
|
2345
2601
|
if (body instanceof Request) {
|
|
2346
|
-
|
|
2602
|
+
ctx.set({
|
|
2603
|
+
headers: body.headers
|
|
2604
|
+
});
|
|
2347
2605
|
return await fetchCallback(
|
|
2348
2606
|
this.#config,
|
|
2349
2607
|
provider,
|
|
@@ -2355,112 +2613,115 @@ var Auth = class {
|
|
|
2355
2613
|
return await fetchCallback(this.#config, provider, body);
|
|
2356
2614
|
}
|
|
2357
2615
|
async signIn(provider, payload, rawResponse) {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2616
|
+
return withNileContext(this.#config, async () => {
|
|
2617
|
+
if (payload instanceof Request) {
|
|
2618
|
+
const body2 = new URLSearchParams(await payload.text());
|
|
2619
|
+
const origin = new URL(payload.url).origin;
|
|
2620
|
+
const payloadUrl = body2?.get("callbackUrl");
|
|
2621
|
+
const csrfToken2 = body2?.get("csrfToken");
|
|
2622
|
+
const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
|
|
2623
|
+
if (!csrfToken2) {
|
|
2624
|
+
throw new Error(
|
|
2625
|
+
"CSRF token in missing from request. Request it by the client before calling sign in"
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
const updatedHeaders = new Headers(payload.headers);
|
|
2629
|
+
updatedHeaders.set("Content-Type", "application/x-www-form-urlencoded");
|
|
2630
|
+
ctx.set({ headers: updatedHeaders });
|
|
2631
|
+
const params = new URLSearchParams({
|
|
2632
|
+
csrfToken: csrfToken2,
|
|
2633
|
+
json: String(true)
|
|
2634
|
+
});
|
|
2635
|
+
if (payloadUrl) {
|
|
2636
|
+
params.set("callbackUrl", callbackUrl);
|
|
2637
|
+
}
|
|
2638
|
+
return await fetchSignIn(this.#config, provider, params);
|
|
2639
|
+
}
|
|
2640
|
+
ctx.set({ headers: null });
|
|
2641
|
+
const { info, error } = this.#logger;
|
|
2642
|
+
const providers = await this.listProviders();
|
|
2643
|
+
info("Obtaining csrf");
|
|
2644
|
+
const csrf = await obtainCsrf(this.#config);
|
|
2645
|
+
let csrfToken;
|
|
2646
|
+
if ("csrfToken" in csrf) {
|
|
2647
|
+
csrfToken = csrf.csrfToken;
|
|
2648
|
+
} else {
|
|
2649
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
2650
|
+
}
|
|
2651
|
+
const { credentials } = providers ?? {};
|
|
2652
|
+
if (!credentials) {
|
|
2365
2653
|
throw new Error(
|
|
2366
|
-
"
|
|
2654
|
+
"Unable to obtain credential provider. Aborting server side sign in."
|
|
2367
2655
|
);
|
|
2368
2656
|
}
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2657
|
+
const { email, password } = payload ?? {};
|
|
2658
|
+
if (provider === "email" && (!email || !password)) {
|
|
2659
|
+
throw new Error(
|
|
2660
|
+
"Server side sign in requires a user email and password."
|
|
2661
|
+
);
|
|
2662
|
+
}
|
|
2663
|
+
info(`Obtaining providers for ${email}`);
|
|
2664
|
+
info(`Attempting sign in with email ${email}`);
|
|
2665
|
+
if (!email) {
|
|
2666
|
+
throw new Error("Email missing from payload, unable to sign in");
|
|
2667
|
+
}
|
|
2668
|
+
const body = JSON.stringify({
|
|
2669
|
+
email,
|
|
2670
|
+
password,
|
|
2671
|
+
csrfToken,
|
|
2672
|
+
callbackUrl: credentials.callbackUrl
|
|
2377
2673
|
});
|
|
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;
|
|
2674
|
+
const signInRes = await this.callback(provider, body);
|
|
2675
|
+
const authCookie = signInRes?.headers.get("set-cookie");
|
|
2676
|
+
if (!authCookie) {
|
|
2677
|
+
throw new Error("authentication failed");
|
|
2678
|
+
}
|
|
2679
|
+
const token = parseToken(signInRes?.headers);
|
|
2680
|
+
const possibleError = signInRes?.headers.get("location");
|
|
2681
|
+
if (possibleError) {
|
|
2682
|
+
let urlError;
|
|
2683
|
+
try {
|
|
2684
|
+
urlError = new URL(possibleError).searchParams.get("error");
|
|
2685
|
+
} catch {
|
|
2686
|
+
}
|
|
2687
|
+
if (urlError) {
|
|
2688
|
+
error("Unable to log user in", { error: urlError });
|
|
2689
|
+
return new Response(urlError, { status: signInRes.status });
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
if (!token) {
|
|
2693
|
+
error("Unable to obtain auth token", {
|
|
2694
|
+
authCookie,
|
|
2695
|
+
signInRes
|
|
2696
|
+
});
|
|
2697
|
+
throw new Error("Server login failed");
|
|
2698
|
+
}
|
|
2699
|
+
info("Server sign in successful", { authCookie });
|
|
2700
|
+
const setCookie = signInRes.headers.get("set-cookie");
|
|
2701
|
+
const { headers } = ctx.get();
|
|
2702
|
+
if (setCookie) {
|
|
2703
|
+
const cookie = [
|
|
2704
|
+
parseCSRF(headers),
|
|
2705
|
+
parseCallback(signInRes.headers),
|
|
2706
|
+
parseToken(signInRes.headers)
|
|
2707
|
+
].filter(Boolean).join("; ");
|
|
2708
|
+
const uHeaders = new Headers({ cookie });
|
|
2709
|
+
updateHeaders(uHeaders);
|
|
2710
|
+
ctx.set({ headers: uHeaders, preserveHeaders: true });
|
|
2711
|
+
} else {
|
|
2712
|
+
error("Unable to set context after sign in", {
|
|
2713
|
+
headers: signInRes.headers
|
|
2714
|
+
});
|
|
2715
|
+
}
|
|
2716
|
+
if (rawResponse) {
|
|
2717
|
+
return signInRes;
|
|
2718
|
+
}
|
|
2426
2719
|
try {
|
|
2427
|
-
|
|
2720
|
+
return await signInRes.clone().json();
|
|
2428
2721
|
} catch {
|
|
2722
|
+
return signInRes;
|
|
2429
2723
|
}
|
|
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
|
-
}
|
|
2724
|
+
});
|
|
2464
2725
|
}
|
|
2465
2726
|
};
|
|
2466
2727
|
function parseCSRF(headers) {
|
|
@@ -2507,25 +2768,56 @@ function parseResetToken(headers) {
|
|
|
2507
2768
|
const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
|
|
2508
2769
|
return token;
|
|
2509
2770
|
}
|
|
2510
|
-
function
|
|
2771
|
+
function parseTenantId(headers) {
|
|
2772
|
+
let authCookie = headers?.get("set-cookie");
|
|
2773
|
+
if (!authCookie) {
|
|
2774
|
+
authCookie = headers?.get("cookie");
|
|
2775
|
+
}
|
|
2776
|
+
if (!authCookie) {
|
|
2777
|
+
return void 0;
|
|
2778
|
+
}
|
|
2779
|
+
const [, token] = /((__Secure-)?nile\.tenant-id=[^;]+)/.exec(authCookie) ?? [];
|
|
2780
|
+
if (token) {
|
|
2781
|
+
const [, tenantId] = token.split("=");
|
|
2782
|
+
return tenantId;
|
|
2783
|
+
}
|
|
2784
|
+
return null;
|
|
2785
|
+
}
|
|
2786
|
+
function defaultCallbackUrl(config) {
|
|
2511
2787
|
let cb = null;
|
|
2512
2788
|
let redirect = null;
|
|
2513
|
-
const
|
|
2789
|
+
const { headers } = ctx.get();
|
|
2790
|
+
const fallbackCb = parseCallback(headers);
|
|
2514
2791
|
if (fallbackCb) {
|
|
2515
2792
|
const [, value] = fallbackCb.split("=");
|
|
2516
2793
|
cb = decodeURIComponent(value);
|
|
2517
2794
|
if (value) {
|
|
2518
|
-
redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2795
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
2519
2796
|
}
|
|
2520
2797
|
}
|
|
2521
2798
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
2522
2799
|
}
|
|
2800
|
+
function fQUrl(path, config) {
|
|
2801
|
+
if (path.startsWith("/")) {
|
|
2802
|
+
const { callbackUrl } = defaultCallbackUrl(config);
|
|
2803
|
+
if (callbackUrl) {
|
|
2804
|
+
const { origin } = new URL(callbackUrl);
|
|
2805
|
+
return `${origin}${path}`;
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
try {
|
|
2809
|
+
new URL(path);
|
|
2810
|
+
} catch {
|
|
2811
|
+
throw new Error("An invalid URL has been passed.");
|
|
2812
|
+
}
|
|
2813
|
+
return path;
|
|
2814
|
+
}
|
|
2523
2815
|
|
|
2524
2816
|
// src/auth/obtainCsrf.ts
|
|
2525
2817
|
async function obtainCsrf(config, rawResponse = false) {
|
|
2818
|
+
const { headers } = ctx.get();
|
|
2526
2819
|
const res = await fetchCsrf(config);
|
|
2527
2820
|
const csrfCook = parseCSRF(res.headers);
|
|
2528
|
-
const h = new Headers();
|
|
2529
2821
|
if (csrfCook) {
|
|
2530
2822
|
const [, value] = csrfCook.split("=");
|
|
2531
2823
|
const [token] = decodeURIComponent(value).split("|");
|
|
@@ -2536,29 +2828,27 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2536
2828
|
parseCallback(res.headers),
|
|
2537
2829
|
parseToken(res.headers)
|
|
2538
2830
|
].filter(Boolean).join("; ");
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
updateHeaders(
|
|
2831
|
+
headers.set("cookie", cookie);
|
|
2832
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2833
|
+
updateHeaders(headers);
|
|
2542
2834
|
}
|
|
2543
2835
|
if (!rawResponse) {
|
|
2544
2836
|
return { csrfToken: token };
|
|
2545
2837
|
}
|
|
2546
2838
|
} else {
|
|
2547
|
-
const existingCookie =
|
|
2839
|
+
const existingCookie = headers.get("cookie");
|
|
2548
2840
|
const cookieParts = [];
|
|
2549
2841
|
if (existingCookie) {
|
|
2550
|
-
cookieParts.push(
|
|
2551
|
-
parseToken(config.headers),
|
|
2552
|
-
parseCallback(config.headers)
|
|
2553
|
-
);
|
|
2842
|
+
cookieParts.push(parseToken(headers), parseCallback(headers));
|
|
2554
2843
|
}
|
|
2555
2844
|
if (csrfCook) {
|
|
2556
2845
|
cookieParts.push(csrfCook);
|
|
2557
2846
|
} else {
|
|
2558
|
-
cookieParts.push(parseCSRF(
|
|
2847
|
+
cookieParts.push(parseCSRF(headers));
|
|
2559
2848
|
}
|
|
2560
2849
|
const cookie = cookieParts.filter(Boolean).join("; ");
|
|
2561
|
-
|
|
2850
|
+
headers.set("cookie", cookie);
|
|
2851
|
+
ctx.set({ headers, preserveHeaders: true });
|
|
2562
2852
|
updateHeaders(new Headers({ cookie }));
|
|
2563
2853
|
}
|
|
2564
2854
|
if (rawResponse) {
|
|
@@ -2571,6 +2861,22 @@ async function obtainCsrf(config, rawResponse = false) {
|
|
|
2571
2861
|
}
|
|
2572
2862
|
}
|
|
2573
2863
|
|
|
2864
|
+
// src/utils/qualifyDomain.ts
|
|
2865
|
+
function fQUrl2(callbackUrl, path) {
|
|
2866
|
+
if (path.startsWith("/")) {
|
|
2867
|
+
if (callbackUrl) {
|
|
2868
|
+
const { origin } = new URL(callbackUrl);
|
|
2869
|
+
return `${origin}${path}`;
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
try {
|
|
2873
|
+
new URL(path);
|
|
2874
|
+
} catch {
|
|
2875
|
+
throw new Error("An invalid URL has been passed.");
|
|
2876
|
+
}
|
|
2877
|
+
return path;
|
|
2878
|
+
}
|
|
2879
|
+
|
|
2574
2880
|
// src/users/index.ts
|
|
2575
2881
|
var Users = class {
|
|
2576
2882
|
#config;
|
|
@@ -2593,15 +2899,17 @@ var Users = class {
|
|
|
2593
2899
|
* @param [rawResponse] - When `true`, return the raw {@link Response}.
|
|
2594
2900
|
*/
|
|
2595
2901
|
async updateSelf(req, rawResponse) {
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2902
|
+
return withNileContext(this.#config, async () => {
|
|
2903
|
+
const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
|
|
2904
|
+
if (rawResponse) {
|
|
2905
|
+
return res;
|
|
2906
|
+
}
|
|
2907
|
+
try {
|
|
2908
|
+
return await res?.clone().json();
|
|
2909
|
+
} catch {
|
|
2910
|
+
return res;
|
|
2911
|
+
}
|
|
2912
|
+
});
|
|
2605
2913
|
}
|
|
2606
2914
|
/**
|
|
2607
2915
|
* Remove the current user using `DELETE /api/me`.
|
|
@@ -2611,59 +2919,73 @@ var Users = class {
|
|
|
2611
2919
|
* `packages/server/src/api/routes/me/index.ts` under `removeSelf`.
|
|
2612
2920
|
*/
|
|
2613
2921
|
async removeSelf() {
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2922
|
+
return withNileContext(this.#config, async () => {
|
|
2923
|
+
const me = await this.getSelf();
|
|
2924
|
+
if ("id" in me) {
|
|
2925
|
+
const userId = me.id;
|
|
2926
|
+
ctx.set({ userId });
|
|
2927
|
+
}
|
|
2928
|
+
const res = await fetchMe(this.#config, "DELETE");
|
|
2929
|
+
updateHeaders(new Headers());
|
|
2930
|
+
return res;
|
|
2931
|
+
});
|
|
2621
2932
|
}
|
|
2622
2933
|
async getSelf(rawResponse) {
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2934
|
+
return withNileContext(this.#config, async () => {
|
|
2935
|
+
const res = await fetchMe(this.#config);
|
|
2936
|
+
if (rawResponse) {
|
|
2937
|
+
return res;
|
|
2938
|
+
}
|
|
2939
|
+
try {
|
|
2940
|
+
return await res?.clone().json();
|
|
2941
|
+
} catch {
|
|
2942
|
+
return res;
|
|
2943
|
+
}
|
|
2944
|
+
});
|
|
2632
2945
|
}
|
|
2633
2946
|
async verifySelf(options, rawResponse = false) {
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
if (!bypassEmail) {
|
|
2646
|
-
let message = "Unable to verify email.";
|
|
2647
|
-
if (e instanceof Error) {
|
|
2648
|
-
message = e.message;
|
|
2947
|
+
return withNileContext(this.#config, async () => {
|
|
2948
|
+
const bypassEmail = typeof options === "object" && options?.bypassEmail === true;
|
|
2949
|
+
const callbackUrl = fQUrl2(
|
|
2950
|
+
defaultCallbackUrl2().callbackUrl,
|
|
2951
|
+
typeof options === "object" ? String(options.callbackUrl) : "/"
|
|
2952
|
+
);
|
|
2953
|
+
let res;
|
|
2954
|
+
try {
|
|
2955
|
+
const me = await this.getSelf();
|
|
2956
|
+
if (me instanceof Response) {
|
|
2957
|
+
return me;
|
|
2649
2958
|
}
|
|
2650
|
-
this.#
|
|
2651
|
-
|
|
2959
|
+
res = await verifyEmailAddress(this.#config, me, String(callbackUrl));
|
|
2960
|
+
return res;
|
|
2961
|
+
} catch (e) {
|
|
2962
|
+
if (!bypassEmail) {
|
|
2963
|
+
let message = "Unable to verify email.";
|
|
2964
|
+
if (e instanceof Error) {
|
|
2965
|
+
message = e.message;
|
|
2966
|
+
}
|
|
2967
|
+
this.#logger?.error(
|
|
2968
|
+
`${message} you can bypass this message by setting bypassEmail: true when calling 'verifySelf'`
|
|
2969
|
+
);
|
|
2970
|
+
res = new Response(message, { status: 400 });
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
if (bypassEmail) {
|
|
2974
|
+
this.#logger?.info(
|
|
2975
|
+
"bypassing email requirements for email verification"
|
|
2652
2976
|
);
|
|
2653
|
-
res =
|
|
2977
|
+
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2654
2978
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
this.#logger?.info("bypassing email requirements for email verification");
|
|
2658
|
-
res = this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2659
|
-
}
|
|
2660
|
-
return res;
|
|
2979
|
+
return res;
|
|
2980
|
+
});
|
|
2661
2981
|
}
|
|
2662
2982
|
};
|
|
2663
2983
|
async function verifyEmailAddress(config, user, callback) {
|
|
2664
|
-
|
|
2984
|
+
const { headers } = ctx.get();
|
|
2985
|
+
headers?.set("content-type", "application/x-www-form-urlencoded");
|
|
2986
|
+
ctx.set({ headers });
|
|
2665
2987
|
const { csrfToken } = await obtainCsrf(config);
|
|
2666
|
-
const defaults = defaultCallbackUrl2(
|
|
2988
|
+
const defaults = defaultCallbackUrl2();
|
|
2667
2989
|
const callbackUrl = callback ?? String(defaults.callbackUrl);
|
|
2668
2990
|
const res = await fetchVerifyEmail(
|
|
2669
2991
|
config,
|
|
@@ -2679,9 +3001,10 @@ async function verifyEmailAddress(config, user, callback) {
|
|
|
2679
3001
|
}
|
|
2680
3002
|
return res;
|
|
2681
3003
|
}
|
|
2682
|
-
function defaultCallbackUrl2(
|
|
3004
|
+
function defaultCallbackUrl2() {
|
|
2683
3005
|
let cb = null;
|
|
2684
|
-
const
|
|
3006
|
+
const { headers } = ctx.get();
|
|
3007
|
+
const fallbackCb = parseCallback(headers);
|
|
2685
3008
|
if (fallbackCb) {
|
|
2686
3009
|
const [, value] = fallbackCb.split("=");
|
|
2687
3010
|
cb = decodeURIComponent(value);
|
|
@@ -2701,24 +3024,26 @@ var Tenants = class {
|
|
|
2701
3024
|
* `createTenant` operation definition.
|
|
2702
3025
|
*/
|
|
2703
3026
|
async create(req, rawResponse) {
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
3027
|
+
return withNileContext(this.#config, async () => {
|
|
3028
|
+
let res;
|
|
3029
|
+
if (typeof req === "string") {
|
|
3030
|
+
res = await fetchTenants(
|
|
3031
|
+
this.#config,
|
|
3032
|
+
"POST",
|
|
3033
|
+
JSON.stringify({ name: req })
|
|
3034
|
+
);
|
|
3035
|
+
} else if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3036
|
+
res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
|
|
3037
|
+
}
|
|
3038
|
+
if (rawResponse) {
|
|
3039
|
+
return res;
|
|
3040
|
+
}
|
|
3041
|
+
try {
|
|
3042
|
+
return await res?.clone().json();
|
|
3043
|
+
} catch {
|
|
3044
|
+
return res;
|
|
3045
|
+
}
|
|
3046
|
+
});
|
|
2722
3047
|
}
|
|
2723
3048
|
/**
|
|
2724
3049
|
* Remove a tenant via `DELETE /api/tenants/{tenantId}`.
|
|
@@ -2726,14 +3051,16 @@ var Tenants = class {
|
|
|
2726
3051
|
* @param req - The tenant to remove or context containing the id.
|
|
2727
3052
|
*/
|
|
2728
3053
|
async delete(req) {
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
3054
|
+
return withNileContext(this.#config, async () => {
|
|
3055
|
+
if (typeof req === "string") {
|
|
3056
|
+
ctx.set({ tenantId: req });
|
|
3057
|
+
}
|
|
3058
|
+
if (typeof req === "object" && "id" in req) {
|
|
3059
|
+
ctx.set({ tenantId: req.id });
|
|
3060
|
+
}
|
|
3061
|
+
const res = await fetchTenant(this.#config, "DELETE");
|
|
3062
|
+
return res;
|
|
3063
|
+
});
|
|
2737
3064
|
}
|
|
2738
3065
|
/**
|
|
2739
3066
|
* Fetch details for a tenant using `GET /api/tenants/{tenantId}`.
|
|
@@ -2742,53 +3069,63 @@ var Tenants = class {
|
|
|
2742
3069
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2743
3070
|
*/
|
|
2744
3071
|
async get(req, rawResponse) {
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
3072
|
+
return withNileContext(this.#config, async () => {
|
|
3073
|
+
if (typeof req === "string") {
|
|
3074
|
+
ctx.set({ tenantId: req });
|
|
3075
|
+
} else if (typeof req === "object" && "id" in req) {
|
|
3076
|
+
ctx.set({ tenantId: req.id });
|
|
3077
|
+
}
|
|
3078
|
+
const res = await fetchTenant(this.#config, "GET");
|
|
3079
|
+
if (rawResponse === true || req === true) {
|
|
3080
|
+
return res;
|
|
3081
|
+
}
|
|
3082
|
+
try {
|
|
3083
|
+
return await res?.clone().json();
|
|
3084
|
+
} catch {
|
|
3085
|
+
return res;
|
|
3086
|
+
}
|
|
3087
|
+
});
|
|
2759
3088
|
}
|
|
2760
3089
|
async update(req, rawResponse) {
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
3090
|
+
return withNileContext(this.#config, async () => {
|
|
3091
|
+
let res;
|
|
3092
|
+
if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
3093
|
+
const { id, ...remaining } = req;
|
|
3094
|
+
if (id) {
|
|
3095
|
+
ctx.set({ tenantId: id });
|
|
3096
|
+
}
|
|
3097
|
+
res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
|
|
2766
3098
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
}
|
|
3099
|
+
if (rawResponse) {
|
|
3100
|
+
return res;
|
|
3101
|
+
}
|
|
3102
|
+
try {
|
|
3103
|
+
return await res?.clone().json();
|
|
3104
|
+
} catch {
|
|
3105
|
+
return res;
|
|
3106
|
+
}
|
|
3107
|
+
});
|
|
2777
3108
|
}
|
|
2778
3109
|
/**
|
|
2779
3110
|
* List tenants for the current user via `GET /api/tenants`.
|
|
2780
3111
|
* See `packages/server/src/api/routes/tenants/GET.ts` for details.
|
|
2781
3112
|
*/
|
|
2782
3113
|
async list(req) {
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
3114
|
+
return withNileContext(
|
|
3115
|
+
this.#config,
|
|
3116
|
+
async () => {
|
|
3117
|
+
const res = await fetchTenantsByUser(this.#config);
|
|
3118
|
+
if (req === true) {
|
|
3119
|
+
return res;
|
|
3120
|
+
}
|
|
3121
|
+
try {
|
|
3122
|
+
return await res?.clone().json();
|
|
3123
|
+
} catch {
|
|
3124
|
+
return res;
|
|
3125
|
+
}
|
|
3126
|
+
},
|
|
3127
|
+
"listTenants"
|
|
3128
|
+
);
|
|
2792
3129
|
}
|
|
2793
3130
|
/**
|
|
2794
3131
|
* Leave the current tenant using `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2796,29 +3133,33 @@ var Tenants = class {
|
|
|
2796
3133
|
* @param [req] - Optionally specify the tenant id to leave.
|
|
2797
3134
|
*/
|
|
2798
3135
|
async leaveTenant(req) {
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
3136
|
+
return withNileContext(this.#config, async () => {
|
|
3137
|
+
const me = await fetchMe(this.#config);
|
|
3138
|
+
try {
|
|
3139
|
+
const json = await me.json();
|
|
3140
|
+
if ("id" in json) {
|
|
3141
|
+
ctx.set({ userId: json.id, preserveHeaders: true });
|
|
3142
|
+
}
|
|
3143
|
+
} catch {
|
|
2804
3144
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
this.#
|
|
2811
|
-
}
|
|
2812
|
-
return await fetchTenantUser(this.#config, "DELETE");
|
|
3145
|
+
if (typeof req === "string") {
|
|
3146
|
+
ctx.set({ tenantId: req, preserveHeaders: true });
|
|
3147
|
+
} else {
|
|
3148
|
+
this.#handleContext(req);
|
|
3149
|
+
}
|
|
3150
|
+
return await fetchTenantUser(this.#config, "DELETE");
|
|
3151
|
+
});
|
|
2813
3152
|
}
|
|
2814
3153
|
async addMember(req, rawResponse) {
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
3154
|
+
return withNileContext(this.#config, async () => {
|
|
3155
|
+
if (typeof req === "string") {
|
|
3156
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3157
|
+
} else {
|
|
3158
|
+
this.#handleContext(req);
|
|
3159
|
+
}
|
|
3160
|
+
const res = await fetchTenantUser(this.#config, "PUT");
|
|
3161
|
+
return responseHandler(res, rawResponse);
|
|
3162
|
+
});
|
|
2822
3163
|
}
|
|
2823
3164
|
/**
|
|
2824
3165
|
* Remove a user from a tenant with `DELETE /api/tenants/{tenantId}/users/{userId}`.
|
|
@@ -2827,57 +3168,83 @@ var Tenants = class {
|
|
|
2827
3168
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2828
3169
|
*/
|
|
2829
3170
|
async removeMember(req, rawResponse) {
|
|
2830
|
-
this.#
|
|
2831
|
-
|
|
2832
|
-
|
|
3171
|
+
return withNileContext(this.#config, async () => {
|
|
3172
|
+
this.#handleContext(req);
|
|
3173
|
+
if (typeof req === "string") {
|
|
3174
|
+
ctx.set({ userId: req, preserveHeaders: true });
|
|
3175
|
+
}
|
|
3176
|
+
const res = await fetchTenantUser(this.#config, "DELETE");
|
|
3177
|
+
return responseHandler(res, rawResponse);
|
|
3178
|
+
});
|
|
2833
3179
|
}
|
|
2834
3180
|
async users(req, rawResponse) {
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
3181
|
+
return withNileContext(
|
|
3182
|
+
this.#config,
|
|
3183
|
+
async () => {
|
|
3184
|
+
this.#handleContext(req);
|
|
3185
|
+
const res = await fetchTenantUsers(this.#config, "GET");
|
|
3186
|
+
return responseHandler(
|
|
3187
|
+
res,
|
|
3188
|
+
rawResponse || typeof req === "boolean" && req
|
|
3189
|
+
);
|
|
3190
|
+
},
|
|
3191
|
+
"users"
|
|
2840
3192
|
);
|
|
2841
3193
|
}
|
|
2842
3194
|
/**
|
|
2843
3195
|
* List invites for the current tenant via `GET /api/tenants/{tenantId}/invites`.
|
|
2844
3196
|
*/
|
|
2845
3197
|
async invites() {
|
|
2846
|
-
|
|
2847
|
-
|
|
3198
|
+
return withNileContext(
|
|
3199
|
+
this.#config,
|
|
3200
|
+
async () => {
|
|
3201
|
+
const res = await fetchInvites(this.#config);
|
|
3202
|
+
return responseHandler(res);
|
|
3203
|
+
},
|
|
3204
|
+
"invites"
|
|
3205
|
+
);
|
|
2848
3206
|
}
|
|
2849
3207
|
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(
|
|
3208
|
+
return withNileContext(
|
|
2871
3209
|
this.#config,
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
3210
|
+
async () => {
|
|
3211
|
+
await runExtensionContext(this.#config);
|
|
3212
|
+
const { csrfToken } = await obtainCsrf(
|
|
3213
|
+
this.#config
|
|
3214
|
+
);
|
|
3215
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3216
|
+
let identifier = req;
|
|
3217
|
+
let callbackUrl = defaults.callbackUrl;
|
|
3218
|
+
let redirectUrl = defaults.redirectUrl;
|
|
3219
|
+
if (typeof req === "object") {
|
|
3220
|
+
if ("email" in req) {
|
|
3221
|
+
identifier = req.email;
|
|
3222
|
+
}
|
|
3223
|
+
const { callbackUrl: cbUrl } = defaultCallbackUrl3(this.#config);
|
|
3224
|
+
if ("callbackUrl" in req) {
|
|
3225
|
+
callbackUrl = fQUrl2(cbUrl, req.callbackUrl ?? "/");
|
|
3226
|
+
}
|
|
3227
|
+
if ("redirectUrl" in req) {
|
|
3228
|
+
redirectUrl = fQUrl2(cbUrl, req.redirectUrl ?? "/");
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
const { headers } = ctx.get();
|
|
3232
|
+
headers?.set("Content-Type", "application/x-www-form-urlencoded");
|
|
3233
|
+
ctx.set({ headers });
|
|
3234
|
+
const res = await fetchInvite(
|
|
3235
|
+
this.#config,
|
|
3236
|
+
"POST",
|
|
3237
|
+
new URLSearchParams({
|
|
3238
|
+
identifier,
|
|
3239
|
+
csrfToken,
|
|
3240
|
+
callbackUrl,
|
|
3241
|
+
redirectUrl
|
|
3242
|
+
}).toString()
|
|
3243
|
+
);
|
|
3244
|
+
return responseHandler(res, rawResponse);
|
|
3245
|
+
},
|
|
3246
|
+
"invites"
|
|
2879
3247
|
);
|
|
2880
|
-
return responseHandler(res, rawResponse);
|
|
2881
3248
|
}
|
|
2882
3249
|
/**
|
|
2883
3250
|
* Accept an invite using `PUT /api/tenants/{tenantId}/invite`.
|
|
@@ -2886,22 +3253,24 @@ var Tenants = class {
|
|
|
2886
3253
|
* @param [rawResponse] - When true, return the raw {@link Response}.
|
|
2887
3254
|
*/
|
|
2888
3255
|
async acceptInvite(req, rawResponse) {
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
3256
|
+
return withNileContext(this.#config, async () => {
|
|
3257
|
+
if (!req) {
|
|
3258
|
+
throw new Error("The identifier and token are required.");
|
|
3259
|
+
}
|
|
3260
|
+
const { identifier, token } = req;
|
|
3261
|
+
const defaults = defaultCallbackUrl3(this.#config);
|
|
3262
|
+
const callbackUrl = String(defaults.callbackUrl);
|
|
3263
|
+
const res = await fetchInvite(
|
|
3264
|
+
this.#config,
|
|
3265
|
+
"PUT",
|
|
3266
|
+
new URLSearchParams({
|
|
3267
|
+
identifier,
|
|
3268
|
+
token,
|
|
3269
|
+
callbackUrl
|
|
3270
|
+
}).toString()
|
|
3271
|
+
);
|
|
3272
|
+
return responseHandler(res, rawResponse);
|
|
3273
|
+
});
|
|
2905
3274
|
}
|
|
2906
3275
|
/**
|
|
2907
3276
|
* Delete a pending invite using `DELETE /api/tenants/{tenantId}/invite/{inviteId}`.
|
|
@@ -2909,25 +3278,27 @@ var Tenants = class {
|
|
|
2909
3278
|
* @param req - Identifier of the invite to remove.
|
|
2910
3279
|
*/
|
|
2911
3280
|
async deleteInvite(req) {
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
3281
|
+
return withNileContext(this.#config, async () => {
|
|
3282
|
+
let id = "";
|
|
3283
|
+
if (typeof req === "object") {
|
|
3284
|
+
id = req.id;
|
|
3285
|
+
} else {
|
|
3286
|
+
id = req;
|
|
3287
|
+
}
|
|
3288
|
+
if (!id) {
|
|
3289
|
+
throw new Error("An invite id is required.");
|
|
3290
|
+
}
|
|
3291
|
+
const res = await fetchInvite(this.#config, "DELETE", id);
|
|
3292
|
+
return responseHandler(res, true);
|
|
3293
|
+
});
|
|
2923
3294
|
}
|
|
2924
3295
|
#handleContext(req) {
|
|
2925
3296
|
if (typeof req === "object") {
|
|
2926
3297
|
if ("tenantId" in req) {
|
|
2927
|
-
|
|
3298
|
+
ctx.set({ tenantId: req.tenantId, preserveHeaders: true });
|
|
2928
3299
|
}
|
|
2929
3300
|
if ("userId" in req) {
|
|
2930
|
-
|
|
3301
|
+
ctx.set({ userId: req.userId, preserveHeaders: true });
|
|
2931
3302
|
}
|
|
2932
3303
|
}
|
|
2933
3304
|
}
|
|
@@ -2945,15 +3316,13 @@ async function responseHandler(res, rawResponse) {
|
|
|
2945
3316
|
function defaultCallbackUrl3(config) {
|
|
2946
3317
|
let cb = null;
|
|
2947
3318
|
let redirect = null;
|
|
2948
|
-
const
|
|
3319
|
+
const { headers, tenantId } = ctx.get();
|
|
3320
|
+
const fallbackCb = parseCallback(headers);
|
|
2949
3321
|
if (fallbackCb) {
|
|
2950
3322
|
const [, value] = fallbackCb.split("=");
|
|
2951
3323
|
cb = decodeURIComponent(value);
|
|
2952
3324
|
if (value) {
|
|
2953
|
-
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace(
|
|
2954
|
-
"{tenantId}",
|
|
2955
|
-
String(config.tenantId)
|
|
2956
|
-
)}`;
|
|
3325
|
+
redirect = `${new URL(cb).origin}${config.routePrefix}${"/tenants/{tenantId}/invite" /* INVITE */.replace("{tenantId}", String(tenantId))}`;
|
|
2957
3326
|
}
|
|
2958
3327
|
}
|
|
2959
3328
|
return { callbackUrl: cb, redirectUrl: redirect };
|
|
@@ -3020,97 +3389,6 @@ function updateConfig(response, config) {
|
|
|
3020
3389
|
};
|
|
3021
3390
|
}
|
|
3022
3391
|
|
|
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
3392
|
// src/Server.ts
|
|
3115
3393
|
var Server = class {
|
|
3116
3394
|
users;
|
|
@@ -3119,35 +3397,38 @@ var Server = class {
|
|
|
3119
3397
|
#config;
|
|
3120
3398
|
#handlers;
|
|
3121
3399
|
#manager;
|
|
3122
|
-
#headers;
|
|
3123
|
-
#preserveHeaders;
|
|
3400
|
+
// #headers: undefined | Headers;
|
|
3401
|
+
// #preserveHeaders: boolean;
|
|
3124
3402
|
constructor(config) {
|
|
3125
3403
|
this.#config = new Config({
|
|
3126
3404
|
...config,
|
|
3127
3405
|
extensionCtx: buildExtensionConfig(this)
|
|
3128
3406
|
});
|
|
3129
3407
|
watchTenantId((tenantId) => {
|
|
3130
|
-
if (tenantId !== this.#config.tenantId) {
|
|
3131
|
-
this.#config.tenantId = tenantId;
|
|
3408
|
+
if (tenantId !== this.#config.context.tenantId) {
|
|
3409
|
+
this.#config.context.tenantId = String(tenantId);
|
|
3132
3410
|
this.#reset();
|
|
3133
3411
|
}
|
|
3134
3412
|
});
|
|
3135
3413
|
watchUserId((userId) => {
|
|
3136
|
-
if (userId !== this.#config.userId) {
|
|
3137
|
-
this.#config.userId = userId;
|
|
3414
|
+
if (userId !== this.#config.context.userId) {
|
|
3415
|
+
this.#config.context.userId = String(userId);
|
|
3138
3416
|
this.#reset();
|
|
3139
3417
|
}
|
|
3140
3418
|
});
|
|
3141
3419
|
watchHeaders((headers) => {
|
|
3142
|
-
|
|
3143
|
-
|
|
3420
|
+
if (headers) {
|
|
3421
|
+
this.#config.context.headers = new Headers(headers);
|
|
3422
|
+
this.#config.context.preserveHeaders = true;
|
|
3423
|
+
this.#reset();
|
|
3424
|
+
}
|
|
3144
3425
|
});
|
|
3145
3426
|
this.#handlers = {
|
|
3146
3427
|
...this.#config.handlers,
|
|
3147
3428
|
withContext: handlersWithContext(this.#config)
|
|
3148
3429
|
};
|
|
3149
|
-
this.#preserveHeaders = config?.preserveHeaders ?? false;
|
|
3150
|
-
this.#config.tenantId = getTenantId({ config: this.#config });
|
|
3430
|
+
this.#config.context.preserveHeaders = config?.preserveHeaders ?? false;
|
|
3431
|
+
this.#config.context.tenantId = getTenantId({ config: this.#config });
|
|
3151
3432
|
this.#manager = new DBManager(this.#config);
|
|
3152
3433
|
this.#handleHeaders(config);
|
|
3153
3434
|
this.users = new Users(this.#config);
|
|
@@ -3202,21 +3483,6 @@ var Server = class {
|
|
|
3202
3483
|
}
|
|
3203
3484
|
};
|
|
3204
3485
|
}
|
|
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
3486
|
get handlers() {
|
|
3221
3487
|
return this.#handlers;
|
|
3222
3488
|
}
|
|
@@ -3226,98 +3492,30 @@ var Server = class {
|
|
|
3226
3492
|
set paths(paths) {
|
|
3227
3493
|
this.#config.paths = paths;
|
|
3228
3494
|
}
|
|
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 {
|
|
3495
|
+
async withContext(context, fn) {
|
|
3496
|
+
const { ddl, ...ctx2 } = context ?? defaultContext;
|
|
3497
|
+
this.#config.context = { ...ctx2 };
|
|
3498
|
+
const preserve = (context && "preserveHeaders" in context && context.preserveHeaders) ?? true;
|
|
3499
|
+
if (preserve) {
|
|
3500
|
+
this.#config.context = { ...this.getContext(), ...context };
|
|
3281
3501
|
}
|
|
3282
|
-
if (
|
|
3283
|
-
|
|
3502
|
+
if (ddl) {
|
|
3503
|
+
delete this.#config.context.tenantId;
|
|
3504
|
+
delete this.#config.context.userId;
|
|
3284
3505
|
}
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
if (headers) {
|
|
3289
|
-
this.#handleHeaders(headers);
|
|
3290
|
-
this.#reset();
|
|
3291
|
-
return;
|
|
3292
|
-
}
|
|
3293
|
-
} catch {
|
|
3506
|
+
return withNileContext(this.#config, async () => {
|
|
3507
|
+
if (fn) {
|
|
3508
|
+
return fn(this);
|
|
3294
3509
|
}
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
};
|
|
3510
|
+
return this;
|
|
3511
|
+
});
|
|
3512
|
+
}
|
|
3513
|
+
/**
|
|
3514
|
+
*
|
|
3515
|
+
* @returns the last used (basically global) context object, useful for debugging or making your own context
|
|
3516
|
+
*/
|
|
3303
3517
|
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
|
-
};
|
|
3518
|
+
return ctx.getLastUsed();
|
|
3321
3519
|
}
|
|
3322
3520
|
/**
|
|
3323
3521
|
* Merge headers together
|
|
@@ -3326,16 +3524,19 @@ var Server = class {
|
|
|
3326
3524
|
#handleHeaders(config) {
|
|
3327
3525
|
const updates = [];
|
|
3328
3526
|
let headers;
|
|
3329
|
-
this.#headers = new Headers();
|
|
3527
|
+
this.#config.context.headers = new Headers();
|
|
3330
3528
|
if (config instanceof Headers) {
|
|
3331
3529
|
headers = config;
|
|
3332
3530
|
} else if (config?.headers) {
|
|
3333
3531
|
headers = config?.headers;
|
|
3334
3532
|
if (config && config.origin) {
|
|
3335
|
-
this.#headers.set(HEADER_ORIGIN, config.origin);
|
|
3533
|
+
this.#config.context.headers.set(HEADER_ORIGIN, config.origin);
|
|
3336
3534
|
}
|
|
3337
3535
|
if (config && config.secureCookies != null) {
|
|
3338
|
-
this.#headers.set(
|
|
3536
|
+
this.#config.context.headers.set(
|
|
3537
|
+
HEADER_SECURE_COOKIES,
|
|
3538
|
+
String(config.secureCookies)
|
|
3539
|
+
);
|
|
3339
3540
|
}
|
|
3340
3541
|
}
|
|
3341
3542
|
if (headers instanceof Headers) {
|
|
@@ -3348,8 +3549,7 @@ var Server = class {
|
|
|
3348
3549
|
}
|
|
3349
3550
|
}
|
|
3350
3551
|
const merged = {};
|
|
3351
|
-
this.#config.
|
|
3352
|
-
this.#headers?.forEach((value, key17) => {
|
|
3552
|
+
this.#config.context.headers?.forEach((value, key17) => {
|
|
3353
3553
|
if (key17.toLowerCase() !== "cookie") {
|
|
3354
3554
|
merged[key17.toLowerCase()] = value;
|
|
3355
3555
|
}
|
|
@@ -3358,16 +3558,14 @@ var Server = class {
|
|
|
3358
3558
|
merged[key17] = value;
|
|
3359
3559
|
}
|
|
3360
3560
|
for (const [key17, value] of Object.entries(merged)) {
|
|
3361
|
-
this.#headers.set(key17, value);
|
|
3561
|
+
this.#config.context.headers.set(key17, value);
|
|
3362
3562
|
}
|
|
3363
3563
|
this.#config.logger("[handleHeaders]").debug(JSON.stringify(merged));
|
|
3364
|
-
this.#config.headers = this.#headers;
|
|
3365
3564
|
}
|
|
3366
3565
|
/**
|
|
3367
3566
|
* Allow some internal mutations to reset our config + headers
|
|
3368
3567
|
*/
|
|
3369
3568
|
#reset = () => {
|
|
3370
|
-
this.#config.headers = this.#headers ?? new Headers();
|
|
3371
3569
|
this.#config.extensionCtx = buildExtensionConfig(this);
|
|
3372
3570
|
this.users = new Users(this.#config);
|
|
3373
3571
|
this.tenants = new Tenants(this.#config);
|
|
@@ -3382,6 +3580,6 @@ function create(config) {
|
|
|
3382
3580
|
return server;
|
|
3383
3581
|
}
|
|
3384
3582
|
|
|
3385
|
-
export { APIErrorErrorCodeEnum, ExtensionState, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseResetToken, parseToken };
|
|
3583
|
+
export { APIErrorErrorCodeEnum, ExtensionState, HEADER_ORIGIN, HEADER_SECURE_COOKIES, LoginUserResponseTokenTypeEnum, create as Nile, Server, TENANT_COOKIE, USER_COOKIE, parseCSRF, parseCallback, parseResetToken, parseTenantId, parseToken };
|
|
3386
3584
|
//# sourceMappingURL=index.mjs.map
|
|
3387
3585
|
//# sourceMappingURL=index.mjs.map
|