@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.js CHANGED
@@ -33,7 +33,8 @@ var LoginUserResponseTokenTypeEnum = {
33
33
 
34
34
  // src/api/utils/routes/index.ts
35
35
  var NILEDB_API_URL = process.env.NILEDB_API_URL;
36
- var appRoutes = (prefix = "/api") => ({
36
+ var DEFAULT_PREFIX = "/api";
37
+ var appRoutes = (prefix = DEFAULT_PREFIX) => ({
37
38
  SIGNIN: `${prefix}${"/auth/signin" /* SIGNIN */}`,
38
39
  PROVIDERS: `${prefix}${"/auth/providers" /* PROVIDERS */}`,
39
40
  SESSION: `${prefix}${"/auth/session" /* SESSION */}`,
@@ -42,7 +43,8 @@ var appRoutes = (prefix = "/api") => ({
42
43
  SIGNOUT: `${prefix}${"/auth/signout" /* SIGNOUT */}`,
43
44
  ERROR: `${prefix}/auth/error`,
44
45
  VERIFY_REQUEST: `${prefix}/auth/verify-request`,
45
- PASSWORD_RESET: `${prefix}/auth/reset-password`,
46
+ VERIFY_EMAIL: `${prefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`,
47
+ PASSWORD_RESET: `${prefix}${"/auth/reset-password" /* PASSWORD_RESET */}`,
46
48
  ME: `${prefix}${"/me" /* ME */}`,
47
49
  USERS: `${prefix}${"/users" /* USERS */}`,
48
50
  USER_TENANTS: `${prefix}${"/users/{userId}/tenants" /* USER_TENANTS */}`,
@@ -76,7 +78,8 @@ var proxyRoutes = (config) => ({
76
78
  SIGNOUT: makeRestUrl(config, "/auth/signout" /* SIGNOUT */),
77
79
  ERROR: makeRestUrl(config, "/auth/error"),
78
80
  VERIFY_REQUEST: makeRestUrl(config, "/auth/verify-request"),
79
- PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password")
81
+ PASSWORD_RESET: makeRestUrl(config, "/auth/reset-password" /* PASSWORD_RESET */),
82
+ VERIFY_EMAIL: makeRestUrl(config, "/auth/verify-email" /* VERIFY_EMAIL */)
80
83
  });
81
84
  function filterNullUndefined(obj) {
82
85
  if (!obj) {
@@ -101,9 +104,9 @@ function makeRestUrl(config, path, qp) {
101
104
  const strParams = params.toString();
102
105
  return `${[url, path.substring(1, path.length)].join("/")}${strParams ? `?${strParams}` : ""}`;
103
106
  }
104
- function urlMatches(requestUrl, route16) {
107
+ function urlMatches(requestUrl, route17) {
105
108
  const url = new URL(requestUrl);
106
- return url.pathname.startsWith(route16);
109
+ return url.pathname.startsWith(route17);
107
110
  }
108
111
  function isUUID(value) {
109
112
  if (!value) {
@@ -173,9 +176,9 @@ function matchesLog(configRoutes, request2) {
173
176
  }
174
177
 
175
178
  // src/utils/constants.ts
176
- var X_NILE_TENANT = "nile.tenant_id";
177
- var X_NILE_ORIGIN = "nile.origin";
178
- var X_NILE_SECURECOOKIES = "nile.secure_cookies";
179
+ var X_NILE_TENANT = "nile-tenant-id";
180
+ var X_NILE_ORIGIN = "nile-origin";
181
+ var X_NILE_SECURECOOKIES = "nile-secure-cookies";
179
182
 
180
183
  // src/api/utils/request.ts
181
184
  async function request(url, _init, config) {
@@ -194,15 +197,29 @@ async function request(url, _init, config) {
194
197
  }
195
198
  if (config.secureCookies != null) {
196
199
  updatedHeaders.set(X_NILE_SECURECOOKIES, String(config.secureCookies));
200
+ } else {
201
+ updatedHeaders.set(
202
+ X_NILE_SECURECOOKIES,
203
+ process.env.NODE_ENV === "production" ? "true" : "false"
204
+ );
197
205
  }
198
206
  updatedHeaders.set("host", requestUrl.host);
199
207
  if (config.callbackUrl) {
200
208
  const cbUrl = new URL(config.callbackUrl);
201
209
  debug(`Obtained origin from config.callbackUrl ${config.callbackUrl}`);
202
210
  updatedHeaders.set(X_NILE_ORIGIN, cbUrl.origin);
211
+ } else if (config.origin) {
212
+ debug(`Obtained origin from config.origin ${config.origin}`);
213
+ updatedHeaders.set(X_NILE_ORIGIN, config.origin);
203
214
  } else {
204
- updatedHeaders.set(X_NILE_ORIGIN, requestUrl.origin);
205
- debug(`Obtained origin from request ${requestUrl.origin}`);
215
+ const passedOrigin = request2.headers.get(X_NILE_ORIGIN);
216
+ if (passedOrigin) {
217
+ updatedHeaders.set(X_NILE_ORIGIN, passedOrigin);
218
+ } else {
219
+ const reqOrigin = config.routePrefix !== DEFAULT_PREFIX ? `${requestUrl.origin}${config.routePrefix}` : requestUrl.origin;
220
+ updatedHeaders.set(X_NILE_ORIGIN, reqOrigin);
221
+ debug(`Obtained origin from request ${reqOrigin}`);
222
+ }
206
223
  }
207
224
  const params = { ...init };
208
225
  if (params.method?.toLowerCase() === "post" || params.method?.toLowerCase() === "put") {
@@ -306,7 +323,7 @@ function matches(configRoutes, request2) {
306
323
  return urlMatches(request2.url, configRoutes[key]);
307
324
  }
308
325
  async function fetchMe(config, method, body) {
309
- const clientUrl = `${config.origin}${config.routePrefix}${"/me" /* ME */}`;
326
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/me" /* ME */}`;
310
327
  const init = {
311
328
  headers: config.headers,
312
329
  method: method ?? "GET"
@@ -336,47 +353,6 @@ async function GET(url, init, config) {
336
353
  return res;
337
354
  }
338
355
 
339
- // src/utils/Event/index.ts
340
- var Eventer = class {
341
- events = {};
342
- publish(eventName, value) {
343
- const callbacks = this.events[eventName];
344
- if (callbacks) {
345
- for (const callback of callbacks) {
346
- callback(value);
347
- }
348
- }
349
- }
350
- subscribe(eventName, callback) {
351
- if (!this.events[eventName]) {
352
- this.events[eventName] = [];
353
- }
354
- this.events[eventName].push(callback);
355
- }
356
- unsubscribe(eventName, callback) {
357
- const callbacks = this.events[eventName];
358
- if (!callbacks) return;
359
- const index = callbacks.indexOf(callback);
360
- if (index !== -1) {
361
- callbacks.splice(index, 1);
362
- }
363
- if (callbacks.length === 0) {
364
- delete this.events[eventName];
365
- }
366
- }
367
- };
368
- var eventer = new Eventer();
369
- var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
370
- var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
371
- var evictPool = (val) => {
372
- eventer.publish("EvictPool" /* EvictPool */, val);
373
- };
374
- var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
375
- var updateHeaders = (val) => {
376
- eventer.publish("headers" /* Headers */, val);
377
- };
378
- var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
379
-
380
356
  // src/utils/fetch.ts
381
357
  function getTokenFromCookie(headers, cookieKey) {
382
358
  const cookie = headers.get("cookie")?.split("; ");
@@ -515,11 +491,11 @@ async function route3(request2, config) {
515
491
  function matches3(configRoutes, request2) {
516
492
  const url = new URL(request2.url);
517
493
  const [userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
518
- let route16 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
494
+ let route17 = configRoutes[key3].replace("{tenantId}", tenantId).replace("{userId}", userId);
519
495
  if (userId === "users") {
520
- route16 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
496
+ route17 = configRoutes[key3].replace("{tenantId}", possibleTenantId);
521
497
  }
522
- return urlMatches(request2.url, route16);
498
+ return urlMatches(request2.url, route17);
523
499
  }
524
500
  async function fetchTenantUsers(config, method, payload) {
525
501
  const { body, params } = {};
@@ -540,7 +516,7 @@ async function fetchTenantUsers(config, method, payload) {
540
516
  if (params?.tenantId) {
541
517
  q.set("tenantId", params.tenantId);
542
518
  }
543
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
519
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users" /* TENANT_USERS */.replace(
544
520
  "{tenantId}",
545
521
  config.tenantId
546
522
  )}`;
@@ -642,7 +618,7 @@ function matches4(configRoutes, request2) {
642
618
  return urlMatches(request2.url, configRoutes[key4]);
643
619
  }
644
620
  async function fetchTenants(config, method, body) {
645
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
621
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants" /* TENANTS */}`;
646
622
  const init = {
647
623
  method,
648
624
  headers: config.headers
@@ -664,7 +640,7 @@ async function fetchTenant(config, method, body) {
664
640
  "nile.tenantId is not a valid UUID. This may lead to unexpected behavior in your application."
665
641
  );
666
642
  }
667
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
643
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}" /* TENANT */.replace("{tenantId}", config.tenantId)}`;
668
644
  const m = method ?? "GET";
669
645
  const init = {
670
646
  method: m,
@@ -688,7 +664,7 @@ async function fetchTenantsByUser(config) {
688
664
  );
689
665
  }
690
666
  }
691
- const clientUrl = `${config.origin}${config.routePrefix}${"/users/{userId}/tenants" /* USER_TENANTS */.replace(
667
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/users/{userId}/tenants" /* USER_TENANTS */.replace(
692
668
  "{userId}",
693
669
  config.userId ?? "WARN_NOT_SET"
694
670
  )}`;
@@ -718,7 +694,7 @@ function matches5(configRoutes, request2) {
718
694
  return urlMatches(request2.url, configRoutes[key5]);
719
695
  }
720
696
  async function fetchSignIn(config, provider, body) {
721
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
697
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signin" /* SIGNIN */}/${provider}`;
722
698
  const req = new Request(clientUrl, {
723
699
  method: "POST",
724
700
  headers: config.headers,
@@ -742,7 +718,7 @@ function matches6(configRoutes, request2) {
742
718
  return urlMatches(request2.url, configRoutes.SESSION);
743
719
  }
744
720
  async function fetchSession(config) {
745
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
721
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/session" /* SESSION */}`;
746
722
  const req = new Request(clientUrl, {
747
723
  method: "GET",
748
724
  headers: config.headers
@@ -765,7 +741,7 @@ function matches7(configRoutes, request2) {
765
741
  return urlMatches(request2.url, configRoutes.PROVIDERS);
766
742
  }
767
743
  async function fetchProviders(config) {
768
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
744
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/providers" /* PROVIDERS */}`;
769
745
  const req = new Request(clientUrl, {
770
746
  method: "GET",
771
747
  headers: config.headers
@@ -788,7 +764,7 @@ function matches8(configRoutes, request2) {
788
764
  return urlMatches(request2.url, configRoutes.CSRF);
789
765
  }
790
766
  async function fetchCsrf(config) {
791
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
767
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/csrf" /* CSRF */}`;
792
768
  const req = new Request(clientUrl, {
793
769
  method: "GET",
794
770
  headers: config.headers
@@ -837,10 +813,10 @@ async function route9(req, config) {
837
813
  function matches9(configRoutes, request2) {
838
814
  return urlMatches(request2.url, configRoutes.CALLBACK);
839
815
  }
840
- async function fetchCallback(config, provider, body) {
841
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}`;
816
+ async function fetchCallback(config, provider, body, request2, method = "POST") {
817
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/callback" /* CALLBACK */}/${provider}${request2 ? `?${new URL(request2.url).searchParams}` : ""}`;
842
818
  const req = new Request(clientUrl, {
843
- method: "POST",
819
+ method,
844
820
  headers: config.headers,
845
821
  body
846
822
  });
@@ -866,7 +842,7 @@ function matches10(configRoutes, request2) {
866
842
  return urlMatches(request2.url, configRoutes[key7]);
867
843
  }
868
844
  async function fetchSignOut(config, body) {
869
- const clientUrl = `${config.origin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
845
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/signout" /* SIGNOUT */}`;
870
846
  const req = new Request(clientUrl, {
871
847
  method: "POST",
872
848
  body,
@@ -934,6 +910,62 @@ async function route13(req, config) {
934
910
  function matches13(configRoutes, request2) {
935
911
  return urlMatches(request2.url, configRoutes.PASSWORD_RESET);
936
912
  }
913
+ async function fetchResetPassword(config, method, body, params, useJson = true) {
914
+ const authParams = new URLSearchParams(params ?? {});
915
+ if (useJson) {
916
+ authParams?.set("json", "true");
917
+ }
918
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/reset-password" /* PASSWORD_RESET */}?${authParams?.toString()}`;
919
+ const init = {
920
+ method,
921
+ headers: config.headers
922
+ };
923
+ if (body && method !== "GET") {
924
+ init.body = body;
925
+ }
926
+ const req = new Request(clientUrl, init);
927
+ return await config.handlers[method](req);
928
+ }
929
+
930
+ // src/api/routes/auth/verify-email.ts
931
+ var key11 = "VERIFY_EMAIL";
932
+ async function route14(req, config) {
933
+ const url = proxyRoutes(config)[key11];
934
+ const res = await request(
935
+ url,
936
+ {
937
+ method: req.method,
938
+ request: req
939
+ },
940
+ config
941
+ );
942
+ const location = res?.headers.get("location");
943
+ if (location) {
944
+ return new Response(res?.body, {
945
+ status: 302,
946
+ headers: res?.headers
947
+ });
948
+ }
949
+ return new Response(res?.body, {
950
+ status: res?.status,
951
+ headers: res?.headers
952
+ });
953
+ }
954
+ function matches14(configRoutes, request2) {
955
+ return urlMatches(request2.url, configRoutes[key11]);
956
+ }
957
+ async function fetchVerifyEmail(config, method, body) {
958
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/auth/verify-email" /* VERIFY_EMAIL */}`;
959
+ const init = {
960
+ method,
961
+ headers: config.headers
962
+ };
963
+ if (body) {
964
+ init.body = body;
965
+ }
966
+ const req = new Request(clientUrl, init);
967
+ return await config.handlers[method](req);
968
+ }
937
969
 
938
970
  // src/api/handlers/GET.ts
939
971
  function GETTER(configRoutes, config) {
@@ -987,6 +1019,10 @@ function GETTER(configRoutes, config) {
987
1019
  info("matches verify-request");
988
1020
  return route12(req, config);
989
1021
  }
1022
+ if (matches14(configRoutes, req)) {
1023
+ info("matches verify-email");
1024
+ return route14(req, config);
1025
+ }
990
1026
  if (matches11(configRoutes, req)) {
991
1027
  info("matches error");
992
1028
  return route11(req, config);
@@ -1005,8 +1041,8 @@ async function POST4(config, init) {
1005
1041
  }
1006
1042
 
1007
1043
  // src/api/routes/signup/index.tsx
1008
- var key11 = "SIGNUP";
1009
- async function route14(request2, config) {
1044
+ var key12 = "SIGNUP";
1045
+ async function route15(request2, config) {
1010
1046
  switch (request2.method) {
1011
1047
  case "POST":
1012
1048
  return await POST4(config, { request: request2 });
@@ -1014,8 +1050,8 @@ async function route14(request2, config) {
1014
1050
  return new Response("method not allowed", { status: 405 });
1015
1051
  }
1016
1052
  }
1017
- function matches14(configRoutes, request2) {
1018
- return urlMatches(request2.url, configRoutes[key11]);
1053
+ function matches15(configRoutes, request2) {
1054
+ return urlMatches(request2.url, configRoutes[key12]);
1019
1055
  }
1020
1056
  async function fetchSignUp(config, payload) {
1021
1057
  const { body, params } = payload ?? {};
@@ -1026,7 +1062,7 @@ async function fetchSignUp(config, payload) {
1026
1062
  if (params?.tenantId) {
1027
1063
  q.set("tenantId", params.tenantId);
1028
1064
  }
1029
- const clientUrl = `${config.origin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1065
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/signup" /* SIGNUP */}${q.size > 0 ? `?${q}` : ""}`;
1030
1066
  const req = new Request(clientUrl, {
1031
1067
  method: "POST",
1032
1068
  headers: config.headers,
@@ -1040,24 +1076,21 @@ function POSTER(configRoutes, config) {
1040
1076
  const { info, warn, error } = Logger(config, "[POST MATCHER]");
1041
1077
  return async function POST5(req) {
1042
1078
  if (matchesLog(configRoutes, req)) {
1043
- if (req.body) {
1044
- try {
1045
- const text = await req.text();
1046
- error(text);
1047
- return new Response(null, {
1048
- status: 200
1049
- });
1050
- } catch (e) {
1051
- }
1079
+ try {
1080
+ const json = await req.clone().json();
1081
+ error(req.body && json);
1082
+ } catch {
1083
+ error(await req.text());
1052
1084
  }
1085
+ return new Response(null, { status: 200 });
1053
1086
  }
1054
1087
  if (matches3(configRoutes, req)) {
1055
1088
  info("matches tenant users");
1056
1089
  return route3(req, config);
1057
1090
  }
1058
- if (matches14(configRoutes, req)) {
1091
+ if (matches15(configRoutes, req)) {
1059
1092
  info("matches signup");
1060
- return route14(req, config);
1093
+ return route15(req, config);
1061
1094
  }
1062
1095
  if (matches2(configRoutes, req)) {
1063
1096
  info("matches users");
@@ -1095,6 +1128,10 @@ function POSTER(configRoutes, config) {
1095
1128
  info("matches signout");
1096
1129
  return route10(req, config);
1097
1130
  }
1131
+ if (matches14(configRoutes, req)) {
1132
+ info("matches verify-email");
1133
+ return route14(req, config);
1134
+ }
1098
1135
  warn(`No POST routes matched ${req.url}`);
1099
1136
  return new Response(null, { status: 404 });
1100
1137
  };
@@ -1123,11 +1160,11 @@ async function PUT4(config, init) {
1123
1160
  }
1124
1161
 
1125
1162
  // src/api/routes/tenants/[tenantId]/users/[userId]/index.ts
1126
- var key12 = "TENANT_USER";
1127
- async function route15(request2, config) {
1163
+ var key13 = "TENANT_USER";
1164
+ async function route16(request2, config) {
1128
1165
  const { info } = Logger(
1129
1166
  { ...config, debug: config.debug },
1130
- `[ROUTES][${key12}]`
1167
+ `[ROUTES][${key13}]`
1131
1168
  );
1132
1169
  const session = await auth(request2, config);
1133
1170
  if (!session) {
@@ -1149,14 +1186,14 @@ async function route15(request2, config) {
1149
1186
  return new Response("method not allowed", { status: 405 });
1150
1187
  }
1151
1188
  }
1152
- function matches15(configRoutes, request2) {
1189
+ function matches16(configRoutes, request2) {
1153
1190
  const url = new URL(request2.url);
1154
1191
  const [, userId, possibleTenantId, tenantId] = url.pathname.split("/").reverse();
1155
- let route16 = configRoutes[key12].replace("{tenantId}", tenantId).replace("{userId}", userId);
1192
+ let route17 = configRoutes[key13].replace("{tenantId}", tenantId).replace("{userId}", userId);
1156
1193
  if (userId === "users") {
1157
- route16 = configRoutes[key12].replace("{tenantId}", possibleTenantId);
1194
+ route17 = configRoutes[key13].replace("{tenantId}", possibleTenantId);
1158
1195
  }
1159
- return urlMatches(request2.url, route16);
1196
+ return urlMatches(request2.url, route17);
1160
1197
  }
1161
1198
  async function fetchTenantUser(config, method) {
1162
1199
  if (!config.tenantId) {
@@ -1169,7 +1206,7 @@ async function fetchTenantUser(config, method) {
1169
1206
  "the userId context is missing. Call nile.setContext({ userId })"
1170
1207
  );
1171
1208
  }
1172
- const clientUrl = `${config.origin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1209
+ const clientUrl = `${config.serverOrigin}${config.routePrefix}${"/tenants/{tenantId}/users/{userId}" /* TENANT_USER */.replace(
1173
1210
  "{tenantId}",
1174
1211
  config.tenantId
1175
1212
  ).replace("{userId}", config.userId)}/link`;
@@ -1184,9 +1221,9 @@ async function fetchTenantUser(config, method) {
1184
1221
  function DELETER(configRoutes, config) {
1185
1222
  const { info, warn } = Logger(config, "[DELETE MATCHER]");
1186
1223
  return async function DELETE4(req) {
1187
- if (matches15(configRoutes, req)) {
1224
+ if (matches16(configRoutes, req)) {
1188
1225
  info("matches tenant user");
1189
- return route15(req, config);
1226
+ return route16(req, config);
1190
1227
  }
1191
1228
  if (matches3(configRoutes, req)) {
1192
1229
  info("matches tenant users");
@@ -1209,9 +1246,9 @@ function DELETER(configRoutes, config) {
1209
1246
  function PUTER(configRoutes, config) {
1210
1247
  const { info, warn } = Logger(config, "[PUT MATCHER]");
1211
1248
  return async function PUT5(req) {
1212
- if (matches15(configRoutes, req)) {
1249
+ if (matches16(configRoutes, req)) {
1213
1250
  info("matches tenant user");
1214
- return route15(req, config);
1251
+ return route16(req, config);
1215
1252
  }
1216
1253
  if (matches3(configRoutes, req)) {
1217
1254
  info("matches tenant users");
@@ -1429,7 +1466,6 @@ var stringCheck = (str) => {
1429
1466
  // src/utils/Config/index.ts
1430
1467
  var Config = class {
1431
1468
  routes;
1432
- // handlersWithContext;
1433
1469
  handlers;
1434
1470
  paths;
1435
1471
  logger;
@@ -1450,6 +1486,10 @@ var Config = class {
1450
1486
  */
1451
1487
  apiUrl;
1452
1488
  origin;
1489
+ /**
1490
+ * important for separating the `origin` config value from a default in order to make requests
1491
+ */
1492
+ serverOrigin;
1453
1493
  debug;
1454
1494
  /**
1455
1495
  * To use secure cookies or not in the fetch
@@ -1468,7 +1508,8 @@ var Config = class {
1468
1508
  this.secureCookies = getSecureCookies(envVarConfig);
1469
1509
  this.callbackUrl = getCallbackUrl(envVarConfig);
1470
1510
  this.debug = config?.debug;
1471
- this.origin = config?.origin ?? "http://localhost:3000";
1511
+ this.origin = config?.origin;
1512
+ this.serverOrigin = config?.origin ?? "http://localhost:3000";
1472
1513
  this.apiUrl = getApiUrl(envVarConfig);
1473
1514
  const user = getUsername(envVarConfig);
1474
1515
  const password = getPassword(envVarConfig);
@@ -1539,6 +1580,47 @@ var Config = class {
1539
1580
  }
1540
1581
  };
1541
1582
 
1583
+ // src/utils/Event/index.ts
1584
+ var Eventer = class {
1585
+ events = {};
1586
+ publish(eventName, value) {
1587
+ const callbacks = this.events[eventName];
1588
+ if (callbacks) {
1589
+ for (const callback of callbacks) {
1590
+ callback(value);
1591
+ }
1592
+ }
1593
+ }
1594
+ subscribe(eventName, callback) {
1595
+ if (!this.events[eventName]) {
1596
+ this.events[eventName] = [];
1597
+ }
1598
+ this.events[eventName].push(callback);
1599
+ }
1600
+ unsubscribe(eventName, callback) {
1601
+ const callbacks = this.events[eventName];
1602
+ if (!callbacks) return;
1603
+ const index = callbacks.indexOf(callback);
1604
+ if (index !== -1) {
1605
+ callbacks.splice(index, 1);
1606
+ }
1607
+ if (callbacks.length === 0) {
1608
+ delete this.events[eventName];
1609
+ }
1610
+ }
1611
+ };
1612
+ var eventer = new Eventer();
1613
+ var watchTenantId = (cb) => eventer.subscribe("tenantId" /* Tenant */, cb);
1614
+ var watchUserId = (cb) => eventer.subscribe("userId" /* User */, cb);
1615
+ var evictPool = (val) => {
1616
+ eventer.publish("EvictPool" /* EvictPool */, val);
1617
+ };
1618
+ var watchEvictPool = (cb) => eventer.subscribe("EvictPool" /* EvictPool */, cb);
1619
+ var updateHeaders = (val) => {
1620
+ eventer.publish("headers" /* Headers */, val);
1621
+ };
1622
+ var watchHeaders = (cb) => eventer.subscribe("headers" /* Headers */, cb);
1623
+
1542
1624
  // src/db/PoolProxy.ts
1543
1625
  function createProxyForPool(pool, config) {
1544
1626
  const { info, error } = Logger(config, "[pool]");
@@ -1763,336 +1845,265 @@ var DBManager = class {
1763
1845
  };
1764
1846
  };
1765
1847
 
1766
- // src/users/index.ts
1767
- var Users = class {
1848
+ // src/auth/index.ts
1849
+ var Auth = class {
1850
+ #logger;
1768
1851
  #config;
1769
1852
  constructor(config) {
1770
1853
  this.#config = config;
1854
+ this.#logger = Logger(config, "[auth]");
1771
1855
  }
1772
- async updateSelf(req, rawResponse) {
1773
- const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
1856
+ async getSession(rawResponse = false) {
1857
+ const res = await fetchSession(this.#config);
1774
1858
  if (rawResponse) {
1775
1859
  return res;
1776
1860
  }
1777
1861
  try {
1778
- return await res?.clone().json();
1862
+ const session = await res.clone().json();
1863
+ if (Object.keys(session).length === 0) {
1864
+ return void 0;
1865
+ }
1866
+ return session;
1779
1867
  } catch {
1780
1868
  return res;
1781
1869
  }
1782
1870
  }
1783
- async removeSelf() {
1784
- const me = await this.getSelf();
1785
- if ("id" in me) {
1786
- this.#config.userId = me.id;
1787
- }
1788
- const res = await fetchMe(this.#config, "DELETE");
1789
- updateHeaders(new Headers());
1790
- return res;
1871
+ async getCsrf(rawResponse = false) {
1872
+ return await getCsrf(this.#config, rawResponse);
1791
1873
  }
1792
- async getSelf(rawResponse) {
1793
- const res = await fetchMe(this.#config);
1874
+ async listProviders(rawResponse = false) {
1875
+ const res = await fetchProviders(this.#config);
1794
1876
  if (rawResponse) {
1795
1877
  return res;
1796
1878
  }
1797
1879
  try {
1798
- return await res?.clone().json();
1880
+ return await res.clone().json();
1799
1881
  } catch {
1800
1882
  return res;
1801
1883
  }
1802
1884
  }
1803
- };
1804
-
1805
- // src/tenants/index.ts
1806
- var Tenants = class {
1807
- #logger;
1808
- #config;
1809
- constructor(config) {
1810
- this.#logger = Logger(config, "[tenants]");
1811
- this.#config = config;
1885
+ async signOut() {
1886
+ const csrfRes = await this.getCsrf();
1887
+ if (!("csrfToken" in csrfRes)) {
1888
+ throw new Error("Unable to obtain CSRF token. Sign out failed.");
1889
+ }
1890
+ const body = JSON.stringify({
1891
+ csrfToken: csrfRes.csrfToken,
1892
+ json: true
1893
+ });
1894
+ const res = await fetchSignOut(this.#config, body);
1895
+ updateHeaders(new Headers({}));
1896
+ this.#config.headers = new Headers();
1897
+ return res;
1812
1898
  }
1813
- async create(req, rawResponse) {
1814
- let res;
1815
- if (typeof req === "string") {
1816
- res = await fetchTenants(
1817
- this.#config,
1818
- "POST",
1819
- JSON.stringify({ name: req })
1899
+ async signUp(payload, rawResponse) {
1900
+ this.#config.headers = new Headers();
1901
+ const { email, password, ...params } = payload;
1902
+ if (!email || !password) {
1903
+ throw new Error(
1904
+ "Server side sign up requires a user email and password."
1820
1905
  );
1821
- } else if (typeof req === "object" && ("name" in req || "id" in req)) {
1822
- res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
1823
- }
1824
- if (rawResponse) {
1825
- return res;
1826
- }
1827
- try {
1828
- return await res?.clone().json();
1829
- } catch {
1830
- return res;
1831
1906
  }
1832
- }
1833
- async delete(req) {
1834
- if (typeof req === "string") {
1835
- this.#config.tenantId = req;
1907
+ const providers = await this.listProviders();
1908
+ const { credentials } = providers ?? {};
1909
+ if (!credentials) {
1910
+ throw new Error(
1911
+ "Unable to obtain credential provider. Aborting server side sign up."
1912
+ );
1836
1913
  }
1837
- if (typeof req === "object" && "id" in req) {
1838
- this.#config.tenantId = req.id;
1914
+ const csrf = await this.getCsrf();
1915
+ let csrfToken;
1916
+ if ("csrfToken" in csrf) {
1917
+ csrfToken = csrf.csrfToken;
1918
+ } else {
1919
+ throw new Error("Unable to obtain parse CSRF. Request blocked.");
1839
1920
  }
1840
- const res = await fetchTenant(this.#config, "DELETE");
1841
- return res;
1842
- }
1843
- async get(req, rawResponse) {
1844
- if (typeof req === "string") {
1845
- this.#config.tenantId = req;
1846
- } else if (typeof req === "object" && "id" in req) {
1847
- this.#config.tenantId = req.id;
1848
- }
1849
- const res = await fetchTenant(this.#config, "GET");
1850
- if (rawResponse === true || req === true) {
1851
- return res;
1852
- }
1853
- try {
1854
- return await res?.clone().json();
1855
- } catch {
1856
- return res;
1921
+ const body = JSON.stringify({
1922
+ email,
1923
+ password,
1924
+ csrfToken,
1925
+ callbackUrl: credentials.callbackUrl
1926
+ });
1927
+ const res = await fetchSignUp(this.#config, { body, params });
1928
+ if (res.status > 299) {
1929
+ this.#logger.error(await res.clone().text());
1930
+ return void 0;
1857
1931
  }
1858
- }
1859
- async update(req, rawResponse) {
1860
- let res;
1861
- if (typeof req === "object" && ("name" in req || "id" in req)) {
1862
- const { id, ...remaining } = req;
1863
- if (id) {
1864
- this.#config.tenantId = id;
1865
- }
1866
- res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
1932
+ const token = parseToken(res.headers);
1933
+ if (!token) {
1934
+ throw new Error("Server side sign up failed. Session token not found");
1867
1935
  }
1936
+ this.#config.headers?.append("cookie", token);
1937
+ updateHeaders(this.#config.headers);
1868
1938
  if (rawResponse) {
1869
1939
  return res;
1870
1940
  }
1871
1941
  try {
1872
- return await res?.clone().json();
1942
+ return await res.clone().json();
1873
1943
  } catch {
1874
1944
  return res;
1875
1945
  }
1876
1946
  }
1877
- async list(req) {
1878
- const res = await fetchTenantsByUser(this.#config);
1879
- if (req === true) {
1880
- return res;
1947
+ async forgotPassword(req) {
1948
+ let email = "";
1949
+ const defaults = defaultCallbackUrl({
1950
+ config: this.#config
1951
+ });
1952
+ let callbackUrl = defaults.callbackUrl;
1953
+ let redirectUrl = defaults.redirectUrl;
1954
+ if ("email" in req) {
1955
+ email = req.email;
1881
1956
  }
1882
- try {
1883
- return await res?.clone().json();
1884
- } catch {
1885
- return res;
1957
+ if ("callbackUrl" in req) {
1958
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
1886
1959
  }
1887
- }
1888
- async leaveTenant(req) {
1889
- const me = await fetchMe(this.#config);
1890
- try {
1891
- const json = await me.json();
1892
- if ("id" in json) {
1893
- this.#config.userId = json.id;
1894
- }
1895
- } catch {
1960
+ if ("redirectUrl" in req) {
1961
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
1896
1962
  }
1897
- if (typeof req === "string") {
1898
- this.#config.tenantId = req;
1899
- } else {
1900
- this.#handleContext(req);
1901
- }
1902
- return await fetchTenantUser(this.#config, "DELETE");
1903
- }
1904
- async addMember(req, rawResponse) {
1905
- if (typeof req === "string") {
1906
- this.#config.userId = req;
1907
- } else {
1908
- this.#handleContext(req);
1909
- }
1910
- const res = await fetchTenantUser(this.#config, "PUT");
1911
- return responseHandler(res, rawResponse);
1912
- }
1913
- async removeMember(req, rawResponse) {
1914
- this.#handleContext(req);
1915
- const res = await fetchTenantUser(this.#config, "DELETE");
1916
- return responseHandler(res, rawResponse);
1917
- }
1918
- async users(req, rawResponse) {
1919
- this.#handleContext(req);
1920
- const res = await fetchTenantUsers(this.#config, "GET");
1921
- return responseHandler(
1922
- res,
1923
- rawResponse || typeof req === "boolean" && req
1963
+ const body = JSON.stringify({
1964
+ email,
1965
+ redirectUrl,
1966
+ callbackUrl
1967
+ });
1968
+ const data = await fetchResetPassword(
1969
+ this.#config,
1970
+ "POST",
1971
+ body,
1972
+ new URLSearchParams(),
1973
+ false
1924
1974
  );
1925
- }
1926
- #handleContext(req) {
1927
- if (typeof req === "object") {
1928
- if ("tenantId" in req) {
1929
- this.#config.tenantId = req.tenantId;
1975
+ return data;
1976
+ }
1977
+ async resetPassword(req) {
1978
+ let email = "";
1979
+ let password = "";
1980
+ const defaults = defaultCallbackUrl({ config: this.#config });
1981
+ let callbackUrl = defaults.callbackUrl;
1982
+ let redirectUrl = defaults.redirectUrl;
1983
+ if (req instanceof Request) {
1984
+ const body2 = await req.json();
1985
+ email = body2.email;
1986
+ password = body2.password;
1987
+ const cbFromHeaders = parseCallback(req.headers);
1988
+ if (cbFromHeaders) {
1989
+ callbackUrl = cbFromHeaders;
1930
1990
  }
1931
- if ("userId" in req) {
1932
- this.#config.tenantId = req.tenantId;
1991
+ if (body2.callbackUrl) {
1992
+ callbackUrl = body2.callbackUrl;
1933
1993
  }
1934
- }
1935
- }
1936
- };
1937
- async function responseHandler(res, rawResponse) {
1938
- if (rawResponse) {
1939
- return res;
1940
- }
1941
- try {
1942
- return await res?.clone().json();
1943
- } catch {
1944
- return res;
1945
- }
1946
- }
1947
-
1948
- // src/auth/index.ts
1949
- var Auth = class {
1950
- #logger;
1951
- #config;
1952
- constructor(config) {
1953
- this.#config = config;
1954
- this.#logger = Logger(config, "[auth]");
1955
- }
1956
- async getSession(rawResponse = false) {
1957
- const res = await fetchSession(this.#config);
1958
- if (rawResponse) {
1959
- return res;
1960
- }
1961
- try {
1962
- const session = await res.clone().json();
1963
- if (Object.keys(session).length === 0) {
1964
- return void 0;
1994
+ if (body2.redirectUrl) {
1995
+ redirectUrl = body2.redirectUrl;
1965
1996
  }
1966
- return session;
1967
- } catch {
1968
- return res;
1969
- }
1970
- }
1971
- async getCsrf(rawResponse = false) {
1972
- const res = await fetchCsrf(this.#config);
1973
- const csrfCook = parseCSRF(res.headers);
1974
- if (csrfCook) {
1975
- const [, value] = csrfCook.split("=");
1976
- const [token] = decodeURIComponent(value).split("|");
1977
- const setCookie = res.headers.get("set-cookie");
1978
- if (setCookie) {
1979
- const cookie = [
1980
- csrfCook,
1981
- parseCallback(res.headers),
1982
- parseToken(res.headers)
1983
- ].filter(Boolean).join("; ");
1984
- this.#config.headers.set("cookie", cookie);
1985
- updateHeaders(new Headers({ cookie }));
1997
+ } else {
1998
+ if ("email" in req) {
1999
+ email = req.email;
1986
2000
  }
1987
- if (!rawResponse) {
1988
- return { csrfToken: token };
2001
+ if ("password" in req) {
2002
+ password = req.password;
1989
2003
  }
1990
- } else {
1991
- const existingCookie = this.#config.headers.get("cookie");
1992
- const cookieParts = [];
1993
- if (existingCookie) {
1994
- cookieParts.push(
1995
- parseToken(this.#config.headers),
1996
- parseCallback(this.#config.headers)
1997
- );
2004
+ if ("callbackUrl" in req) {
2005
+ callbackUrl = req.callbackUrl ? req.callbackUrl : null;
2006
+ }
2007
+ if ("redirectUrl" in req) {
2008
+ redirectUrl = req.redirectUrl ? req.redirectUrl : null;
1998
2009
  }
1999
- cookieParts.push(csrfCook);
2000
- const cookie = cookieParts.filter(Boolean).join("; ");
2001
- this.#config.headers.set("cookie", cookie);
2002
- updateHeaders(new Headers({ cookie }));
2003
- }
2004
- if (rawResponse) {
2005
- return res;
2006
2010
  }
2011
+ await this.getCsrf();
2012
+ const body = JSON.stringify({
2013
+ email,
2014
+ password,
2015
+ redirectUrl,
2016
+ callbackUrl
2017
+ });
2018
+ let urlWithParams;
2007
2019
  try {
2008
- return await res.clone().json();
2020
+ const data = await fetchResetPassword(this.#config, "POST", body);
2021
+ const cloned = data.clone();
2022
+ if (data.status === 400) {
2023
+ const text = await cloned.text();
2024
+ this.#logger.error(text);
2025
+ return data;
2026
+ }
2027
+ const { url } = await data.json();
2028
+ urlWithParams = url;
2009
2029
  } catch {
2010
- return res;
2011
- }
2012
- }
2013
- async listProviders(rawResponse = false) {
2014
- const res = await fetchProviders(this.#config);
2015
- if (rawResponse) {
2016
- return res;
2017
2030
  }
2031
+ let token;
2018
2032
  try {
2019
- return await res.clone().json();
2033
+ const worthyParams = new URL(urlWithParams).searchParams;
2034
+ const answer = await fetchResetPassword(
2035
+ this.#config,
2036
+ "GET",
2037
+ null,
2038
+ worthyParams
2039
+ );
2040
+ token = parseResetToken(answer.headers);
2020
2041
  } catch {
2021
- return res;
2022
- }
2023
- }
2024
- async signOut() {
2025
- const csrfRes = await this.getCsrf();
2026
- if (!("csrfToken" in csrfRes)) {
2027
- throw new Error("Unable to obtain CSRF token. Sign out failed.");
2028
- }
2029
- const body = JSON.stringify({
2030
- csrfToken: csrfRes.csrfToken,
2031
- json: true
2032
- });
2033
- const res = await fetchSignOut(this.#config, body);
2034
- updateHeaders(new Headers({}));
2035
- this.#config.headers = new Headers();
2036
- return res;
2037
- }
2038
- async signUp(payload, rawResponse) {
2039
- this.#config.headers = new Headers();
2040
- const { email, password, ...params } = payload;
2041
- if (!email || !password) {
2042
- throw new Error(
2043
- "Server side sign up requires a user email and password."
2042
+ this.#logger.warn(
2043
+ "Unable to parse reset password url. Password not reset."
2044
2044
  );
2045
2045
  }
2046
- const providers = await this.listProviders();
2047
- const { credentials } = providers ?? {};
2048
- if (!credentials) {
2046
+ const cookie = this.#config.headers.get("cookie")?.split("; ");
2047
+ if (token) {
2048
+ cookie?.push(token);
2049
+ } else {
2049
2050
  throw new Error(
2050
- "Unable to obtain credential provider. Aborting server side sign up."
2051
+ "Unable to reset password, reset token is missing from response"
2051
2052
  );
2052
2053
  }
2053
- const csrf = await this.getCsrf();
2054
- let csrfToken;
2055
- if ("csrfToken" in csrf) {
2056
- csrfToken = csrf.csrfToken;
2057
- } else {
2058
- throw new Error("Unable to obtain parse CSRF. Request blocked.");
2059
- }
2060
- const body = JSON.stringify({
2061
- email,
2062
- password,
2063
- csrfToken,
2064
- callbackUrl: credentials.callbackUrl
2054
+ this.#config.headers = new Headers({
2055
+ ...this.#config.headers,
2056
+ cookie: cookie?.join("; ")
2065
2057
  });
2066
- const res = await fetchSignUp(this.#config, { body, params });
2067
- if (res.status > 299) {
2068
- this.#logger.error(await res.clone().text());
2069
- return void 0;
2070
- }
2071
- const token = parseToken(res.headers);
2072
- if (!token) {
2073
- throw new Error("Server side sign up failed. Session token not found");
2074
- }
2075
- this.#config.headers?.append("cookie", token);
2076
- updateHeaders(this.#config.headers);
2077
- if (rawResponse) {
2078
- return res;
2079
- }
2080
- try {
2081
- return await res.clone().json();
2082
- } catch {
2083
- return res;
2058
+ const res = await fetchResetPassword(this.#config, "PUT", body);
2059
+ cookie?.pop();
2060
+ const cleaned = cookie?.filter((c) => !c.includes("nile.session")) ?? [];
2061
+ cleaned.push(String(parseToken(res.headers)));
2062
+ const updatedHeaders = new Headers({ cookie: cleaned.join("; ") });
2063
+ updateHeaders(updatedHeaders);
2064
+ return res;
2065
+ }
2066
+ async callback(provider, body) {
2067
+ if (body instanceof Request) {
2068
+ this.#config.headers = body.headers;
2069
+ return await fetchCallback(
2070
+ this.#config,
2071
+ provider,
2072
+ void 0,
2073
+ body,
2074
+ "GET"
2075
+ );
2084
2076
  }
2077
+ return await fetchCallback(this.#config, provider, body);
2085
2078
  }
2086
2079
  async signIn(provider, payload, rawResponse) {
2087
- this.#config.headers = new Headers();
2088
- const { info, error } = this.#logger;
2089
- const { email, password } = payload ?? {};
2090
- if (provider === "email" && (!email || !password)) {
2091
- throw new Error(
2092
- "Server side sign in requires a user email and password."
2080
+ if (payload instanceof Request) {
2081
+ const body2 = new URLSearchParams(await payload.text());
2082
+ const origin = new URL(payload.url).origin;
2083
+ const payloadUrl = body2?.get("callbackUrl");
2084
+ const csrfToken2 = body2?.get("csrfToken");
2085
+ const callbackUrl = `${!payloadUrl?.startsWith("http") ? origin : ""}${payloadUrl}`;
2086
+ if (!csrfToken2) {
2087
+ throw new Error(
2088
+ "CSRF token in missing from request. Request it by the client before calling sign in"
2089
+ );
2090
+ }
2091
+ this.#config.headers = new Headers(payload.headers);
2092
+ this.#config.headers.set(
2093
+ "Content-Type",
2094
+ "application/x-www-form-urlencoded"
2093
2095
  );
2096
+ const params = new URLSearchParams({
2097
+ csrfToken: csrfToken2,
2098
+ json: String(true)
2099
+ });
2100
+ if (payloadUrl) {
2101
+ params.set("callbackUrl", callbackUrl);
2102
+ }
2103
+ return await fetchSignIn(this.#config, provider, params);
2094
2104
  }
2095
- info(`Obtaining providers for ${email}`);
2105
+ this.#config.headers = new Headers();
2106
+ const { info, error } = this.#logger;
2096
2107
  const providers = await this.listProviders();
2097
2108
  info("Obtaining csrf");
2098
2109
  const csrf = await this.getCsrf();
@@ -2108,13 +2119,13 @@ var Auth = class {
2108
2119
  "Unable to obtain credential provider. Aborting server side sign in."
2109
2120
  );
2110
2121
  }
2111
- if (provider !== "credentials") {
2112
- return await fetchSignIn(
2113
- this.#config,
2114
- provider,
2115
- JSON.stringify({ csrfToken })
2122
+ const { email, password } = payload ?? {};
2123
+ if (provider === "email" && (!email || !password)) {
2124
+ throw new Error(
2125
+ "Server side sign in requires a user email and password."
2116
2126
  );
2117
2127
  }
2128
+ info(`Obtaining providers for ${email}`);
2118
2129
  info(`Attempting sign in with email ${email}`);
2119
2130
  const body = JSON.stringify({
2120
2131
  email,
@@ -2122,7 +2133,7 @@ var Auth = class {
2122
2133
  csrfToken,
2123
2134
  callbackUrl: credentials.callbackUrl
2124
2135
  });
2125
- const signInRes = await fetchCallback(this.#config, provider, body);
2136
+ const signInRes = await this.callback(provider, body);
2126
2137
  const authCookie = signInRes?.headers.get("set-cookie");
2127
2138
  if (!authCookie) {
2128
2139
  throw new Error("authentication failed");
@@ -2204,6 +2215,296 @@ function parseToken(headers) {
2204
2215
  const [, token] = /((__Secure-)?nile\.session-token=[^;]+)/.exec(authCookie) ?? [];
2205
2216
  return token;
2206
2217
  }
2218
+ function parseResetToken(headers) {
2219
+ let authCookie = headers?.get("set-cookie");
2220
+ if (!authCookie) {
2221
+ authCookie = headers?.get("cookie");
2222
+ }
2223
+ if (!authCookie) {
2224
+ return void 0;
2225
+ }
2226
+ const [, token] = /((__Secure-)?nile\.reset=[^;]+)/.exec(authCookie) ?? [];
2227
+ return token;
2228
+ }
2229
+ function defaultCallbackUrl({ config }) {
2230
+ let cb = null;
2231
+ let redirect = null;
2232
+ const fallbackCb = parseCallback(config.headers);
2233
+ if (fallbackCb) {
2234
+ const [, value] = fallbackCb.split("=");
2235
+ cb = decodeURIComponent(value);
2236
+ if (value) {
2237
+ redirect = `${new URL(cb).origin}${"/auth/reset-password" /* PASSWORD_RESET */}`;
2238
+ }
2239
+ }
2240
+ return { callbackUrl: cb, redirectUrl: redirect };
2241
+ }
2242
+
2243
+ // src/auth/getCsrf.ts
2244
+ async function getCsrf(config, rawResponse = false) {
2245
+ const res = await fetchCsrf(config);
2246
+ const csrfCook = parseCSRF(res.headers);
2247
+ if (csrfCook) {
2248
+ const [, value] = csrfCook.split("=");
2249
+ const [token] = decodeURIComponent(value).split("|");
2250
+ const setCookie = res.headers.get("set-cookie");
2251
+ if (setCookie) {
2252
+ const cookie = [
2253
+ csrfCook,
2254
+ parseCallback(res.headers),
2255
+ parseToken(res.headers)
2256
+ ].filter(Boolean).join("; ");
2257
+ config.headers.set("cookie", cookie);
2258
+ updateHeaders(new Headers({ cookie }));
2259
+ }
2260
+ if (!rawResponse) {
2261
+ return { csrfToken: token };
2262
+ }
2263
+ } else {
2264
+ const existingCookie = config.headers.get("cookie");
2265
+ const cookieParts = [];
2266
+ if (existingCookie) {
2267
+ cookieParts.push(
2268
+ parseToken(config.headers),
2269
+ parseCallback(config.headers)
2270
+ );
2271
+ }
2272
+ if (csrfCook) {
2273
+ cookieParts.push(csrfCook);
2274
+ } else {
2275
+ cookieParts.push(parseCSRF(config.headers));
2276
+ }
2277
+ const cookie = cookieParts.filter(Boolean).join("; ");
2278
+ config.headers.set("cookie", cookie);
2279
+ updateHeaders(new Headers({ cookie }));
2280
+ }
2281
+ if (rawResponse) {
2282
+ return res;
2283
+ }
2284
+ try {
2285
+ return await res.clone().json();
2286
+ } catch {
2287
+ return res;
2288
+ }
2289
+ }
2290
+
2291
+ // src/users/index.ts
2292
+ var Users = class {
2293
+ #config;
2294
+ #logger;
2295
+ constructor(config) {
2296
+ this.#config = config;
2297
+ this.#logger = Logger(config, "[me]");
2298
+ }
2299
+ async updateSelf(req, rawResponse) {
2300
+ const res = await fetchMe(this.#config, "PUT", JSON.stringify(req));
2301
+ if (rawResponse) {
2302
+ return res;
2303
+ }
2304
+ try {
2305
+ return await res?.clone().json();
2306
+ } catch {
2307
+ return res;
2308
+ }
2309
+ }
2310
+ async removeSelf() {
2311
+ const me = await this.getSelf();
2312
+ if ("id" in me) {
2313
+ this.#config.userId = me.id;
2314
+ }
2315
+ const res = await fetchMe(this.#config, "DELETE");
2316
+ updateHeaders(new Headers());
2317
+ return res;
2318
+ }
2319
+ async getSelf(rawResponse) {
2320
+ const res = await fetchMe(this.#config);
2321
+ if (rawResponse) {
2322
+ return res;
2323
+ }
2324
+ try {
2325
+ return await res?.clone().json();
2326
+ } catch {
2327
+ return res;
2328
+ }
2329
+ }
2330
+ async verifySelf(bypassEmail = process.env.NODE_ENV !== "production", rawResponse = false) {
2331
+ try {
2332
+ const me = await this.getSelf();
2333
+ if (me instanceof Response) {
2334
+ return me;
2335
+ }
2336
+ const res = await verifyEmailAddress(this.#config, me);
2337
+ return res;
2338
+ } catch {
2339
+ this.#logger?.warn(
2340
+ "Unable to verify email. The current user's email will be set to verified any way. Be sure to configure emails for production."
2341
+ );
2342
+ }
2343
+ if (bypassEmail) {
2344
+ return await this.updateSelf({ emailVerified: true }, rawResponse);
2345
+ }
2346
+ this.#logger.error(
2347
+ "Unable to verify email address. Configure your SMTP server in the console."
2348
+ );
2349
+ return void 0;
2350
+ }
2351
+ };
2352
+ async function verifyEmailAddress(config, user) {
2353
+ config.headers.set("content-type", "application/x-www-form-urlencoded");
2354
+ const { csrfToken } = await getCsrf(config);
2355
+ const res = await fetchVerifyEmail(
2356
+ config,
2357
+ "POST",
2358
+ new URLSearchParams({ csrfToken, email: user.email }).toString()
2359
+ );
2360
+ if (res.status > 299) {
2361
+ throw new Error(await res.text());
2362
+ }
2363
+ return res;
2364
+ }
2365
+
2366
+ // src/tenants/index.ts
2367
+ var Tenants = class {
2368
+ #logger;
2369
+ #config;
2370
+ constructor(config) {
2371
+ this.#logger = Logger(config, "[tenants]");
2372
+ this.#config = config;
2373
+ }
2374
+ async create(req, rawResponse) {
2375
+ let res;
2376
+ if (typeof req === "string") {
2377
+ res = await fetchTenants(
2378
+ this.#config,
2379
+ "POST",
2380
+ JSON.stringify({ name: req })
2381
+ );
2382
+ } else if (typeof req === "object" && ("name" in req || "id" in req)) {
2383
+ res = await fetchTenants(this.#config, "POST", JSON.stringify(req));
2384
+ }
2385
+ if (rawResponse) {
2386
+ return res;
2387
+ }
2388
+ try {
2389
+ return await res?.clone().json();
2390
+ } catch {
2391
+ return res;
2392
+ }
2393
+ }
2394
+ async delete(req) {
2395
+ if (typeof req === "string") {
2396
+ this.#config.tenantId = req;
2397
+ }
2398
+ if (typeof req === "object" && "id" in req) {
2399
+ this.#config.tenantId = req.id;
2400
+ }
2401
+ const res = await fetchTenant(this.#config, "DELETE");
2402
+ return res;
2403
+ }
2404
+ async get(req, rawResponse) {
2405
+ if (typeof req === "string") {
2406
+ this.#config.tenantId = req;
2407
+ } else if (typeof req === "object" && "id" in req) {
2408
+ this.#config.tenantId = req.id;
2409
+ }
2410
+ const res = await fetchTenant(this.#config, "GET");
2411
+ if (rawResponse === true || req === true) {
2412
+ return res;
2413
+ }
2414
+ try {
2415
+ return await res?.clone().json();
2416
+ } catch {
2417
+ return res;
2418
+ }
2419
+ }
2420
+ async update(req, rawResponse) {
2421
+ let res;
2422
+ if (typeof req === "object" && ("name" in req || "id" in req)) {
2423
+ const { id, ...remaining } = req;
2424
+ if (id) {
2425
+ this.#config.tenantId = id;
2426
+ }
2427
+ res = await fetchTenant(this.#config, "PUT", JSON.stringify(remaining));
2428
+ }
2429
+ if (rawResponse) {
2430
+ return res;
2431
+ }
2432
+ try {
2433
+ return await res?.clone().json();
2434
+ } catch {
2435
+ return res;
2436
+ }
2437
+ }
2438
+ async list(req) {
2439
+ const res = await fetchTenantsByUser(this.#config);
2440
+ if (req === true) {
2441
+ return res;
2442
+ }
2443
+ try {
2444
+ return await res?.clone().json();
2445
+ } catch {
2446
+ return res;
2447
+ }
2448
+ }
2449
+ async leaveTenant(req) {
2450
+ const me = await fetchMe(this.#config);
2451
+ try {
2452
+ const json = await me.json();
2453
+ if ("id" in json) {
2454
+ this.#config.userId = json.id;
2455
+ }
2456
+ } catch {
2457
+ }
2458
+ if (typeof req === "string") {
2459
+ this.#config.tenantId = req;
2460
+ } else {
2461
+ this.#handleContext(req);
2462
+ }
2463
+ return await fetchTenantUser(this.#config, "DELETE");
2464
+ }
2465
+ async addMember(req, rawResponse) {
2466
+ if (typeof req === "string") {
2467
+ this.#config.userId = req;
2468
+ } else {
2469
+ this.#handleContext(req);
2470
+ }
2471
+ const res = await fetchTenantUser(this.#config, "PUT");
2472
+ return responseHandler(res, rawResponse);
2473
+ }
2474
+ async removeMember(req, rawResponse) {
2475
+ this.#handleContext(req);
2476
+ const res = await fetchTenantUser(this.#config, "DELETE");
2477
+ return responseHandler(res, rawResponse);
2478
+ }
2479
+ async users(req, rawResponse) {
2480
+ this.#handleContext(req);
2481
+ const res = await fetchTenantUsers(this.#config, "GET");
2482
+ return responseHandler(
2483
+ res,
2484
+ rawResponse || typeof req === "boolean" && req
2485
+ );
2486
+ }
2487
+ #handleContext(req) {
2488
+ if (typeof req === "object") {
2489
+ if ("tenantId" in req) {
2490
+ this.#config.tenantId = req.tenantId;
2491
+ }
2492
+ if ("userId" in req) {
2493
+ this.#config.tenantId = req.tenantId;
2494
+ }
2495
+ }
2496
+ }
2497
+ };
2498
+ async function responseHandler(res, rawResponse) {
2499
+ if (rawResponse) {
2500
+ return res;
2501
+ }
2502
+ try {
2503
+ return await res?.clone().json();
2504
+ } catch {
2505
+ return res;
2506
+ }
2507
+ }
2207
2508
 
2208
2509
  // src/api/handlers/withContext/index.ts
2209
2510
  function handlersWithContext(config) {
@@ -2240,14 +2541,14 @@ function updateConfig(response, config) {
2240
2541
  if (response?.status === 302) {
2241
2542
  const location = response.headers.get("location");
2242
2543
  if (location) {
2243
- const normalized = location.endsWith("/") ? location.slice(0, -1) : location;
2244
- origin = normalized;
2544
+ const urlLocation = new URL(location);
2545
+ origin = urlLocation.origin;
2245
2546
  }
2246
2547
  }
2247
2548
  const setCookies = [];
2248
2549
  if (response?.headers) {
2249
- for (const [key13, value] of response.headers) {
2250
- if (key13.toLowerCase() === "set-cookie") {
2550
+ for (const [key14, value] of response.headers) {
2551
+ if (key14.toLowerCase() === "set-cookie") {
2251
2552
  setCookies.push(value);
2252
2553
  }
2253
2554
  }
@@ -2406,25 +2707,25 @@ var Server = class {
2406
2707
  }
2407
2708
  }
2408
2709
  if (headers instanceof Headers) {
2409
- headers.forEach((value, key13) => {
2410
- updates.push([key13.toLowerCase(), value]);
2710
+ headers.forEach((value, key14) => {
2711
+ updates.push([key14.toLowerCase(), value]);
2411
2712
  });
2412
2713
  } else {
2413
- for (const [key13, value] of Object.entries(headers ?? {})) {
2414
- updates.push([key13.toLowerCase(), value]);
2714
+ for (const [key14, value] of Object.entries(headers ?? {})) {
2715
+ updates.push([key14.toLowerCase(), value]);
2415
2716
  }
2416
2717
  }
2417
2718
  const merged = {};
2418
- this.#headers?.forEach((value, key13) => {
2419
- if (key13.toLowerCase() !== "cookie") {
2420
- merged[key13.toLowerCase()] = value;
2719
+ this.#headers?.forEach((value, key14) => {
2720
+ if (key14.toLowerCase() !== "cookie") {
2721
+ merged[key14.toLowerCase()] = value;
2421
2722
  }
2422
2723
  });
2423
- for (const [key13, value] of updates) {
2424
- merged[key13] = value;
2724
+ for (const [key14, value] of updates) {
2725
+ merged[key14] = value;
2425
2726
  }
2426
- for (const [key13, value] of Object.entries(merged)) {
2427
- this.#headers.set(key13, value);
2727
+ for (const [key14, value] of Object.entries(merged)) {
2728
+ this.#headers.set(key14, value);
2428
2729
  }
2429
2730
  this.#config.headers = this.#headers;
2430
2731
  }