@niledatabase/server 5.0.0-alpha.0 → 5.0.0-alpha.2
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/express.d.mts +2 -2
- package/dist/express.d.ts +2 -2
- package/dist/express.js +1279 -13
- package/dist/express.js.map +1 -1
- package/dist/express.mjs +1279 -13
- package/dist/express.mjs.map +1 -1
- package/dist/index.d.mts +358 -197
- package/dist/index.d.ts +358 -197
- package/dist/index.js +2256 -2134
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2253 -2135
- package/dist/index.mjs.map +1 -1
- package/dist/nitro.js +1 -1
- package/dist/nitro.js.map +1 -1
- package/dist/nitro.mjs +1 -1
- package/dist/nitro.mjs.map +1 -1
- package/package.json +2 -5
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import 'dotenv/config';
|
|
2
2
|
import pg from 'pg';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
// src/types.ts
|
|
5
|
+
var APIErrorErrorCodeEnum = {
|
|
6
|
+
InternalError: "internal_error",
|
|
7
|
+
BadRequest: "bad_request",
|
|
8
|
+
EntityNotFound: "entity_not_found",
|
|
9
|
+
DuplicateEntity: "duplicate_entity",
|
|
10
|
+
InvalidCredentials: "invalid_credentials",
|
|
11
|
+
UnknownOidcProvider: "unknown_oidc_provider",
|
|
12
|
+
ProviderAlreadyExists: "provider_already_exists",
|
|
13
|
+
ProviderConfigError: "provider_config_error",
|
|
14
|
+
ProviderMismatch: "provider_mismatch",
|
|
15
|
+
ProviderUpdateError: "provider_update_error",
|
|
16
|
+
SessionStateMissing: "session_state_missing",
|
|
17
|
+
SessionStateMismatch: "session_state_mismatch",
|
|
18
|
+
OidcCodeMissing: "oidc_code_missing"
|
|
19
|
+
};
|
|
4
20
|
|
|
5
21
|
// src/users/types.ts
|
|
6
22
|
var LoginUserResponseTokenTypeEnum = {
|
|
@@ -9,10 +25,89 @@ var LoginUserResponseTokenTypeEnum = {
|
|
|
9
25
|
IdToken: "ID_TOKEN"
|
|
10
26
|
};
|
|
11
27
|
|
|
12
|
-
// src/api/utils/routes/
|
|
13
|
-
|
|
28
|
+
// src/api/utils/routes/index.ts
|
|
29
|
+
var NILEDB_API_URL = process.env.NILEDB_API_URL;
|
|
30
|
+
var DEFAULT_PREFIX = "/api";
|
|
31
|
+
var appRoutes = (prefix = DEFAULT_PREFIX) => ({
|
|
32
|
+
SIGNIN: `${prefix}${"/auth/signin" /* SIGNIN */}`,
|
|
33
|
+
PROVIDERS: `${prefix}${"/auth/providers" /* PROVIDERS */}`,
|
|
34
|
+
SESSION: `${prefix}${"/auth/session" /* SESSION */}`,
|
|
35
|
+
CSRF: `${prefix}${"/auth/csrf" /* CSRF */}`,
|
|
36
|
+
CALLBACK: `${prefix}${"/auth/callback" /* CALLBACK */}`,
|
|
37
|
+
SIGNOUT: `${prefix}${"/auth/signout" /* SIGNOUT */}`,
|
|
38
|
+
ERROR: `${prefix}/auth/error`,
|
|
39
|
+
VERIFY_REQUEST: `${prefix}/auth/verify-request`,
|
|
40
|
+
VERIFY_EMAIL: `${prefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`,
|
|
41
|
+
PASSWORD_RESET: `${prefix}${"/auth/reset-password" /* PASSWORD_RESET */}`,
|
|
42
|
+
ME: `${prefix}${"/me" /* ME */}`,
|
|
43
|
+
USERS: `${prefix}${"/users" /* USERS */}`,
|
|
44
|
+
USER_TENANTS: `${prefix}${"/users/{userId}/tenants" /* USER_TENANTS */}`,
|
|
45
|
+
TENANTS: `${prefix}${"/tenants" /* TENANTS */}`,
|
|
46
|
+
TENANT: `${prefix}${"/tenants/{tenantId}" /* TENANT */}`,
|
|
47
|
+
TENANT_USER: `${prefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */}`,
|
|
48
|
+
TENANT_USERS: `${prefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */}`,
|
|
49
|
+
SIGNUP: `${prefix}${"/signup" /* SIGNUP */}`,
|
|
50
|
+
LOG: `${prefix}/_log`
|
|
51
|
+
});
|
|
52
|
+
var apiRoutes = (config) => ({
|
|
53
|
+
ME: makeRestUrl(config, "/me"),
|
|
54
|
+
USERS: (qp) => makeRestUrl(config, "/users", qp),
|
|
55
|
+
USER: (userId) => makeRestUrl(config, `/users/${userId}`),
|
|
56
|
+
TENANTS: makeRestUrl(config, "/tenants"),
|
|
57
|
+
TENANT: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}`),
|
|
58
|
+
SIGNUP: makeRestUrl(config, "/signup"),
|
|
59
|
+
TENANT_USERS: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/users`),
|
|
60
|
+
TENANT_USER: makeRestUrl(
|
|
61
|
+
config,
|
|
62
|
+
`/tenants/${config.tenantId}/users/${config.userId}`
|
|
63
|
+
),
|
|
64
|
+
USER_TENANTS: (userId) => makeRestUrl(config, `/users/${userId}/tenants`)
|
|
65
|
+
});
|
|
66
|
+
var proxyRoutes = (config) => ({
|
|
67
|
+
SIGNIN: makeRestUrl(config, "/auth/signin" /* SIGNIN */),
|
|
68
|
+
PROVIDERS: makeRestUrl(config, "/auth/providers" /* PROVIDERS */),
|
|
69
|
+
SESSION: makeRestUrl(config, "/auth/session" /* SESSION */),
|
|
70
|
+
CSRF: makeRestUrl(config, "/auth/csrf" /* CSRF */),
|
|
71
|
+
CALLBACK: makeRestUrl(config, "/auth/callback" /* CALLBACK */),
|
|
72
|
+
SIGNOUT: makeRestUrl(config, "/auth/signout" /* SIGNOUT */),
|
|
73
|
+
ERROR: makeRestUrl(config, "/auth/error"),
|
|
74
|
+
VERIFY_REQUEST: makeRestUrl(config, "/auth/verify-request"),
|
|
75
|
+
PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password" /* PASSWORD_RESET */),
|
|
76
|
+
VERIFY_EMAIL: makeRestUrl(config, "/auth/verify-email" /* VERIFY_EMAIL */)
|
|
77
|
+
});
|
|
78
|
+
function filterNullUndefined(obj) {
|
|
79
|
+
if (!obj) {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
return Object.fromEntries(
|
|
83
|
+
Object.entries(obj).filter(
|
|
84
|
+
([, value]) => value !== null && value !== void 0
|
|
85
|
+
)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function makeRestUrl(config, path, qp) {
|
|
89
|
+
const url = config.apiUrl || NILEDB_API_URL;
|
|
90
|
+
if (!url) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
const params = new URLSearchParams(
|
|
96
|
+
filterNullUndefined(qp)
|
|
97
|
+
);
|
|
98
|
+
const strParams = params.toString();
|
|
99
|
+
return `${[url, path.substring(1, path.length)].join("/")}${strParams ? `?${strParams}` : ""}`;
|
|
100
|
+
}
|
|
101
|
+
function urlMatches(requestUrl, route17) {
|
|
14
102
|
const url = new URL(requestUrl);
|
|
15
|
-
return url.pathname.startsWith(
|
|
103
|
+
return url.pathname.startsWith(route17);
|
|
104
|
+
}
|
|
105
|
+
function isUUID(value) {
|
|
106
|
+
if (!value) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5|7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
110
|
+
return regex.test(value);
|
|
16
111
|
}
|
|
17
112
|
|
|
18
113
|
// src/utils/Logger.ts
|
|
@@ -75,77 +170,9 @@ function matchesLog(configRoutes, request2) {
|
|
|
75
170
|
}
|
|
76
171
|
|
|
77
172
|
// src/utils/constants.ts
|
|
78
|
-
var X_NILE_TENANT = "nile
|
|
79
|
-
var
|
|
80
|
-
var
|
|
81
|
-
var X_NILE_SECURECOOKIES = "nile.secure_cookies";
|
|
82
|
-
|
|
83
|
-
// src/context/asyncStorage.ts
|
|
84
|
-
var globalContext = null;
|
|
85
|
-
function setContext(headers) {
|
|
86
|
-
const origin = headers.get(X_NILE_ORIGIN);
|
|
87
|
-
const host = headers.get("host");
|
|
88
|
-
const cookie = headers.get("cookie");
|
|
89
|
-
const tenantId = headers.get(X_NILE_TENANT);
|
|
90
|
-
const userId = headers.get(X_NILE_USER_ID);
|
|
91
|
-
const context = {};
|
|
92
|
-
if (origin) {
|
|
93
|
-
context.origin = origin;
|
|
94
|
-
} else if (host) {
|
|
95
|
-
context.origin = host;
|
|
96
|
-
}
|
|
97
|
-
if (cookie) {
|
|
98
|
-
context.cookie = cookie;
|
|
99
|
-
}
|
|
100
|
-
if (tenantId) {
|
|
101
|
-
context.tenantId = tenantId;
|
|
102
|
-
}
|
|
103
|
-
if (userId) {
|
|
104
|
-
context.userId = userId;
|
|
105
|
-
}
|
|
106
|
-
globalContext = context;
|
|
107
|
-
}
|
|
108
|
-
function getOrigin() {
|
|
109
|
-
return globalContext?.origin;
|
|
110
|
-
}
|
|
111
|
-
function getCookie() {
|
|
112
|
-
return globalContext?.cookie;
|
|
113
|
-
}
|
|
114
|
-
function setCookie(headers) {
|
|
115
|
-
const getSet = headers?.getSetCookie?.();
|
|
116
|
-
if (getSet?.length) {
|
|
117
|
-
const updatedCookie = [];
|
|
118
|
-
for (const cook of getSet) {
|
|
119
|
-
const [c] = cook.split("; ");
|
|
120
|
-
const [, val] = c.split("=");
|
|
121
|
-
if (val) {
|
|
122
|
-
updatedCookie.push(c);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
const cookie = mergeCookies(updatedCookie);
|
|
126
|
-
globalContext = { ...globalContext, cookie };
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
function mergeCookies(overrideArray) {
|
|
130
|
-
const cookieString = getCookie();
|
|
131
|
-
const cookieMap = {};
|
|
132
|
-
if (!cookieString) {
|
|
133
|
-
return overrideArray.join("; ");
|
|
134
|
-
}
|
|
135
|
-
cookieString.split(";").forEach((cookie) => {
|
|
136
|
-
const [rawKey, ...rawVal] = cookie.trim().split("=");
|
|
137
|
-
const key12 = rawKey.trim();
|
|
138
|
-
const value = rawVal.join("=").trim();
|
|
139
|
-
if (key12) cookieMap[key12] = value;
|
|
140
|
-
});
|
|
141
|
-
overrideArray.forEach((cookie) => {
|
|
142
|
-
const [rawKey, ...rawVal] = cookie.trim().split("=");
|
|
143
|
-
const key12 = rawKey.trim();
|
|
144
|
-
const value = rawVal.join("=").trim();
|
|
145
|
-
if (key12) cookieMap[key12] = value;
|
|
146
|
-
});
|
|
147
|
-
return Object.entries(cookieMap).map(([k, v]) => `${k}=${v}`).join("; ");
|
|
148
|
-
}
|
|
173
|
+
var X_NILE_TENANT = "nile-tenant-id";
|
|
174
|
+
var X_NILE_ORIGIN = "nile-origin";
|
|
175
|
+
var X_NILE_SECURECOOKIES = "nile-secure-cookies";
|
|
149
176
|
|
|
150
177
|
// src/api/utils/request.ts
|
|
151
178
|
async function request(url, _init, config) {
|
|
@@ -162,24 +189,33 @@ async function request(url, _init, config) {
|
|
|
162
189
|
String(request2.headers.get(X_NILE_TENANT))
|
|
163
190
|
);
|
|
164
191
|
}
|
|
165
|
-
if (config.
|
|
166
|
-
updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.
|
|
192
|
+
if (config.secureCookies != null) {
|
|
193
|
+
updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
|
|
194
|
+
} else {
|
|
195
|
+
updatedHeaders.set(
|
|
196
|
+
X_NILE_SECURECOOKIES,
|
|
197
|
+
process.env.NODE_ENV === "production" ? "true" : "false"
|
|
198
|
+
);
|
|
167
199
|
}
|
|
168
200
|
updatedHeaders.set("host", requestUrl.host);
|
|
169
|
-
if (config.
|
|
170
|
-
const cbUrl = new URL(config.
|
|
171
|
-
debug(
|
|
172
|
-
`Obtained origin from config.api.callbackUrl ${config.api.callbackUrl}`
|
|
173
|
-
);
|
|
201
|
+
if (config.callbackUrl) {
|
|
202
|
+
const cbUrl = new URL(config.callbackUrl);
|
|
203
|
+
debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
|
|
174
204
|
updatedHeaders.set(X_NILE_ORIGIN, cbUrl.origin);
|
|
175
|
-
} else if (config.
|
|
176
|
-
debug(`Obtained origin from config.
|
|
177
|
-
updatedHeaders.set(X_NILE_ORIGIN, config.
|
|
205
|
+
} else if (config.origin) {
|
|
206
|
+
debug(`Obtained origin from config.origin ${config.origin}`);
|
|
207
|
+
updatedHeaders.set(X_NILE_ORIGIN, config.origin);
|
|
178
208
|
} else {
|
|
179
|
-
|
|
180
|
-
|
|
209
|
+
const passedOrigin = request2.headers.get(X_NILE_ORIGIN);
|
|
210
|
+
if (passedOrigin) {
|
|
211
|
+
updatedHeaders.set(X_NILE_ORIGIN, passedOrigin);
|
|
212
|
+
} else {
|
|
213
|
+
const reqOrigin = config.routePrefix !== DEFAULT_PREFIX ? `${requestUrl.origin}${config.routePrefix}` : requestUrl.origin;
|
|
214
|
+
updatedHeaders.set(X_NILE_ORIGIN, reqOrigin);
|
|
215
|
+
debug(`Obtained origin from request ${reqOrigin}`);
|
|
216
|
+
}
|
|
181
217
|
}
|
|
182
|
-
const params = { ...init
|
|
218
|
+
const params = { ...init };
|
|
183
219
|
if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
|
|
184
220
|
try {
|
|
185
221
|
updatedHeaders.set("content-type", "application/json");
|
|
@@ -193,28 +229,31 @@ async function request(url, _init, config) {
|
|
|
193
229
|
params.body = initBody ?? requestBody;
|
|
194
230
|
}
|
|
195
231
|
}
|
|
232
|
+
params.headers = updatedHeaders;
|
|
196
233
|
const fullUrl = `${url}${requestUrl.search}`;
|
|
234
|
+
if (config.debug) {
|
|
235
|
+
params.headers.set("request-id", crypto.randomUUID());
|
|
236
|
+
params.cache = "no-store";
|
|
237
|
+
}
|
|
197
238
|
try {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
);
|
|
239
|
+
const res = await fetch(fullUrl, {
|
|
240
|
+
...params
|
|
241
|
+
}).catch((e) => {
|
|
242
|
+
error("An error has occurred in the fetch", {
|
|
243
|
+
message: e.message,
|
|
244
|
+
stack: e.stack
|
|
245
|
+
});
|
|
246
|
+
return new Response(
|
|
247
|
+
"An unexpected (most likely configuration) problem has occurred",
|
|
248
|
+
{ status: 500 }
|
|
249
|
+
);
|
|
250
|
+
});
|
|
211
251
|
const loggingRes = typeof res?.clone === "function" ? res?.clone() : null;
|
|
212
252
|
info(`[${params.method ?? "GET"}] ${fullUrl}`, {
|
|
213
253
|
status: res?.status,
|
|
214
254
|
statusText: res?.statusText,
|
|
215
255
|
text: await loggingRes?.text()
|
|
216
256
|
});
|
|
217
|
-
setCookie(res?.headers);
|
|
218
257
|
return res;
|
|
219
258
|
} catch (e) {
|
|
220
259
|
if (e instanceof Error) {
|
|
@@ -234,8 +273,8 @@ async function request(url, _init, config) {
|
|
|
234
273
|
async function auth(req, config) {
|
|
235
274
|
const { info, error } = Logger(config, "[nileauth]");
|
|
236
275
|
info("checking auth");
|
|
237
|
-
const sessionUrl = `${config.
|
|
238
|
-
info(`using session${sessionUrl}`);
|
|
276
|
+
const sessionUrl = `${config.apiUrl}/auth/session`;
|
|
277
|
+
info(`using session ${sessionUrl}`);
|
|
239
278
|
req.headers.delete("content-length");
|
|
240
279
|
const res = await request(sessionUrl, { request: req }, config);
|
|
241
280
|
if (!res) {
|
|
@@ -254,962 +293,870 @@ async function auth(req, config) {
|
|
|
254
293
|
return void 0;
|
|
255
294
|
}
|
|
256
295
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
};
|
|
264
|
-
var getSecureCookies = (cfg) => {
|
|
265
|
-
const { config } = cfg;
|
|
266
|
-
if (config?.api?.secureCookies != null) {
|
|
267
|
-
return config?.api?.secureCookies;
|
|
296
|
+
|
|
297
|
+
// src/api/routes/me/index.ts
|
|
298
|
+
var key = "ME";
|
|
299
|
+
async function route(request2, config) {
|
|
300
|
+
const url = apiRoutes(config)[key];
|
|
301
|
+
if (request2.method === "GET") {
|
|
302
|
+
return await GET(url, { request: request2 }, config);
|
|
268
303
|
}
|
|
269
|
-
if (
|
|
270
|
-
return
|
|
304
|
+
if (request2.method === "PUT") {
|
|
305
|
+
return await PUT(url, { request: request2 }, config);
|
|
271
306
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const { info } = Logger(config, "[databaseId]");
|
|
277
|
-
if (stringCheck(config?.databaseId)) {
|
|
278
|
-
logger && info(`${logger}[config] ${config?.databaseId}`);
|
|
279
|
-
return String(config?.databaseId);
|
|
280
|
-
}
|
|
281
|
-
const dbFromEnv = stringCheck(process.env.NILEDB_ID);
|
|
282
|
-
if (dbFromEnv) {
|
|
283
|
-
logger && info(`${logger}[NILEDB_ID] ${dbFromEnv}`);
|
|
284
|
-
return dbFromEnv;
|
|
285
|
-
}
|
|
286
|
-
const dbId = stringCheck(process.env.NILEDB_API_URL);
|
|
287
|
-
if (dbId) {
|
|
288
|
-
try {
|
|
289
|
-
const pgUrl = new URL(dbId);
|
|
290
|
-
return pgUrl.pathname.split("/")[3];
|
|
291
|
-
} catch (e) {
|
|
307
|
+
if (request2.method === "DELETE") {
|
|
308
|
+
const session = await auth(request2, config);
|
|
309
|
+
if (!session) {
|
|
310
|
+
return new Response(null, { status: 401 });
|
|
292
311
|
}
|
|
312
|
+
return await DELETE(url, { request: request2 }, config);
|
|
293
313
|
}
|
|
294
|
-
return
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
309
|
-
if (pg2) {
|
|
310
|
-
try {
|
|
311
|
-
const url = new URL(pg2);
|
|
312
|
-
if (url.username) {
|
|
313
|
-
return url.username;
|
|
314
|
-
}
|
|
315
|
-
} catch (e) {
|
|
316
|
-
}
|
|
314
|
+
return new Response("method not allowed", { status: 405 });
|
|
315
|
+
}
|
|
316
|
+
function matches(configRoutes, request2) {
|
|
317
|
+
return urlMatches(request2.url, configRoutes[key]);
|
|
318
|
+
}
|
|
319
|
+
async function fetchMe(config, method, body) {
|
|
320
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
|
|
321
|
+
const init = {
|
|
322
|
+
headers: config.headers,
|
|
323
|
+
method: method ?? "GET"
|
|
324
|
+
};
|
|
325
|
+
if (method === "PUT") {
|
|
326
|
+
init.body = body;
|
|
317
327
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const { config, logger } = cfg;
|
|
322
|
-
const log = logProtector(logger);
|
|
323
|
-
const { info } = Logger(config, "[password]");
|
|
324
|
-
if (stringCheck(config?.password)) {
|
|
325
|
-
log && info(`${logger}[config] ***`);
|
|
326
|
-
return String(config?.password);
|
|
328
|
+
const req = new Request(clientUrl, init);
|
|
329
|
+
if (method === "DELETE") {
|
|
330
|
+
return await config.handlers.DELETE(req);
|
|
327
331
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
logger && info(`${logger}[NILEDB_PASSWORD] ***`);
|
|
331
|
-
return pass;
|
|
332
|
+
if (method === "PUT") {
|
|
333
|
+
return await config.handlers.PUT(req);
|
|
332
334
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
335
|
+
return await config.handlers.GET(req);
|
|
336
|
+
}
|
|
337
|
+
async function DELETE(url, init, config) {
|
|
338
|
+
init.method = "DELETE";
|
|
339
|
+
return await request(url, init, config);
|
|
340
|
+
}
|
|
341
|
+
async function PUT(url, init, config) {
|
|
342
|
+
init.method = "PUT";
|
|
343
|
+
return await request(url, init, config);
|
|
344
|
+
}
|
|
345
|
+
async function GET(url, init, config) {
|
|
346
|
+
const res = await request(url, init, config);
|
|
347
|
+
return res;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/utils/fetch.ts
|
|
351
|
+
function getTokenFromCookie(headers, cookieKey) {
|
|
352
|
+
const cookie = headers.get("cookie")?.split("; ");
|
|
353
|
+
const _cookies = {};
|
|
354
|
+
if (cookie) {
|
|
355
|
+
for (const parts of cookie) {
|
|
356
|
+
const cookieParts = parts.split("=");
|
|
357
|
+
const _cookie = cookieParts.slice(1).join("=");
|
|
358
|
+
const name = cookieParts[0];
|
|
359
|
+
_cookies[name] = _cookie;
|
|
341
360
|
}
|
|
342
361
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
logger && info(`${logger}[config] ${config?.api?.token}`);
|
|
350
|
-
return String(config?.api?.token);
|
|
351
|
-
}
|
|
352
|
-
const token = stringCheck(process.env.NILEDB_TOKEN);
|
|
353
|
-
if (token) {
|
|
354
|
-
logger && info(`${logger}[NILEDB_TOKEN] ${token}`);
|
|
355
|
-
return token;
|
|
356
|
-
}
|
|
357
|
-
return void 0;
|
|
358
|
-
};
|
|
359
|
-
var getDatabaseName = (cfg) => {
|
|
360
|
-
const { config, logger } = cfg;
|
|
361
|
-
const { info } = Logger(config, "[databaseName]");
|
|
362
|
-
if (stringCheck(config?.databaseName)) {
|
|
363
|
-
logger && info(`${logger}[config] ${config?.databaseName}`);
|
|
364
|
-
return String(config?.databaseName);
|
|
365
|
-
}
|
|
366
|
-
const name = stringCheck(process.env.NILEDB_NAME);
|
|
367
|
-
if (name) {
|
|
368
|
-
logger && info(`${logger}[NILEDB_NAME] ${name}`);
|
|
369
|
-
return name;
|
|
370
|
-
}
|
|
371
|
-
if (process.env.NILEDB_POSTGRES_URL) {
|
|
372
|
-
try {
|
|
373
|
-
const pgUrl = new URL(process.env.NILEDB_POSTGRES_URL);
|
|
374
|
-
return pgUrl.pathname.substring(1);
|
|
375
|
-
} catch (e) {
|
|
362
|
+
if (cookie) {
|
|
363
|
+
for (const parts of cookie) {
|
|
364
|
+
const cookieParts = parts.split("=");
|
|
365
|
+
const _cookie = cookieParts.slice(1).join("=");
|
|
366
|
+
const name = cookieParts[0];
|
|
367
|
+
_cookies[name] = _cookie;
|
|
376
368
|
}
|
|
377
369
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
var getTenantId = (cfg) => {
|
|
381
|
-
const { config, logger } = cfg;
|
|
382
|
-
const { info } = Logger(config, "[tenantId]");
|
|
383
|
-
if (stringCheck(config?.tenantId)) {
|
|
384
|
-
logger && info(`${logger}[config] ${config?.tenantId}`);
|
|
385
|
-
return String(config?.tenantId);
|
|
386
|
-
}
|
|
387
|
-
if (stringCheck(process.env.NILEDB_TENANT)) {
|
|
388
|
-
logger && info(`${logger}[NILEDB_TENANT] ${process.env.NILEDB_TENANT}`);
|
|
389
|
-
return String(process.env.NILEDB_TENANT);
|
|
370
|
+
{
|
|
371
|
+
return _cookies[cookieKey];
|
|
390
372
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
373
|
+
}
|
|
374
|
+
function getTenantFromHttp(headers, config) {
|
|
375
|
+
const cookieTenant = getTokenFromCookie(headers, X_NILE_TENANT);
|
|
376
|
+
return cookieTenant ?? headers?.get(X_NILE_TENANT) ?? config?.tenantId;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// src/api/routes/users/POST.ts
|
|
380
|
+
async function POST(config, init) {
|
|
381
|
+
init.body = init.request.body;
|
|
382
|
+
init.method = "POST";
|
|
383
|
+
const yurl = new URL(init.request.url);
|
|
384
|
+
const tenantId = yurl.searchParams.get("tenantId");
|
|
385
|
+
const newTenantName = yurl.searchParams.get("newTenantName");
|
|
386
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
387
|
+
const url = apiRoutes(config).USERS({ tenantId: tenant, newTenantName });
|
|
388
|
+
return await request(url, init, config);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/api/routes/users/GET.ts
|
|
392
|
+
async function GET2(config, init, log) {
|
|
393
|
+
const yurl = new URL(init.request.url);
|
|
394
|
+
const tenantId = yurl.searchParams.get("tenantId");
|
|
395
|
+
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
396
|
+
if (!tenant) {
|
|
397
|
+
log("[GET] No tenant id provided.");
|
|
398
|
+
return new Response(null, { status: 404 });
|
|
399
399
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
400
|
+
const url = apiRoutes(config).TENANT_USERS(tenant);
|
|
401
|
+
init.method = "GET";
|
|
402
|
+
return await request(url, init, config);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// src/api/routes/users/[userId]/PUT.ts
|
|
406
|
+
async function PUT2(config, session, init) {
|
|
407
|
+
if (!session) {
|
|
408
|
+
return new Response(null, { status: 401 });
|
|
403
409
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
|
|
410
|
+
init.body = init.request.body;
|
|
411
|
+
init.method = "PUT";
|
|
412
|
+
const [userId] = new URL(init.request.url).pathname.split("/").reverse();
|
|
413
|
+
const url = apiRoutes(config).USER(userId);
|
|
414
|
+
return await request(url, init, config);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// src/api/routes/users/index.ts
|
|
418
|
+
var key2 = "USERS";
|
|
419
|
+
async function route2(request2, config) {
|
|
420
|
+
const { info } = Logger(
|
|
421
|
+
{ ...config, debug: config.debug },
|
|
422
|
+
`[ROUTES][${key2}]`
|
|
423
|
+
);
|
|
424
|
+
const session = await auth(request2, config);
|
|
425
|
+
switch (request2.method) {
|
|
426
|
+
case "GET":
|
|
427
|
+
return await GET2(config, { request: request2 }, info);
|
|
428
|
+
case "POST":
|
|
429
|
+
return await POST(config, { request: request2 });
|
|
430
|
+
case "PUT":
|
|
431
|
+
return await PUT2(config, session, { request: request2 });
|
|
432
|
+
default:
|
|
433
|
+
return new Response("method not allowed", { status: 405 });
|
|
425
434
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
+
}
|
|
436
|
+
function matches2(configRoutes, request2) {
|
|
437
|
+
return urlMatches(request2.url, configRoutes[key2]);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/api/routes/tenants/[tenantId]/users/GET.ts
|
|
441
|
+
async function GET3(config, init) {
|
|
442
|
+
const yurl = new URL(init.request.url);
|
|
443
|
+
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
444
|
+
const url = `${apiRoutes(config).TENANT_USERS(tenantId)}`;
|
|
445
|
+
return await request(url, init, config);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/api/routes/tenants/[tenantId]/users/POST.ts
|
|
449
|
+
async function POST2(config, session, init) {
|
|
450
|
+
const yurl = new URL(init.request.url);
|
|
451
|
+
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
452
|
+
init.body = JSON.stringify({ email: session.email });
|
|
453
|
+
init.method = "POST";
|
|
454
|
+
const url = apiRoutes(config).TENANT_USERS(tenantId);
|
|
455
|
+
return await request(url, init, config);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// src/api/routes/tenants/[tenantId]/users/index.ts
|
|
459
|
+
var key3 = "TENANT_USERS";
|
|
460
|
+
async function route3(request2, config) {
|
|
461
|
+
const { info } = Logger(
|
|
462
|
+
{ ...config, debug: config.debug },
|
|
463
|
+
`[ROUTES][${key3}]`
|
|
464
|
+
);
|
|
465
|
+
const session = await auth(request2, config);
|
|
466
|
+
if (!session) {
|
|
467
|
+
info("401");
|
|
468
|
+
return new Response(null, { status: 401 });
|
|
435
469
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
470
|
+
const yurl = new URL(request2.url);
|
|
471
|
+
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
472
|
+
if (!tenantId) {
|
|
473
|
+
info("No tenant id found in path");
|
|
474
|
+
return new Response(null, { status: 404 });
|
|
439
475
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
476
|
+
switch (request2.method) {
|
|
477
|
+
case "GET":
|
|
478
|
+
return await GET3(config, { request: request2 });
|
|
479
|
+
case "POST":
|
|
480
|
+
return await POST2(config, session, { request: request2 });
|
|
481
|
+
default:
|
|
482
|
+
return new Response("method not allowed", { status: 405 });
|
|
448
483
|
}
|
|
449
|
-
logger && info(`${logger}[default] db.thenile.dev`);
|
|
450
|
-
return "db.thenile.dev";
|
|
451
484
|
}
|
|
452
|
-
function
|
|
453
|
-
const
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
485
|
+
function matches3(configRoutes, request2) {
|
|
486
|
+
const url = new URL(request2.url);
|
|
487
|
+
const [userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
|
|
488
|
+
let route17 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
|
|
489
|
+
if (userId === "users") {
|
|
490
|
+
route17 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
|
|
458
491
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
492
|
+
return urlMatches(request2.url, route17);
|
|
493
|
+
}
|
|
494
|
+
async function fetchTenantUsers(config, method, payload) {
|
|
495
|
+
const { body, params } = {};
|
|
496
|
+
if (!config.tenantId) {
|
|
497
|
+
throw new Error(
|
|
498
|
+
'Unable to fetch tenant, the tenantId context is missing. Call nile.setContext({ tenantId }), set nile.tenantId = "tenantId", or add it to the function call'
|
|
499
|
+
);
|
|
462
500
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (pgUrl.port) {
|
|
468
|
-
return Number(pgUrl.port);
|
|
469
|
-
}
|
|
470
|
-
} catch (e) {
|
|
471
|
-
}
|
|
501
|
+
if (!isUUID(config.tenantId) && config.logger?.warn) {
|
|
502
|
+
config.logger?.warn(
|
|
503
|
+
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
504
|
+
);
|
|
472
505
|
}
|
|
473
|
-
|
|
474
|
-
|
|
506
|
+
const q = new URLSearchParams();
|
|
507
|
+
if (params?.newTenantName) {
|
|
508
|
+
q.set("newTenantName", params.newTenantName);
|
|
509
|
+
}
|
|
510
|
+
if (params?.tenantId) {
|
|
511
|
+
q.set("tenantId", params.tenantId);
|
|
512
|
+
}
|
|
513
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
|
|
514
|
+
"{tenantId}",
|
|
515
|
+
config.tenantId
|
|
516
|
+
)}`;
|
|
517
|
+
const m = method;
|
|
518
|
+
const init = {
|
|
519
|
+
method: m,
|
|
520
|
+
headers: config.headers
|
|
521
|
+
};
|
|
522
|
+
const req = new Request(clientUrl, init);
|
|
523
|
+
return await config.handlers[m](req);
|
|
475
524
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
if (
|
|
481
|
-
|
|
525
|
+
|
|
526
|
+
// src/api/routes/tenants/GET.ts
|
|
527
|
+
async function GET4(config, session, init) {
|
|
528
|
+
let url = `${apiRoutes(config).USER_TENANTS(session.id)}`;
|
|
529
|
+
if (typeof session === "object" && "user" in session && session.user) {
|
|
530
|
+
url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
|
|
482
531
|
}
|
|
483
|
-
|
|
484
|
-
|
|
532
|
+
const res = await request(url, init, config);
|
|
533
|
+
return res;
|
|
534
|
+
}
|
|
485
535
|
|
|
486
|
-
// src/
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
origin;
|
|
494
|
-
/**
|
|
495
|
-
* The client side callback url. Defaults to nothing (so nile.origin will be it), but in the cases of x-origin, you want to set this explicitly to be sure nile-auth does the right thing
|
|
496
|
-
* If this is set, any `callbackUrl` from the client will be ignored.
|
|
497
|
-
*/
|
|
498
|
-
callbackUrl;
|
|
499
|
-
#token;
|
|
500
|
-
constructor(config, logger) {
|
|
501
|
-
const envVarConfig = { config, logger };
|
|
502
|
-
this.cookieKey = getCookieKey(envVarConfig);
|
|
503
|
-
this.#token = getToken(envVarConfig);
|
|
504
|
-
this.callbackUrl = getCallbackUrl(envVarConfig);
|
|
505
|
-
this.secureCookies = getSecureCookies(envVarConfig);
|
|
506
|
-
this.basePath = getBasePath(envVarConfig);
|
|
507
|
-
this.routes = config?.api?.routes;
|
|
508
|
-
this.routePrefix = config?.api?.routePrefix;
|
|
509
|
-
this.origin = config?.api?.origin;
|
|
536
|
+
// src/api/routes/tenants/[tenantId]/GET.ts
|
|
537
|
+
async function GET5(config, init, log) {
|
|
538
|
+
const yurl = new URL(init.request.url);
|
|
539
|
+
const [tenantId] = yurl.pathname.split("/").reverse();
|
|
540
|
+
if (!tenantId) {
|
|
541
|
+
log("[GET] No tenant id provided.");
|
|
542
|
+
return new Response(null, { status: 404 });
|
|
510
543
|
}
|
|
511
|
-
|
|
512
|
-
|
|
544
|
+
init.method = "GET";
|
|
545
|
+
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
546
|
+
return await request(url, init, config);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// src/api/routes/tenants/[tenantId]/DELETE.ts
|
|
550
|
+
async function DELETE2(config, init) {
|
|
551
|
+
const yurl = new URL(init.request.url);
|
|
552
|
+
const [tenantId] = yurl.pathname.split("/").reverse();
|
|
553
|
+
if (!tenantId) {
|
|
554
|
+
return new Response(null, { status: 404 });
|
|
513
555
|
}
|
|
514
|
-
|
|
515
|
-
|
|
556
|
+
init.method = "DELETE";
|
|
557
|
+
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
558
|
+
return await request(url, init, config);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// src/api/routes/tenants/[tenantId]/PUT.ts
|
|
562
|
+
async function PUT3(config, init) {
|
|
563
|
+
const yurl = new URL(init.request.url);
|
|
564
|
+
const [tenantId] = yurl.pathname.split("/").reverse();
|
|
565
|
+
if (!tenantId) {
|
|
566
|
+
return new Response(null, { status: 404 });
|
|
516
567
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
568
|
+
init.body = init.request.body;
|
|
569
|
+
init.method = "PUT";
|
|
570
|
+
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
571
|
+
return await request(url, init, config);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// src/api/routes/tenants/POST.ts
|
|
575
|
+
async function POST3(config, init) {
|
|
576
|
+
init.body = init.request.body;
|
|
577
|
+
init.method = "POST";
|
|
578
|
+
const url = `${apiRoutes(config).TENANTS}`;
|
|
579
|
+
return await request(url, init, config);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// src/api/routes/tenants/index.ts
|
|
583
|
+
var key4 = "TENANTS";
|
|
584
|
+
async function route4(request2, config) {
|
|
585
|
+
const { info } = Logger(
|
|
586
|
+
{ ...config, debug: config.debug },
|
|
587
|
+
`[ROUTES][${key4}]`
|
|
588
|
+
);
|
|
589
|
+
const session = await auth(request2, config);
|
|
590
|
+
if (!session) {
|
|
591
|
+
info("401");
|
|
592
|
+
return new Response(null, { status: 401 });
|
|
593
|
+
}
|
|
594
|
+
const [possibleTenantId] = request2.url.split("/").reverse();
|
|
595
|
+
switch (request2.method) {
|
|
596
|
+
case "GET":
|
|
597
|
+
if (isUUID(possibleTenantId)) {
|
|
598
|
+
return await GET5(config, { request: request2 }, info);
|
|
599
|
+
}
|
|
600
|
+
return await GET4(config, session, { request: request2 });
|
|
601
|
+
case "POST":
|
|
602
|
+
return await POST3(config, { request: request2 });
|
|
603
|
+
case "DELETE":
|
|
604
|
+
return await DELETE2(config, { request: request2 });
|
|
605
|
+
case "PUT":
|
|
606
|
+
return await PUT3(config, { request: request2 });
|
|
607
|
+
default:
|
|
608
|
+
return new Response("method not allowed", { status: 405 });
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
function matches4(configRoutes, request2) {
|
|
612
|
+
return urlMatches(request2.url, configRoutes[key4]);
|
|
613
|
+
}
|
|
614
|
+
async function fetchTenants(config, method, body) {
|
|
615
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
|
|
616
|
+
const init = {
|
|
617
|
+
method,
|
|
618
|
+
headers: config.headers
|
|
619
|
+
};
|
|
620
|
+
{
|
|
621
|
+
init.body = body;
|
|
531
622
|
}
|
|
532
|
-
|
|
533
|
-
|
|
623
|
+
const req = new Request(clientUrl, init);
|
|
624
|
+
return await config.handlers.POST(req);
|
|
625
|
+
}
|
|
626
|
+
async function fetchTenant(config, method, body) {
|
|
627
|
+
if (!config.tenantId) {
|
|
628
|
+
throw new Error(
|
|
629
|
+
'Unable to fetch tenant, the tenantId context is missing. Call nile.setContext({ tenantId }), set nile.tenantId = "tenantId", or add it to the function call'
|
|
630
|
+
);
|
|
534
631
|
}
|
|
535
|
-
|
|
536
|
-
|
|
632
|
+
if (!isUUID(config.tenantId) && config.logger?.warn) {
|
|
633
|
+
config.logger?.warn(
|
|
634
|
+
"nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
635
|
+
);
|
|
537
636
|
}
|
|
538
|
-
|
|
539
|
-
|
|
637
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
|
|
638
|
+
const m = method ?? "GET";
|
|
639
|
+
const init = {
|
|
640
|
+
method: m,
|
|
641
|
+
headers: config.headers
|
|
642
|
+
};
|
|
643
|
+
if (m === "PUT") {
|
|
644
|
+
init.body = body;
|
|
540
645
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
if (
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
"Password is required. Set NILEDB_PASSWORD as an environment variable or set `password` in the config options."
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
this.databaseId = getDatabaseId(envVarConfig);
|
|
559
|
-
this.databaseName = getDatabaseName(envVarConfig);
|
|
560
|
-
this.#tenantId = getTenantId(envVarConfig);
|
|
561
|
-
this.debug = Boolean(config?.debug);
|
|
562
|
-
this.#userId = config?.userId;
|
|
563
|
-
const { host, port, ...dbConfig } = config?.db ?? {};
|
|
564
|
-
const configuredHost = host ?? getDbHost(envVarConfig);
|
|
565
|
-
const configuredPort = port ?? getDbPort(envVarConfig);
|
|
566
|
-
this.api = new ApiConfig(config, logger);
|
|
567
|
-
this.db = {
|
|
568
|
-
user: this.user,
|
|
569
|
-
password: this.password,
|
|
570
|
-
host: configuredHost,
|
|
571
|
-
port: configuredPort,
|
|
572
|
-
...dbConfig
|
|
573
|
-
};
|
|
574
|
-
if (this.databaseName) {
|
|
575
|
-
this.db.database = this.databaseName;
|
|
646
|
+
const req = new Request(clientUrl, init);
|
|
647
|
+
return await config.handlers[m](req);
|
|
648
|
+
}
|
|
649
|
+
async function fetchTenantsByUser(config) {
|
|
650
|
+
if (config.logger?.warn) {
|
|
651
|
+
if (!config.userId) {
|
|
652
|
+
config.logger?.warn(
|
|
653
|
+
"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."
|
|
654
|
+
);
|
|
655
|
+
} else if (!isUUID(config.userId)) {
|
|
656
|
+
config.logger?.warn(
|
|
657
|
+
"nile.userId is not a valid UUID. This may lead to unexpected behavior in your application."
|
|
658
|
+
);
|
|
576
659
|
}
|
|
577
660
|
}
|
|
578
|
-
}
|
|
661
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/users/{userId}/tenants" /* USER_TENANTS */.replace(
|
|
662
|
+
"{userId}",
|
|
663
|
+
config.userId ?? "WARN_NOT_SET"
|
|
664
|
+
)}`;
|
|
665
|
+
const req = new Request(clientUrl, { headers: config.headers });
|
|
666
|
+
return await config.handlers.GET(req);
|
|
667
|
+
}
|
|
579
668
|
|
|
580
|
-
// src/
|
|
581
|
-
var
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
// Subscribe to events
|
|
593
|
-
subscribe(eventName, callback) {
|
|
594
|
-
if (!this.events[eventName]) {
|
|
595
|
-
this.events[eventName] = [];
|
|
596
|
-
}
|
|
597
|
-
this.events[eventName].push(callback);
|
|
598
|
-
}
|
|
599
|
-
// Unsubscribe from an event
|
|
600
|
-
unsubscribe(eventName, callback) {
|
|
601
|
-
const callbackList = this.events[eventName];
|
|
602
|
-
if (!callbackList) {
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
const index = callbackList.indexOf(callback);
|
|
606
|
-
if (index !== -1) {
|
|
607
|
-
callbackList.splice(index, 1);
|
|
608
|
-
}
|
|
609
|
-
if (callbackList.length === 0) {
|
|
610
|
-
delete this.events[eventName];
|
|
611
|
-
}
|
|
669
|
+
// src/api/routes/auth/signin.ts
|
|
670
|
+
var key5 = "SIGNIN";
|
|
671
|
+
async function route5(req, config) {
|
|
672
|
+
let url = proxyRoutes(config)[key5];
|
|
673
|
+
const init = {
|
|
674
|
+
method: req.method,
|
|
675
|
+
headers: req.headers
|
|
676
|
+
};
|
|
677
|
+
if (req.method === "POST") {
|
|
678
|
+
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
679
|
+
url = `${proxyRoutes(config)[key5]}/${provider}`;
|
|
612
680
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
681
|
+
const passThroughUrl = new URL(req.url);
|
|
682
|
+
const params = new URLSearchParams(passThroughUrl.search);
|
|
683
|
+
url = `${url}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
684
|
+
const res = await request(url, { ...init, request: req }, config);
|
|
685
|
+
return res;
|
|
686
|
+
}
|
|
687
|
+
function matches5(configRoutes, request2) {
|
|
688
|
+
return urlMatches(request2.url, configRoutes[key5]);
|
|
689
|
+
}
|
|
690
|
+
async function fetchSignIn(config, provider, body) {
|
|
691
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
|
|
692
|
+
const req = new Request(clientUrl, {
|
|
693
|
+
method: "POST",
|
|
694
|
+
headers: config.headers,
|
|
695
|
+
body
|
|
696
|
+
});
|
|
697
|
+
return await config.handlers.POST(req);
|
|
698
|
+
}
|
|
628
699
|
|
|
629
|
-
// src/
|
|
630
|
-
function
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
info("query", ...args);
|
|
649
|
-
const called = caller.apply(this, args);
|
|
650
|
-
return called;
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
return target[property];
|
|
654
|
-
}
|
|
700
|
+
// src/api/routes/auth/session.ts
|
|
701
|
+
async function route6(req, config) {
|
|
702
|
+
return request(
|
|
703
|
+
proxyRoutes(config).SESSION,
|
|
704
|
+
{
|
|
705
|
+
method: req.method,
|
|
706
|
+
request: req
|
|
707
|
+
},
|
|
708
|
+
config
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
function matches6(configRoutes, request2) {
|
|
712
|
+
return urlMatches(request2.url, configRoutes.SESSION);
|
|
713
|
+
}
|
|
714
|
+
async function fetchSession(config) {
|
|
715
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
|
|
716
|
+
const req = new Request(clientUrl, {
|
|
717
|
+
method: "GET",
|
|
718
|
+
headers: config.headers
|
|
655
719
|
});
|
|
720
|
+
return await config.handlers.GET(req);
|
|
656
721
|
}
|
|
657
722
|
|
|
658
|
-
// src/
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
config.
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
723
|
+
// src/api/routes/auth/providers.ts
|
|
724
|
+
async function route7(req, config) {
|
|
725
|
+
return request(
|
|
726
|
+
proxyRoutes(config).PROVIDERS,
|
|
727
|
+
{
|
|
728
|
+
method: req.method,
|
|
729
|
+
request: req
|
|
730
|
+
},
|
|
731
|
+
config
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
function matches7(configRoutes, request2) {
|
|
735
|
+
return urlMatches(request2.url, configRoutes.PROVIDERS);
|
|
736
|
+
}
|
|
737
|
+
async function fetchProviders(config) {
|
|
738
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
|
|
739
|
+
const req = new Request(clientUrl, {
|
|
740
|
+
method: "GET",
|
|
741
|
+
headers: config.headers
|
|
742
|
+
});
|
|
743
|
+
return await config.handlers.GET(req);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// src/api/routes/auth/csrf.ts
|
|
747
|
+
async function route8(req, config) {
|
|
748
|
+
return request(
|
|
749
|
+
proxyRoutes(config).CSRF,
|
|
750
|
+
{
|
|
751
|
+
method: req.method,
|
|
752
|
+
request: req
|
|
753
|
+
},
|
|
754
|
+
config
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
function matches8(configRoutes, request2) {
|
|
758
|
+
return urlMatches(request2.url, configRoutes.CSRF);
|
|
759
|
+
}
|
|
760
|
+
async function fetchCsrf(config) {
|
|
761
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
|
|
762
|
+
const req = new Request(clientUrl, {
|
|
763
|
+
method: "GET",
|
|
764
|
+
headers: config.headers
|
|
765
|
+
});
|
|
766
|
+
return await config.handlers.GET(req);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// src/api/routes/auth/callback.ts
|
|
770
|
+
var key6 = "CALLBACK";
|
|
771
|
+
async function route9(req, config) {
|
|
772
|
+
const { error } = Logger(
|
|
773
|
+
{ ...config, debug: config.debug },
|
|
774
|
+
`[ROUTES][${key6}]`
|
|
775
|
+
);
|
|
776
|
+
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
777
|
+
try {
|
|
778
|
+
const passThroughUrl = new URL(req.url);
|
|
779
|
+
const params = new URLSearchParams(passThroughUrl.search);
|
|
780
|
+
const url = `${proxyRoutes(config)[key6]}/${provider}${params.toString() !== "" ? `?${params.toString()}` : ""}`;
|
|
781
|
+
const res = await request(
|
|
782
|
+
url,
|
|
783
|
+
{
|
|
784
|
+
request: req,
|
|
785
|
+
method: req.method
|
|
786
|
+
},
|
|
787
|
+
config
|
|
788
|
+
).catch((e) => {
|
|
789
|
+
error("an error as occurred", e);
|
|
706
790
|
});
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
791
|
+
const location = res?.headers.get("location");
|
|
792
|
+
if (location) {
|
|
793
|
+
return new Response(res?.body, {
|
|
794
|
+
status: 302,
|
|
795
|
+
headers: res?.headers
|
|
712
796
|
});
|
|
713
|
-
evictPool(this.id);
|
|
714
|
-
});
|
|
715
|
-
this.pool.on("release", (destroy) => {
|
|
716
|
-
if (destroy) {
|
|
717
|
-
clearTimeout(this.timer);
|
|
718
|
-
evictPool(this.id);
|
|
719
|
-
debug(`destroying pool ${this.id}`);
|
|
720
|
-
}
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
|
-
startTimeout() {
|
|
724
|
-
const { debug } = Logger(this.config, "[NileInstance]");
|
|
725
|
-
if (this.timer) {
|
|
726
|
-
clearTimeout(this.timer);
|
|
727
797
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
);
|
|
732
|
-
this.pool.end(() => {
|
|
733
|
-
clearTimeout(this.timer);
|
|
734
|
-
evictPool(this.id);
|
|
735
|
-
});
|
|
736
|
-
}, Number(this.config.db.idleTimeoutMillis) ?? 3e4);
|
|
737
|
-
}
|
|
738
|
-
shutdown() {
|
|
739
|
-
const { debug } = Logger(this.config, "[NileInstance]");
|
|
740
|
-
debug(`attempting to shut down ${this.id}`);
|
|
741
|
-
clearTimeout(this.timer);
|
|
742
|
-
this.pool.end(() => {
|
|
743
|
-
debug(`${this.id} has been shut down`);
|
|
798
|
+
return new Response(res?.body, {
|
|
799
|
+
status: res?.status,
|
|
800
|
+
headers: res?.headers
|
|
744
801
|
});
|
|
802
|
+
} catch (e) {
|
|
803
|
+
error(e);
|
|
745
804
|
}
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
function
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
const query = [`SET nile.tenant_id = '${config.tenantId}'`];
|
|
760
|
-
if (config.userId) {
|
|
761
|
-
if (!config.tenantId) {
|
|
762
|
-
warn("A user id cannot be set in context without a tenant id");
|
|
763
|
-
}
|
|
764
|
-
query.push(`SET nile.user_id = '${config.userId}'`);
|
|
765
|
-
}
|
|
766
|
-
conn.query(query.join(";"), function(err) {
|
|
767
|
-
if (err) {
|
|
768
|
-
error("query connection failed", {
|
|
769
|
-
cause: err.cause,
|
|
770
|
-
stack: err.stack,
|
|
771
|
-
message: err.message,
|
|
772
|
-
name: err.name,
|
|
773
|
-
id
|
|
774
|
-
});
|
|
775
|
-
} else {
|
|
776
|
-
if (query.length === 1) {
|
|
777
|
-
debug(`connection context set: tenantId=${config.tenantId}`);
|
|
778
|
-
}
|
|
779
|
-
if (query.length === 2) {
|
|
780
|
-
debug(
|
|
781
|
-
`connection context set: tenantId=${config.tenantId} userId=${config.userId}`
|
|
782
|
-
);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
done(err, conn);
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
done(null, conn);
|
|
789
|
-
};
|
|
805
|
+
return new Response("An unexpected error has occurred.", { status: 400 });
|
|
806
|
+
}
|
|
807
|
+
function matches9(configRoutes, request2) {
|
|
808
|
+
return urlMatches(request2.url, configRoutes.CALLBACK);
|
|
809
|
+
}
|
|
810
|
+
async function fetchCallback(config, provider, body, request2, method = "POST") {
|
|
811
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
|
|
812
|
+
const req = new Request(clientUrl, {
|
|
813
|
+
method,
|
|
814
|
+
headers: config.headers,
|
|
815
|
+
body
|
|
816
|
+
});
|
|
817
|
+
return await config.handlers.POST(req);
|
|
790
818
|
}
|
|
791
819
|
|
|
792
|
-
// src/
|
|
793
|
-
var
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
if (tenantId && userId) {
|
|
799
|
-
return `${tenantId}:${userId}`;
|
|
800
|
-
}
|
|
801
|
-
if (tenantId) {
|
|
802
|
-
return `${tenantId}`;
|
|
803
|
-
}
|
|
804
|
-
return "base";
|
|
805
|
-
}
|
|
806
|
-
constructor(config) {
|
|
807
|
-
this.cleared = false;
|
|
808
|
-
this.connections = /* @__PURE__ */ new Map();
|
|
809
|
-
this.poolWatcherFn = this.poolWatcher(config);
|
|
810
|
-
watchEvictPool(this.poolWatcherFn);
|
|
811
|
-
}
|
|
812
|
-
poolWatcher = (config) => (id) => {
|
|
813
|
-
const { info, warn } = Logger(config, "[DBManager]");
|
|
814
|
-
if (id && this.connections.has(id)) {
|
|
815
|
-
info(`Removing ${id} from db connection pool.`);
|
|
816
|
-
const connection = this.connections.get(id);
|
|
817
|
-
connection?.shutdown();
|
|
818
|
-
this.connections.delete(id);
|
|
819
|
-
} else {
|
|
820
|
-
warn(`missed eviction of ${id}`);
|
|
821
|
-
}
|
|
822
|
-
};
|
|
823
|
-
getConnection = (config) => {
|
|
824
|
-
const { info } = Logger(config, "[DBManager]");
|
|
825
|
-
const id = this.makeId(config.tenantId, config.userId);
|
|
826
|
-
const existing = this.connections.get(id);
|
|
827
|
-
info(`# of instances: ${this.connections.size}`);
|
|
828
|
-
if (existing) {
|
|
829
|
-
info(`returning existing ${id}`);
|
|
830
|
-
existing.startTimeout();
|
|
831
|
-
return existing.pool;
|
|
832
|
-
}
|
|
833
|
-
const newOne = new NileInstance_default(new Config(config), id);
|
|
834
|
-
this.connections.set(id, newOne);
|
|
835
|
-
info(`created new ${id}`);
|
|
836
|
-
info(`# of instances: ${this.connections.size}`);
|
|
837
|
-
if (this.cleared) {
|
|
838
|
-
this.cleared = false;
|
|
839
|
-
}
|
|
840
|
-
return newOne.pool;
|
|
841
|
-
};
|
|
842
|
-
clear = (config) => {
|
|
843
|
-
const { info } = Logger(config, "[DBManager]");
|
|
844
|
-
info(`Clearing all connections ${this.connections.size}`);
|
|
845
|
-
this.cleared = true;
|
|
846
|
-
this.connections.forEach((connection) => {
|
|
847
|
-
connection.shutdown();
|
|
848
|
-
});
|
|
849
|
-
this.connections.clear();
|
|
820
|
+
// src/api/routes/auth/signout.ts
|
|
821
|
+
var key7 = "SIGNOUT";
|
|
822
|
+
async function route10(request2, config) {
|
|
823
|
+
let url = proxyRoutes(config)[key7];
|
|
824
|
+
const init = {
|
|
825
|
+
method: request2.method
|
|
850
826
|
};
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
function filterNullUndefined(obj) {
|
|
856
|
-
if (!obj) {
|
|
857
|
-
return void 0;
|
|
827
|
+
if (request2.method === "POST") {
|
|
828
|
+
init.body = request2.body;
|
|
829
|
+
const [provider] = new URL(request2.url).pathname.split("/").reverse();
|
|
830
|
+
url = `${proxyRoutes(config)[key7]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
858
831
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
([, value]) => value !== null && value !== void 0
|
|
862
|
-
)
|
|
863
|
-
);
|
|
832
|
+
const res = await request(url, { ...init, request: request2 }, config);
|
|
833
|
+
return res;
|
|
864
834
|
}
|
|
865
|
-
function
|
|
866
|
-
|
|
867
|
-
if (!url) {
|
|
868
|
-
throw new Error(
|
|
869
|
-
"An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?"
|
|
870
|
-
);
|
|
871
|
-
}
|
|
872
|
-
const params = new URLSearchParams(
|
|
873
|
-
filterNullUndefined(qp)
|
|
874
|
-
);
|
|
875
|
-
const strParams = params.toString();
|
|
876
|
-
return `${[url, path.substring(1, path.length)].join("/")}${strParams ? `?${strParams}` : ""}`;
|
|
835
|
+
function matches10(configRoutes, request2) {
|
|
836
|
+
return urlMatches(request2.url, configRoutes[key7]);
|
|
877
837
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
SIGNUP: makeRestUrl(config, "/signup"),
|
|
887
|
-
TENANT_USERS: (tenantId) => makeRestUrl(config, `/tenants/${tenantId}/users`),
|
|
888
|
-
TENANT_USER: (tenantId, userId) => makeRestUrl(config, `/tenants/${tenantId}/users/${userId}`),
|
|
889
|
-
USER_TENANTS: (userId) => makeRestUrl(config, `/users/${userId}/tenants`)
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
// src/api/routes/me/index.ts
|
|
893
|
-
var key = "ME";
|
|
894
|
-
async function GET(url, init, config) {
|
|
895
|
-
const res = await request(url, init, config);
|
|
896
|
-
return res;
|
|
838
|
+
async function fetchSignOut(config, body) {
|
|
839
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
|
|
840
|
+
const req = new Request(clientUrl, {
|
|
841
|
+
method: "POST",
|
|
842
|
+
body,
|
|
843
|
+
headers: config.headers
|
|
844
|
+
});
|
|
845
|
+
return await config.handlers.POST(req);
|
|
897
846
|
}
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
847
|
+
|
|
848
|
+
// src/api/routes/auth/error.ts
|
|
849
|
+
var key8 = "ERROR";
|
|
850
|
+
async function route11(req, config) {
|
|
851
|
+
return request(
|
|
852
|
+
proxyRoutes(config)[key8],
|
|
853
|
+
{
|
|
854
|
+
method: req.method,
|
|
855
|
+
request: req
|
|
856
|
+
},
|
|
857
|
+
config
|
|
858
|
+
);
|
|
906
859
|
}
|
|
907
|
-
function
|
|
908
|
-
return urlMatches(request2.url, configRoutes[
|
|
860
|
+
function matches11(configRoutes, request2) {
|
|
861
|
+
return urlMatches(request2.url, configRoutes[key8]);
|
|
909
862
|
}
|
|
910
863
|
|
|
911
|
-
// src/
|
|
912
|
-
var
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
864
|
+
// src/api/routes/auth/verify-request.ts
|
|
865
|
+
var key9 = "VERIFY_REQUEST";
|
|
866
|
+
async function route12(req, config) {
|
|
867
|
+
return request(
|
|
868
|
+
proxyRoutes(config)[key9],
|
|
869
|
+
{
|
|
870
|
+
method: req.method,
|
|
871
|
+
request: req
|
|
872
|
+
},
|
|
873
|
+
config
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
function matches12(configRoutes, request2) {
|
|
877
|
+
return urlMatches(request2.url, configRoutes[key9]);
|
|
878
|
+
}
|
|
918
879
|
|
|
919
|
-
// src/
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
if (cookieKey) {
|
|
940
|
-
return _cookies[cookieKey];
|
|
880
|
+
// src/api/routes/auth/password-reset.ts
|
|
881
|
+
var key10 = "PASSWORD_RESET";
|
|
882
|
+
async function route13(req, config) {
|
|
883
|
+
const url = proxyRoutes(config)[key10];
|
|
884
|
+
const res = await request(
|
|
885
|
+
url,
|
|
886
|
+
{
|
|
887
|
+
method: req.method,
|
|
888
|
+
request: req
|
|
889
|
+
},
|
|
890
|
+
config
|
|
891
|
+
);
|
|
892
|
+
const location = res?.headers.get("location");
|
|
893
|
+
if (location) {
|
|
894
|
+
return new Response(res?.body, {
|
|
895
|
+
status: 302,
|
|
896
|
+
headers: res?.headers
|
|
897
|
+
});
|
|
941
898
|
}
|
|
942
|
-
return
|
|
899
|
+
return new Response(res?.body, {
|
|
900
|
+
status: res?.status,
|
|
901
|
+
headers: res?.headers
|
|
902
|
+
});
|
|
943
903
|
}
|
|
944
|
-
function
|
|
945
|
-
|
|
946
|
-
return cookieTenant ?? headers?.get(X_NILE_TENANT) ?? config?.tenantId;
|
|
904
|
+
function matches13(configRoutes, request2) {
|
|
905
|
+
return urlMatches(request2.url, configRoutes.PASSWORD_RESET);
|
|
947
906
|
}
|
|
948
|
-
function
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
const headers = new Headers(opts?.headers);
|
|
959
|
-
headers.set("content-type", "application/json; charset=utf-8");
|
|
960
|
-
const cookieKey = config.api?.cookieKey;
|
|
961
|
-
const authHeader = headers.get("Authorization");
|
|
962
|
-
if (!authHeader) {
|
|
963
|
-
const token = getTokenFromCookie(headers, cookieKey);
|
|
964
|
-
if (token) {
|
|
965
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
966
|
-
} else if (getToken({ config })) {
|
|
967
|
-
headers.set("Authorization", `Bearer ${getToken({ config })}`);
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
const cookie = headers.get("cookie");
|
|
971
|
-
if (!cookie) {
|
|
972
|
-
const contextCookie = getCookie();
|
|
973
|
-
if (contextCookie) {
|
|
974
|
-
headers.set("cookie", contextCookie);
|
|
975
|
-
} else {
|
|
976
|
-
if (!url.endsWith("/users")) {
|
|
977
|
-
error(
|
|
978
|
-
"Missing cookie header from request. Call nile.api.setContext(request) before making additional calls."
|
|
979
|
-
);
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
if (config && config.api.secureCookies != null) {
|
|
984
|
-
headers.set(X_NILE_SECURECOOKIES, String(config.api.secureCookies));
|
|
907
|
+
async function fetchResetPassword(config, method, body, params) {
|
|
908
|
+
const authParams = new URLSearchParams(params ?? {});
|
|
909
|
+
authParams?.set("json", "true");
|
|
910
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
|
|
911
|
+
const init = {
|
|
912
|
+
method,
|
|
913
|
+
headers: config.headers
|
|
914
|
+
};
|
|
915
|
+
if (body && method !== "GET") {
|
|
916
|
+
init.body = body;
|
|
985
917
|
}
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
const
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
if (url.includes("{tenantId}") && !tenantId) {
|
|
1008
|
-
return new ResponseError("tenantId is not set for request", {
|
|
1009
|
-
status: 400
|
|
918
|
+
const req = new Request(clientUrl, init);
|
|
919
|
+
return await config.handlers[method](req);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
// src/api/routes/auth/verify-email.ts
|
|
923
|
+
var key11 = "VERIFY_EMAIL";
|
|
924
|
+
async function route14(req, config) {
|
|
925
|
+
const url = proxyRoutes(config)[key11];
|
|
926
|
+
const res = await request(
|
|
927
|
+
url,
|
|
928
|
+
{
|
|
929
|
+
method: req.method,
|
|
930
|
+
request: req
|
|
931
|
+
},
|
|
932
|
+
config
|
|
933
|
+
);
|
|
934
|
+
const location = res?.headers.get("location");
|
|
935
|
+
if (location) {
|
|
936
|
+
return new Response(res?.body, {
|
|
937
|
+
status: 302,
|
|
938
|
+
headers: res?.headers
|
|
1010
939
|
});
|
|
1011
940
|
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
941
|
+
return new Response(res?.body, {
|
|
942
|
+
status: res?.status,
|
|
943
|
+
headers: res?.headers
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
function matches14(configRoutes, request2) {
|
|
947
|
+
return urlMatches(request2.url, configRoutes[key11]);
|
|
948
|
+
}
|
|
949
|
+
async function fetchVerifyEmail(config, method, body) {
|
|
950
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
|
|
951
|
+
const init = {
|
|
952
|
+
method,
|
|
953
|
+
headers: config.headers
|
|
954
|
+
};
|
|
955
|
+
if (body) {
|
|
956
|
+
init.body = body;
|
|
957
|
+
}
|
|
958
|
+
const req = new Request(clientUrl, init);
|
|
959
|
+
return await config.handlers[method](req);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// src/api/handlers/GET.ts
|
|
963
|
+
function GETTER(configRoutes, config) {
|
|
964
|
+
const { info, warn } = Logger(config, "[GET MATCHER]");
|
|
965
|
+
return async function GET6(req) {
|
|
966
|
+
if (matches(configRoutes, req)) {
|
|
967
|
+
info("matches me");
|
|
968
|
+
return route(req, config);
|
|
1030
969
|
}
|
|
1031
|
-
if (
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
debug(
|
|
1035
|
-
`[fetch][response][${opts?.method ?? "GET"}] ${response.status} ${useableUrl}`,
|
|
1036
|
-
{
|
|
1037
|
-
body: await response.clone().json()
|
|
1038
|
-
}
|
|
1039
|
-
);
|
|
1040
|
-
} catch (e) {
|
|
1041
|
-
debug(
|
|
1042
|
-
`[fetch][response][${opts?.method ?? "GET"}] ${response.status} ${useableUrl}`,
|
|
1043
|
-
{
|
|
1044
|
-
body: await response.clone().text()
|
|
1045
|
-
}
|
|
1046
|
-
);
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
return response;
|
|
970
|
+
if (matches3(configRoutes, req)) {
|
|
971
|
+
info("matches tenant users");
|
|
972
|
+
return route3(req, config);
|
|
1050
973
|
}
|
|
1051
|
-
if (
|
|
1052
|
-
|
|
974
|
+
if (matches2(configRoutes, req)) {
|
|
975
|
+
info("matches users");
|
|
976
|
+
return route2(req, config);
|
|
1053
977
|
}
|
|
1054
|
-
if (
|
|
1055
|
-
|
|
978
|
+
if (matches4(configRoutes, req)) {
|
|
979
|
+
info("matches tenants");
|
|
980
|
+
return route4(req, config);
|
|
1056
981
|
}
|
|
1057
|
-
if (
|
|
1058
|
-
|
|
982
|
+
if (matches6(configRoutes, req)) {
|
|
983
|
+
info("matches session");
|
|
984
|
+
return route6(req, config);
|
|
1059
985
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
return
|
|
1079
|
-
}
|
|
1080
|
-
if (
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
return
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
}
|
|
1098
|
-
);
|
|
1099
|
-
return new ResponseError(null, {
|
|
1100
|
-
status: response?.status ?? 500
|
|
1101
|
-
});
|
|
1102
|
-
} catch (e) {
|
|
1103
|
-
return new ResponseError("an unexpected error has occurred", {
|
|
1104
|
-
status: 500
|
|
1105
|
-
});
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// src/api/routes/users/POST.ts
|
|
1110
|
-
async function POST(config, init) {
|
|
1111
|
-
init.body = init.request.body;
|
|
1112
|
-
init.method = "POST";
|
|
1113
|
-
const yurl = new URL(init.request.url);
|
|
1114
|
-
const tenantId = yurl.searchParams.get("tenantId");
|
|
1115
|
-
const newTenantName = yurl.searchParams.get("newTenantName");
|
|
1116
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
1117
|
-
const url = apiRoutes(config).USERS({ tenantId: tenant, newTenantName });
|
|
1118
|
-
return await request(url, init, config);
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
// src/api/routes/users/GET.ts
|
|
1122
|
-
async function GET2(config, init, log) {
|
|
1123
|
-
const yurl = new URL(init.request.url);
|
|
1124
|
-
const tenantId = yurl.searchParams.get("tenantId");
|
|
1125
|
-
const tenant = tenantId ?? getTenantFromHttp(init.request.headers);
|
|
1126
|
-
if (!tenant) {
|
|
1127
|
-
log("[GET] No tenant id provided.");
|
|
986
|
+
if (matches5(configRoutes, req)) {
|
|
987
|
+
info("matches signin");
|
|
988
|
+
return route5(req, config);
|
|
989
|
+
}
|
|
990
|
+
if (matches7(configRoutes, req)) {
|
|
991
|
+
info("matches providers");
|
|
992
|
+
return route7(req, config);
|
|
993
|
+
}
|
|
994
|
+
if (matches8(configRoutes, req)) {
|
|
995
|
+
info("matches csrf");
|
|
996
|
+
return route8(req, config);
|
|
997
|
+
}
|
|
998
|
+
if (matches13(configRoutes, req)) {
|
|
999
|
+
info("matches password reset");
|
|
1000
|
+
return route13(req, config);
|
|
1001
|
+
}
|
|
1002
|
+
if (matches9(configRoutes, req)) {
|
|
1003
|
+
info("matches callback");
|
|
1004
|
+
return route9(req, config);
|
|
1005
|
+
}
|
|
1006
|
+
if (matches10(configRoutes, req)) {
|
|
1007
|
+
info("matches signout");
|
|
1008
|
+
return route10(req, config);
|
|
1009
|
+
}
|
|
1010
|
+
if (matches12(configRoutes, req)) {
|
|
1011
|
+
info("matches verify-request");
|
|
1012
|
+
return route12(req, config);
|
|
1013
|
+
}
|
|
1014
|
+
if (matches14(configRoutes, req)) {
|
|
1015
|
+
info("matches verify-email");
|
|
1016
|
+
return route14(req, config);
|
|
1017
|
+
}
|
|
1018
|
+
if (matches11(configRoutes, req)) {
|
|
1019
|
+
info("matches error");
|
|
1020
|
+
return route11(req, config);
|
|
1021
|
+
}
|
|
1022
|
+
warn(`No GET routes matched ${req.url}`);
|
|
1128
1023
|
return new Response(null, { status: 404 });
|
|
1129
|
-
}
|
|
1130
|
-
const url = apiRoutes(config).TENANT_USERS(tenant);
|
|
1131
|
-
init.method = "GET";
|
|
1132
|
-
return await request(url, init, config);
|
|
1024
|
+
};
|
|
1133
1025
|
}
|
|
1134
1026
|
|
|
1135
|
-
// src/api/routes/
|
|
1136
|
-
async function
|
|
1137
|
-
if (!session) {
|
|
1138
|
-
return new Response(null, { status: 401 });
|
|
1139
|
-
}
|
|
1027
|
+
// src/api/routes/signup/POST.ts
|
|
1028
|
+
async function POST4(config, init) {
|
|
1140
1029
|
init.body = init.request.body;
|
|
1141
|
-
init.method = "
|
|
1142
|
-
const
|
|
1143
|
-
const url = apiRoutes(config).USER(userId);
|
|
1030
|
+
init.method = "POST";
|
|
1031
|
+
const url = `${apiRoutes(config).SIGNUP}`;
|
|
1144
1032
|
return await request(url, init, config);
|
|
1145
1033
|
}
|
|
1146
1034
|
|
|
1147
|
-
// src/api/routes/
|
|
1148
|
-
var
|
|
1149
|
-
async function
|
|
1150
|
-
const { info } = Logger(
|
|
1151
|
-
{ ...config, debug: config.debug },
|
|
1152
|
-
`[ROUTES][${key2}]`
|
|
1153
|
-
);
|
|
1154
|
-
const session = await auth(request2, config);
|
|
1035
|
+
// src/api/routes/signup/index.tsx
|
|
1036
|
+
var key12 = "SIGNUP";
|
|
1037
|
+
async function route15(request2, config) {
|
|
1155
1038
|
switch (request2.method) {
|
|
1156
|
-
case "GET":
|
|
1157
|
-
return await GET2(config, { request: request2 }, info);
|
|
1158
1039
|
case "POST":
|
|
1159
|
-
return await
|
|
1160
|
-
case "PUT":
|
|
1161
|
-
return await PUT(config, session, { request: request2 });
|
|
1040
|
+
return await POST4(config, { request: request2 });
|
|
1162
1041
|
default:
|
|
1163
1042
|
return new Response("method not allowed", { status: 405 });
|
|
1164
1043
|
}
|
|
1165
1044
|
}
|
|
1166
|
-
function
|
|
1167
|
-
return urlMatches(request2.url, configRoutes[
|
|
1045
|
+
function matches15(configRoutes, request2) {
|
|
1046
|
+
return urlMatches(request2.url, configRoutes[key12]);
|
|
1168
1047
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1048
|
+
async function fetchSignUp(config, payload) {
|
|
1049
|
+
const { body, params } = payload ?? {};
|
|
1050
|
+
const q = new URLSearchParams();
|
|
1051
|
+
if (params?.newTenantName) {
|
|
1052
|
+
q.set("newTenantName", params.newTenantName);
|
|
1053
|
+
}
|
|
1054
|
+
if (params?.tenantId) {
|
|
1055
|
+
q.set("tenantId", params.tenantId);
|
|
1056
|
+
}
|
|
1057
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
|
|
1058
|
+
const req = new Request(clientUrl, {
|
|
1059
|
+
method: "POST",
|
|
1060
|
+
headers: config.headers,
|
|
1061
|
+
body
|
|
1062
|
+
});
|
|
1063
|
+
return await config.handlers.POST(req);
|
|
1176
1064
|
}
|
|
1177
1065
|
|
|
1178
|
-
// src/api/
|
|
1179
|
-
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1066
|
+
// src/api/handlers/POST.ts
|
|
1067
|
+
function POSTER(configRoutes, config) {
|
|
1068
|
+
const { info, warn, error } = Logger(config, "[POST MATCHER]");
|
|
1069
|
+
return async function POST5(req) {
|
|
1070
|
+
if (matchesLog(configRoutes, req)) {
|
|
1071
|
+
try {
|
|
1072
|
+
const json = await req.clone().json();
|
|
1073
|
+
error(req.body && json);
|
|
1074
|
+
} catch {
|
|
1075
|
+
error(await req.text());
|
|
1076
|
+
}
|
|
1077
|
+
return new Response(null, { status: 200 });
|
|
1078
|
+
}
|
|
1079
|
+
if (matches3(configRoutes, req)) {
|
|
1080
|
+
info("matches tenant users");
|
|
1081
|
+
return route3(req, config);
|
|
1082
|
+
}
|
|
1083
|
+
if (matches15(configRoutes, req)) {
|
|
1084
|
+
info("matches signup");
|
|
1085
|
+
return route15(req, config);
|
|
1086
|
+
}
|
|
1087
|
+
if (matches2(configRoutes, req)) {
|
|
1088
|
+
info("matches users");
|
|
1089
|
+
return route2(req, config);
|
|
1090
|
+
}
|
|
1091
|
+
if (matches4(configRoutes, req)) {
|
|
1092
|
+
info("matches tenants");
|
|
1093
|
+
return route4(req, config);
|
|
1094
|
+
}
|
|
1095
|
+
if (matches6(configRoutes, req)) {
|
|
1096
|
+
info("matches session");
|
|
1097
|
+
return route6(req, config);
|
|
1098
|
+
}
|
|
1099
|
+
if (matches5(configRoutes, req)) {
|
|
1100
|
+
info("matches signin");
|
|
1101
|
+
return route5(req, config);
|
|
1102
|
+
}
|
|
1103
|
+
if (matches13(configRoutes, req)) {
|
|
1104
|
+
info("matches password reset");
|
|
1105
|
+
return route13(req, config);
|
|
1106
|
+
}
|
|
1107
|
+
if (matches7(configRoutes, req)) {
|
|
1108
|
+
info("matches providers");
|
|
1109
|
+
return route7(req, config);
|
|
1110
|
+
}
|
|
1111
|
+
if (matches8(configRoutes, req)) {
|
|
1112
|
+
info("matches csrf");
|
|
1113
|
+
return route8(req, config);
|
|
1114
|
+
}
|
|
1115
|
+
if (matches9(configRoutes, req)) {
|
|
1116
|
+
info("matches callback");
|
|
1117
|
+
return route9(req, config);
|
|
1118
|
+
}
|
|
1119
|
+
if (matches10(configRoutes, req)) {
|
|
1120
|
+
info("matches signout");
|
|
1121
|
+
return route10(req, config);
|
|
1122
|
+
}
|
|
1123
|
+
if (matches14(configRoutes, req)) {
|
|
1124
|
+
info("matches verify-email");
|
|
1125
|
+
return route14(req, config);
|
|
1126
|
+
}
|
|
1127
|
+
warn(`No POST routes matched ${req.url}`);
|
|
1128
|
+
return new Response(null, { status: 404 });
|
|
1129
|
+
};
|
|
1186
1130
|
}
|
|
1187
1131
|
|
|
1188
1132
|
// src/api/routes/tenants/[tenantId]/users/[userId]/DELETE.ts
|
|
1189
|
-
async function
|
|
1133
|
+
async function DELETE3(config, init) {
|
|
1190
1134
|
const yurl = new URL(init.request.url);
|
|
1191
|
-
const [userId,
|
|
1135
|
+
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1136
|
+
config.tenantId = tenantId;
|
|
1137
|
+
config.userId = userId;
|
|
1192
1138
|
init.method = "DELETE";
|
|
1193
|
-
|
|
1194
|
-
const url = `${apiRoutes(config).TENANT_USER(tenantId, userId)}`;
|
|
1139
|
+
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1195
1140
|
return await request(url, init, config);
|
|
1196
1141
|
}
|
|
1197
1142
|
|
|
1198
|
-
// src/api/routes/tenants/[tenantId]/users/PUT.ts
|
|
1199
|
-
async function
|
|
1143
|
+
// src/api/routes/tenants/[tenantId]/users/[userId]/PUT.ts
|
|
1144
|
+
async function PUT4(config, init) {
|
|
1200
1145
|
const yurl = new URL(init.request.url);
|
|
1201
|
-
const [, tenantId] = yurl.pathname.split("/").reverse();
|
|
1146
|
+
const [, userId, , tenantId] = yurl.pathname.split("/").reverse();
|
|
1147
|
+
config.tenantId = tenantId;
|
|
1148
|
+
config.userId = userId;
|
|
1202
1149
|
init.method = "PUT";
|
|
1203
|
-
const url = `${apiRoutes(config).
|
|
1150
|
+
const url = `${apiRoutes(config).TENANT_USER}/link`;
|
|
1204
1151
|
return await request(url, init, config);
|
|
1205
1152
|
}
|
|
1206
1153
|
|
|
1207
|
-
// src/api/routes/tenants/[tenantId]/users/index.ts
|
|
1208
|
-
var
|
|
1209
|
-
async function
|
|
1154
|
+
// src/api/routes/tenants/[tenantId]/users/[userId]/index.ts
|
|
1155
|
+
var key13 = "TENANT_USER";
|
|
1156
|
+
async function route16(request2, config) {
|
|
1210
1157
|
const { info } = Logger(
|
|
1211
1158
|
{ ...config, debug: config.debug },
|
|
1212
|
-
`[ROUTES][${
|
|
1159
|
+
`[ROUTES][${key13}]`
|
|
1213
1160
|
);
|
|
1214
1161
|
const session = await auth(request2, config);
|
|
1215
1162
|
if (!session) {
|
|
@@ -1217,760 +1164,1019 @@ async function route3(request2, config) {
|
|
|
1217
1164
|
return new Response(null, { status: 401 });
|
|
1218
1165
|
}
|
|
1219
1166
|
const yurl = new URL(request2.url);
|
|
1220
|
-
const [,
|
|
1221
|
-
if (!
|
|
1167
|
+
const [, userId] = yurl.pathname.split("/").reverse();
|
|
1168
|
+
if (!userId) {
|
|
1222
1169
|
info("No tenant id found in path");
|
|
1223
1170
|
return new Response(null, { status: 404 });
|
|
1224
1171
|
}
|
|
1225
1172
|
switch (request2.method) {
|
|
1226
|
-
case "GET":
|
|
1227
|
-
return await GET3(config, { request: request2 });
|
|
1228
|
-
case "POST":
|
|
1229
|
-
return await POST2(config, session, { request: request2 });
|
|
1230
1173
|
case "PUT":
|
|
1231
|
-
return await
|
|
1174
|
+
return await PUT4(config, { request: request2 });
|
|
1232
1175
|
case "DELETE":
|
|
1233
|
-
return await
|
|
1176
|
+
return await DELETE3(config, { request: request2 });
|
|
1234
1177
|
default:
|
|
1235
1178
|
return new Response("method not allowed", { status: 405 });
|
|
1236
1179
|
}
|
|
1237
1180
|
}
|
|
1238
|
-
function
|
|
1181
|
+
function matches16(configRoutes, request2) {
|
|
1239
1182
|
const url = new URL(request2.url);
|
|
1240
|
-
const [userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
|
|
1241
|
-
let
|
|
1183
|
+
const [, userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
|
|
1184
|
+
let route17 = configRoutes[key13].replace("{tenantId}", tenantId).replace("{userId}", userId);
|
|
1242
1185
|
if (userId === "users") {
|
|
1243
|
-
|
|
1186
|
+
route17 = configRoutes[key13].replace("{tenantId}", possibleTenantId);
|
|
1244
1187
|
}
|
|
1245
|
-
return urlMatches(request2.url,
|
|
1188
|
+
return urlMatches(request2.url, route17);
|
|
1246
1189
|
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
url = `${apiRoutes(config).USER_TENANTS(session.user.id)}`;
|
|
1190
|
+
async function fetchTenantUser(config, method) {
|
|
1191
|
+
if (!config.tenantId) {
|
|
1192
|
+
throw new Error(
|
|
1193
|
+
"The tenantId context is missing. Call nile.setContext({ tenantId })"
|
|
1194
|
+
);
|
|
1253
1195
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
// src/api/routes/tenants/[tenantId]/GET.ts
|
|
1259
|
-
async function GET5(config, init, log) {
|
|
1260
|
-
const yurl = new URL(init.request.url);
|
|
1261
|
-
const [tenantId] = yurl.pathname.split("/").reverse();
|
|
1262
|
-
if (!tenantId) {
|
|
1263
|
-
log("[GET] No tenant id provided.");
|
|
1264
|
-
return new Response(null, { status: 404 });
|
|
1196
|
+
if (!config.userId) {
|
|
1197
|
+
throw new Error(
|
|
1198
|
+
"the userId context is missing. Call nile.setContext({ userId })"
|
|
1199
|
+
);
|
|
1265
1200
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1201
|
+
const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
|
|
1202
|
+
"{tenantId}",
|
|
1203
|
+
config.tenantId
|
|
1204
|
+
).replace("{userId}", config.userId)}/link`;
|
|
1205
|
+
const req = new Request(clientUrl, {
|
|
1206
|
+
headers: config.headers,
|
|
1207
|
+
method
|
|
1208
|
+
});
|
|
1209
|
+
return await config.handlers[method](req);
|
|
1269
1210
|
}
|
|
1270
1211
|
|
|
1271
|
-
// src/api/
|
|
1272
|
-
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1212
|
+
// src/api/handlers/DELETE.ts
|
|
1213
|
+
function DELETER(configRoutes, config) {
|
|
1214
|
+
const { info, warn } = Logger(config, "[DELETE MATCHER]");
|
|
1215
|
+
return async function DELETE4(req) {
|
|
1216
|
+
if (matches16(configRoutes, req)) {
|
|
1217
|
+
info("matches tenant user");
|
|
1218
|
+
return route16(req, config);
|
|
1219
|
+
}
|
|
1220
|
+
if (matches3(configRoutes, req)) {
|
|
1221
|
+
info("matches tenant users");
|
|
1222
|
+
return route3(req, config);
|
|
1223
|
+
}
|
|
1224
|
+
if (matches4(configRoutes, req)) {
|
|
1225
|
+
info("matches tenants");
|
|
1226
|
+
return route4(req, config);
|
|
1227
|
+
}
|
|
1228
|
+
if (matches(configRoutes, req)) {
|
|
1229
|
+
info("matches me");
|
|
1230
|
+
return route(req, config);
|
|
1231
|
+
}
|
|
1232
|
+
warn("No DELETE routes matched");
|
|
1276
1233
|
return new Response(null, { status: 404 });
|
|
1277
|
-
}
|
|
1278
|
-
init.method = "DELETE";
|
|
1279
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
1280
|
-
return await request(url, init, config);
|
|
1234
|
+
};
|
|
1281
1235
|
}
|
|
1282
1236
|
|
|
1283
|
-
// src/api/
|
|
1284
|
-
|
|
1285
|
-
const
|
|
1286
|
-
|
|
1287
|
-
|
|
1237
|
+
// src/api/handlers/PUT.ts
|
|
1238
|
+
function PUTER(configRoutes, config) {
|
|
1239
|
+
const { info, warn } = Logger(config, "[PUT MATCHER]");
|
|
1240
|
+
return async function PUT5(req) {
|
|
1241
|
+
if (matches16(configRoutes, req)) {
|
|
1242
|
+
info("matches tenant user");
|
|
1243
|
+
return route16(req, config);
|
|
1244
|
+
}
|
|
1245
|
+
if (matches3(configRoutes, req)) {
|
|
1246
|
+
info("matches tenant users");
|
|
1247
|
+
return route3(req, config);
|
|
1248
|
+
}
|
|
1249
|
+
if (matches2(configRoutes, req)) {
|
|
1250
|
+
info("matches users");
|
|
1251
|
+
return route2(req, config);
|
|
1252
|
+
}
|
|
1253
|
+
if (matches(configRoutes, req)) {
|
|
1254
|
+
info("matches me");
|
|
1255
|
+
return route(req, config);
|
|
1256
|
+
}
|
|
1257
|
+
if (matches4(configRoutes, req)) {
|
|
1258
|
+
info("matches tenants");
|
|
1259
|
+
return route4(req, config);
|
|
1260
|
+
}
|
|
1261
|
+
if (matches13(configRoutes, req)) {
|
|
1262
|
+
info("matches reset password");
|
|
1263
|
+
return route13(req, config);
|
|
1264
|
+
}
|
|
1265
|
+
warn("No PUT routes matched");
|
|
1288
1266
|
return new Response(null, { status: 404 });
|
|
1289
|
-
}
|
|
1290
|
-
init.body = init.request.body;
|
|
1291
|
-
init.method = "PUT";
|
|
1292
|
-
const url = `${apiRoutes(config).TENANT(tenantId)}`;
|
|
1293
|
-
return await request(url, init, config);
|
|
1267
|
+
};
|
|
1294
1268
|
}
|
|
1295
1269
|
|
|
1296
|
-
// src/api/
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
const
|
|
1301
|
-
|
|
1270
|
+
// src/api/handlers/index.ts
|
|
1271
|
+
function Handlers(configRoutes, config) {
|
|
1272
|
+
const GET6 = GETTER(configRoutes, config);
|
|
1273
|
+
const POST5 = POSTER(configRoutes, config);
|
|
1274
|
+
const DELETE4 = DELETER(configRoutes, config);
|
|
1275
|
+
const PUT5 = PUTER(configRoutes, config);
|
|
1276
|
+
return {
|
|
1277
|
+
GET: GET6,
|
|
1278
|
+
POST: POST5,
|
|
1279
|
+
DELETE: DELETE4,
|
|
1280
|
+
PUT: PUT5
|
|
1281
|
+
};
|
|
1302
1282
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
return false;
|
|
1283
|
+
var getApiUrl = (cfg) => {
|
|
1284
|
+
const { config } = cfg;
|
|
1285
|
+
if (config?.apiUrl != null) {
|
|
1286
|
+
return config?.apiUrl;
|
|
1308
1287
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
const { info } = Logger(
|
|
1315
|
-
{ ...config, debug: config.debug },
|
|
1316
|
-
`[ROUTES][${key4}]`
|
|
1288
|
+
if (stringCheck(process.env.NILEDB_API_URL)) {
|
|
1289
|
+
return process.env.NILEDB_API_URL;
|
|
1290
|
+
}
|
|
1291
|
+
throw new Error(
|
|
1292
|
+
"A connection to nile-auth is required. Set NILEDB_API_URL as an environment variable."
|
|
1317
1293
|
);
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1294
|
+
};
|
|
1295
|
+
var getCallbackUrl = (cfg) => {
|
|
1296
|
+
const { config } = cfg;
|
|
1297
|
+
if (stringCheck(config?.callbackUrl)) {
|
|
1298
|
+
return config?.callbackUrl;
|
|
1322
1299
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1300
|
+
return process.env.NILEDB_CALLBACK_URL;
|
|
1301
|
+
};
|
|
1302
|
+
var getSecureCookies = (cfg) => {
|
|
1303
|
+
const { config } = cfg;
|
|
1304
|
+
if (config?.secureCookies != null) {
|
|
1305
|
+
return config?.secureCookies;
|
|
1306
|
+
}
|
|
1307
|
+
if (stringCheck(process.env.NILEDB_SECURECOOKIES)) {
|
|
1308
|
+
return Boolean(process.env.NILEDB_SECURECOOKIES);
|
|
1309
|
+
}
|
|
1310
|
+
return void 0;
|
|
1311
|
+
};
|
|
1312
|
+
var getUsername = (cfg) => {
|
|
1313
|
+
const { config, logger } = cfg;
|
|
1314
|
+
const { info } = Logger(config, "[username]");
|
|
1315
|
+
if (config?.user) {
|
|
1316
|
+
logger && info(`${logger}[config] ${config.user}`);
|
|
1317
|
+
return String(config?.user);
|
|
1318
|
+
}
|
|
1319
|
+
const user = stringCheck(process.env.NILEDB_USER);
|
|
1320
|
+
if (user) {
|
|
1321
|
+
logger && info(`${logger}[NILEDB_USER] ${user}`);
|
|
1322
|
+
return user;
|
|
1323
|
+
}
|
|
1324
|
+
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
1325
|
+
if (pg2) {
|
|
1326
|
+
try {
|
|
1327
|
+
const url = new URL(pg2);
|
|
1328
|
+
if (url.username) {
|
|
1329
|
+
return url.username;
|
|
1328
1330
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
return await POST3(config, { request: request2 });
|
|
1332
|
-
case "DELETE":
|
|
1333
|
-
return await DELETE2(config, { request: request2 });
|
|
1334
|
-
case "PUT":
|
|
1335
|
-
return await PUT3(config, { request: request2 });
|
|
1336
|
-
default:
|
|
1337
|
-
return new Response("method not allowed", { status: 405 });
|
|
1331
|
+
} catch (e) {
|
|
1332
|
+
}
|
|
1338
1333
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
CALLBACK: makeRestUrl(config, "/auth/callback"),
|
|
1351
|
-
SIGNOUT: makeRestUrl(config, "/auth/signout"),
|
|
1352
|
-
ERROR: makeRestUrl(config, "/auth/error"),
|
|
1353
|
-
VERIFY_REQUEST: makeRestUrl(config, "/auth/verify-request"),
|
|
1354
|
-
PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password")
|
|
1355
|
-
});
|
|
1356
|
-
|
|
1357
|
-
// src/api/routes/auth/signin.ts
|
|
1358
|
-
var key5 = "SIGNIN";
|
|
1359
|
-
async function route5(req, config) {
|
|
1360
|
-
let url = proxyRoutes(config)[key5];
|
|
1361
|
-
const init = {
|
|
1362
|
-
method: req.method,
|
|
1363
|
-
headers: req.headers
|
|
1364
|
-
};
|
|
1365
|
-
if (req.method === "POST") {
|
|
1366
|
-
const [provider] = new URL(req.url).pathname.split("/").reverse();
|
|
1367
|
-
url = `${proxyRoutes(config)[key5]}/${provider}`;
|
|
1334
|
+
throw new Error(
|
|
1335
|
+
"A database user is required. Set NILEDB_USER as an environment variable."
|
|
1336
|
+
);
|
|
1337
|
+
};
|
|
1338
|
+
var getPassword = (cfg) => {
|
|
1339
|
+
const { config, logger } = cfg;
|
|
1340
|
+
const log = logProtector(logger);
|
|
1341
|
+
const { info } = Logger(config, "[password]");
|
|
1342
|
+
if (stringCheck(config?.password)) {
|
|
1343
|
+
log && info(`${logger}[config] ***`);
|
|
1344
|
+
return String(config?.password);
|
|
1368
1345
|
}
|
|
1369
|
-
const
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
},
|
|
1387
|
-
config
|
|
1346
|
+
const pass = stringCheck(process.env.NILEDB_PASSWORD);
|
|
1347
|
+
if (pass) {
|
|
1348
|
+
logger && info(`${logger}[NILEDB_PASSWORD] ***`);
|
|
1349
|
+
return pass;
|
|
1350
|
+
}
|
|
1351
|
+
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
1352
|
+
if (pg2) {
|
|
1353
|
+
try {
|
|
1354
|
+
const url = new URL(pg2);
|
|
1355
|
+
if (url.password) {
|
|
1356
|
+
return url.password;
|
|
1357
|
+
}
|
|
1358
|
+
} catch (e) {
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
throw new Error(
|
|
1362
|
+
"A database password is required. Set NILEDB_PASSWORD as an environment variable."
|
|
1388
1363
|
);
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1364
|
+
};
|
|
1365
|
+
var getDatabaseName = (cfg) => {
|
|
1366
|
+
const { config, logger } = cfg;
|
|
1367
|
+
const { info } = Logger(config, "[databaseName]");
|
|
1368
|
+
if (stringCheck(config?.databaseName)) {
|
|
1369
|
+
logger && info(`${logger}[config] ${config?.databaseName}`);
|
|
1370
|
+
return String(config?.databaseName);
|
|
1371
|
+
}
|
|
1372
|
+
const name = stringCheck(process.env.NILEDB_NAME);
|
|
1373
|
+
if (name) {
|
|
1374
|
+
logger && info(`${logger}[NILEDB_NAME] ${name}`);
|
|
1375
|
+
return name;
|
|
1376
|
+
}
|
|
1377
|
+
if (process.env.NILEDB_POSTGRES_URL) {
|
|
1378
|
+
try {
|
|
1379
|
+
const pgUrl = new URL(process.env.NILEDB_POSTGRES_URL);
|
|
1380
|
+
return pgUrl.pathname.substring(1);
|
|
1381
|
+
} catch (e) {
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
throw new Error(
|
|
1385
|
+
"A database name is required. Set NILEDB_PASSWORD as an environment variable."
|
|
1403
1386
|
);
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
{
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
)
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
const res = await request(
|
|
1437
|
-
url,
|
|
1438
|
-
{
|
|
1439
|
-
request: req,
|
|
1440
|
-
method: req.method
|
|
1441
|
-
},
|
|
1442
|
-
config
|
|
1443
|
-
).catch((e) => {
|
|
1444
|
-
error("an error as occurred", e);
|
|
1445
|
-
});
|
|
1446
|
-
const location = res?.headers.get("location");
|
|
1447
|
-
if (location) {
|
|
1448
|
-
return new Response(res?.body, {
|
|
1449
|
-
status: 302,
|
|
1450
|
-
headers: res?.headers
|
|
1451
|
-
});
|
|
1387
|
+
};
|
|
1388
|
+
var getTenantId = (cfg) => {
|
|
1389
|
+
const { config, logger } = cfg;
|
|
1390
|
+
const { info } = Logger(config, "[tenantId]");
|
|
1391
|
+
if (stringCheck(config?.tenantId)) {
|
|
1392
|
+
logger && info(`${logger}[config] ${config?.tenantId}`);
|
|
1393
|
+
return String(config?.tenantId);
|
|
1394
|
+
}
|
|
1395
|
+
if (stringCheck(process.env.NILEDB_TENANT)) {
|
|
1396
|
+
logger && info(`${logger}[NILEDB_TENANT] ${process.env.NILEDB_TENANT}`);
|
|
1397
|
+
return String(process.env.NILEDB_TENANT);
|
|
1398
|
+
}
|
|
1399
|
+
return null;
|
|
1400
|
+
};
|
|
1401
|
+
function getDbHost(cfg) {
|
|
1402
|
+
const { config, logger } = cfg;
|
|
1403
|
+
const { info } = Logger(config, "[db.host]");
|
|
1404
|
+
if (stringCheck(config?.db && config.db.host)) {
|
|
1405
|
+
logger && info(`${logger}[config] ${config?.db?.host}`);
|
|
1406
|
+
return String(config?.db?.host);
|
|
1407
|
+
}
|
|
1408
|
+
if (stringCheck(process.env.NILEDB_HOST)) {
|
|
1409
|
+
logger && info(`${logger}[NILEDB_HOST] ${process.env.NILEDB_HOST}`);
|
|
1410
|
+
return process.env.NILEDB_HOST;
|
|
1411
|
+
}
|
|
1412
|
+
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
1413
|
+
if (pg2) {
|
|
1414
|
+
try {
|
|
1415
|
+
const pgUrl = new URL(pg2);
|
|
1416
|
+
logger && info(`${logger}[NILEDB_POSTGRES_URL] ${pgUrl.hostname}`);
|
|
1417
|
+
return pgUrl.hostname;
|
|
1418
|
+
} catch (e) {
|
|
1452
1419
|
}
|
|
1453
|
-
return new Response(res?.body, {
|
|
1454
|
-
status: res?.status,
|
|
1455
|
-
headers: res?.headers
|
|
1456
|
-
});
|
|
1457
|
-
} catch (e) {
|
|
1458
|
-
error(e);
|
|
1459
1420
|
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
function matches9(configRoutes, request2) {
|
|
1463
|
-
return urlMatches(request2.url, configRoutes.CALLBACK);
|
|
1421
|
+
logger && info(`${logger}[default] db.thenile.dev`);
|
|
1422
|
+
return "db.thenile.dev";
|
|
1464
1423
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
method: request2.method
|
|
1472
|
-
};
|
|
1473
|
-
if (request2.method === "POST") {
|
|
1474
|
-
init.body = request2.body;
|
|
1475
|
-
const [provider] = new URL(request2.url).pathname.split("/").reverse();
|
|
1476
|
-
url = `${proxyRoutes(config)[key7]}${provider !== "signout" ? `/${provider}` : ""}`;
|
|
1424
|
+
function getDbPort(cfg) {
|
|
1425
|
+
const { config, logger } = cfg;
|
|
1426
|
+
const { info } = Logger(config, "[db.port]");
|
|
1427
|
+
if (config?.db?.port && config.db.port != null) {
|
|
1428
|
+
logger && info(`${logger}[config] ${config?.db.port}`);
|
|
1429
|
+
return Number(config.db?.port);
|
|
1477
1430
|
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
function matches10(configRoutes, request2) {
|
|
1482
|
-
return urlMatches(request2.url, configRoutes[key7]);
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
// src/api/routes/auth/error.ts
|
|
1486
|
-
var key8 = "ERROR";
|
|
1487
|
-
async function route11(req, config) {
|
|
1488
|
-
return request(
|
|
1489
|
-
proxyRoutes(config)[key8],
|
|
1490
|
-
{
|
|
1491
|
-
method: req.method,
|
|
1492
|
-
request: req
|
|
1493
|
-
},
|
|
1494
|
-
config
|
|
1495
|
-
);
|
|
1496
|
-
}
|
|
1497
|
-
function matches11(configRoutes, request2) {
|
|
1498
|
-
return urlMatches(request2.url, configRoutes[key8]);
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
// src/api/routes/auth/verify-request.ts
|
|
1502
|
-
var key9 = "VERIFY_REQUEST";
|
|
1503
|
-
async function route12(req, config) {
|
|
1504
|
-
return request(
|
|
1505
|
-
proxyRoutes(config)[key9],
|
|
1506
|
-
{
|
|
1507
|
-
method: req.method,
|
|
1508
|
-
request: req
|
|
1509
|
-
},
|
|
1510
|
-
config
|
|
1511
|
-
);
|
|
1512
|
-
}
|
|
1513
|
-
function matches12(configRoutes, request2) {
|
|
1514
|
-
return urlMatches(request2.url, configRoutes[key9]);
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
// src/api/routes/auth/password-reset.ts
|
|
1518
|
-
var key10 = "PASSWORD_RESET";
|
|
1519
|
-
async function route13(req, config) {
|
|
1520
|
-
const url = proxyRoutes(config)[key10];
|
|
1521
|
-
const res = await request(
|
|
1522
|
-
url,
|
|
1523
|
-
{
|
|
1524
|
-
method: req.method,
|
|
1525
|
-
request: req
|
|
1526
|
-
},
|
|
1527
|
-
config
|
|
1528
|
-
);
|
|
1529
|
-
const location = res?.headers.get("location");
|
|
1530
|
-
if (location) {
|
|
1531
|
-
return new Response(res?.body, {
|
|
1532
|
-
status: 302,
|
|
1533
|
-
headers: res?.headers
|
|
1534
|
-
});
|
|
1431
|
+
if (stringCheck(process.env.NILEDB_PORT)) {
|
|
1432
|
+
logger && info(`${logger}[NILEDB_PORT] ${process.env.NILEDB_PORT}`);
|
|
1433
|
+
return Number(process.env.NILEDB_PORT);
|
|
1535
1434
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1435
|
+
const pg2 = stringCheck(process.env.NILEDB_POSTGRES_URL);
|
|
1436
|
+
if (pg2) {
|
|
1437
|
+
try {
|
|
1438
|
+
const pgUrl = new URL(pg2);
|
|
1439
|
+
if (pgUrl.port) {
|
|
1440
|
+
return Number(pgUrl.port);
|
|
1441
|
+
}
|
|
1442
|
+
} catch (e) {
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
logger && info(`${logger}[default] 5432`);
|
|
1446
|
+
return 5432;
|
|
1543
1447
|
}
|
|
1448
|
+
var logProtector = (logger) => {
|
|
1449
|
+
return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test" ? logger : null;
|
|
1450
|
+
};
|
|
1451
|
+
var stringCheck = (str) => {
|
|
1452
|
+
if (str && str !== "") {
|
|
1453
|
+
return str;
|
|
1454
|
+
}
|
|
1455
|
+
return;
|
|
1456
|
+
};
|
|
1544
1457
|
|
|
1545
|
-
// src/
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1458
|
+
// src/utils/Config/index.ts
|
|
1459
|
+
var Config = class {
|
|
1460
|
+
routes;
|
|
1461
|
+
handlers;
|
|
1462
|
+
paths;
|
|
1463
|
+
logger;
|
|
1464
|
+
/**
|
|
1465
|
+
* Stores the set tenant id from Server for use in sub classes
|
|
1466
|
+
*/
|
|
1467
|
+
tenantId;
|
|
1468
|
+
/**
|
|
1469
|
+
* Stores the set user id from Server for use in sub classes
|
|
1470
|
+
*/
|
|
1471
|
+
userId;
|
|
1472
|
+
/**
|
|
1473
|
+
* Stores the headers to be used in `fetch` calls
|
|
1474
|
+
*/
|
|
1475
|
+
headers;
|
|
1476
|
+
/**
|
|
1477
|
+
* The nile-auth url
|
|
1478
|
+
*/
|
|
1479
|
+
apiUrl;
|
|
1480
|
+
origin;
|
|
1481
|
+
/**
|
|
1482
|
+
* important for separating the `origin` config value from a default in order to make requests
|
|
1483
|
+
*/
|
|
1484
|
+
serverOrigin;
|
|
1485
|
+
debug;
|
|
1486
|
+
/**
|
|
1487
|
+
* To use secure cookies or not in the fetch
|
|
1488
|
+
*/
|
|
1489
|
+
secureCookies;
|
|
1490
|
+
callbackUrl;
|
|
1491
|
+
/**
|
|
1492
|
+
* change the starting route
|
|
1493
|
+
*/
|
|
1494
|
+
routePrefix;
|
|
1495
|
+
db;
|
|
1496
|
+
// api: ApiConfig;
|
|
1497
|
+
constructor(config, logger) {
|
|
1498
|
+
const envVarConfig = { config, logger };
|
|
1499
|
+
this.routePrefix = config?.routePrefix ?? "/api";
|
|
1500
|
+
this.secureCookies = getSecureCookies(envVarConfig);
|
|
1501
|
+
this.callbackUrl = getCallbackUrl(envVarConfig);
|
|
1502
|
+
this.debug = config?.debug;
|
|
1503
|
+
this.origin = config?.origin;
|
|
1504
|
+
this.serverOrigin = config?.origin ?? "http://localhost:3000";
|
|
1505
|
+
this.apiUrl = getApiUrl(envVarConfig);
|
|
1506
|
+
const user = getUsername(envVarConfig);
|
|
1507
|
+
const password = getPassword(envVarConfig);
|
|
1508
|
+
const databaseName = getDatabaseName(envVarConfig);
|
|
1509
|
+
const { host, port, ...dbConfig } = config?.db ?? {};
|
|
1510
|
+
const configuredHost = host ?? getDbHost(envVarConfig);
|
|
1511
|
+
const configuredPort = port ?? getDbPort(envVarConfig);
|
|
1512
|
+
this.db = {
|
|
1513
|
+
user,
|
|
1514
|
+
password,
|
|
1515
|
+
host: configuredHost,
|
|
1516
|
+
port: configuredPort,
|
|
1517
|
+
...dbConfig
|
|
1518
|
+
};
|
|
1519
|
+
if (databaseName) {
|
|
1520
|
+
this.db.database = databaseName;
|
|
1580
1521
|
}
|
|
1581
|
-
if (
|
|
1582
|
-
|
|
1583
|
-
|
|
1522
|
+
if (config?.headers) {
|
|
1523
|
+
this.headers = config?.headers;
|
|
1524
|
+
} else {
|
|
1525
|
+
this.headers = new Headers();
|
|
1584
1526
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1527
|
+
this.routes = {
|
|
1528
|
+
...appRoutes(config?.routePrefix),
|
|
1529
|
+
...config?.routes
|
|
1530
|
+
};
|
|
1531
|
+
this.handlers = Handlers(this.routes, this);
|
|
1532
|
+
this.paths = {
|
|
1533
|
+
get: [
|
|
1534
|
+
this.routes.ME,
|
|
1535
|
+
this.routes.TENANT_USERS,
|
|
1536
|
+
this.routes.TENANTS,
|
|
1537
|
+
this.routes.TENANT,
|
|
1538
|
+
this.routes.SESSION,
|
|
1539
|
+
this.routes.SIGNIN,
|
|
1540
|
+
this.routes.PROVIDERS,
|
|
1541
|
+
this.routes.CSRF,
|
|
1542
|
+
this.routes.PASSWORD_RESET,
|
|
1543
|
+
this.routes.CALLBACK,
|
|
1544
|
+
this.routes.SIGNOUT,
|
|
1545
|
+
this.routes.VERIFY_REQUEST,
|
|
1546
|
+
this.routes.ERROR
|
|
1547
|
+
],
|
|
1548
|
+
post: [
|
|
1549
|
+
this.routes.TENANT_USERS,
|
|
1550
|
+
this.routes.SIGNUP,
|
|
1551
|
+
this.routes.USERS,
|
|
1552
|
+
this.routes.TENANTS,
|
|
1553
|
+
this.routes.SESSION,
|
|
1554
|
+
`${this.routes.SIGNIN}/{provider}`,
|
|
1555
|
+
this.routes.PASSWORD_RESET,
|
|
1556
|
+
this.routes.PROVIDERS,
|
|
1557
|
+
this.routes.CSRF,
|
|
1558
|
+
`${this.routes.CALLBACK}/{provider}`,
|
|
1559
|
+
this.routes.SIGNOUT
|
|
1560
|
+
],
|
|
1561
|
+
put: [
|
|
1562
|
+
this.routes.TENANT_USERS,
|
|
1563
|
+
this.routes.USERS,
|
|
1564
|
+
this.routes.TENANT,
|
|
1565
|
+
this.routes.PASSWORD_RESET
|
|
1566
|
+
],
|
|
1567
|
+
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
1568
|
+
};
|
|
1569
|
+
this.tenantId = config?.tenantId;
|
|
1570
|
+
this.userId = config?.userId;
|
|
1571
|
+
this.logger = config?.logger;
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
|
|
1575
|
+
// src/utils/Event/index.ts
|
|
1576
|
+
var Eventer = class {
|
|
1577
|
+
events = {};
|
|
1578
|
+
publish(eventName, value) {
|
|
1579
|
+
const callbacks = this.events[eventName];
|
|
1580
|
+
if (callbacks) {
|
|
1581
|
+
for (const callback of callbacks) {
|
|
1582
|
+
callback(value);
|
|
1583
|
+
}
|
|
1588
1584
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1585
|
+
}
|
|
1586
|
+
subscribe(eventName, callback) {
|
|
1587
|
+
if (!this.events[eventName]) {
|
|
1588
|
+
this.events[eventName] = [];
|
|
1592
1589
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1590
|
+
this.events[eventName].push(callback);
|
|
1591
|
+
}
|
|
1592
|
+
unsubscribe(eventName, callback) {
|
|
1593
|
+
const callbacks = this.events[eventName];
|
|
1594
|
+
if (!callbacks) return;
|
|
1595
|
+
const index = callbacks.indexOf(callback);
|
|
1596
|
+
if (index !== -1) {
|
|
1597
|
+
callbacks.splice(index, 1);
|
|
1596
1598
|
}
|
|
1597
|
-
if (
|
|
1598
|
-
|
|
1599
|
-
return route11(req, config);
|
|
1599
|
+
if (callbacks.length === 0) {
|
|
1600
|
+
delete this.events[eventName];
|
|
1600
1601
|
}
|
|
1601
|
-
warn("No GET routes matched");
|
|
1602
|
-
return new Response(null, { status: 404 });
|
|
1603
|
-
};
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
// src/api/routes/signup/POST.ts
|
|
1607
|
-
async function POST4(config, init) {
|
|
1608
|
-
init.body = init.request.body;
|
|
1609
|
-
init.method = "POST";
|
|
1610
|
-
const url = `${apiRoutes(config).SIGNUP}`;
|
|
1611
|
-
return await request(url, init, config);
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
// src/api/routes/signup/index.tsx
|
|
1615
|
-
var key11 = "SIGNUP";
|
|
1616
|
-
async function route14(request2, config) {
|
|
1617
|
-
switch (request2.method) {
|
|
1618
|
-
case "POST":
|
|
1619
|
-
return await POST4(config, { request: request2 });
|
|
1620
|
-
default:
|
|
1621
|
-
return new Response("method not allowed", { status: 405 });
|
|
1622
1602
|
}
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1603
|
+
};
|
|
1604
|
+
var eventer = new Eventer();
|
|
1605
|
+
var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
|
|
1606
|
+
var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
|
|
1607
|
+
var evictPool = (val) => {
|
|
1608
|
+
eventer.publish("EvictPool" /* EvictPool */, val);
|
|
1609
|
+
};
|
|
1610
|
+
var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
|
|
1611
|
+
var updateHeaders = (val) => {
|
|
1612
|
+
eventer.publish("headers" /* Headers */, val);
|
|
1613
|
+
};
|
|
1614
|
+
var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
|
|
1627
1615
|
|
|
1628
|
-
// src/
|
|
1629
|
-
function
|
|
1630
|
-
const { info,
|
|
1631
|
-
return
|
|
1632
|
-
|
|
1633
|
-
if (
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
})
|
|
1640
|
-
|
|
1616
|
+
// src/db/PoolProxy.ts
|
|
1617
|
+
function createProxyForPool(pool, config) {
|
|
1618
|
+
const { info, error } = Logger(config, "[pool]");
|
|
1619
|
+
return new Proxy(pool, {
|
|
1620
|
+
get(target, property) {
|
|
1621
|
+
if (property === "query") {
|
|
1622
|
+
if (!config.db.connectionString) {
|
|
1623
|
+
if (!config.db.user || !config.db.password) {
|
|
1624
|
+
error(
|
|
1625
|
+
"Cannot connect to the database. User and/or password are missing. Generate them at https://console.thenile.dev"
|
|
1626
|
+
);
|
|
1627
|
+
} else if (!config.db.database) {
|
|
1628
|
+
error(
|
|
1629
|
+
"Unable to obtain database name. Is process.env.NILEDB_POSTGRES_URL set?"
|
|
1630
|
+
);
|
|
1631
|
+
}
|
|
1641
1632
|
}
|
|
1633
|
+
const caller = target[property];
|
|
1634
|
+
return function query(...args) {
|
|
1635
|
+
info("query", ...args);
|
|
1636
|
+
const called = caller.apply(this, args);
|
|
1637
|
+
return called;
|
|
1638
|
+
};
|
|
1642
1639
|
}
|
|
1640
|
+
return target[property];
|
|
1643
1641
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
}
|
|
1676
|
-
if (matches8(configRoutes, req)) {
|
|
1677
|
-
info("matches csrf");
|
|
1678
|
-
return route8(req, config);
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// src/db/NileInstance.ts
|
|
1646
|
+
var NileDatabase = class {
|
|
1647
|
+
pool;
|
|
1648
|
+
tenantId;
|
|
1649
|
+
userId;
|
|
1650
|
+
id;
|
|
1651
|
+
config;
|
|
1652
|
+
timer;
|
|
1653
|
+
constructor(config, id) {
|
|
1654
|
+
const { warn, info, debug } = Logger(config, "[NileInstance]");
|
|
1655
|
+
this.id = id;
|
|
1656
|
+
const poolConfig = {
|
|
1657
|
+
min: 0,
|
|
1658
|
+
max: 10,
|
|
1659
|
+
idleTimeoutMillis: 3e4,
|
|
1660
|
+
...config.db
|
|
1661
|
+
};
|
|
1662
|
+
const { afterCreate, ...remaining } = poolConfig;
|
|
1663
|
+
config.db = poolConfig;
|
|
1664
|
+
this.config = config;
|
|
1665
|
+
const cloned = { ...this.config.db };
|
|
1666
|
+
cloned.password = "***";
|
|
1667
|
+
debug(`Connection pool config ${JSON.stringify(cloned)}`);
|
|
1668
|
+
this.pool = createProxyForPool(new pg.Pool(remaining), this.config);
|
|
1669
|
+
if (typeof afterCreate === "function") {
|
|
1670
|
+
warn(
|
|
1671
|
+
"Providing an pool configuration will stop automatic tenant context setting."
|
|
1672
|
+
);
|
|
1679
1673
|
}
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1674
|
+
this.startTimeout();
|
|
1675
|
+
this.pool.on("connect", async (client) => {
|
|
1676
|
+
debug(`pool connected ${this.id}`);
|
|
1677
|
+
this.startTimeout();
|
|
1678
|
+
const afterCreate2 = makeAfterCreate(
|
|
1679
|
+
config,
|
|
1680
|
+
`${this.id}-${this.timer}`
|
|
1681
|
+
);
|
|
1682
|
+
afterCreate2(client, (err) => {
|
|
1683
|
+
const { error } = Logger(config, "[after create callback]");
|
|
1684
|
+
if (err) {
|
|
1685
|
+
clearTimeout(this.timer);
|
|
1686
|
+
error("after create failed", {
|
|
1687
|
+
message: err.message,
|
|
1688
|
+
stack: err.stack
|
|
1689
|
+
});
|
|
1690
|
+
evictPool(this.id);
|
|
1691
|
+
}
|
|
1692
|
+
});
|
|
1693
|
+
});
|
|
1694
|
+
this.pool.on("error", (err) => {
|
|
1695
|
+
clearTimeout(this.timer);
|
|
1696
|
+
info(`pool ${this.id} failed`, {
|
|
1697
|
+
message: err.message,
|
|
1698
|
+
stack: err.stack
|
|
1699
|
+
});
|
|
1700
|
+
evictPool(this.id);
|
|
1701
|
+
});
|
|
1702
|
+
this.pool.on("release", (destroy) => {
|
|
1703
|
+
if (destroy) {
|
|
1704
|
+
clearTimeout(this.timer);
|
|
1705
|
+
evictPool(this.id);
|
|
1706
|
+
debug(`destroying pool ${this.id}`);
|
|
1707
|
+
}
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
startTimeout() {
|
|
1711
|
+
const { debug } = Logger(this.config, "[NileInstance]");
|
|
1712
|
+
if (this.timer) {
|
|
1713
|
+
clearTimeout(this.timer);
|
|
1683
1714
|
}
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1715
|
+
this.timer = setTimeout(() => {
|
|
1716
|
+
debug(
|
|
1717
|
+
`Pool reached idleTimeoutMillis. ${this.id} evicted after ${Number(this.config.db.idleTimeoutMillis) ?? 3e4}ms`
|
|
1718
|
+
);
|
|
1719
|
+
this.pool.end(() => {
|
|
1720
|
+
clearTimeout(this.timer);
|
|
1721
|
+
evictPool(this.id);
|
|
1722
|
+
});
|
|
1723
|
+
}, Number(this.config.db.idleTimeoutMillis) ?? 3e4);
|
|
1724
|
+
}
|
|
1725
|
+
shutdown() {
|
|
1726
|
+
const { debug } = Logger(this.config, "[NileInstance]");
|
|
1727
|
+
debug(`attempting to shut down ${this.id}`);
|
|
1728
|
+
clearTimeout(this.timer);
|
|
1729
|
+
this.pool.end(() => {
|
|
1730
|
+
debug(`${this.id} has been shut down`);
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
};
|
|
1734
|
+
var NileInstance_default = NileDatabase;
|
|
1735
|
+
function makeAfterCreate(config, id) {
|
|
1736
|
+
const { error, warn, debug } = Logger(config, "[afterCreate]");
|
|
1737
|
+
return (conn, done) => {
|
|
1738
|
+
conn.on("error", function errorHandler(e) {
|
|
1739
|
+
error(`Connection ${id} was terminated by server`, {
|
|
1740
|
+
message: e.message,
|
|
1741
|
+
stack: e.stack
|
|
1742
|
+
});
|
|
1743
|
+
done(e, conn);
|
|
1744
|
+
});
|
|
1745
|
+
if (config.tenantId) {
|
|
1746
|
+
const query = [`SET nile.tenant_id = '${config.tenantId}'`];
|
|
1747
|
+
if (config.userId) {
|
|
1748
|
+
if (!config.tenantId) {
|
|
1749
|
+
warn("A user id cannot be set in context without a tenant id");
|
|
1750
|
+
}
|
|
1751
|
+
query.push(`SET nile.user_id = '${config.userId}'`);
|
|
1752
|
+
}
|
|
1753
|
+
conn.query(query.join(";"), function(err) {
|
|
1754
|
+
if (err) {
|
|
1755
|
+
error("query connection failed", {
|
|
1756
|
+
cause: err.cause,
|
|
1757
|
+
stack: err.stack,
|
|
1758
|
+
message: err.message,
|
|
1759
|
+
name: err.name,
|
|
1760
|
+
id
|
|
1761
|
+
});
|
|
1762
|
+
} else {
|
|
1763
|
+
if (query.length === 1) {
|
|
1764
|
+
debug(`connection context set: tenantId=${config.tenantId}`);
|
|
1765
|
+
}
|
|
1766
|
+
if (query.length === 2) {
|
|
1767
|
+
debug(
|
|
1768
|
+
`connection context set: tenantId=${config.tenantId} userId=${config.userId}`
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
done(err, conn);
|
|
1773
|
+
});
|
|
1687
1774
|
}
|
|
1688
|
-
|
|
1689
|
-
return new Response(null, { status: 404 });
|
|
1775
|
+
done(null, conn);
|
|
1690
1776
|
};
|
|
1691
1777
|
}
|
|
1692
1778
|
|
|
1693
|
-
// src/
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
if (matches4(configRoutes, req)) {
|
|
1702
|
-
info("matches tenants");
|
|
1703
|
-
return route4(req, config);
|
|
1779
|
+
// src/db/DBManager.ts
|
|
1780
|
+
var DBManager = class {
|
|
1781
|
+
connections;
|
|
1782
|
+
cleared;
|
|
1783
|
+
poolWatcherFn;
|
|
1784
|
+
makeId(tenantId, userId) {
|
|
1785
|
+
if (tenantId && userId) {
|
|
1786
|
+
return `${tenantId}:${userId}`;
|
|
1704
1787
|
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
};
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
// src/api/handlers/PUT.ts
|
|
1711
|
-
function PUTER(configRoutes, config) {
|
|
1712
|
-
const { info, warn } = Logger(config, "[PUT MATCHER]");
|
|
1713
|
-
return async function PUT4(req) {
|
|
1714
|
-
if (matches3(configRoutes, req)) {
|
|
1715
|
-
info("matches tenant users");
|
|
1716
|
-
return route3(req, config);
|
|
1788
|
+
if (tenantId) {
|
|
1789
|
+
return `${tenantId}`;
|
|
1717
1790
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1791
|
+
return "base";
|
|
1792
|
+
}
|
|
1793
|
+
constructor(config) {
|
|
1794
|
+
this.cleared = false;
|
|
1795
|
+
this.connections = /* @__PURE__ */ new Map();
|
|
1796
|
+
this.poolWatcherFn = this.poolWatcher(config);
|
|
1797
|
+
watchEvictPool(this.poolWatcherFn);
|
|
1798
|
+
}
|
|
1799
|
+
poolWatcher = (config) => (id) => {
|
|
1800
|
+
const { info, warn } = Logger(config, "[DBManager]");
|
|
1801
|
+
if (id && this.connections.has(id)) {
|
|
1802
|
+
info(`Removing ${id} from db connection pool.`);
|
|
1803
|
+
const connection = this.connections.get(id);
|
|
1804
|
+
connection?.shutdown();
|
|
1805
|
+
this.connections.delete(id);
|
|
1806
|
+
} else {
|
|
1807
|
+
warn(`missed eviction of ${id}`);
|
|
1721
1808
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1809
|
+
};
|
|
1810
|
+
getConnection = (config) => {
|
|
1811
|
+
const { info } = Logger(config, "[DBManager]");
|
|
1812
|
+
const id = this.makeId(config.tenantId, config.userId);
|
|
1813
|
+
const existing = this.connections.get(id);
|
|
1814
|
+
info(`# of instances: ${this.connections.size}`);
|
|
1815
|
+
if (existing) {
|
|
1816
|
+
info(`returning existing ${id}`);
|
|
1817
|
+
existing.startTimeout();
|
|
1818
|
+
return existing.pool;
|
|
1725
1819
|
}
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1820
|
+
const newOne = new NileInstance_default(new Config(config), id);
|
|
1821
|
+
this.connections.set(id, newOne);
|
|
1822
|
+
info(`created new ${id}`);
|
|
1823
|
+
info(`# of instances: ${this.connections.size}`);
|
|
1824
|
+
if (this.cleared) {
|
|
1825
|
+
this.cleared = false;
|
|
1729
1826
|
}
|
|
1730
|
-
|
|
1731
|
-
return new Response(null, { status: 404 });
|
|
1827
|
+
return newOne.pool;
|
|
1732
1828
|
};
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
return {
|
|
1742
|
-
GET: GET6,
|
|
1743
|
-
POST: POST5,
|
|
1744
|
-
DELETE: DELETE3,
|
|
1745
|
-
PUT: PUT4
|
|
1829
|
+
clear = (config) => {
|
|
1830
|
+
const { info } = Logger(config, "[DBManager]");
|
|
1831
|
+
info(`Clearing all connections ${this.connections.size}`);
|
|
1832
|
+
this.cleared = true;
|
|
1833
|
+
this.connections.forEach((connection) => {
|
|
1834
|
+
connection.shutdown();
|
|
1835
|
+
});
|
|
1836
|
+
this.connections.clear();
|
|
1746
1837
|
};
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
// src/api/utils/routes/defaultRoutes.ts
|
|
1750
|
-
var appRoutes = (prefix = "/api") => ({
|
|
1751
|
-
SIGNIN: `${prefix}/auth/signin`,
|
|
1752
|
-
PROVIDERS: `${prefix}/auth/providers`,
|
|
1753
|
-
SESSION: `${prefix}/auth/session`,
|
|
1754
|
-
CSRF: `${prefix}/auth/csrf`,
|
|
1755
|
-
CALLBACK: `${prefix}/auth/callback`,
|
|
1756
|
-
SIGNOUT: `${prefix}/auth/signout`,
|
|
1757
|
-
ERROR: `${prefix}/auth/error`,
|
|
1758
|
-
VERIFY_REQUEST: `${prefix}/auth/verify-request`,
|
|
1759
|
-
PASSWORD_RESET: `${prefix}/auth/reset-password`,
|
|
1760
|
-
ME: `${prefix}/me`,
|
|
1761
|
-
USERS: `${prefix}/users`,
|
|
1762
|
-
TENANTS: `${prefix}/tenants`,
|
|
1763
|
-
TENANT: `${prefix}/tenants/{tenantId}`,
|
|
1764
|
-
TENANT_USER: `${prefix}/tenants/{tenantId}/users/{userId}`,
|
|
1765
|
-
TENANT_USERS: `${prefix}/tenants/{tenantId}/users`,
|
|
1766
|
-
SIGNUP: `${prefix}/signup`,
|
|
1767
|
-
LOG: `${prefix}/_log`
|
|
1768
|
-
});
|
|
1838
|
+
};
|
|
1769
1839
|
|
|
1770
|
-
// src/
|
|
1771
|
-
var
|
|
1840
|
+
// src/auth/index.ts
|
|
1841
|
+
var Auth = class {
|
|
1842
|
+
#logger;
|
|
1843
|
+
#config;
|
|
1772
1844
|
constructor(config) {
|
|
1773
|
-
|
|
1845
|
+
this.#config = config;
|
|
1846
|
+
this.#logger = Logger(config, "[auth]");
|
|
1774
1847
|
}
|
|
1775
|
-
async
|
|
1776
|
-
const
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1848
|
+
async getSession(rawResponse = false) {
|
|
1849
|
+
const res = await fetchSession(this.#config);
|
|
1850
|
+
if (rawResponse) {
|
|
1851
|
+
return res;
|
|
1852
|
+
}
|
|
1853
|
+
try {
|
|
1854
|
+
const session = await res.clone().json();
|
|
1855
|
+
if (Object.keys(session).length === 0) {
|
|
1856
|
+
return void 0;
|
|
1857
|
+
}
|
|
1858
|
+
return session;
|
|
1859
|
+
} catch {
|
|
1860
|
+
return res;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
async getCsrf(rawResponse = false) {
|
|
1864
|
+
return await getCsrf(this.#config, rawResponse);
|
|
1865
|
+
}
|
|
1866
|
+
async listProviders(rawResponse = false) {
|
|
1867
|
+
const res = await fetchProviders(this.#config);
|
|
1868
|
+
if (rawResponse) {
|
|
1869
|
+
return res;
|
|
1784
1870
|
}
|
|
1871
|
+
try {
|
|
1872
|
+
return await res.clone().json();
|
|
1873
|
+
} catch {
|
|
1874
|
+
return res;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
async signOut() {
|
|
1878
|
+
const csrfRes = await this.getCsrf();
|
|
1879
|
+
if (!("csrfToken" in csrfRes)) {
|
|
1880
|
+
throw new Error("Unable to obtain CSRF token. Sign out failed.");
|
|
1881
|
+
}
|
|
1882
|
+
const body = JSON.stringify({
|
|
1883
|
+
csrfToken: csrfRes.csrfToken,
|
|
1884
|
+
json: true
|
|
1885
|
+
});
|
|
1886
|
+
const res = await fetchSignOut(this.#config, body);
|
|
1887
|
+
updateHeaders(new Headers({}));
|
|
1888
|
+
this.#config.headers = new Headers();
|
|
1785
1889
|
return res;
|
|
1786
1890
|
}
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1891
|
+
async signUp(payload, rawResponse) {
|
|
1892
|
+
this.#config.headers = new Headers();
|
|
1893
|
+
const { email, password, ...params } = payload;
|
|
1894
|
+
if (!email || !password) {
|
|
1895
|
+
throw new Error(
|
|
1896
|
+
"Server side sign up requires a user email and password."
|
|
1897
|
+
);
|
|
1898
|
+
}
|
|
1899
|
+
const providers = await this.listProviders();
|
|
1900
|
+
const { credentials } = providers ?? {};
|
|
1901
|
+
if (!credentials) {
|
|
1902
|
+
throw new Error(
|
|
1903
|
+
"Unable to obtain credential provider. Aborting server side sign up."
|
|
1904
|
+
);
|
|
1905
|
+
}
|
|
1906
|
+
const csrf = await this.getCsrf();
|
|
1907
|
+
let csrfToken;
|
|
1908
|
+
if ("csrfToken" in csrf) {
|
|
1909
|
+
csrfToken = csrf.csrfToken;
|
|
1910
|
+
} else {
|
|
1911
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
1912
|
+
}
|
|
1913
|
+
const body = JSON.stringify({
|
|
1914
|
+
email,
|
|
1915
|
+
password,
|
|
1916
|
+
csrfToken,
|
|
1917
|
+
callbackUrl: credentials.callbackUrl
|
|
1918
|
+
});
|
|
1919
|
+
const res = await fetchSignUp(this.#config, { body, params });
|
|
1920
|
+
if (res.status > 299) {
|
|
1921
|
+
this.#logger.error(await res.clone().text());
|
|
1922
|
+
return void 0;
|
|
1923
|
+
}
|
|
1924
|
+
const token = parseToken(res.headers);
|
|
1925
|
+
if (!token) {
|
|
1926
|
+
throw new Error("Server side sign up failed. Session token not found");
|
|
1927
|
+
}
|
|
1928
|
+
this.#config.headers?.append("cookie", token);
|
|
1929
|
+
updateHeaders(this.#config.headers);
|
|
1930
|
+
if (rawResponse) {
|
|
1931
|
+
return res;
|
|
1932
|
+
}
|
|
1933
|
+
try {
|
|
1934
|
+
return await res.clone().json();
|
|
1935
|
+
} catch {
|
|
1936
|
+
return res;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
async resetPassword(req) {
|
|
1940
|
+
let email = "";
|
|
1941
|
+
let password = "";
|
|
1942
|
+
let callbackUrl = null;
|
|
1943
|
+
let redirectUrl = null;
|
|
1944
|
+
if (req instanceof Request) {
|
|
1945
|
+
const body2 = await req.json();
|
|
1946
|
+
email = body2.email;
|
|
1947
|
+
password = body2.password;
|
|
1948
|
+
const cbFromHeaders = parseCallback(req.headers);
|
|
1949
|
+
if (cbFromHeaders) {
|
|
1950
|
+
callbackUrl = cbFromHeaders;
|
|
1805
1951
|
}
|
|
1806
|
-
if (
|
|
1807
|
-
|
|
1952
|
+
if (body2.callbackUrl) {
|
|
1953
|
+
callbackUrl = body2.callbackUrl;
|
|
1808
1954
|
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
const tenantId = _headers.get(X_NILE_TENANT);
|
|
1812
|
-
const cookie = _headers.get("cookie");
|
|
1813
|
-
if (tenantId) {
|
|
1814
|
-
headers.set(X_NILE_TENANT, tenantId);
|
|
1955
|
+
if (body2.redirectUrl) {
|
|
1956
|
+
redirectUrl = body2.redirectUrl;
|
|
1815
1957
|
}
|
|
1816
|
-
|
|
1817
|
-
|
|
1958
|
+
} else {
|
|
1959
|
+
if ("email" in req) {
|
|
1960
|
+
email = req.email;
|
|
1818
1961
|
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
req instanceof Headers || JSON.stringify(req) === "{}" || req && typeof req === "object" && Object.values(req).length === 0
|
|
1828
|
-
) {
|
|
1829
|
-
body = void 0;
|
|
1830
|
-
}
|
|
1831
|
-
const _init = {
|
|
1832
|
-
...init,
|
|
1833
|
-
headers
|
|
1834
|
-
};
|
|
1835
|
-
return await this.rawRequest(method, url, _init, body);
|
|
1836
|
-
}
|
|
1837
|
-
async post(req, url, init) {
|
|
1838
|
-
const response = await this.request("POST", url, req, init);
|
|
1839
|
-
if (response && response.status >= 200 && response.status < 300) {
|
|
1840
|
-
const cloned = response.clone();
|
|
1841
|
-
try {
|
|
1842
|
-
return await cloned.json();
|
|
1843
|
-
} catch (e) {
|
|
1962
|
+
if ("password" in req) {
|
|
1963
|
+
password = req.password;
|
|
1964
|
+
}
|
|
1965
|
+
if ("callbackUrl" in req) {
|
|
1966
|
+
callbackUrl = req.callbackUrl ? req.callbackUrl : null;
|
|
1967
|
+
}
|
|
1968
|
+
if ("redirectUrl" in req) {
|
|
1969
|
+
redirectUrl = req.redirectUrl ? req.redirectUrl : null;
|
|
1844
1970
|
}
|
|
1845
1971
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
} catch (e) {
|
|
1972
|
+
const fallbackCb = parseCallback(this.#config.headers);
|
|
1973
|
+
if (fallbackCb) {
|
|
1974
|
+
const [, value] = fallbackCb.split("=");
|
|
1975
|
+
if (value) {
|
|
1976
|
+
const parsedUrl = decodeURIComponent(value);
|
|
1977
|
+
if (!redirectUrl) {
|
|
1978
|
+
redirectUrl = `${new URL(parsedUrl).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
if (!callbackUrl) {
|
|
1982
|
+
callbackUrl = value;
|
|
1858
1983
|
}
|
|
1859
1984
|
}
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1985
|
+
await this.getCsrf();
|
|
1986
|
+
const body = JSON.stringify({
|
|
1987
|
+
email,
|
|
1988
|
+
password,
|
|
1989
|
+
redirectUrl,
|
|
1990
|
+
callbackUrl
|
|
1991
|
+
});
|
|
1992
|
+
let urlWithParams;
|
|
1993
|
+
try {
|
|
1994
|
+
const data = await fetchResetPassword(this.#config, "POST", body);
|
|
1995
|
+
const cloned = data.clone();
|
|
1996
|
+
if (data.status === 400) {
|
|
1997
|
+
const text = await cloned.text();
|
|
1998
|
+
this.#logger.error(text);
|
|
1999
|
+
return data;
|
|
1869
2000
|
}
|
|
2001
|
+
const { url } = await data.json();
|
|
2002
|
+
urlWithParams = url;
|
|
2003
|
+
} catch {
|
|
1870
2004
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
email,
|
|
1886
|
-
password
|
|
1887
|
-
}) {
|
|
1888
|
-
if (!email || !password) {
|
|
1889
|
-
throw new Error("Server side login requires a user email and password.");
|
|
2005
|
+
let token;
|
|
2006
|
+
try {
|
|
2007
|
+
const worthyParams = new URL(urlWithParams).searchParams;
|
|
2008
|
+
const answer = await fetchResetPassword(
|
|
2009
|
+
this.#config,
|
|
2010
|
+
"GET",
|
|
2011
|
+
null,
|
|
2012
|
+
worthyParams
|
|
2013
|
+
);
|
|
2014
|
+
token = parseResetToken(answer.headers);
|
|
2015
|
+
} catch {
|
|
2016
|
+
this.#logger.warn(
|
|
2017
|
+
"Unable to parse reset password url. Password not reset."
|
|
2018
|
+
);
|
|
1890
2019
|
}
|
|
1891
|
-
const
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
2020
|
+
const cookie = this.#config.headers.get("cookie")?.split("; ");
|
|
2021
|
+
if (token) {
|
|
2022
|
+
cookie?.push(token);
|
|
2023
|
+
} else {
|
|
2024
|
+
throw new Error(
|
|
2025
|
+
"Unable to reset password, reset token is missing from response"
|
|
2026
|
+
);
|
|
2027
|
+
}
|
|
2028
|
+
this.#config.headers = new Headers({
|
|
2029
|
+
...this.#config.headers,
|
|
2030
|
+
cookie: cookie?.join("; ")
|
|
1900
2031
|
});
|
|
1901
|
-
const
|
|
1902
|
-
|
|
1903
|
-
|
|
2032
|
+
const res = await fetchResetPassword(this.#config, "PUT", body);
|
|
2033
|
+
cookie?.pop();
|
|
2034
|
+
const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
|
|
2035
|
+
cleaned.push(String(parseToken(res.headers)));
|
|
2036
|
+
const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
|
|
2037
|
+
updateHeaders(updatedHeaders);
|
|
2038
|
+
return res;
|
|
2039
|
+
}
|
|
2040
|
+
async callback(provider, body) {
|
|
2041
|
+
if (body instanceof Request) {
|
|
2042
|
+
this.#config.headers = body.headers;
|
|
2043
|
+
return await fetchCallback(
|
|
2044
|
+
this.#config,
|
|
2045
|
+
provider,
|
|
2046
|
+
void 0,
|
|
2047
|
+
body,
|
|
2048
|
+
"GET"
|
|
2049
|
+
);
|
|
1904
2050
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
2051
|
+
return await fetchCallback(this.#config, provider, body);
|
|
2052
|
+
}
|
|
2053
|
+
async signIn(provider, payload, rawResponse) {
|
|
2054
|
+
if (payload instanceof Request) {
|
|
2055
|
+
const body2 = new URLSearchParams(await payload.text());
|
|
2056
|
+
const origin = new URL(payload.url).origin;
|
|
2057
|
+
const payloadUrl = body2?.get("callbackUrl");
|
|
2058
|
+
const csrfToken2 = body2?.get("csrfToken");
|
|
2059
|
+
const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
|
|
2060
|
+
if (!csrfToken2) {
|
|
2061
|
+
throw new Error(
|
|
2062
|
+
"CSRF token in missing from request. Request it by the client before calling sign in"
|
|
2063
|
+
);
|
|
2064
|
+
}
|
|
2065
|
+
this.#config.headers = new Headers(payload.headers);
|
|
2066
|
+
this.#config.headers.set(
|
|
2067
|
+
"Content-Type",
|
|
2068
|
+
"application/x-www-form-urlencoded"
|
|
2069
|
+
);
|
|
2070
|
+
const params = new URLSearchParams({
|
|
2071
|
+
csrfToken: csrfToken2,
|
|
2072
|
+
json: String(true)
|
|
2073
|
+
});
|
|
2074
|
+
if (payloadUrl) {
|
|
2075
|
+
params.set("callbackUrl", callbackUrl);
|
|
2076
|
+
}
|
|
2077
|
+
return await fetchSignIn(this.#config, provider, params);
|
|
1911
2078
|
}
|
|
2079
|
+
this.#config.headers = new Headers();
|
|
2080
|
+
const { info, error } = this.#logger;
|
|
2081
|
+
const providers = await this.listProviders();
|
|
1912
2082
|
info("Obtaining csrf");
|
|
1913
|
-
const csrf =
|
|
1914
|
-
const csrfReq = new Request(csrf, {
|
|
1915
|
-
method: "GET",
|
|
1916
|
-
headers: new Headers({
|
|
1917
|
-
...baseHeaders
|
|
1918
|
-
})
|
|
1919
|
-
});
|
|
1920
|
-
const csrfRes = await handlers.POST(csrfReq);
|
|
2083
|
+
const csrf = await this.getCsrf();
|
|
1921
2084
|
let csrfToken;
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
info(sessionUrl, { csrfRes });
|
|
1927
|
-
error(e, { csrfRes });
|
|
2085
|
+
if ("csrfToken" in csrf) {
|
|
2086
|
+
csrfToken = csrf.csrfToken;
|
|
2087
|
+
} else {
|
|
2088
|
+
throw new Error("Unable to obtain parse CSRF. Request blocked.");
|
|
1928
2089
|
}
|
|
1929
2090
|
const { credentials } = providers ?? {};
|
|
1930
|
-
const csrfCookie = csrfRes?.headers.get("set-cookie");
|
|
1931
2091
|
if (!credentials) {
|
|
1932
2092
|
throw new Error(
|
|
1933
|
-
"Unable to obtain credential provider. Aborting server side
|
|
2093
|
+
"Unable to obtain credential provider. Aborting server side sign in."
|
|
1934
2094
|
);
|
|
1935
2095
|
}
|
|
1936
|
-
const
|
|
1937
|
-
if (!
|
|
1938
|
-
|
|
1939
|
-
|
|
2096
|
+
const { email, password } = payload ?? {};
|
|
2097
|
+
if (provider === "email" && (!email || !password)) {
|
|
2098
|
+
throw new Error(
|
|
2099
|
+
"Server side sign in requires a user email and password."
|
|
2100
|
+
);
|
|
1940
2101
|
}
|
|
1941
|
-
info(`
|
|
2102
|
+
info(`Obtaining providers for ${email}`);
|
|
2103
|
+
info(`Attempting sign in with email ${email}`);
|
|
1942
2104
|
const body = JSON.stringify({
|
|
1943
2105
|
email,
|
|
1944
2106
|
password,
|
|
1945
2107
|
csrfToken,
|
|
1946
2108
|
callbackUrl: credentials.callbackUrl
|
|
1947
2109
|
});
|
|
1948
|
-
const
|
|
1949
|
-
|
|
1950
|
-
headers: new Headers({
|
|
1951
|
-
...baseHeaders,
|
|
1952
|
-
"content-type": "application/json",
|
|
1953
|
-
cookie: csrfCookie.split(",").join("; ")
|
|
1954
|
-
}),
|
|
1955
|
-
body
|
|
1956
|
-
});
|
|
1957
|
-
const loginRes = await handlers.POST(postReq);
|
|
1958
|
-
const authCookie = loginRes?.headers.get("set-cookie");
|
|
2110
|
+
const signInRes = await this.callback(provider, body);
|
|
2111
|
+
const authCookie = signInRes?.headers.get("set-cookie");
|
|
1959
2112
|
if (!authCookie) {
|
|
1960
2113
|
throw new Error("authentication failed");
|
|
1961
2114
|
}
|
|
1962
|
-
const token = parseToken(
|
|
2115
|
+
const token = parseToken(signInRes?.headers);
|
|
2116
|
+
const possibleError = signInRes?.headers.get("location");
|
|
2117
|
+
if (possibleError) {
|
|
2118
|
+
let urlError;
|
|
2119
|
+
try {
|
|
2120
|
+
urlError = new URL(possibleError).searchParams.get("error");
|
|
2121
|
+
} catch {
|
|
2122
|
+
}
|
|
2123
|
+
if (urlError) {
|
|
2124
|
+
error("Unable to log user in", { error: urlError });
|
|
2125
|
+
return void 0;
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
1963
2128
|
if (!token) {
|
|
1964
|
-
error("Unable to obtain auth token", {
|
|
2129
|
+
error("Unable to obtain auth token", {
|
|
2130
|
+
authCookie,
|
|
2131
|
+
signInRes
|
|
2132
|
+
});
|
|
1965
2133
|
throw new Error("Server login failed");
|
|
1966
2134
|
}
|
|
1967
|
-
info("Server
|
|
1968
|
-
const
|
|
1969
|
-
|
|
1970
|
-
cookie
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
2135
|
+
info("Server sign in successful", { authCookie });
|
|
2136
|
+
const setCookie = signInRes.headers.get("set-cookie");
|
|
2137
|
+
if (setCookie) {
|
|
2138
|
+
const cookie = [
|
|
2139
|
+
parseCSRF(this.#config.headers),
|
|
2140
|
+
parseCallback(signInRes.headers),
|
|
2141
|
+
parseToken(signInRes.headers)
|
|
2142
|
+
].filter(Boolean).join("; ");
|
|
2143
|
+
updateHeaders(new Headers({ cookie }));
|
|
2144
|
+
} else {
|
|
2145
|
+
error("Unable to set context after sign in", {
|
|
2146
|
+
headers: signInRes.headers
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
if (rawResponse) {
|
|
2150
|
+
return signInRes;
|
|
2151
|
+
}
|
|
2152
|
+
try {
|
|
2153
|
+
return await signInRes.clone().json();
|
|
2154
|
+
} catch {
|
|
2155
|
+
return signInRes;
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
};
|
|
2159
|
+
function parseCSRF(headers) {
|
|
2160
|
+
let cookie = headers?.get("set-cookie");
|
|
2161
|
+
if (!cookie) {
|
|
2162
|
+
cookie = headers?.get("cookie");
|
|
2163
|
+
}
|
|
2164
|
+
if (!cookie) {
|
|
2165
|
+
return void 0;
|
|
2166
|
+
}
|
|
2167
|
+
const [, token] = /((__Secure-)?nile\.csrf-token=[^;]+)/.exec(cookie) ?? [];
|
|
2168
|
+
return token;
|
|
2169
|
+
}
|
|
2170
|
+
function parseCallback(headers) {
|
|
2171
|
+
let cookie = headers?.get("set-cookie");
|
|
2172
|
+
if (!cookie) {
|
|
2173
|
+
cookie = headers?.get("cookie");
|
|
2174
|
+
}
|
|
2175
|
+
if (!cookie) {
|
|
2176
|
+
return void 0;
|
|
2177
|
+
}
|
|
2178
|
+
const [, token] = /((__Secure-)?nile\.callback-url=[^;]+)/.exec(cookie) ?? [];
|
|
2179
|
+
return token;
|
|
1974
2180
|
}
|
|
1975
2181
|
function parseToken(headers) {
|
|
1976
2182
|
let authCookie = headers?.get("set-cookie");
|
|
@@ -1983,604 +2189,516 @@ function parseToken(headers) {
|
|
|
1983
2189
|
const [, token] = /((__Secure-)?nile\.session-token=[^;]+)/.exec(authCookie) ?? [];
|
|
1984
2190
|
return token;
|
|
1985
2191
|
}
|
|
1986
|
-
|
|
1987
|
-
headers;
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
}
|
|
2192
|
+
function parseResetToken(headers) {
|
|
2193
|
+
let authCookie = headers?.get("set-cookie");
|
|
2194
|
+
if (!authCookie) {
|
|
2195
|
+
authCookie = headers?.get("cookie");
|
|
2196
|
+
}
|
|
2197
|
+
if (!authCookie) {
|
|
2198
|
+
return void 0;
|
|
2199
|
+
}
|
|
2200
|
+
const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
|
|
2201
|
+
return token;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
// src/auth/getCsrf.ts
|
|
2205
|
+
async function getCsrf(config, rawResponse = false) {
|
|
2206
|
+
const res = await fetchCsrf(config);
|
|
2207
|
+
const csrfCook = parseCSRF(res.headers);
|
|
2208
|
+
if (csrfCook) {
|
|
2209
|
+
const [, value] = csrfCook.split("=");
|
|
2210
|
+
const [token] = decodeURIComponent(value).split("|");
|
|
2211
|
+
const setCookie = res.headers.get("set-cookie");
|
|
2212
|
+
if (setCookie) {
|
|
2213
|
+
const cookie = [
|
|
2214
|
+
csrfCook,
|
|
2215
|
+
parseCallback(res.headers),
|
|
2216
|
+
parseToken(res.headers)
|
|
2217
|
+
].filter(Boolean).join("; ");
|
|
2218
|
+
config.headers.set("cookie", cookie);
|
|
2219
|
+
updateHeaders(new Headers({ cookie }));
|
|
2220
|
+
}
|
|
2221
|
+
if (!rawResponse) {
|
|
2222
|
+
return { csrfToken: token };
|
|
2223
|
+
}
|
|
2224
|
+
} else {
|
|
2225
|
+
const existingCookie = config.headers.get("cookie");
|
|
2226
|
+
const cookieParts = [];
|
|
2227
|
+
if (existingCookie) {
|
|
2228
|
+
cookieParts.push(
|
|
2229
|
+
parseToken(config.headers),
|
|
2230
|
+
parseCallback(config.headers)
|
|
2231
|
+
);
|
|
2017
2232
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
}
|
|
2023
|
-
getSession = async (req, init) => {
|
|
2024
|
-
const _requester = new Requester(this);
|
|
2025
|
-
const _init = this.handleHeaders(init);
|
|
2026
|
-
const session = await _requester.get(req, this.sessionUrl, _init);
|
|
2027
|
-
if (Object.keys(session).length === 0) {
|
|
2028
|
-
return void 0;
|
|
2233
|
+
if (csrfCook) {
|
|
2234
|
+
cookieParts.push(csrfCook);
|
|
2235
|
+
} else {
|
|
2236
|
+
cookieParts.push(parseCSRF(config.headers));
|
|
2029
2237
|
}
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
return "/auth/csrf";
|
|
2238
|
+
const cookie = cookieParts.filter(Boolean).join("; ");
|
|
2239
|
+
config.headers.set("cookie", cookie);
|
|
2240
|
+
updateHeaders(new Headers({ cookie }));
|
|
2034
2241
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
const _init = this.handleHeaders(init);
|
|
2038
|
-
return await _requester.get(req, this.getCsrfUrl, _init, raw);
|
|
2039
|
-
}
|
|
2040
|
-
get listProvidersUrl() {
|
|
2041
|
-
return "/auth/providers";
|
|
2242
|
+
if (rawResponse) {
|
|
2243
|
+
return res;
|
|
2042
2244
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
return await _requester.get(req, this.listProvidersUrl, _init);
|
|
2047
|
-
};
|
|
2048
|
-
get signOutUrl() {
|
|
2049
|
-
return "/auth/signout";
|
|
2050
|
-
}
|
|
2051
|
-
signOut = async (req, init) => {
|
|
2052
|
-
const _requester = new Requester(this);
|
|
2053
|
-
const _init = this.handleHeaders(init);
|
|
2054
|
-
const csrf = await this.getCsrf(
|
|
2055
|
-
req,
|
|
2056
|
-
void 0,
|
|
2057
|
-
true
|
|
2058
|
-
);
|
|
2059
|
-
const csrfHeader = getCsrfToken(csrf.headers, this.headers);
|
|
2060
|
-
const callbackUrl = req && "callbackUrl" in req ? String(req.callbackUrl) : "/";
|
|
2061
|
-
if (!csrfHeader) {
|
|
2062
|
-
this.logger?.debug && this.logger.debug("Request blocked from invalid csrf header");
|
|
2063
|
-
return new Response("Request blocked", { status: 400 });
|
|
2064
|
-
}
|
|
2065
|
-
const headers = new Headers(_init?.headers);
|
|
2066
|
-
const { csrfToken } = await csrf.json() ?? {};
|
|
2067
|
-
const cooks = getCookies(headers);
|
|
2068
|
-
if (csrfHeader) {
|
|
2069
|
-
if (cooks["__Secure-nile.csrf-token"]) {
|
|
2070
|
-
cooks["__Secure-nile.csrf-token"] = encodeURIComponent(csrfHeader);
|
|
2071
|
-
}
|
|
2072
|
-
if (cooks["nile.csrf-token"]) {
|
|
2073
|
-
cooks["nile.csrf-token"] = encodeURIComponent(csrfHeader);
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
headers.set(
|
|
2077
|
-
"cookie",
|
|
2078
|
-
Object.keys(cooks).map((key12) => `${key12}=${cooks[key12]}`).join("; ")
|
|
2079
|
-
);
|
|
2080
|
-
const res = await _requester.post(req, this.signOutUrl, {
|
|
2081
|
-
method: "post",
|
|
2082
|
-
body: JSON.stringify({
|
|
2083
|
-
csrfToken,
|
|
2084
|
-
callbackUrl,
|
|
2085
|
-
json: String(true)
|
|
2086
|
-
}),
|
|
2087
|
-
..._init,
|
|
2088
|
-
headers
|
|
2089
|
-
});
|
|
2090
|
-
this.resetHeaders && this.resetHeaders();
|
|
2245
|
+
try {
|
|
2246
|
+
return await res.clone().json();
|
|
2247
|
+
} catch {
|
|
2091
2248
|
return res;
|
|
2092
|
-
};
|
|
2093
|
-
};
|
|
2094
|
-
function getCallbackUrl2(headers) {
|
|
2095
|
-
if (headers) {
|
|
2096
|
-
const cookies = getCookies(headers);
|
|
2097
|
-
if (cookies) {
|
|
2098
|
-
return cookies["__Secure-nile.callback-url"] || cookies["nile.callback-url"];
|
|
2099
|
-
}
|
|
2100
2249
|
}
|
|
2101
2250
|
}
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2251
|
+
|
|
2252
|
+
// src/users/index.ts
|
|
2253
|
+
var Users = class {
|
|
2254
|
+
#config;
|
|
2255
|
+
#logger;
|
|
2256
|
+
constructor(config) {
|
|
2257
|
+
this.#config = config;
|
|
2258
|
+
this.#logger = Logger(config, "[me]");
|
|
2259
|
+
}
|
|
2260
|
+
async updateSelf(req, rawResponse) {
|
|
2261
|
+
const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
|
|
2262
|
+
if (rawResponse) {
|
|
2263
|
+
return res;
|
|
2108
2264
|
}
|
|
2109
|
-
|
|
2110
|
-
return
|
|
2265
|
+
try {
|
|
2266
|
+
return await res?.clone().json();
|
|
2267
|
+
} catch {
|
|
2268
|
+
return res;
|
|
2111
2269
|
}
|
|
2112
2270
|
}
|
|
2113
|
-
|
|
2114
|
-
const
|
|
2115
|
-
if (
|
|
2116
|
-
|
|
2271
|
+
async removeSelf() {
|
|
2272
|
+
const me = await this.getSelf();
|
|
2273
|
+
if ("id" in me) {
|
|
2274
|
+
this.#config.userId = me.id;
|
|
2117
2275
|
}
|
|
2276
|
+
const res = await fetchMe(this.#config, "DELETE");
|
|
2277
|
+
updateHeaders(new Headers());
|
|
2278
|
+
return res;
|
|
2118
2279
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
const
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
decodeURIComponent(val.join("=").trim())
|
|
2136
|
-
];
|
|
2137
|
-
})
|
|
2138
|
-
);
|
|
2139
|
-
};
|
|
2140
|
-
|
|
2141
|
-
// src/tenants/index.ts
|
|
2142
|
-
var Tenants = class extends Config {
|
|
2143
|
-
headers;
|
|
2144
|
-
constructor(config, headers) {
|
|
2145
|
-
super(config);
|
|
2146
|
-
this.headers = headers;
|
|
2147
|
-
}
|
|
2148
|
-
handleHeaders(init) {
|
|
2149
|
-
if (this.headers) {
|
|
2150
|
-
if (init) {
|
|
2151
|
-
init.headers = new Headers({ ...this.headers, ...init?.headers });
|
|
2152
|
-
return init;
|
|
2153
|
-
} else {
|
|
2154
|
-
init = {
|
|
2155
|
-
headers: this.headers
|
|
2156
|
-
};
|
|
2157
|
-
return init;
|
|
2280
|
+
async getSelf(rawResponse) {
|
|
2281
|
+
const res = await fetchMe(this.#config);
|
|
2282
|
+
if (rawResponse) {
|
|
2283
|
+
return res;
|
|
2284
|
+
}
|
|
2285
|
+
try {
|
|
2286
|
+
return await res?.clone().json();
|
|
2287
|
+
} catch {
|
|
2288
|
+
return res;
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
async verifySelf(bypassEmail = process.env.NODE_ENV !== "production", rawResponse = false) {
|
|
2292
|
+
try {
|
|
2293
|
+
const me = await this.getSelf();
|
|
2294
|
+
if (me instanceof Response) {
|
|
2295
|
+
return me;
|
|
2158
2296
|
}
|
|
2297
|
+
const res = await verifyEmailAddress(this.#config, me);
|
|
2298
|
+
return res;
|
|
2299
|
+
} catch {
|
|
2300
|
+
this.#logger?.warn(
|
|
2301
|
+
"Unable to verify email. The current user's email will be set to verified any way. Be sure to configure emails for production."
|
|
2302
|
+
);
|
|
2159
2303
|
}
|
|
2304
|
+
if (bypassEmail) {
|
|
2305
|
+
return await this.updateSelf({ emailVerified: true }, rawResponse);
|
|
2306
|
+
}
|
|
2307
|
+
this.#logger.error(
|
|
2308
|
+
"Unable to verify email address. Configure your SMTP server in the console."
|
|
2309
|
+
);
|
|
2160
2310
|
return void 0;
|
|
2161
2311
|
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2312
|
+
};
|
|
2313
|
+
async function verifyEmailAddress(config, user) {
|
|
2314
|
+
config.headers.set("content-type", "application/x-www-form-urlencoded");
|
|
2315
|
+
const { csrfToken } = await getCsrf(config);
|
|
2316
|
+
const res = await fetchVerifyEmail(
|
|
2317
|
+
config,
|
|
2318
|
+
"POST",
|
|
2319
|
+
new URLSearchParams({ csrfToken, email: user.email }).toString()
|
|
2320
|
+
);
|
|
2321
|
+
if (res.status > 299) {
|
|
2322
|
+
throw new Error(await res.text());
|
|
2164
2323
|
}
|
|
2165
|
-
|
|
2166
|
-
|
|
2324
|
+
return res;
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
// src/tenants/index.ts
|
|
2328
|
+
var Tenants = class {
|
|
2329
|
+
#logger;
|
|
2330
|
+
#config;
|
|
2331
|
+
constructor(config) {
|
|
2332
|
+
this.#logger = Logger(config, "[tenants]");
|
|
2333
|
+
this.#config = config;
|
|
2167
2334
|
}
|
|
2168
|
-
|
|
2169
|
-
let
|
|
2335
|
+
async create(req, rawResponse) {
|
|
2336
|
+
let res;
|
|
2170
2337
|
if (typeof req === "string") {
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
} else if ("name" in req || "id" in req) {
|
|
2179
|
-
_req = new Request(`${this.api.basePath}${this.tenantsUrl}`, {
|
|
2180
|
-
body: JSON.stringify(req),
|
|
2181
|
-
method: "POST",
|
|
2182
|
-
headers: {
|
|
2183
|
-
"content-type": "application/json"
|
|
2184
|
-
}
|
|
2185
|
-
});
|
|
2186
|
-
} else {
|
|
2187
|
-
_req = req;
|
|
2338
|
+
res = await fetchTenants(
|
|
2339
|
+
this.#config,
|
|
2340
|
+
"POST",
|
|
2341
|
+
JSON.stringify({ name: req })
|
|
2342
|
+
);
|
|
2343
|
+
} else if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
2344
|
+
res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
|
|
2188
2345
|
}
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2346
|
+
if (rawResponse) {
|
|
2347
|
+
return res;
|
|
2348
|
+
}
|
|
2349
|
+
try {
|
|
2350
|
+
return await res?.clone().json();
|
|
2351
|
+
} catch {
|
|
2352
|
+
return res;
|
|
2196
2353
|
}
|
|
2197
|
-
const _requester = new Requester(this);
|
|
2198
|
-
const _init = this.handleHeaders(init);
|
|
2199
|
-
return _requester.get(req, this.tenantUrl, _init);
|
|
2200
|
-
};
|
|
2201
|
-
get tenantListUrl() {
|
|
2202
|
-
return `/users/${this.userId ?? "{userId}"}/tenants`;
|
|
2203
2354
|
}
|
|
2204
|
-
|
|
2205
|
-
const _requester = new Requester(this);
|
|
2206
|
-
const _init = this.handleHeaders(init);
|
|
2207
|
-
return _requester.get(req, this.tenantListUrl, _init);
|
|
2208
|
-
};
|
|
2209
|
-
deleteTenant = async (req, init) => {
|
|
2355
|
+
async delete(req) {
|
|
2210
2356
|
if (typeof req === "string") {
|
|
2211
|
-
this.tenantId = req;
|
|
2357
|
+
this.#config.tenantId = req;
|
|
2212
2358
|
}
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
return _requester.delete(req, this.tenantUrl, _init);
|
|
2216
|
-
};
|
|
2217
|
-
updateTenant = async (req, init) => {
|
|
2218
|
-
let _req;
|
|
2219
|
-
if (req && "name" in req) {
|
|
2220
|
-
_req = new Request(`${this.api.basePath}${this.tenantUrl}`, {
|
|
2221
|
-
body: JSON.stringify(req),
|
|
2222
|
-
method: "PUT"
|
|
2223
|
-
});
|
|
2224
|
-
} else {
|
|
2225
|
-
_req = req;
|
|
2359
|
+
if (typeof req === "object" && "id" in req) {
|
|
2360
|
+
this.#config.tenantId = req.id;
|
|
2226
2361
|
}
|
|
2227
|
-
const
|
|
2228
|
-
|
|
2229
|
-
return _requester.put(_req, this.tenantUrl, _init);
|
|
2230
|
-
};
|
|
2231
|
-
};
|
|
2232
|
-
|
|
2233
|
-
// src/users/index.ts
|
|
2234
|
-
var Users = class extends Config {
|
|
2235
|
-
headers;
|
|
2236
|
-
constructor(config, headers) {
|
|
2237
|
-
super(config);
|
|
2238
|
-
this.headers = headers;
|
|
2362
|
+
const res = await fetchTenant(this.#config, "DELETE");
|
|
2363
|
+
return res;
|
|
2239
2364
|
}
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2365
|
+
async get(req, rawResponse) {
|
|
2366
|
+
if (typeof req === "string") {
|
|
2367
|
+
this.#config.tenantId = req;
|
|
2368
|
+
} else if (typeof req === "object" && "id" in req) {
|
|
2369
|
+
this.#config.tenantId = req.id;
|
|
2244
2370
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2371
|
+
const res = await fetchTenant(this.#config, "GET");
|
|
2372
|
+
if (rawResponse === true || req === true) {
|
|
2373
|
+
return res;
|
|
2374
|
+
}
|
|
2375
|
+
try {
|
|
2376
|
+
return await res?.clone().json();
|
|
2377
|
+
} catch {
|
|
2378
|
+
return res;
|
|
2247
2379
|
}
|
|
2248
|
-
return `/users?${params.size > 0 ? params : ""}`;
|
|
2249
|
-
}
|
|
2250
|
-
get tenantUsersUrl() {
|
|
2251
|
-
return `/tenants/${this.tenantId ?? "{tenantId}"}/users`;
|
|
2252
|
-
}
|
|
2253
|
-
get linkUsersUrl() {
|
|
2254
|
-
return `/tenants/${this.tenantId ?? "{tenantId}"}/users/${this.userId ?? "{userId}"}/link`;
|
|
2255
|
-
}
|
|
2256
|
-
get tenantUserUrl() {
|
|
2257
|
-
return `/tenants/${this.tenantId ?? "{tenantId}"}/users/${this.userId ?? "{userId}"}`;
|
|
2258
2380
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
init = {
|
|
2266
|
-
headers: this.headers
|
|
2267
|
-
};
|
|
2268
|
-
return init;
|
|
2381
|
+
async update(req, rawResponse) {
|
|
2382
|
+
let res;
|
|
2383
|
+
if (typeof req === "object" && ("name" in req || "id" in req)) {
|
|
2384
|
+
const { id, ...remaining } = req;
|
|
2385
|
+
if (id) {
|
|
2386
|
+
this.#config.tenantId = id;
|
|
2269
2387
|
}
|
|
2388
|
+
res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
|
|
2389
|
+
}
|
|
2390
|
+
if (rawResponse) {
|
|
2391
|
+
return res;
|
|
2392
|
+
}
|
|
2393
|
+
try {
|
|
2394
|
+
return await res?.clone().json();
|
|
2395
|
+
} catch {
|
|
2396
|
+
return res;
|
|
2270
2397
|
}
|
|
2271
|
-
return void 0;
|
|
2272
2398
|
}
|
|
2273
|
-
|
|
2274
|
-
const
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
};
|
|
2278
|
-
createTenantUser = async (req, init) => {
|
|
2279
|
-
const _requester = new Requester(this);
|
|
2280
|
-
const _init = this.handleHeaders(init);
|
|
2281
|
-
return await _requester.post(req, this.tenantUsersUrl, _init);
|
|
2282
|
-
};
|
|
2283
|
-
updateUser = async (req, init) => {
|
|
2284
|
-
let _req;
|
|
2285
|
-
if (req && "id" in req) {
|
|
2286
|
-
_req = new Request(`${this.api.basePath}${this.tenantUserUrl}`, {
|
|
2287
|
-
body: JSON.stringify(req),
|
|
2288
|
-
method: "PUT"
|
|
2289
|
-
});
|
|
2290
|
-
this.userId = String(req.id);
|
|
2291
|
-
} else {
|
|
2292
|
-
_req = req;
|
|
2399
|
+
async list(req) {
|
|
2400
|
+
const res = await fetchTenantsByUser(this.#config);
|
|
2401
|
+
if (req === true) {
|
|
2402
|
+
return res;
|
|
2293
2403
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
this.userId = req;
|
|
2307
|
-
} else {
|
|
2308
|
-
if ("id" in req) {
|
|
2309
|
-
this.userId = req.id;
|
|
2310
|
-
}
|
|
2311
|
-
if ("tenantId" in req) {
|
|
2312
|
-
this.tenantId = req.tenantId;
|
|
2404
|
+
try {
|
|
2405
|
+
return await res?.clone().json();
|
|
2406
|
+
} catch {
|
|
2407
|
+
return res;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
async leaveTenant(req) {
|
|
2411
|
+
const me = await fetchMe(this.#config);
|
|
2412
|
+
try {
|
|
2413
|
+
const json = await me.json();
|
|
2414
|
+
if ("id" in json) {
|
|
2415
|
+
this.#config.userId = json.id;
|
|
2313
2416
|
}
|
|
2417
|
+
} catch {
|
|
2314
2418
|
}
|
|
2315
|
-
const _init = this.handleHeaders(init);
|
|
2316
|
-
return await _requester.put(req, this.linkUsersUrl, _init);
|
|
2317
|
-
};
|
|
2318
|
-
unlinkUser = async (req, init) => {
|
|
2319
2419
|
if (typeof req === "string") {
|
|
2320
|
-
this.
|
|
2420
|
+
this.#config.tenantId = req;
|
|
2321
2421
|
} else {
|
|
2322
|
-
|
|
2323
|
-
this.userId = req.id;
|
|
2324
|
-
}
|
|
2325
|
-
if ("tenantId" in req) {
|
|
2326
|
-
this.tenantId = req.tenantId;
|
|
2327
|
-
}
|
|
2422
|
+
this.#handleContext(req);
|
|
2328
2423
|
}
|
|
2329
|
-
|
|
2330
|
-
const _init = this.handleHeaders(init);
|
|
2331
|
-
return await _requester.delete(req, this.linkUsersUrl, _init);
|
|
2332
|
-
};
|
|
2333
|
-
get meUrl() {
|
|
2334
|
-
return "/me";
|
|
2335
|
-
}
|
|
2336
|
-
me = async (req, init) => {
|
|
2337
|
-
const _requester = new Requester(this);
|
|
2338
|
-
const _init = this.handleHeaders(init);
|
|
2339
|
-
return await _requester.get(req, this.meUrl, _init);
|
|
2340
|
-
};
|
|
2341
|
-
updateMe = async (req, init) => {
|
|
2342
|
-
const _requester = new Requester(this);
|
|
2343
|
-
const _init = this.handleHeaders(init);
|
|
2344
|
-
return await _requester.put(req, this.meUrl, _init);
|
|
2345
|
-
};
|
|
2346
|
-
};
|
|
2347
|
-
|
|
2348
|
-
// src/Api.ts
|
|
2349
|
-
var Api = class {
|
|
2350
|
-
config;
|
|
2351
|
-
users;
|
|
2352
|
-
auth;
|
|
2353
|
-
tenants;
|
|
2354
|
-
routes;
|
|
2355
|
-
#headers;
|
|
2356
|
-
handlers;
|
|
2357
|
-
paths;
|
|
2358
|
-
constructor(config) {
|
|
2359
|
-
this.config = config;
|
|
2360
|
-
this.auth = new Auth(config, void 0, {
|
|
2361
|
-
resetHeaders: this.resetHeaders
|
|
2362
|
-
});
|
|
2363
|
-
this.users = new Users(config);
|
|
2364
|
-
this.tenants = new Tenants(config);
|
|
2365
|
-
this.routes = {
|
|
2366
|
-
...appRoutes(config?.api.routePrefix),
|
|
2367
|
-
...config?.api.routes
|
|
2368
|
-
};
|
|
2369
|
-
this.handlers = Handlers(this.routes, config);
|
|
2370
|
-
this.paths = {
|
|
2371
|
-
get: [
|
|
2372
|
-
this.routes.ME,
|
|
2373
|
-
this.routes.TENANT_USERS,
|
|
2374
|
-
this.routes.TENANTS,
|
|
2375
|
-
this.routes.TENANT,
|
|
2376
|
-
this.routes.SESSION,
|
|
2377
|
-
this.routes.SIGNIN,
|
|
2378
|
-
this.routes.PROVIDERS,
|
|
2379
|
-
this.routes.CSRF,
|
|
2380
|
-
this.routes.PASSWORD_RESET,
|
|
2381
|
-
this.routes.CALLBACK,
|
|
2382
|
-
this.routes.SIGNOUT,
|
|
2383
|
-
this.routes.VERIFY_REQUEST,
|
|
2384
|
-
this.routes.ERROR
|
|
2385
|
-
],
|
|
2386
|
-
post: [
|
|
2387
|
-
this.routes.TENANT_USERS,
|
|
2388
|
-
this.routes.SIGNUP,
|
|
2389
|
-
this.routes.USERS,
|
|
2390
|
-
this.routes.TENANTS,
|
|
2391
|
-
this.routes.SESSION,
|
|
2392
|
-
`${this.routes.SIGNIN}/{provider}`,
|
|
2393
|
-
this.routes.PASSWORD_RESET,
|
|
2394
|
-
this.routes.PROVIDERS,
|
|
2395
|
-
this.routes.CSRF,
|
|
2396
|
-
`${this.routes.CALLBACK}/{provider}`,
|
|
2397
|
-
this.routes.SIGNOUT
|
|
2398
|
-
],
|
|
2399
|
-
put: [
|
|
2400
|
-
this.routes.TENANT_USERS,
|
|
2401
|
-
this.routes.USERS,
|
|
2402
|
-
this.routes.TENANT,
|
|
2403
|
-
this.routes.PASSWORD_RESET
|
|
2404
|
-
],
|
|
2405
|
-
delete: [this.routes.TENANT_USER, this.routes.TENANT]
|
|
2406
|
-
};
|
|
2424
|
+
return await fetchTenantUser(this.#config, "DELETE");
|
|
2407
2425
|
}
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
this.auth = new Auth(this.config, this.#headers, {
|
|
2412
|
-
resetHeaders: this.resetHeaders
|
|
2413
|
-
});
|
|
2414
|
-
};
|
|
2415
|
-
updateConfig = (config) => {
|
|
2416
|
-
this.config = config;
|
|
2417
|
-
this.handlers = Handlers(this.routes, config);
|
|
2418
|
-
};
|
|
2419
|
-
resetHeaders = (headers) => {
|
|
2420
|
-
this.#headers = new Headers(headers ?? {});
|
|
2421
|
-
setContext(new Headers());
|
|
2422
|
-
this.reset();
|
|
2423
|
-
};
|
|
2424
|
-
set headers(headers) {
|
|
2425
|
-
const updates = [];
|
|
2426
|
-
if (headers instanceof Headers) {
|
|
2427
|
-
headers.forEach((value, key12) => {
|
|
2428
|
-
updates.push([key12.toLowerCase(), value]);
|
|
2429
|
-
});
|
|
2426
|
+
async addMember(req, rawResponse) {
|
|
2427
|
+
if (typeof req === "string") {
|
|
2428
|
+
this.#config.userId = req;
|
|
2430
2429
|
} else {
|
|
2431
|
-
|
|
2432
|
-
|
|
2430
|
+
this.#handleContext(req);
|
|
2431
|
+
}
|
|
2432
|
+
const res = await fetchTenantUser(this.#config, "PUT");
|
|
2433
|
+
return responseHandler(res, rawResponse);
|
|
2434
|
+
}
|
|
2435
|
+
async removeMember(req, rawResponse) {
|
|
2436
|
+
this.#handleContext(req);
|
|
2437
|
+
const res = await fetchTenantUser(this.#config, "DELETE");
|
|
2438
|
+
return responseHandler(res, rawResponse);
|
|
2439
|
+
}
|
|
2440
|
+
async users(req, rawResponse) {
|
|
2441
|
+
this.#handleContext(req);
|
|
2442
|
+
const res = await fetchTenantUsers(this.#config, "GET");
|
|
2443
|
+
return responseHandler(
|
|
2444
|
+
res,
|
|
2445
|
+
rawResponse || typeof req === "boolean" && req
|
|
2446
|
+
);
|
|
2447
|
+
}
|
|
2448
|
+
#handleContext(req) {
|
|
2449
|
+
if (typeof req === "object") {
|
|
2450
|
+
if ("tenantId" in req) {
|
|
2451
|
+
this.#config.tenantId = req.tenantId;
|
|
2452
|
+
}
|
|
2453
|
+
if ("userId" in req) {
|
|
2454
|
+
this.#config.tenantId = req.tenantId;
|
|
2433
2455
|
}
|
|
2434
2456
|
}
|
|
2435
|
-
const merged = {};
|
|
2436
|
-
this.#headers?.forEach((value, key12) => {
|
|
2437
|
-
merged[key12.toLowerCase()] = value;
|
|
2438
|
-
});
|
|
2439
|
-
for (const [key12, value] of updates) {
|
|
2440
|
-
merged[key12] = value;
|
|
2441
|
-
}
|
|
2442
|
-
this.#headers = new Headers();
|
|
2443
|
-
for (const [key12, value] of Object.entries(merged)) {
|
|
2444
|
-
this.#headers.set(key12, value);
|
|
2445
|
-
}
|
|
2446
|
-
this.reset();
|
|
2447
2457
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2458
|
+
};
|
|
2459
|
+
async function responseHandler(res, rawResponse) {
|
|
2460
|
+
if (rawResponse) {
|
|
2461
|
+
return res;
|
|
2450
2462
|
}
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
return parseToken(req.headers);
|
|
2456
|
-
}
|
|
2457
|
-
return null;
|
|
2463
|
+
try {
|
|
2464
|
+
return await res?.clone().json();
|
|
2465
|
+
} catch {
|
|
2466
|
+
return res;
|
|
2458
2467
|
}
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
// src/api/handlers/withContext/index.ts
|
|
2471
|
+
function handlersWithContext(config) {
|
|
2472
|
+
const GET6 = GETTER(config.routes, config);
|
|
2473
|
+
const POST5 = POSTER(config.routes, config);
|
|
2474
|
+
const DELETE4 = DELETER(config.routes, config);
|
|
2475
|
+
const PUT5 = PUTER(config.routes, config);
|
|
2476
|
+
return {
|
|
2477
|
+
GET: async (req) => {
|
|
2478
|
+
const response = await GET6(req);
|
|
2479
|
+
const updatedConfig = updateConfig(response, config);
|
|
2480
|
+
return { response, nile: new Server(updatedConfig) };
|
|
2481
|
+
},
|
|
2482
|
+
POST: async (req) => {
|
|
2483
|
+
const response = await POST5(req);
|
|
2484
|
+
const updatedConfig = updateConfig(response, config);
|
|
2485
|
+
return { response, nile: new Server(updatedConfig) };
|
|
2486
|
+
},
|
|
2487
|
+
DELETE: async (req) => {
|
|
2488
|
+
const response = await DELETE4(req);
|
|
2489
|
+
const updatedConfig = updateConfig(response, config);
|
|
2490
|
+
return { response, nile: new Server(updatedConfig) };
|
|
2491
|
+
},
|
|
2492
|
+
PUT: async (req) => {
|
|
2493
|
+
const response = await PUT5(req);
|
|
2494
|
+
const updatedConfig = updateConfig(response, config);
|
|
2495
|
+
return { response, nile: new Server(updatedConfig) };
|
|
2476
2496
|
}
|
|
2477
|
-
return this.auth.getSession(this.#headers);
|
|
2478
2497
|
};
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2498
|
+
}
|
|
2499
|
+
function updateConfig(response, config) {
|
|
2500
|
+
let origin = "http://localhost:3000";
|
|
2501
|
+
let headers = null;
|
|
2502
|
+
if (response?.status === 302) {
|
|
2503
|
+
const location = response.headers.get("location");
|
|
2504
|
+
if (location) {
|
|
2505
|
+
const urlLocation = new URL(location);
|
|
2506
|
+
origin = urlLocation.origin;
|
|
2486
2507
|
}
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
warn("Set context expects a Request or Header object");
|
|
2508
|
+
}
|
|
2509
|
+
const setCookies = [];
|
|
2510
|
+
if (response?.headers) {
|
|
2511
|
+
for (const [key14, value] of response.headers) {
|
|
2512
|
+
if (key14.toLowerCase() === "set-cookie") {
|
|
2513
|
+
setCookies.push(value);
|
|
2494
2514
|
}
|
|
2495
2515
|
}
|
|
2516
|
+
}
|
|
2517
|
+
if (setCookies.length > 0) {
|
|
2518
|
+
const cookieHeader = setCookies.map((cookieStr) => cookieStr.split(";")[0]).join("; ");
|
|
2519
|
+
headers = new Headers({ cookie: cookieHeader });
|
|
2520
|
+
}
|
|
2521
|
+
return {
|
|
2522
|
+
...config,
|
|
2523
|
+
origin,
|
|
2524
|
+
headers: headers ?? void 0
|
|
2496
2525
|
};
|
|
2497
|
-
}
|
|
2526
|
+
}
|
|
2498
2527
|
|
|
2499
2528
|
// src/Server.ts
|
|
2500
2529
|
var Server = class {
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2530
|
+
users;
|
|
2531
|
+
tenants;
|
|
2532
|
+
auth;
|
|
2533
|
+
#config;
|
|
2534
|
+
#handlers;
|
|
2535
|
+
#paths;
|
|
2536
|
+
#manager;
|
|
2537
|
+
#headers;
|
|
2504
2538
|
constructor(config) {
|
|
2505
|
-
this
|
|
2506
|
-
this.api = new Api(this.config);
|
|
2507
|
-
this.manager = new DBManager(this.config);
|
|
2539
|
+
this.#config = new Config(config, "[initial config]");
|
|
2508
2540
|
watchTenantId((tenantId) => {
|
|
2509
|
-
this.tenantId
|
|
2541
|
+
if (tenantId !== this.#config.tenantId) {
|
|
2542
|
+
this.#config.tenantId = tenantId;
|
|
2543
|
+
this.#reset();
|
|
2544
|
+
}
|
|
2510
2545
|
});
|
|
2511
2546
|
watchUserId((userId) => {
|
|
2512
|
-
this.userId
|
|
2547
|
+
if (userId !== this.#config.userId) {
|
|
2548
|
+
this.#config.userId = userId;
|
|
2549
|
+
this.#reset();
|
|
2550
|
+
}
|
|
2513
2551
|
});
|
|
2514
|
-
|
|
2515
|
-
this.
|
|
2552
|
+
watchHeaders((headers) => {
|
|
2553
|
+
this.setContext(headers);
|
|
2554
|
+
this.#reset();
|
|
2516
2555
|
});
|
|
2556
|
+
this.#handlers = {
|
|
2557
|
+
...this.#config.handlers,
|
|
2558
|
+
withContext: handlersWithContext(this.#config)
|
|
2559
|
+
};
|
|
2560
|
+
this.#paths = this.#config.paths;
|
|
2561
|
+
this.#config.tenantId = getTenantId({ config: this.#config });
|
|
2562
|
+
this.#manager = new DBManager(this.#config);
|
|
2563
|
+
this.#handleHeaders(config);
|
|
2564
|
+
this.users = new Users(this.#config);
|
|
2565
|
+
this.tenants = new Tenants(this.#config);
|
|
2566
|
+
this.auth = new Auth(this.#config);
|
|
2517
2567
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2568
|
+
get db() {
|
|
2569
|
+
const pool = this.#manager.getConnection(this.#config);
|
|
2570
|
+
return Object.assign(pool, {
|
|
2571
|
+
clearConnections: () => {
|
|
2572
|
+
this.#manager.clear(this.#config);
|
|
2573
|
+
}
|
|
2574
|
+
});
|
|
2521
2575
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2576
|
+
/**
|
|
2577
|
+
* A convenience function that applies a config and ensures whatever was passed is set properly
|
|
2578
|
+
*/
|
|
2579
|
+
getInstance(config, req) {
|
|
2580
|
+
const _config = { ...this.#config, ...config };
|
|
2581
|
+
const updatedConfig = new Config(_config);
|
|
2582
|
+
this.#config = new Config(updatedConfig);
|
|
2583
|
+
this.#config.tenantId = config.tenantId;
|
|
2584
|
+
this.#config.userId = config.userId;
|
|
2585
|
+
if (req) {
|
|
2586
|
+
this.setContext(req);
|
|
2527
2587
|
}
|
|
2588
|
+
this.#reset();
|
|
2589
|
+
return this;
|
|
2528
2590
|
}
|
|
2529
|
-
|
|
2530
|
-
return this
|
|
2531
|
-
}
|
|
2532
|
-
set userId(userId) {
|
|
2533
|
-
this.databaseId = this.config.databaseId;
|
|
2534
|
-
this.config.userId = userId;
|
|
2535
|
-
if (this.api) {
|
|
2536
|
-
this.api.users.userId = this.config.userId;
|
|
2537
|
-
this.api.tenants.userId = this.config.userId;
|
|
2538
|
-
}
|
|
2591
|
+
getPaths() {
|
|
2592
|
+
return this.#paths;
|
|
2539
2593
|
}
|
|
2540
|
-
get
|
|
2541
|
-
return this
|
|
2594
|
+
get handlers() {
|
|
2595
|
+
return this.#handlers;
|
|
2542
2596
|
}
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2597
|
+
/**
|
|
2598
|
+
* Allow the setting of headers from a req or header object.
|
|
2599
|
+
* Makes it possible to handle REST requests easily
|
|
2600
|
+
* Also makes it easy to set user + tenant in some way
|
|
2601
|
+
* @param req
|
|
2602
|
+
* @returns undefined
|
|
2603
|
+
*/
|
|
2604
|
+
setContext(req) {
|
|
2605
|
+
try {
|
|
2606
|
+
if (req instanceof Headers) {
|
|
2607
|
+
this.#handleHeaders(req);
|
|
2608
|
+
this.#reset();
|
|
2609
|
+
return;
|
|
2610
|
+
} else if (req instanceof Request) {
|
|
2611
|
+
this.#handleHeaders(new Headers(req.headers));
|
|
2612
|
+
this.#reset();
|
|
2613
|
+
return;
|
|
2614
|
+
}
|
|
2615
|
+
} catch {
|
|
2549
2616
|
}
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
if (
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2617
|
+
let ok = false;
|
|
2618
|
+
if (req && typeof req === "object" && "tenantId" in req) {
|
|
2619
|
+
ok = true;
|
|
2620
|
+
this.#config.tenantId = req.tenantId;
|
|
2621
|
+
}
|
|
2622
|
+
if (req && typeof req === "object" && "userId" in req) {
|
|
2623
|
+
ok = true;
|
|
2624
|
+
this.#config.userId = req.userId;
|
|
2625
|
+
}
|
|
2626
|
+
if (ok) {
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
if (typeof req === "object") {
|
|
2630
|
+
const headers = new Headers(req);
|
|
2631
|
+
if (headers) {
|
|
2632
|
+
this.#handleHeaders(headers);
|
|
2633
|
+
this.#reset();
|
|
2634
|
+
return;
|
|
2560
2635
|
}
|
|
2561
2636
|
}
|
|
2637
|
+
const { warn } = Logger(this.#config, "[API]");
|
|
2638
|
+
if (warn) {
|
|
2639
|
+
warn(
|
|
2640
|
+
"Set context expects a Request, Header instance or an object of Record<string, string>"
|
|
2641
|
+
);
|
|
2642
|
+
}
|
|
2562
2643
|
}
|
|
2563
|
-
|
|
2564
|
-
return
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2644
|
+
getContext() {
|
|
2645
|
+
return {
|
|
2646
|
+
headers: this.#headers,
|
|
2647
|
+
userId: this.#config.userId,
|
|
2648
|
+
tenantId: this.#config.tenantId
|
|
2649
|
+
};
|
|
2568
2650
|
}
|
|
2569
2651
|
/**
|
|
2570
|
-
*
|
|
2652
|
+
* Merge headers together
|
|
2653
|
+
* Internally, passed a NileConfig, externally, should be using Headers
|
|
2571
2654
|
*/
|
|
2572
|
-
|
|
2573
|
-
const
|
|
2574
|
-
|
|
2575
|
-
this
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
if (
|
|
2579
|
-
|
|
2655
|
+
#handleHeaders(config) {
|
|
2656
|
+
const updates = [];
|
|
2657
|
+
let headers;
|
|
2658
|
+
this.#headers = new Headers();
|
|
2659
|
+
if (config instanceof Headers) {
|
|
2660
|
+
headers = config;
|
|
2661
|
+
} else if (config?.headers) {
|
|
2662
|
+
headers = config?.headers;
|
|
2663
|
+
if (config && config.origin) {
|
|
2664
|
+
this.#headers.set(X_NILE_ORIGIN, config.origin);
|
|
2665
|
+
}
|
|
2666
|
+
if (config && config.secureCookies != null) {
|
|
2667
|
+
this.#headers.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
|
|
2668
|
+
}
|
|
2580
2669
|
}
|
|
2581
|
-
|
|
2582
|
-
|
|
2670
|
+
if (headers instanceof Headers) {
|
|
2671
|
+
headers.forEach((value, key14) => {
|
|
2672
|
+
updates.push([key14.toLowerCase(), value]);
|
|
2673
|
+
});
|
|
2674
|
+
} else {
|
|
2675
|
+
for (const [key14, value] of Object.entries(headers ?? {})) {
|
|
2676
|
+
updates.push([key14.toLowerCase(), value]);
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
const merged = {};
|
|
2680
|
+
this.#headers?.forEach((value, key14) => {
|
|
2681
|
+
if (key14.toLowerCase() !== "cookie") {
|
|
2682
|
+
merged[key14.toLowerCase()] = value;
|
|
2683
|
+
}
|
|
2684
|
+
});
|
|
2685
|
+
for (const [key14, value] of updates) {
|
|
2686
|
+
merged[key14] = value;
|
|
2687
|
+
}
|
|
2688
|
+
for (const [key14, value] of Object.entries(merged)) {
|
|
2689
|
+
this.#headers.set(key14, value);
|
|
2690
|
+
}
|
|
2691
|
+
this.#config.headers = this.#headers;
|
|
2583
2692
|
}
|
|
2693
|
+
/**
|
|
2694
|
+
* Allow some internal mutations to reset our config + headers
|
|
2695
|
+
*/
|
|
2696
|
+
#reset = () => {
|
|
2697
|
+
this.#config.headers = this.#headers ?? new Headers();
|
|
2698
|
+
this.users = new Users(this.#config);
|
|
2699
|
+
this.tenants = new Tenants(this.#config);
|
|
2700
|
+
this.auth = new Auth(this.#config);
|
|
2701
|
+
};
|
|
2584
2702
|
};
|
|
2585
2703
|
var server;
|
|
2586
2704
|
function create(config) {
|
|
@@ -2590,6 +2708,6 @@ function create(config) {
|
|
|
2590
2708
|
return server;
|
|
2591
2709
|
}
|
|
2592
2710
|
|
|
2593
|
-
export { LoginUserResponseTokenTypeEnum, create as Nile, Server };
|
|
2711
|
+
export { APIErrorErrorCodeEnum, LoginUserResponseTokenTypeEnum, create as Nile, Server, parseCSRF, parseCallback, parseToken };
|
|
2594
2712
|
//# sourceMappingURL=index.mjs.map
|
|
2595
2713
|
//# sourceMappingURL=index.mjs.map
|