@niledatabase/server 5.0.0-alpha.1 → 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/index.mjs CHANGED
@@ -27,7 +27,8 @@ var LoginUserResponseTokenTypeEnum = {
27
27
 
28
28
  // src/api/utils/routes/index.ts
29
29
  var NILEDB_API_URL = process.env.NILEDB_API_URL;
30
- var appRoutes = (prefix = "/api") => ({
30
+ var DEFAULT_PREFIX = "/api";
31
+ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
31
32
  SIGNIN: `${prefix}${"/auth/signin" /* SIGNIN */}`,
32
33
  PROVIDERS: `${prefix}${"/auth/providers" /* PROVIDERS */}`,
33
34
  SESSION: `${prefix}${"/auth/session" /* SESSION */}`,
@@ -36,7 +37,8 @@ var appRoutes = (prefix = "/api") => ({
36
37
  SIGNOUT: `${prefix}${"/auth/signout" /* SIGNOUT */}`,
37
38
  ERROR: `${prefix}/auth/error`,
38
39
  VERIFY_REQUEST: `${prefix}/auth/verify-request`,
39
- PASSWORD_RESET: `${prefix}/auth/reset-password`,
40
+ VERIFY_EMAIL: `${prefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`,
41
+ PASSWORD_RESET: `${prefix}${"/auth/reset-password" /* PASSWORD_RESET */}`,
40
42
  ME: `${prefix}${"/me" /* ME */}`,
41
43
  USERS: `${prefix}${"/users" /* USERS */}`,
42
44
  USER_TENANTS: `${prefix}${"/users/{userId}/tenants" /* USER_TENANTS */}`,
@@ -70,7 +72,8 @@ var proxyRoutes = (config) => ({
70
72
  SIGNOUT: makeRestUrl(config, "/auth/signout" /* SIGNOUT */),
71
73
  ERROR: makeRestUrl(config, "/auth/error"),
72
74
  VERIFY_REQUEST: makeRestUrl(config, "/auth/verify-request"),
73
- PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password")
75
+ PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password" /* PASSWORD_RESET */),
76
+ VERIFY_EMAIL: makeRestUrl(config, "/auth/verify-email" /* VERIFY_EMAIL */)
74
77
  });
75
78
  function filterNullUndefined(obj) {
76
79
  if (!obj) {
@@ -95,9 +98,9 @@ function makeRestUrl(config, path, qp) {
95
98
  const strParams = params.toString();
96
99
  return `${[url, path.substring(1, path.length)].join("/")}${strParams ? `?${strParams}` : ""}`;
97
100
  }
98
- function urlMatches(requestUrl, route16) {
101
+ function urlMatches(requestUrl, route17) {
99
102
  const url = new URL(requestUrl);
100
- return url.pathname.startsWith(route16);
103
+ return url.pathname.startsWith(route17);
101
104
  }
102
105
  function isUUID(value) {
103
106
  if (!value) {
@@ -167,9 +170,9 @@ function matchesLog(configRoutes, request2) {
167
170
  }
168
171
 
169
172
  // src/utils/constants.ts
170
- var X_NILE_TENANT = "nile.tenant_id";
171
- var X_NILE_ORIGIN = "nile.origin";
172
- var X_NILE_SECURECOOKIES = "nile.secure_cookies";
173
+ var X_NILE_TENANT = "nile-tenant-id";
174
+ var X_NILE_ORIGIN = "nile-origin";
175
+ var X_NILE_SECURECOOKIES = "nile-secure-cookies";
173
176
 
174
177
  // src/api/utils/request.ts
175
178
  async function request(url, _init, config) {
@@ -188,15 +191,29 @@ async function request(url, _init, config) {
188
191
  }
189
192
  if (config.secureCookies != null) {
190
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
+ );
191
199
  }
192
200
  updatedHeaders.set("host", requestUrl.host);
193
201
  if (config.callbackUrl) {
194
202
  const cbUrl = new URL(config.callbackUrl);
195
203
  debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
196
204
  updatedHeaders.set(X_NILE_ORIGIN, cbUrl.origin);
205
+ } else if (config.origin) {
206
+ debug(`Obtained origin from config.origin ${config.origin}`);
207
+ updatedHeaders.set(X_NILE_ORIGIN, config.origin);
197
208
  } else {
198
- updatedHeaders.set(X_NILE_ORIGIN, requestUrl.origin);
199
- debug(`Obtained origin from request ${requestUrl.origin}`);
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
+ }
200
217
  }
201
218
  const params = { ...init };
202
219
  if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
@@ -300,7 +317,7 @@ function matches(configRoutes, request2) {
300
317
  return urlMatches(request2.url, configRoutes[key]);
301
318
  }
302
319
  async function fetchMe(config, method, body) {
303
- const clientUrl = `${config.origin}${config.routePrefix}${"/me" /* ME */}`;
320
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
304
321
  const init = {
305
322
  headers: config.headers,
306
323
  method: method ?? "GET"
@@ -330,47 +347,6 @@ async function GET(url, init, config) {
330
347
  return res;
331
348
  }
332
349
 
333
- // src/utils/Event/index.ts
334
- var Eventer = class {
335
- events = {};
336
- publish(eventName, value) {
337
- const callbacks = this.events[eventName];
338
- if (callbacks) {
339
- for (const callback of callbacks) {
340
- callback(value);
341
- }
342
- }
343
- }
344
- subscribe(eventName, callback) {
345
- if (!this.events[eventName]) {
346
- this.events[eventName] = [];
347
- }
348
- this.events[eventName].push(callback);
349
- }
350
- unsubscribe(eventName, callback) {
351
- const callbacks = this.events[eventName];
352
- if (!callbacks) return;
353
- const index = callbacks.indexOf(callback);
354
- if (index !== -1) {
355
- callbacks.splice(index, 1);
356
- }
357
- if (callbacks.length === 0) {
358
- delete this.events[eventName];
359
- }
360
- }
361
- };
362
- var eventer = new Eventer();
363
- var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
364
- var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
365
- var evictPool = (val) => {
366
- eventer.publish("EvictPool" /* EvictPool */, val);
367
- };
368
- var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
369
- var updateHeaders = (val) => {
370
- eventer.publish("headers" /* Headers */, val);
371
- };
372
- var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
373
-
374
350
  // src/utils/fetch.ts
375
351
  function getTokenFromCookie(headers, cookieKey) {
376
352
  const cookie = headers.get("cookie")?.split("; ");
@@ -509,11 +485,11 @@ async function route3(request2, config) {
509
485
  function matches3(configRoutes, request2) {
510
486
  const url = new URL(request2.url);
511
487
  const [userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
512
- let route16 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
488
+ let route17 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
513
489
  if (userId === "users") {
514
- route16 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
490
+ route17 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
515
491
  }
516
- return urlMatches(request2.url, route16);
492
+ return urlMatches(request2.url, route17);
517
493
  }
518
494
  async function fetchTenantUsers(config, method, payload) {
519
495
  const { body, params } = {};
@@ -534,7 +510,7 @@ async function fetchTenantUsers(config, method, payload) {
534
510
  if (params?.tenantId) {
535
511
  q.set("tenantId", params.tenantId);
536
512
  }
537
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
513
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
538
514
  "{tenantId}",
539
515
  config.tenantId
540
516
  )}`;
@@ -636,7 +612,7 @@ function matches4(configRoutes, request2) {
636
612
  return urlMatches(request2.url, configRoutes[key4]);
637
613
  }
638
614
  async function fetchTenants(config, method, body) {
639
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
615
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
640
616
  const init = {
641
617
  method,
642
618
  headers: config.headers
@@ -658,7 +634,7 @@ async function fetchTenant(config, method, body) {
658
634
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
659
635
  );
660
636
  }
661
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
637
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
662
638
  const m = method ?? "GET";
663
639
  const init = {
664
640
  method: m,
@@ -682,7 +658,7 @@ async function fetchTenantsByUser(config) {
682
658
  );
683
659
  }
684
660
  }
685
- const clientUrl = `${config.origin}${config.routePrefix}${"/users/{userId}/tenants" /* USER_TENANTS */.replace(
661
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/users/{userId}/tenants" /* USER_TENANTS */.replace(
686
662
  "{userId}",
687
663
  config.userId ?? "WARN_NOT_SET"
688
664
  )}`;
@@ -712,7 +688,7 @@ function matches5(configRoutes, request2) {
712
688
  return urlMatches(request2.url, configRoutes[key5]);
713
689
  }
714
690
  async function fetchSignIn(config, provider, body) {
715
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
691
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
716
692
  const req = new Request(clientUrl, {
717
693
  method: "POST",
718
694
  headers: config.headers,
@@ -736,7 +712,7 @@ function matches6(configRoutes, request2) {
736
712
  return urlMatches(request2.url, configRoutes.SESSION);
737
713
  }
738
714
  async function fetchSession(config) {
739
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
715
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
740
716
  const req = new Request(clientUrl, {
741
717
  method: "GET",
742
718
  headers: config.headers
@@ -759,7 +735,7 @@ function matches7(configRoutes, request2) {
759
735
  return urlMatches(request2.url, configRoutes.PROVIDERS);
760
736
  }
761
737
  async function fetchProviders(config) {
762
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
738
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
763
739
  const req = new Request(clientUrl, {
764
740
  method: "GET",
765
741
  headers: config.headers
@@ -782,7 +758,7 @@ function matches8(configRoutes, request2) {
782
758
  return urlMatches(request2.url, configRoutes.CSRF);
783
759
  }
784
760
  async function fetchCsrf(config) {
785
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
761
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
786
762
  const req = new Request(clientUrl, {
787
763
  method: "GET",
788
764
  headers: config.headers
@@ -831,10 +807,10 @@ async function route9(req, config) {
831
807
  function matches9(configRoutes, request2) {
832
808
  return urlMatches(request2.url, configRoutes.CALLBACK);
833
809
  }
834
- async function fetchCallback(config, provider, body) {
835
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}`;
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}` : ""}`;
836
812
  const req = new Request(clientUrl, {
837
- method: "POST",
813
+ method,
838
814
  headers: config.headers,
839
815
  body
840
816
  });
@@ -860,7 +836,7 @@ function matches10(configRoutes, request2) {
860
836
  return urlMatches(request2.url, configRoutes[key7]);
861
837
  }
862
838
  async function fetchSignOut(config, body) {
863
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
839
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
864
840
  const req = new Request(clientUrl, {
865
841
  method: "POST",
866
842
  body,
@@ -928,6 +904,60 @@ async function route13(req, config) {
928
904
  function matches13(configRoutes, request2) {
929
905
  return urlMatches(request2.url, configRoutes.PASSWORD_RESET);
930
906
  }
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;
917
+ }
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
939
+ });
940
+ }
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
+ }
931
961
 
932
962
  // src/api/handlers/GET.ts
933
963
  function GETTER(configRoutes, config) {
@@ -981,6 +1011,10 @@ function GETTER(configRoutes, config) {
981
1011
  info("matches verify-request");
982
1012
  return route12(req, config);
983
1013
  }
1014
+ if (matches14(configRoutes, req)) {
1015
+ info("matches verify-email");
1016
+ return route14(req, config);
1017
+ }
984
1018
  if (matches11(configRoutes, req)) {
985
1019
  info("matches error");
986
1020
  return route11(req, config);
@@ -999,8 +1033,8 @@ async function POST4(config, init) {
999
1033
  }
1000
1034
 
1001
1035
  // src/api/routes/signup/index.tsx
1002
- var key11 = "SIGNUP";
1003
- async function route14(request2, config) {
1036
+ var key12 = "SIGNUP";
1037
+ async function route15(request2, config) {
1004
1038
  switch (request2.method) {
1005
1039
  case "POST":
1006
1040
  return await POST4(config, { request: request2 });
@@ -1008,8 +1042,8 @@ async function route14(request2, config) {
1008
1042
  return new Response("method not allowed", { status: 405 });
1009
1043
  }
1010
1044
  }
1011
- function matches14(configRoutes, request2) {
1012
- return urlMatches(request2.url, configRoutes[key11]);
1045
+ function matches15(configRoutes, request2) {
1046
+ return urlMatches(request2.url, configRoutes[key12]);
1013
1047
  }
1014
1048
  async function fetchSignUp(config, payload) {
1015
1049
  const { body, params } = payload ?? {};
@@ -1020,7 +1054,7 @@ async function fetchSignUp(config, payload) {
1020
1054
  if (params?.tenantId) {
1021
1055
  q.set("tenantId", params.tenantId);
1022
1056
  }
1023
- const clientUrl = `${config.origin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1057
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1024
1058
  const req = new Request(clientUrl, {
1025
1059
  method: "POST",
1026
1060
  headers: config.headers,
@@ -1034,24 +1068,21 @@ function POSTER(configRoutes, config) {
1034
1068
  const { info, warn, error } = Logger(config, "[POST MATCHER]");
1035
1069
  return async function POST5(req) {
1036
1070
  if (matchesLog(configRoutes, req)) {
1037
- if (req.body) {
1038
- try {
1039
- const text = await req.text();
1040
- error(text);
1041
- return new Response(null, {
1042
- status: 200
1043
- });
1044
- } catch (e) {
1045
- }
1071
+ try {
1072
+ const json = await req.clone().json();
1073
+ error(req.body && json);
1074
+ } catch {
1075
+ error(await req.text());
1046
1076
  }
1077
+ return new Response(null, { status: 200 });
1047
1078
  }
1048
1079
  if (matches3(configRoutes, req)) {
1049
1080
  info("matches tenant users");
1050
1081
  return route3(req, config);
1051
1082
  }
1052
- if (matches14(configRoutes, req)) {
1083
+ if (matches15(configRoutes, req)) {
1053
1084
  info("matches signup");
1054
- return route14(req, config);
1085
+ return route15(req, config);
1055
1086
  }
1056
1087
  if (matches2(configRoutes, req)) {
1057
1088
  info("matches users");
@@ -1089,6 +1120,10 @@ function POSTER(configRoutes, config) {
1089
1120
  info("matches signout");
1090
1121
  return route10(req, config);
1091
1122
  }
1123
+ if (matches14(configRoutes, req)) {
1124
+ info("matches verify-email");
1125
+ return route14(req, config);
1126
+ }
1092
1127
  warn(`No POST routes matched ${req.url}`);
1093
1128
  return new Response(null, { status: 404 });
1094
1129
  };
@@ -1117,11 +1152,11 @@ async function PUT4(config, init) {
1117
1152
  }
1118
1153
 
1119
1154
  // src/api/routes/tenants/[tenantId]/users/[userId]/index.ts
1120
- var key12 = "TENANT_USER";
1121
- async function route15(request2, config) {
1155
+ var key13 = "TENANT_USER";
1156
+ async function route16(request2, config) {
1122
1157
  const { info } = Logger(
1123
1158
  { ...config, debug: config.debug },
1124
- `[ROUTES][${key12}]`
1159
+ `[ROUTES][${key13}]`
1125
1160
  );
1126
1161
  const session = await auth(request2, config);
1127
1162
  if (!session) {
@@ -1143,14 +1178,14 @@ async function route15(request2, config) {
1143
1178
  return new Response("method not allowed", { status: 405 });
1144
1179
  }
1145
1180
  }
1146
- function matches15(configRoutes, request2) {
1181
+ function matches16(configRoutes, request2) {
1147
1182
  const url = new URL(request2.url);
1148
1183
  const [, userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
1149
- let route16 = configRoutes[key12].replace("{tenantId}", tenantId).replace("{userId}", userId);
1184
+ let route17 = configRoutes[key13].replace("{tenantId}", tenantId).replace("{userId}", userId);
1150
1185
  if (userId === "users") {
1151
- route16 = configRoutes[key12].replace("{tenantId}", possibleTenantId);
1186
+ route17 = configRoutes[key13].replace("{tenantId}", possibleTenantId);
1152
1187
  }
1153
- return urlMatches(request2.url, route16);
1188
+ return urlMatches(request2.url, route17);
1154
1189
  }
1155
1190
  async function fetchTenantUser(config, method) {
1156
1191
  if (!config.tenantId) {
@@ -1163,7 +1198,7 @@ async function fetchTenantUser(config, method) {
1163
1198
  "the userId context is missing. Call nile.setContext({ userId })"
1164
1199
  );
1165
1200
  }
1166
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1201
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1167
1202
  "{tenantId}",
1168
1203
  config.tenantId
1169
1204
  ).replace("{userId}", config.userId)}/link`;
@@ -1178,9 +1213,9 @@ async function fetchTenantUser(config, method) {
1178
1213
  function DELETER(configRoutes, config) {
1179
1214
  const { info, warn } = Logger(config, "[DELETE MATCHER]");
1180
1215
  return async function DELETE4(req) {
1181
- if (matches15(configRoutes, req)) {
1216
+ if (matches16(configRoutes, req)) {
1182
1217
  info("matches tenant user");
1183
- return route15(req, config);
1218
+ return route16(req, config);
1184
1219
  }
1185
1220
  if (matches3(configRoutes, req)) {
1186
1221
  info("matches tenant users");
@@ -1203,9 +1238,9 @@ function DELETER(configRoutes, config) {
1203
1238
  function PUTER(configRoutes, config) {
1204
1239
  const { info, warn } = Logger(config, "[PUT MATCHER]");
1205
1240
  return async function PUT5(req) {
1206
- if (matches15(configRoutes, req)) {
1241
+ if (matches16(configRoutes, req)) {
1207
1242
  info("matches tenant user");
1208
- return route15(req, config);
1243
+ return route16(req, config);
1209
1244
  }
1210
1245
  if (matches3(configRoutes, req)) {
1211
1246
  info("matches tenant users");
@@ -1423,7 +1458,6 @@ var stringCheck = (str) => {
1423
1458
  // src/utils/Config/index.ts
1424
1459
  var Config = class {
1425
1460
  routes;
1426
- // handlersWithContext;
1427
1461
  handlers;
1428
1462
  paths;
1429
1463
  logger;
@@ -1444,6 +1478,10 @@ var Config = class {
1444
1478
  */
1445
1479
  apiUrl;
1446
1480
  origin;
1481
+ /**
1482
+ * important for separating the `origin` config value from a default in order to make requests
1483
+ */
1484
+ serverOrigin;
1447
1485
  debug;
1448
1486
  /**
1449
1487
  * To use secure cookies or not in the fetch
@@ -1462,7 +1500,8 @@ var Config = class {
1462
1500
  this.secureCookies = getSecureCookies(envVarConfig);
1463
1501
  this.callbackUrl = getCallbackUrl(envVarConfig);
1464
1502
  this.debug = config?.debug;
1465
- this.origin = config?.origin ?? "http://localhost:3000";
1503
+ this.origin = config?.origin;
1504
+ this.serverOrigin = config?.origin ?? "http://localhost:3000";
1466
1505
  this.apiUrl = getApiUrl(envVarConfig);
1467
1506
  const user = getUsername(envVarConfig);
1468
1507
  const password = getPassword(envVarConfig);
@@ -1533,6 +1572,47 @@ var Config = class {
1533
1572
  }
1534
1573
  };
1535
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
+ }
1584
+ }
1585
+ }
1586
+ subscribe(eventName, callback) {
1587
+ if (!this.events[eventName]) {
1588
+ this.events[eventName] = [];
1589
+ }
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);
1598
+ }
1599
+ if (callbacks.length === 0) {
1600
+ delete this.events[eventName];
1601
+ }
1602
+ }
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);
1615
+
1536
1616
  // src/db/PoolProxy.ts
1537
1617
  function createProxyForPool(pool, config) {
1538
1618
  const { info, error } = Logger(config, "[pool]");
@@ -1757,336 +1837,247 @@ var DBManager = class {
1757
1837
  };
1758
1838
  };
1759
1839
 
1760
- // src/users/index.ts
1761
- var Users = class {
1840
+ // src/auth/index.ts
1841
+ var Auth = class {
1842
+ #logger;
1762
1843
  #config;
1763
1844
  constructor(config) {
1764
1845
  this.#config = config;
1846
+ this.#logger = Logger(config, "[auth]");
1765
1847
  }
1766
- async updateSelf(req, rawResponse) {
1767
- const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
1848
+ async getSession(rawResponse = false) {
1849
+ const res = await fetchSession(this.#config);
1768
1850
  if (rawResponse) {
1769
1851
  return res;
1770
1852
  }
1771
1853
  try {
1772
- return await res?.clone().json();
1854
+ const session = await res.clone().json();
1855
+ if (Object.keys(session).length === 0) {
1856
+ return void 0;
1857
+ }
1858
+ return session;
1773
1859
  } catch {
1774
1860
  return res;
1775
1861
  }
1776
1862
  }
1777
- async removeSelf() {
1778
- const me = await this.getSelf();
1779
- if ("id" in me) {
1780
- this.#config.userId = me.id;
1781
- }
1782
- const res = await fetchMe(this.#config, "DELETE");
1783
- updateHeaders(new Headers());
1784
- return res;
1863
+ async getCsrf(rawResponse = false) {
1864
+ return await getCsrf(this.#config, rawResponse);
1785
1865
  }
1786
- async getSelf(rawResponse) {
1787
- const res = await fetchMe(this.#config);
1866
+ async listProviders(rawResponse = false) {
1867
+ const res = await fetchProviders(this.#config);
1788
1868
  if (rawResponse) {
1789
1869
  return res;
1790
1870
  }
1791
1871
  try {
1792
- return await res?.clone().json();
1872
+ return await res.clone().json();
1793
1873
  } catch {
1794
1874
  return res;
1795
1875
  }
1796
1876
  }
1797
- };
1798
-
1799
- // src/tenants/index.ts
1800
- var Tenants = class {
1801
- #logger;
1802
- #config;
1803
- constructor(config) {
1804
- this.#logger = Logger(config, "[tenants]");
1805
- this.#config = config;
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();
1889
+ return res;
1806
1890
  }
1807
- async create(req, rawResponse) {
1808
- let res;
1809
- if (typeof req === "string") {
1810
- res = await fetchTenants(
1811
- this.#config,
1812
- "POST",
1813
- JSON.stringify({ name: req })
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."
1814
1897
  );
1815
- } else if (typeof req === "object" && ("name" in req || "id" in req)) {
1816
- res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
1817
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);
1818
1930
  if (rawResponse) {
1819
1931
  return res;
1820
1932
  }
1821
1933
  try {
1822
- return await res?.clone().json();
1823
- } catch {
1824
- return res;
1825
- }
1826
- }
1827
- async delete(req) {
1828
- if (typeof req === "string") {
1829
- this.#config.tenantId = req;
1830
- }
1831
- if (typeof req === "object" && "id" in req) {
1832
- this.#config.tenantId = req.id;
1833
- }
1834
- const res = await fetchTenant(this.#config, "DELETE");
1835
- return res;
1836
- }
1837
- async get(req, rawResponse) {
1838
- if (typeof req === "string") {
1839
- this.#config.tenantId = req;
1840
- } else if (typeof req === "object" && "id" in req) {
1841
- this.#config.tenantId = req.id;
1842
- }
1843
- const res = await fetchTenant(this.#config, "GET");
1844
- if (rawResponse === true || req === true) {
1845
- return res;
1846
- }
1847
- try {
1848
- return await res?.clone().json();
1934
+ return await res.clone().json();
1849
1935
  } catch {
1850
1936
  return res;
1851
1937
  }
1852
1938
  }
1853
- async update(req, rawResponse) {
1854
- let res;
1855
- if (typeof req === "object" && ("name" in req || "id" in req)) {
1856
- const { id, ...remaining } = req;
1857
- if (id) {
1858
- this.#config.tenantId = id;
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;
1859
1951
  }
1860
- res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
1861
- }
1862
- if (rawResponse) {
1863
- return res;
1864
- }
1865
- try {
1866
- return await res?.clone().json();
1867
- } catch {
1868
- return res;
1869
- }
1870
- }
1871
- async list(req) {
1872
- const res = await fetchTenantsByUser(this.#config);
1873
- if (req === true) {
1874
- return res;
1875
- }
1876
- try {
1877
- return await res?.clone().json();
1878
- } catch {
1879
- return res;
1880
- }
1881
- }
1882
- async leaveTenant(req) {
1883
- const me = await fetchMe(this.#config);
1884
- try {
1885
- const json = await me.json();
1886
- if ("id" in json) {
1887
- this.#config.userId = json.id;
1952
+ if (body2.callbackUrl) {
1953
+ callbackUrl = body2.callbackUrl;
1954
+ }
1955
+ if (body2.redirectUrl) {
1956
+ redirectUrl = body2.redirectUrl;
1888
1957
  }
1889
- } catch {
1890
- }
1891
- if (typeof req === "string") {
1892
- this.#config.tenantId = req;
1893
- } else {
1894
- this.#handleContext(req);
1895
- }
1896
- return await fetchTenantUser(this.#config, "DELETE");
1897
- }
1898
- async addMember(req, rawResponse) {
1899
- if (typeof req === "string") {
1900
- this.#config.userId = req;
1901
1958
  } else {
1902
- this.#handleContext(req);
1903
- }
1904
- const res = await fetchTenantUser(this.#config, "PUT");
1905
- return responseHandler(res, rawResponse);
1906
- }
1907
- async removeMember(req, rawResponse) {
1908
- this.#handleContext(req);
1909
- const res = await fetchTenantUser(this.#config, "DELETE");
1910
- return responseHandler(res, rawResponse);
1911
- }
1912
- async users(req, rawResponse) {
1913
- this.#handleContext(req);
1914
- const res = await fetchTenantUsers(this.#config, "GET");
1915
- return responseHandler(
1916
- res,
1917
- rawResponse || typeof req === "boolean" && req
1918
- );
1919
- }
1920
- #handleContext(req) {
1921
- if (typeof req === "object") {
1922
- if ("tenantId" in req) {
1923
- this.#config.tenantId = req.tenantId;
1959
+ if ("email" in req) {
1960
+ email = req.email;
1924
1961
  }
1925
- if ("userId" in req) {
1926
- this.#config.tenantId = req.tenantId;
1962
+ if ("password" in req) {
1963
+ password = req.password;
1927
1964
  }
1928
- }
1929
- }
1930
- };
1931
- async function responseHandler(res, rawResponse) {
1932
- if (rawResponse) {
1933
- return res;
1934
- }
1935
- try {
1936
- return await res?.clone().json();
1937
- } catch {
1938
- return res;
1939
- }
1940
- }
1941
-
1942
- // src/auth/index.ts
1943
- var Auth = class {
1944
- #logger;
1945
- #config;
1946
- constructor(config) {
1947
- this.#config = config;
1948
- this.#logger = Logger(config, "[auth]");
1949
- }
1950
- async getSession(rawResponse = false) {
1951
- const res = await fetchSession(this.#config);
1952
- if (rawResponse) {
1953
- return res;
1954
- }
1955
- try {
1956
- const session = await res.clone().json();
1957
- if (Object.keys(session).length === 0) {
1958
- return void 0;
1965
+ if ("callbackUrl" in req) {
1966
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
1959
1967
  }
1960
- return session;
1961
- } catch {
1962
- return res;
1963
- }
1964
- }
1965
- async getCsrf(rawResponse = false) {
1966
- const res = await fetchCsrf(this.#config);
1967
- const csrfCook = parseCSRF(res.headers);
1968
- if (csrfCook) {
1969
- const [, value] = csrfCook.split("=");
1970
- const [token] = decodeURIComponent(value).split("|");
1971
- const setCookie = res.headers.get("set-cookie");
1972
- if (setCookie) {
1973
- const cookie = [
1974
- csrfCook,
1975
- parseCallback(res.headers),
1976
- parseToken(res.headers)
1977
- ].filter(Boolean).join("; ");
1978
- this.#config.headers.set("cookie", cookie);
1979
- updateHeaders(new Headers({ cookie }));
1968
+ if ("redirectUrl" in req) {
1969
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
1980
1970
  }
1981
- if (!rawResponse) {
1982
- return { csrfToken: token };
1971
+ }
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
+ }
1983
1980
  }
1984
- } else {
1985
- const existingCookie = this.#config.headers.get("cookie");
1986
- const cookieParts = [];
1987
- if (existingCookie) {
1988
- cookieParts.push(
1989
- parseToken(this.#config.headers),
1990
- parseCallback(this.#config.headers)
1991
- );
1981
+ if (!callbackUrl) {
1982
+ callbackUrl = value;
1992
1983
  }
1993
- cookieParts.push(csrfCook);
1994
- const cookie = cookieParts.filter(Boolean).join("; ");
1995
- this.#config.headers.set("cookie", cookie);
1996
- updateHeaders(new Headers({ cookie }));
1997
- }
1998
- if (rawResponse) {
1999
- return res;
2000
1984
  }
1985
+ await this.getCsrf();
1986
+ const body = JSON.stringify({
1987
+ email,
1988
+ password,
1989
+ redirectUrl,
1990
+ callbackUrl
1991
+ });
1992
+ let urlWithParams;
2001
1993
  try {
2002
- return await res.clone().json();
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;
2000
+ }
2001
+ const { url } = await data.json();
2002
+ urlWithParams = url;
2003
2003
  } catch {
2004
- return res;
2005
- }
2006
- }
2007
- async listProviders(rawResponse = false) {
2008
- const res = await fetchProviders(this.#config);
2009
- if (rawResponse) {
2010
- return res;
2011
2004
  }
2005
+ let token;
2012
2006
  try {
2013
- return await res.clone().json();
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);
2014
2015
  } catch {
2015
- return res;
2016
- }
2017
- }
2018
- async signOut() {
2019
- const csrfRes = await this.getCsrf();
2020
- if (!("csrfToken" in csrfRes)) {
2021
- throw new Error("Unable to obtain CSRF token. Sign out failed.");
2022
- }
2023
- const body = JSON.stringify({
2024
- csrfToken: csrfRes.csrfToken,
2025
- json: true
2026
- });
2027
- const res = await fetchSignOut(this.#config, body);
2028
- updateHeaders(new Headers({}));
2029
- this.#config.headers = new Headers();
2030
- return res;
2031
- }
2032
- async signUp(payload, rawResponse) {
2033
- this.#config.headers = new Headers();
2034
- const { email, password, ...params } = payload;
2035
- if (!email || !password) {
2036
- throw new Error(
2037
- "Server side sign up requires a user email and password."
2016
+ this.#logger.warn(
2017
+ "Unable to parse reset password url. Password not reset."
2038
2018
  );
2039
2019
  }
2040
- const providers = await this.listProviders();
2041
- const { credentials } = providers ?? {};
2042
- if (!credentials) {
2020
+ const cookie = this.#config.headers.get("cookie")?.split("; ");
2021
+ if (token) {
2022
+ cookie?.push(token);
2023
+ } else {
2043
2024
  throw new Error(
2044
- "Unable to obtain credential provider. Aborting server side sign up."
2025
+ "Unable to reset password, reset token is missing from response"
2045
2026
  );
2046
2027
  }
2047
- const csrf = await this.getCsrf();
2048
- let csrfToken;
2049
- if ("csrfToken" in csrf) {
2050
- csrfToken = csrf.csrfToken;
2051
- } else {
2052
- throw new Error("Unable to obtain parse CSRF. Request blocked.");
2053
- }
2054
- const body = JSON.stringify({
2055
- email,
2056
- password,
2057
- csrfToken,
2058
- callbackUrl: credentials.callbackUrl
2028
+ this.#config.headers = new Headers({
2029
+ ...this.#config.headers,
2030
+ cookie: cookie?.join("; ")
2059
2031
  });
2060
- const res = await fetchSignUp(this.#config, { body, params });
2061
- if (res.status > 299) {
2062
- this.#logger.error(await res.clone().text());
2063
- return void 0;
2064
- }
2065
- const token = parseToken(res.headers);
2066
- if (!token) {
2067
- throw new Error("Server side sign up failed. Session token not found");
2068
- }
2069
- this.#config.headers?.append("cookie", token);
2070
- updateHeaders(this.#config.headers);
2071
- if (rawResponse) {
2072
- return res;
2073
- }
2074
- try {
2075
- return await res.clone().json();
2076
- } catch {
2077
- return res;
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
+ );
2078
2050
  }
2051
+ return await fetchCallback(this.#config, provider, body);
2079
2052
  }
2080
2053
  async signIn(provider, payload, rawResponse) {
2081
- this.#config.headers = new Headers();
2082
- const { info, error } = this.#logger;
2083
- const { email, password } = payload ?? {};
2084
- if (provider === "email" && (!email || !password)) {
2085
- throw new Error(
2086
- "Server side sign in requires a user email and password."
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"
2087
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);
2088
2078
  }
2089
- info(`Obtaining providers for ${email}`);
2079
+ this.#config.headers = new Headers();
2080
+ const { info, error } = this.#logger;
2090
2081
  const providers = await this.listProviders();
2091
2082
  info("Obtaining csrf");
2092
2083
  const csrf = await this.getCsrf();
@@ -2102,13 +2093,13 @@ var Auth = class {
2102
2093
  "Unable to obtain credential provider. Aborting server side sign in."
2103
2094
  );
2104
2095
  }
2105
- if (provider !== "credentials") {
2106
- return await fetchSignIn(
2107
- this.#config,
2108
- provider,
2109
- JSON.stringify({ csrfToken })
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."
2110
2100
  );
2111
2101
  }
2102
+ info(`Obtaining providers for ${email}`);
2112
2103
  info(`Attempting sign in with email ${email}`);
2113
2104
  const body = JSON.stringify({
2114
2105
  email,
@@ -2116,7 +2107,7 @@ var Auth = class {
2116
2107
  csrfToken,
2117
2108
  callbackUrl: credentials.callbackUrl
2118
2109
  });
2119
- const signInRes = await fetchCallback(this.#config, provider, body);
2110
+ const signInRes = await this.callback(provider, body);
2120
2111
  const authCookie = signInRes?.headers.get("set-cookie");
2121
2112
  if (!authCookie) {
2122
2113
  throw new Error("authentication failed");
@@ -2198,6 +2189,283 @@ function parseToken(headers) {
2198
2189
  const [, token] = /((__Secure-)?nile\.session-token=[^;]+)/.exec(authCookie) ?? [];
2199
2190
  return token;
2200
2191
  }
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
+ );
2232
+ }
2233
+ if (csrfCook) {
2234
+ cookieParts.push(csrfCook);
2235
+ } else {
2236
+ cookieParts.push(parseCSRF(config.headers));
2237
+ }
2238
+ const cookie = cookieParts.filter(Boolean).join("; ");
2239
+ config.headers.set("cookie", cookie);
2240
+ updateHeaders(new Headers({ cookie }));
2241
+ }
2242
+ if (rawResponse) {
2243
+ return res;
2244
+ }
2245
+ try {
2246
+ return await res.clone().json();
2247
+ } catch {
2248
+ return res;
2249
+ }
2250
+ }
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;
2264
+ }
2265
+ try {
2266
+ return await res?.clone().json();
2267
+ } catch {
2268
+ return res;
2269
+ }
2270
+ }
2271
+ async removeSelf() {
2272
+ const me = await this.getSelf();
2273
+ if ("id" in me) {
2274
+ this.#config.userId = me.id;
2275
+ }
2276
+ const res = await fetchMe(this.#config, "DELETE");
2277
+ updateHeaders(new Headers());
2278
+ return res;
2279
+ }
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;
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
+ );
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
+ );
2310
+ return void 0;
2311
+ }
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());
2323
+ }
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;
2334
+ }
2335
+ async create(req, rawResponse) {
2336
+ let res;
2337
+ if (typeof req === "string") {
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));
2345
+ }
2346
+ if (rawResponse) {
2347
+ return res;
2348
+ }
2349
+ try {
2350
+ return await res?.clone().json();
2351
+ } catch {
2352
+ return res;
2353
+ }
2354
+ }
2355
+ async delete(req) {
2356
+ if (typeof req === "string") {
2357
+ this.#config.tenantId = req;
2358
+ }
2359
+ if (typeof req === "object" && "id" in req) {
2360
+ this.#config.tenantId = req.id;
2361
+ }
2362
+ const res = await fetchTenant(this.#config, "DELETE");
2363
+ return res;
2364
+ }
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;
2370
+ }
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;
2379
+ }
2380
+ }
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;
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;
2397
+ }
2398
+ }
2399
+ async list(req) {
2400
+ const res = await fetchTenantsByUser(this.#config);
2401
+ if (req === true) {
2402
+ return res;
2403
+ }
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;
2416
+ }
2417
+ } catch {
2418
+ }
2419
+ if (typeof req === "string") {
2420
+ this.#config.tenantId = req;
2421
+ } else {
2422
+ this.#handleContext(req);
2423
+ }
2424
+ return await fetchTenantUser(this.#config, "DELETE");
2425
+ }
2426
+ async addMember(req, rawResponse) {
2427
+ if (typeof req === "string") {
2428
+ this.#config.userId = req;
2429
+ } else {
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;
2455
+ }
2456
+ }
2457
+ }
2458
+ };
2459
+ async function responseHandler(res, rawResponse) {
2460
+ if (rawResponse) {
2461
+ return res;
2462
+ }
2463
+ try {
2464
+ return await res?.clone().json();
2465
+ } catch {
2466
+ return res;
2467
+ }
2468
+ }
2201
2469
 
2202
2470
  // src/api/handlers/withContext/index.ts
2203
2471
  function handlersWithContext(config) {
@@ -2234,14 +2502,14 @@ function updateConfig(response, config) {
2234
2502
  if (response?.status === 302) {
2235
2503
  const location = response.headers.get("location");
2236
2504
  if (location) {
2237
- const normalized = location.endsWith("/") ? location.slice(0, -1) : location;
2238
- origin = normalized;
2505
+ const urlLocation = new URL(location);
2506
+ origin = urlLocation.origin;
2239
2507
  }
2240
2508
  }
2241
2509
  const setCookies = [];
2242
2510
  if (response?.headers) {
2243
- for (const [key13, value] of response.headers) {
2244
- if (key13.toLowerCase() === "set-cookie") {
2511
+ for (const [key14, value] of response.headers) {
2512
+ if (key14.toLowerCase() === "set-cookie") {
2245
2513
  setCookies.push(value);
2246
2514
  }
2247
2515
  }
@@ -2400,25 +2668,25 @@ var Server = class {
2400
2668
  }
2401
2669
  }
2402
2670
  if (headers instanceof Headers) {
2403
- headers.forEach((value, key13) => {
2404
- updates.push([key13.toLowerCase(), value]);
2671
+ headers.forEach((value, key14) => {
2672
+ updates.push([key14.toLowerCase(), value]);
2405
2673
  });
2406
2674
  } else {
2407
- for (const [key13, value] of Object.entries(headers ?? {})) {
2408
- updates.push([key13.toLowerCase(), value]);
2675
+ for (const [key14, value] of Object.entries(headers ?? {})) {
2676
+ updates.push([key14.toLowerCase(), value]);
2409
2677
  }
2410
2678
  }
2411
2679
  const merged = {};
2412
- this.#headers?.forEach((value, key13) => {
2413
- if (key13.toLowerCase() !== "cookie") {
2414
- merged[key13.toLowerCase()] = value;
2680
+ this.#headers?.forEach((value, key14) => {
2681
+ if (key14.toLowerCase() !== "cookie") {
2682
+ merged[key14.toLowerCase()] = value;
2415
2683
  }
2416
2684
  });
2417
- for (const [key13, value] of updates) {
2418
- merged[key13] = value;
2685
+ for (const [key14, value] of updates) {
2686
+ merged[key14] = value;
2419
2687
  }
2420
- for (const [key13, value] of Object.entries(merged)) {
2421
- this.#headers.set(key13, value);
2688
+ for (const [key14, value] of Object.entries(merged)) {
2689
+ this.#headers.set(key14, value);
2422
2690
  }
2423
2691
  this.#config.headers = this.#headers;
2424
2692
  }