@niledatabase/server 5.0.0-alpha.1 → 5.0.0-alpha.3

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,62 @@ 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, useJson = true) {
908
+ const authParams = new URLSearchParams(params ?? {});
909
+ if (useJson) {
910
+ authParams?.set("json", "true");
911
+ }
912
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
913
+ const init = {
914
+ method,
915
+ headers: config.headers
916
+ };
917
+ if (body && method !== "GET") {
918
+ init.body = body;
919
+ }
920
+ const req = new Request(clientUrl, init);
921
+ return await config.handlers[method](req);
922
+ }
923
+
924
+ // src/api/routes/auth/verify-email.ts
925
+ var key11 = "VERIFY_EMAIL";
926
+ async function route14(req, config) {
927
+ const url = proxyRoutes(config)[key11];
928
+ const res = await request(
929
+ url,
930
+ {
931
+ method: req.method,
932
+ request: req
933
+ },
934
+ config
935
+ );
936
+ const location = res?.headers.get("location");
937
+ if (location) {
938
+ return new Response(res?.body, {
939
+ status: 302,
940
+ headers: res?.headers
941
+ });
942
+ }
943
+ return new Response(res?.body, {
944
+ status: res?.status,
945
+ headers: res?.headers
946
+ });
947
+ }
948
+ function matches14(configRoutes, request2) {
949
+ return urlMatches(request2.url, configRoutes[key11]);
950
+ }
951
+ async function fetchVerifyEmail(config, method, body) {
952
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
953
+ const init = {
954
+ method,
955
+ headers: config.headers
956
+ };
957
+ if (body) {
958
+ init.body = body;
959
+ }
960
+ const req = new Request(clientUrl, init);
961
+ return await config.handlers[method](req);
962
+ }
931
963
 
932
964
  // src/api/handlers/GET.ts
933
965
  function GETTER(configRoutes, config) {
@@ -981,6 +1013,10 @@ function GETTER(configRoutes, config) {
981
1013
  info("matches verify-request");
982
1014
  return route12(req, config);
983
1015
  }
1016
+ if (matches14(configRoutes, req)) {
1017
+ info("matches verify-email");
1018
+ return route14(req, config);
1019
+ }
984
1020
  if (matches11(configRoutes, req)) {
985
1021
  info("matches error");
986
1022
  return route11(req, config);
@@ -999,8 +1035,8 @@ async function POST4(config, init) {
999
1035
  }
1000
1036
 
1001
1037
  // src/api/routes/signup/index.tsx
1002
- var key11 = "SIGNUP";
1003
- async function route14(request2, config) {
1038
+ var key12 = "SIGNUP";
1039
+ async function route15(request2, config) {
1004
1040
  switch (request2.method) {
1005
1041
  case "POST":
1006
1042
  return await POST4(config, { request: request2 });
@@ -1008,8 +1044,8 @@ async function route14(request2, config) {
1008
1044
  return new Response("method not allowed", { status: 405 });
1009
1045
  }
1010
1046
  }
1011
- function matches14(configRoutes, request2) {
1012
- return urlMatches(request2.url, configRoutes[key11]);
1047
+ function matches15(configRoutes, request2) {
1048
+ return urlMatches(request2.url, configRoutes[key12]);
1013
1049
  }
1014
1050
  async function fetchSignUp(config, payload) {
1015
1051
  const { body, params } = payload ?? {};
@@ -1020,7 +1056,7 @@ async function fetchSignUp(config, payload) {
1020
1056
  if (params?.tenantId) {
1021
1057
  q.set("tenantId", params.tenantId);
1022
1058
  }
1023
- const clientUrl = `${config.origin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1059
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1024
1060
  const req = new Request(clientUrl, {
1025
1061
  method: "POST",
1026
1062
  headers: config.headers,
@@ -1034,24 +1070,21 @@ function POSTER(configRoutes, config) {
1034
1070
  const { info, warn, error } = Logger(config, "[POST MATCHER]");
1035
1071
  return async function POST5(req) {
1036
1072
  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
- }
1073
+ try {
1074
+ const json = await req.clone().json();
1075
+ error(req.body && json);
1076
+ } catch {
1077
+ error(await req.text());
1046
1078
  }
1079
+ return new Response(null, { status: 200 });
1047
1080
  }
1048
1081
  if (matches3(configRoutes, req)) {
1049
1082
  info("matches tenant users");
1050
1083
  return route3(req, config);
1051
1084
  }
1052
- if (matches14(configRoutes, req)) {
1085
+ if (matches15(configRoutes, req)) {
1053
1086
  info("matches signup");
1054
- return route14(req, config);
1087
+ return route15(req, config);
1055
1088
  }
1056
1089
  if (matches2(configRoutes, req)) {
1057
1090
  info("matches users");
@@ -1089,6 +1122,10 @@ function POSTER(configRoutes, config) {
1089
1122
  info("matches signout");
1090
1123
  return route10(req, config);
1091
1124
  }
1125
+ if (matches14(configRoutes, req)) {
1126
+ info("matches verify-email");
1127
+ return route14(req, config);
1128
+ }
1092
1129
  warn(`No POST routes matched ${req.url}`);
1093
1130
  return new Response(null, { status: 404 });
1094
1131
  };
@@ -1117,11 +1154,11 @@ async function PUT4(config, init) {
1117
1154
  }
1118
1155
 
1119
1156
  // src/api/routes/tenants/[tenantId]/users/[userId]/index.ts
1120
- var key12 = "TENANT_USER";
1121
- async function route15(request2, config) {
1157
+ var key13 = "TENANT_USER";
1158
+ async function route16(request2, config) {
1122
1159
  const { info } = Logger(
1123
1160
  { ...config, debug: config.debug },
1124
- `[ROUTES][${key12}]`
1161
+ `[ROUTES][${key13}]`
1125
1162
  );
1126
1163
  const session = await auth(request2, config);
1127
1164
  if (!session) {
@@ -1143,14 +1180,14 @@ async function route15(request2, config) {
1143
1180
  return new Response("method not allowed", { status: 405 });
1144
1181
  }
1145
1182
  }
1146
- function matches15(configRoutes, request2) {
1183
+ function matches16(configRoutes, request2) {
1147
1184
  const url = new URL(request2.url);
1148
1185
  const [, userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
1149
- let route16 = configRoutes[key12].replace("{tenantId}", tenantId).replace("{userId}", userId);
1186
+ let route17 = configRoutes[key13].replace("{tenantId}", tenantId).replace("{userId}", userId);
1150
1187
  if (userId === "users") {
1151
- route16 = configRoutes[key12].replace("{tenantId}", possibleTenantId);
1188
+ route17 = configRoutes[key13].replace("{tenantId}", possibleTenantId);
1152
1189
  }
1153
- return urlMatches(request2.url, route16);
1190
+ return urlMatches(request2.url, route17);
1154
1191
  }
1155
1192
  async function fetchTenantUser(config, method) {
1156
1193
  if (!config.tenantId) {
@@ -1163,7 +1200,7 @@ async function fetchTenantUser(config, method) {
1163
1200
  "the userId context is missing. Call nile.setContext({ userId })"
1164
1201
  );
1165
1202
  }
1166
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1203
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1167
1204
  "{tenantId}",
1168
1205
  config.tenantId
1169
1206
  ).replace("{userId}", config.userId)}/link`;
@@ -1178,9 +1215,9 @@ async function fetchTenantUser(config, method) {
1178
1215
  function DELETER(configRoutes, config) {
1179
1216
  const { info, warn } = Logger(config, "[DELETE MATCHER]");
1180
1217
  return async function DELETE4(req) {
1181
- if (matches15(configRoutes, req)) {
1218
+ if (matches16(configRoutes, req)) {
1182
1219
  info("matches tenant user");
1183
- return route15(req, config);
1220
+ return route16(req, config);
1184
1221
  }
1185
1222
  if (matches3(configRoutes, req)) {
1186
1223
  info("matches tenant users");
@@ -1203,9 +1240,9 @@ function DELETER(configRoutes, config) {
1203
1240
  function PUTER(configRoutes, config) {
1204
1241
  const { info, warn } = Logger(config, "[PUT MATCHER]");
1205
1242
  return async function PUT5(req) {
1206
- if (matches15(configRoutes, req)) {
1243
+ if (matches16(configRoutes, req)) {
1207
1244
  info("matches tenant user");
1208
- return route15(req, config);
1245
+ return route16(req, config);
1209
1246
  }
1210
1247
  if (matches3(configRoutes, req)) {
1211
1248
  info("matches tenant users");
@@ -1423,7 +1460,6 @@ var stringCheck = (str) => {
1423
1460
  // src/utils/Config/index.ts
1424
1461
  var Config = class {
1425
1462
  routes;
1426
- // handlersWithContext;
1427
1463
  handlers;
1428
1464
  paths;
1429
1465
  logger;
@@ -1444,6 +1480,10 @@ var Config = class {
1444
1480
  */
1445
1481
  apiUrl;
1446
1482
  origin;
1483
+ /**
1484
+ * important for separating the `origin` config value from a default in order to make requests
1485
+ */
1486
+ serverOrigin;
1447
1487
  debug;
1448
1488
  /**
1449
1489
  * To use secure cookies or not in the fetch
@@ -1462,7 +1502,8 @@ var Config = class {
1462
1502
  this.secureCookies = getSecureCookies(envVarConfig);
1463
1503
  this.callbackUrl = getCallbackUrl(envVarConfig);
1464
1504
  this.debug = config?.debug;
1465
- this.origin = config?.origin ?? "http://localhost:3000";
1505
+ this.origin = config?.origin;
1506
+ this.serverOrigin = config?.origin ?? "http://localhost:3000";
1466
1507
  this.apiUrl = getApiUrl(envVarConfig);
1467
1508
  const user = getUsername(envVarConfig);
1468
1509
  const password = getPassword(envVarConfig);
@@ -1533,6 +1574,47 @@ var Config = class {
1533
1574
  }
1534
1575
  };
1535
1576
 
1577
+ // src/utils/Event/index.ts
1578
+ var Eventer = class {
1579
+ events = {};
1580
+ publish(eventName, value) {
1581
+ const callbacks = this.events[eventName];
1582
+ if (callbacks) {
1583
+ for (const callback of callbacks) {
1584
+ callback(value);
1585
+ }
1586
+ }
1587
+ }
1588
+ subscribe(eventName, callback) {
1589
+ if (!this.events[eventName]) {
1590
+ this.events[eventName] = [];
1591
+ }
1592
+ this.events[eventName].push(callback);
1593
+ }
1594
+ unsubscribe(eventName, callback) {
1595
+ const callbacks = this.events[eventName];
1596
+ if (!callbacks) return;
1597
+ const index = callbacks.indexOf(callback);
1598
+ if (index !== -1) {
1599
+ callbacks.splice(index, 1);
1600
+ }
1601
+ if (callbacks.length === 0) {
1602
+ delete this.events[eventName];
1603
+ }
1604
+ }
1605
+ };
1606
+ var eventer = new Eventer();
1607
+ var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
1608
+ var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
1609
+ var evictPool = (val) => {
1610
+ eventer.publish("EvictPool" /* EvictPool */, val);
1611
+ };
1612
+ var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
1613
+ var updateHeaders = (val) => {
1614
+ eventer.publish("headers" /* Headers */, val);
1615
+ };
1616
+ var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
1617
+
1536
1618
  // src/db/PoolProxy.ts
1537
1619
  function createProxyForPool(pool, config) {
1538
1620
  const { info, error } = Logger(config, "[pool]");
@@ -1757,336 +1839,265 @@ var DBManager = class {
1757
1839
  };
1758
1840
  };
1759
1841
 
1760
- // src/users/index.ts
1761
- var Users = class {
1842
+ // src/auth/index.ts
1843
+ var Auth = class {
1844
+ #logger;
1762
1845
  #config;
1763
1846
  constructor(config) {
1764
1847
  this.#config = config;
1848
+ this.#logger = Logger(config, "[auth]");
1765
1849
  }
1766
- async updateSelf(req, rawResponse) {
1767
- const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
1850
+ async getSession(rawResponse = false) {
1851
+ const res = await fetchSession(this.#config);
1768
1852
  if (rawResponse) {
1769
1853
  return res;
1770
1854
  }
1771
1855
  try {
1772
- return await res?.clone().json();
1856
+ const session = await res.clone().json();
1857
+ if (Object.keys(session).length === 0) {
1858
+ return void 0;
1859
+ }
1860
+ return session;
1773
1861
  } catch {
1774
1862
  return res;
1775
1863
  }
1776
1864
  }
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;
1865
+ async getCsrf(rawResponse = false) {
1866
+ return await getCsrf(this.#config, rawResponse);
1785
1867
  }
1786
- async getSelf(rawResponse) {
1787
- const res = await fetchMe(this.#config);
1868
+ async listProviders(rawResponse = false) {
1869
+ const res = await fetchProviders(this.#config);
1788
1870
  if (rawResponse) {
1789
1871
  return res;
1790
1872
  }
1791
1873
  try {
1792
- return await res?.clone().json();
1874
+ return await res.clone().json();
1793
1875
  } catch {
1794
1876
  return res;
1795
1877
  }
1796
1878
  }
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;
1879
+ async signOut() {
1880
+ const csrfRes = await this.getCsrf();
1881
+ if (!("csrfToken" in csrfRes)) {
1882
+ throw new Error("Unable to obtain CSRF token. Sign out failed.");
1883
+ }
1884
+ const body = JSON.stringify({
1885
+ csrfToken: csrfRes.csrfToken,
1886
+ json: true
1887
+ });
1888
+ const res = await fetchSignOut(this.#config, body);
1889
+ updateHeaders(new Headers({}));
1890
+ this.#config.headers = new Headers();
1891
+ return res;
1806
1892
  }
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 })
1893
+ async signUp(payload, rawResponse) {
1894
+ this.#config.headers = new Headers();
1895
+ const { email, password, ...params } = payload;
1896
+ if (!email || !password) {
1897
+ throw new Error(
1898
+ "Server side sign up requires a user email and password."
1814
1899
  );
1815
- } else if (typeof req === "object" && ("name" in req || "id" in req)) {
1816
- res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
1817
- }
1818
- if (rawResponse) {
1819
- return res;
1820
- }
1821
- try {
1822
- return await res?.clone().json();
1823
- } catch {
1824
- return res;
1825
1900
  }
1826
- }
1827
- async delete(req) {
1828
- if (typeof req === "string") {
1829
- this.#config.tenantId = req;
1901
+ const providers = await this.listProviders();
1902
+ const { credentials } = providers ?? {};
1903
+ if (!credentials) {
1904
+ throw new Error(
1905
+ "Unable to obtain credential provider. Aborting server side sign up."
1906
+ );
1830
1907
  }
1831
- if (typeof req === "object" && "id" in req) {
1832
- this.#config.tenantId = req.id;
1908
+ const csrf = await this.getCsrf();
1909
+ let csrfToken;
1910
+ if ("csrfToken" in csrf) {
1911
+ csrfToken = csrf.csrfToken;
1912
+ } else {
1913
+ throw new Error("Unable to obtain parse CSRF. Request blocked.");
1833
1914
  }
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();
1849
- } catch {
1850
- return res;
1915
+ const body = JSON.stringify({
1916
+ email,
1917
+ password,
1918
+ csrfToken,
1919
+ callbackUrl: credentials.callbackUrl
1920
+ });
1921
+ const res = await fetchSignUp(this.#config, { body, params });
1922
+ if (res.status > 299) {
1923
+ this.#logger.error(await res.clone().text());
1924
+ return void 0;
1851
1925
  }
1852
- }
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;
1859
- }
1860
- res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
1926
+ const token = parseToken(res.headers);
1927
+ if (!token) {
1928
+ throw new Error("Server side sign up failed. Session token not found");
1861
1929
  }
1930
+ this.#config.headers?.append("cookie", token);
1931
+ updateHeaders(this.#config.headers);
1862
1932
  if (rawResponse) {
1863
1933
  return res;
1864
1934
  }
1865
1935
  try {
1866
- return await res?.clone().json();
1936
+ return await res.clone().json();
1867
1937
  } catch {
1868
1938
  return res;
1869
1939
  }
1870
1940
  }
1871
- async list(req) {
1872
- const res = await fetchTenantsByUser(this.#config);
1873
- if (req === true) {
1874
- return res;
1941
+ async forgotPassword(req) {
1942
+ let email = "";
1943
+ const defaults = defaultCallbackUrl({
1944
+ config: this.#config
1945
+ });
1946
+ let callbackUrl = defaults.callbackUrl;
1947
+ let redirectUrl = defaults.redirectUrl;
1948
+ if ("email" in req) {
1949
+ email = req.email;
1875
1950
  }
1876
- try {
1877
- return await res?.clone().json();
1878
- } catch {
1879
- return res;
1951
+ if ("callbackUrl" in req) {
1952
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
1880
1953
  }
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;
1888
- }
1889
- } catch {
1954
+ if ("redirectUrl" in req) {
1955
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
1890
1956
  }
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
- } 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
1957
+ const body = JSON.stringify({
1958
+ email,
1959
+ redirectUrl,
1960
+ callbackUrl
1961
+ });
1962
+ const data = await fetchResetPassword(
1963
+ this.#config,
1964
+ "POST",
1965
+ body,
1966
+ new URLSearchParams(),
1967
+ false
1918
1968
  );
1919
- }
1920
- #handleContext(req) {
1921
- if (typeof req === "object") {
1922
- if ("tenantId" in req) {
1923
- this.#config.tenantId = req.tenantId;
1969
+ return data;
1970
+ }
1971
+ async resetPassword(req) {
1972
+ let email = "";
1973
+ let password = "";
1974
+ const defaults = defaultCallbackUrl({ config: this.#config });
1975
+ let callbackUrl = defaults.callbackUrl;
1976
+ let redirectUrl = defaults.redirectUrl;
1977
+ if (req instanceof Request) {
1978
+ const body2 = await req.json();
1979
+ email = body2.email;
1980
+ password = body2.password;
1981
+ const cbFromHeaders = parseCallback(req.headers);
1982
+ if (cbFromHeaders) {
1983
+ callbackUrl = cbFromHeaders;
1924
1984
  }
1925
- if ("userId" in req) {
1926
- this.#config.tenantId = req.tenantId;
1985
+ if (body2.callbackUrl) {
1986
+ callbackUrl = body2.callbackUrl;
1927
1987
  }
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;
1988
+ if (body2.redirectUrl) {
1989
+ redirectUrl = body2.redirectUrl;
1959
1990
  }
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 }));
1991
+ } else {
1992
+ if ("email" in req) {
1993
+ email = req.email;
1980
1994
  }
1981
- if (!rawResponse) {
1982
- return { csrfToken: token };
1995
+ if ("password" in req) {
1996
+ password = req.password;
1983
1997
  }
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
- );
1998
+ if ("callbackUrl" in req) {
1999
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2000
+ }
2001
+ if ("redirectUrl" in req) {
2002
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
1992
2003
  }
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
2004
  }
2005
+ await this.getCsrf();
2006
+ const body = JSON.stringify({
2007
+ email,
2008
+ password,
2009
+ redirectUrl,
2010
+ callbackUrl
2011
+ });
2012
+ let urlWithParams;
2001
2013
  try {
2002
- return await res.clone().json();
2014
+ const data = await fetchResetPassword(this.#config, "POST", body);
2015
+ const cloned = data.clone();
2016
+ if (data.status === 400) {
2017
+ const text = await cloned.text();
2018
+ this.#logger.error(text);
2019
+ return data;
2020
+ }
2021
+ const { url } = await data.json();
2022
+ urlWithParams = url;
2003
2023
  } 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
2024
  }
2025
+ let token;
2012
2026
  try {
2013
- return await res.clone().json();
2027
+ const worthyParams = new URL(urlWithParams).searchParams;
2028
+ const answer = await fetchResetPassword(
2029
+ this.#config,
2030
+ "GET",
2031
+ null,
2032
+ worthyParams
2033
+ );
2034
+ token = parseResetToken(answer.headers);
2014
2035
  } 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."
2036
+ this.#logger.warn(
2037
+ "Unable to parse reset password url. Password not reset."
2038
2038
  );
2039
2039
  }
2040
- const providers = await this.listProviders();
2041
- const { credentials } = providers ?? {};
2042
- if (!credentials) {
2040
+ const cookie = this.#config.headers.get("cookie")?.split("; ");
2041
+ if (token) {
2042
+ cookie?.push(token);
2043
+ } else {
2043
2044
  throw new Error(
2044
- "Unable to obtain credential provider. Aborting server side sign up."
2045
+ "Unable to reset password, reset token is missing from response"
2045
2046
  );
2046
2047
  }
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
2048
+ this.#config.headers = new Headers({
2049
+ ...this.#config.headers,
2050
+ cookie: cookie?.join("; ")
2059
2051
  });
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;
2052
+ const res = await fetchResetPassword(this.#config, "PUT", body);
2053
+ cookie?.pop();
2054
+ const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2055
+ cleaned.push(String(parseToken(res.headers)));
2056
+ const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2057
+ updateHeaders(updatedHeaders);
2058
+ return res;
2059
+ }
2060
+ async callback(provider, body) {
2061
+ if (body instanceof Request) {
2062
+ this.#config.headers = body.headers;
2063
+ return await fetchCallback(
2064
+ this.#config,
2065
+ provider,
2066
+ void 0,
2067
+ body,
2068
+ "GET"
2069
+ );
2078
2070
  }
2071
+ return await fetchCallback(this.#config, provider, body);
2079
2072
  }
2080
2073
  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."
2074
+ if (payload instanceof Request) {
2075
+ const body2 = new URLSearchParams(await payload.text());
2076
+ const origin = new URL(payload.url).origin;
2077
+ const payloadUrl = body2?.get("callbackUrl");
2078
+ const csrfToken2 = body2?.get("csrfToken");
2079
+ const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2080
+ if (!csrfToken2) {
2081
+ throw new Error(
2082
+ "CSRF token in missing from request. Request it by the client before calling sign in"
2083
+ );
2084
+ }
2085
+ this.#config.headers = new Headers(payload.headers);
2086
+ this.#config.headers.set(
2087
+ "Content-Type",
2088
+ "application/x-www-form-urlencoded"
2087
2089
  );
2090
+ const params = new URLSearchParams({
2091
+ csrfToken: csrfToken2,
2092
+ json: String(true)
2093
+ });
2094
+ if (payloadUrl) {
2095
+ params.set("callbackUrl", callbackUrl);
2096
+ }
2097
+ return await fetchSignIn(this.#config, provider, params);
2088
2098
  }
2089
- info(`Obtaining providers for ${email}`);
2099
+ this.#config.headers = new Headers();
2100
+ const { info, error } = this.#logger;
2090
2101
  const providers = await this.listProviders();
2091
2102
  info("Obtaining csrf");
2092
2103
  const csrf = await this.getCsrf();
@@ -2102,13 +2113,13 @@ var Auth = class {
2102
2113
  "Unable to obtain credential provider. Aborting server side sign in."
2103
2114
  );
2104
2115
  }
2105
- if (provider !== "credentials") {
2106
- return await fetchSignIn(
2107
- this.#config,
2108
- provider,
2109
- JSON.stringify({ csrfToken })
2116
+ const { email, password } = payload ?? {};
2117
+ if (provider === "email" && (!email || !password)) {
2118
+ throw new Error(
2119
+ "Server side sign in requires a user email and password."
2110
2120
  );
2111
2121
  }
2122
+ info(`Obtaining providers for ${email}`);
2112
2123
  info(`Attempting sign in with email ${email}`);
2113
2124
  const body = JSON.stringify({
2114
2125
  email,
@@ -2116,7 +2127,7 @@ var Auth = class {
2116
2127
  csrfToken,
2117
2128
  callbackUrl: credentials.callbackUrl
2118
2129
  });
2119
- const signInRes = await fetchCallback(this.#config, provider, body);
2130
+ const signInRes = await this.callback(provider, body);
2120
2131
  const authCookie = signInRes?.headers.get("set-cookie");
2121
2132
  if (!authCookie) {
2122
2133
  throw new Error("authentication failed");
@@ -2198,6 +2209,296 @@ function parseToken(headers) {
2198
2209
  const [, token] = /((__Secure-)?nile\.session-token=[^;]+)/.exec(authCookie) ?? [];
2199
2210
  return token;
2200
2211
  }
2212
+ function parseResetToken(headers) {
2213
+ let authCookie = headers?.get("set-cookie");
2214
+ if (!authCookie) {
2215
+ authCookie = headers?.get("cookie");
2216
+ }
2217
+ if (!authCookie) {
2218
+ return void 0;
2219
+ }
2220
+ const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
2221
+ return token;
2222
+ }
2223
+ function defaultCallbackUrl({ config }) {
2224
+ let cb = null;
2225
+ let redirect = null;
2226
+ const fallbackCb = parseCallback(config.headers);
2227
+ if (fallbackCb) {
2228
+ const [, value] = fallbackCb.split("=");
2229
+ cb = decodeURIComponent(value);
2230
+ if (value) {
2231
+ redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2232
+ }
2233
+ }
2234
+ return { callbackUrl: cb, redirectUrl: redirect };
2235
+ }
2236
+
2237
+ // src/auth/getCsrf.ts
2238
+ async function getCsrf(config, rawResponse = false) {
2239
+ const res = await fetchCsrf(config);
2240
+ const csrfCook = parseCSRF(res.headers);
2241
+ if (csrfCook) {
2242
+ const [, value] = csrfCook.split("=");
2243
+ const [token] = decodeURIComponent(value).split("|");
2244
+ const setCookie = res.headers.get("set-cookie");
2245
+ if (setCookie) {
2246
+ const cookie = [
2247
+ csrfCook,
2248
+ parseCallback(res.headers),
2249
+ parseToken(res.headers)
2250
+ ].filter(Boolean).join("; ");
2251
+ config.headers.set("cookie", cookie);
2252
+ updateHeaders(new Headers({ cookie }));
2253
+ }
2254
+ if (!rawResponse) {
2255
+ return { csrfToken: token };
2256
+ }
2257
+ } else {
2258
+ const existingCookie = config.headers.get("cookie");
2259
+ const cookieParts = [];
2260
+ if (existingCookie) {
2261
+ cookieParts.push(
2262
+ parseToken(config.headers),
2263
+ parseCallback(config.headers)
2264
+ );
2265
+ }
2266
+ if (csrfCook) {
2267
+ cookieParts.push(csrfCook);
2268
+ } else {
2269
+ cookieParts.push(parseCSRF(config.headers));
2270
+ }
2271
+ const cookie = cookieParts.filter(Boolean).join("; ");
2272
+ config.headers.set("cookie", cookie);
2273
+ updateHeaders(new Headers({ cookie }));
2274
+ }
2275
+ if (rawResponse) {
2276
+ return res;
2277
+ }
2278
+ try {
2279
+ return await res.clone().json();
2280
+ } catch {
2281
+ return res;
2282
+ }
2283
+ }
2284
+
2285
+ // src/users/index.ts
2286
+ var Users = class {
2287
+ #config;
2288
+ #logger;
2289
+ constructor(config) {
2290
+ this.#config = config;
2291
+ this.#logger = Logger(config, "[me]");
2292
+ }
2293
+ async updateSelf(req, rawResponse) {
2294
+ const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2295
+ if (rawResponse) {
2296
+ return res;
2297
+ }
2298
+ try {
2299
+ return await res?.clone().json();
2300
+ } catch {
2301
+ return res;
2302
+ }
2303
+ }
2304
+ async removeSelf() {
2305
+ const me = await this.getSelf();
2306
+ if ("id" in me) {
2307
+ this.#config.userId = me.id;
2308
+ }
2309
+ const res = await fetchMe(this.#config, "DELETE");
2310
+ updateHeaders(new Headers());
2311
+ return res;
2312
+ }
2313
+ async getSelf(rawResponse) {
2314
+ const res = await fetchMe(this.#config);
2315
+ if (rawResponse) {
2316
+ return res;
2317
+ }
2318
+ try {
2319
+ return await res?.clone().json();
2320
+ } catch {
2321
+ return res;
2322
+ }
2323
+ }
2324
+ async verifySelf(bypassEmail = process.env.NODE_ENV !== "production", rawResponse = false) {
2325
+ try {
2326
+ const me = await this.getSelf();
2327
+ if (me instanceof Response) {
2328
+ return me;
2329
+ }
2330
+ const res = await verifyEmailAddress(this.#config, me);
2331
+ return res;
2332
+ } catch {
2333
+ this.#logger?.warn(
2334
+ "Unable to verify email. The current user's email will be set to verified any way. Be sure to configure emails for production."
2335
+ );
2336
+ }
2337
+ if (bypassEmail) {
2338
+ return await this.updateSelf({ emailVerified: true }, rawResponse);
2339
+ }
2340
+ this.#logger.error(
2341
+ "Unable to verify email address. Configure your SMTP server in the console."
2342
+ );
2343
+ return void 0;
2344
+ }
2345
+ };
2346
+ async function verifyEmailAddress(config, user) {
2347
+ config.headers.set("content-type", "application/x-www-form-urlencoded");
2348
+ const { csrfToken } = await getCsrf(config);
2349
+ const res = await fetchVerifyEmail(
2350
+ config,
2351
+ "POST",
2352
+ new URLSearchParams({ csrfToken, email: user.email }).toString()
2353
+ );
2354
+ if (res.status > 299) {
2355
+ throw new Error(await res.text());
2356
+ }
2357
+ return res;
2358
+ }
2359
+
2360
+ // src/tenants/index.ts
2361
+ var Tenants = class {
2362
+ #logger;
2363
+ #config;
2364
+ constructor(config) {
2365
+ this.#logger = Logger(config, "[tenants]");
2366
+ this.#config = config;
2367
+ }
2368
+ async create(req, rawResponse) {
2369
+ let res;
2370
+ if (typeof req === "string") {
2371
+ res = await fetchTenants(
2372
+ this.#config,
2373
+ "POST",
2374
+ JSON.stringify({ name: req })
2375
+ );
2376
+ } else if (typeof req === "object" && ("name" in req || "id" in req)) {
2377
+ res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
2378
+ }
2379
+ if (rawResponse) {
2380
+ return res;
2381
+ }
2382
+ try {
2383
+ return await res?.clone().json();
2384
+ } catch {
2385
+ return res;
2386
+ }
2387
+ }
2388
+ async delete(req) {
2389
+ if (typeof req === "string") {
2390
+ this.#config.tenantId = req;
2391
+ }
2392
+ if (typeof req === "object" && "id" in req) {
2393
+ this.#config.tenantId = req.id;
2394
+ }
2395
+ const res = await fetchTenant(this.#config, "DELETE");
2396
+ return res;
2397
+ }
2398
+ async get(req, rawResponse) {
2399
+ if (typeof req === "string") {
2400
+ this.#config.tenantId = req;
2401
+ } else if (typeof req === "object" && "id" in req) {
2402
+ this.#config.tenantId = req.id;
2403
+ }
2404
+ const res = await fetchTenant(this.#config, "GET");
2405
+ if (rawResponse === true || req === true) {
2406
+ return res;
2407
+ }
2408
+ try {
2409
+ return await res?.clone().json();
2410
+ } catch {
2411
+ return res;
2412
+ }
2413
+ }
2414
+ async update(req, rawResponse) {
2415
+ let res;
2416
+ if (typeof req === "object" && ("name" in req || "id" in req)) {
2417
+ const { id, ...remaining } = req;
2418
+ if (id) {
2419
+ this.#config.tenantId = id;
2420
+ }
2421
+ res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2422
+ }
2423
+ if (rawResponse) {
2424
+ return res;
2425
+ }
2426
+ try {
2427
+ return await res?.clone().json();
2428
+ } catch {
2429
+ return res;
2430
+ }
2431
+ }
2432
+ async list(req) {
2433
+ const res = await fetchTenantsByUser(this.#config);
2434
+ if (req === true) {
2435
+ return res;
2436
+ }
2437
+ try {
2438
+ return await res?.clone().json();
2439
+ } catch {
2440
+ return res;
2441
+ }
2442
+ }
2443
+ async leaveTenant(req) {
2444
+ const me = await fetchMe(this.#config);
2445
+ try {
2446
+ const json = await me.json();
2447
+ if ("id" in json) {
2448
+ this.#config.userId = json.id;
2449
+ }
2450
+ } catch {
2451
+ }
2452
+ if (typeof req === "string") {
2453
+ this.#config.tenantId = req;
2454
+ } else {
2455
+ this.#handleContext(req);
2456
+ }
2457
+ return await fetchTenantUser(this.#config, "DELETE");
2458
+ }
2459
+ async addMember(req, rawResponse) {
2460
+ if (typeof req === "string") {
2461
+ this.#config.userId = req;
2462
+ } else {
2463
+ this.#handleContext(req);
2464
+ }
2465
+ const res = await fetchTenantUser(this.#config, "PUT");
2466
+ return responseHandler(res, rawResponse);
2467
+ }
2468
+ async removeMember(req, rawResponse) {
2469
+ this.#handleContext(req);
2470
+ const res = await fetchTenantUser(this.#config, "DELETE");
2471
+ return responseHandler(res, rawResponse);
2472
+ }
2473
+ async users(req, rawResponse) {
2474
+ this.#handleContext(req);
2475
+ const res = await fetchTenantUsers(this.#config, "GET");
2476
+ return responseHandler(
2477
+ res,
2478
+ rawResponse || typeof req === "boolean" && req
2479
+ );
2480
+ }
2481
+ #handleContext(req) {
2482
+ if (typeof req === "object") {
2483
+ if ("tenantId" in req) {
2484
+ this.#config.tenantId = req.tenantId;
2485
+ }
2486
+ if ("userId" in req) {
2487
+ this.#config.tenantId = req.tenantId;
2488
+ }
2489
+ }
2490
+ }
2491
+ };
2492
+ async function responseHandler(res, rawResponse) {
2493
+ if (rawResponse) {
2494
+ return res;
2495
+ }
2496
+ try {
2497
+ return await res?.clone().json();
2498
+ } catch {
2499
+ return res;
2500
+ }
2501
+ }
2201
2502
 
2202
2503
  // src/api/handlers/withContext/index.ts
2203
2504
  function handlersWithContext(config) {
@@ -2234,14 +2535,14 @@ function updateConfig(response, config) {
2234
2535
  if (response?.status === 302) {
2235
2536
  const location = response.headers.get("location");
2236
2537
  if (location) {
2237
- const normalized = location.endsWith("/") ? location.slice(0, -1) : location;
2238
- origin = normalized;
2538
+ const urlLocation = new URL(location);
2539
+ origin = urlLocation.origin;
2239
2540
  }
2240
2541
  }
2241
2542
  const setCookies = [];
2242
2543
  if (response?.headers) {
2243
- for (const [key13, value] of response.headers) {
2244
- if (key13.toLowerCase() === "set-cookie") {
2544
+ for (const [key14, value] of response.headers) {
2545
+ if (key14.toLowerCase() === "set-cookie") {
2245
2546
  setCookies.push(value);
2246
2547
  }
2247
2548
  }
@@ -2400,25 +2701,25 @@ var Server = class {
2400
2701
  }
2401
2702
  }
2402
2703
  if (headers instanceof Headers) {
2403
- headers.forEach((value, key13) => {
2404
- updates.push([key13.toLowerCase(), value]);
2704
+ headers.forEach((value, key14) => {
2705
+ updates.push([key14.toLowerCase(), value]);
2405
2706
  });
2406
2707
  } else {
2407
- for (const [key13, value] of Object.entries(headers ?? {})) {
2408
- updates.push([key13.toLowerCase(), value]);
2708
+ for (const [key14, value] of Object.entries(headers ?? {})) {
2709
+ updates.push([key14.toLowerCase(), value]);
2409
2710
  }
2410
2711
  }
2411
2712
  const merged = {};
2412
- this.#headers?.forEach((value, key13) => {
2413
- if (key13.toLowerCase() !== "cookie") {
2414
- merged[key13.toLowerCase()] = value;
2713
+ this.#headers?.forEach((value, key14) => {
2714
+ if (key14.toLowerCase() !== "cookie") {
2715
+ merged[key14.toLowerCase()] = value;
2415
2716
  }
2416
2717
  });
2417
- for (const [key13, value] of updates) {
2418
- merged[key13] = value;
2718
+ for (const [key14, value] of updates) {
2719
+ merged[key14] = value;
2419
2720
  }
2420
- for (const [key13, value] of Object.entries(merged)) {
2421
- this.#headers.set(key13, value);
2721
+ for (const [key14, value] of Object.entries(merged)) {
2722
+ this.#headers.set(key14, value);
2422
2723
  }
2423
2724
  this.#config.headers = this.#headers;
2424
2725
  }