@datrix/api 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1213,7 +1213,91 @@ function createAuthHandlers(config) {
1213
1213
  );
1214
1214
  }
1215
1215
  }
1216
- return { register, login, logout, me };
1216
+ async function forgotPassword(request) {
1217
+ try {
1218
+ const onForgotPassword = authConfig.passwordReset?.onForgotPassword;
1219
+ if (!onForgotPassword) {
1220
+ throw handlerError.permissionDenied("Password reset is not configured");
1221
+ }
1222
+ const body = await request.json();
1223
+ const { email } = body;
1224
+ if (!email || typeof email !== "string") {
1225
+ throw handlerError.invalidBody("Email is required");
1226
+ }
1227
+ const authRecord = await datrix.raw.findOne(
1228
+ authSchemaName,
1229
+ { email },
1230
+ {
1231
+ populate: true,
1232
+ select: ["email", "role", "resetToken", "resetTokenExpiry"]
1233
+ }
1234
+ );
1235
+ if (!authRecord) {
1236
+ return jsonResponse({ data: { success: true } });
1237
+ }
1238
+ const tokenBytes = new Uint8Array(32);
1239
+ crypto.getRandomValues(tokenBytes);
1240
+ const token = Array.from(tokenBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1241
+ const expirySeconds = authConfig.passwordReset?.tokenExpirySeconds ?? DEFAULT_API_AUTH_CONFIG3.passwordReset.tokenExpirySeconds;
1242
+ const expiry = new Date(Date.now() + expirySeconds * 1e3);
1243
+ await datrix.raw.update(authSchemaName, authRecord.id, {
1244
+ resetToken: token,
1245
+ resetTokenExpiry: expiry
1246
+ });
1247
+ await onForgotPassword(authRecord, token);
1248
+ return jsonResponse({ data: { success: true } });
1249
+ } catch (error) {
1250
+ if (error instanceof DatrixError3) {
1251
+ return datrixErrorResponse(error);
1252
+ }
1253
+ const message = error instanceof Error ? error.message : "Internal server error";
1254
+ return datrixErrorResponse(
1255
+ handlerError.internalError(
1256
+ message,
1257
+ error instanceof Error ? error : void 0
1258
+ )
1259
+ );
1260
+ }
1261
+ }
1262
+ async function resetPassword(request) {
1263
+ try {
1264
+ const body = await request.json();
1265
+ const { token, password } = body;
1266
+ if (!token || typeof token !== "string") {
1267
+ throw handlerError.invalidBody("Token is required");
1268
+ }
1269
+ if (!password || typeof password !== "string") {
1270
+ throw handlerError.invalidBody("Password is required");
1271
+ }
1272
+ const authRecord = await datrix.raw.findOne(
1273
+ authSchemaName,
1274
+ { resetToken: token }
1275
+ );
1276
+ if (!authRecord || !authRecord.resetTokenExpiry || new Date(authRecord.resetTokenExpiry) < /* @__PURE__ */ new Date()) {
1277
+ throw handlerError.invalidBody("Invalid or expired reset token");
1278
+ }
1279
+ const { hash, salt } = await authManager.hashPassword(password);
1280
+ await datrix.raw.update(authSchemaName, authRecord.id, {
1281
+ password: hash,
1282
+ passwordSalt: salt,
1283
+ resetToken: null,
1284
+ resetTokenExpiry: null
1285
+ });
1286
+ return jsonResponse({ data: { success: true } });
1287
+ } catch (error) {
1288
+ if (error instanceof DatrixError3) {
1289
+ return datrixErrorResponse(error);
1290
+ }
1291
+ const message = error instanceof Error ? error.message : "Internal server error";
1292
+ return datrixErrorResponse(
1293
+ handlerError.internalError(
1294
+ message,
1295
+ error instanceof Error ? error : void 0
1296
+ )
1297
+ );
1298
+ }
1299
+ }
1300
+ return { register, login, logout, me, forgotPassword, resetPassword };
1217
1301
  }
1218
1302
  function createUnifiedAuthHandler(config, apiPrefix = "/api") {
1219
1303
  const handlers = createAuthHandlers(config);
@@ -1222,7 +1306,9 @@ function createUnifiedAuthHandler(config, apiPrefix = "/api") {
1222
1306
  register: authConfig.endpoints?.register ?? DEFAULT_API_AUTH_CONFIG3.endpoints.register,
1223
1307
  login: authConfig.endpoints?.login ?? DEFAULT_API_AUTH_CONFIG3.endpoints.login,
1224
1308
  logout: authConfig.endpoints?.logout ?? DEFAULT_API_AUTH_CONFIG3.endpoints.logout,
1225
- me: authConfig.endpoints?.me ?? DEFAULT_API_AUTH_CONFIG3.endpoints.me
1309
+ me: authConfig.endpoints?.me ?? DEFAULT_API_AUTH_CONFIG3.endpoints.me,
1310
+ forgotPassword: authConfig.endpoints?.forgotPassword ?? DEFAULT_API_AUTH_CONFIG3.endpoints.forgotPassword,
1311
+ resetPassword: authConfig.endpoints?.resetPassword ?? DEFAULT_API_AUTH_CONFIG3.endpoints.resetPassword
1226
1312
  };
1227
1313
  return async function authHandler(request) {
1228
1314
  const url = new URL(request.url);
@@ -1240,6 +1326,12 @@ function createUnifiedAuthHandler(config, apiPrefix = "/api") {
1240
1326
  if (path === endpoints.me && method === "GET") {
1241
1327
  return handlers.me(request);
1242
1328
  }
1329
+ if (path === endpoints.forgotPassword && method === "POST") {
1330
+ return handlers.forgotPassword(request);
1331
+ }
1332
+ if (path === endpoints.resetPassword && method === "POST") {
1333
+ return handlers.resetPassword(request);
1334
+ }
1243
1335
  return datrixErrorResponse(
1244
1336
  handlerError.recordNotFound("Auth Route", url.pathname)
1245
1337
  );
@@ -1396,7 +1488,10 @@ import {
1396
1488
  ParserError,
1397
1489
  buildErrorLocation
1398
1490
  } from "@datrix/core";
1399
- import { MAX_WHERE_VALUE_LENGTH, MAX_LOGICAL_NESTING_DEPTH } from "@datrix/core";
1491
+ import {
1492
+ MAX_WHERE_VALUE_LENGTH,
1493
+ MAX_LOGICAL_NESTING_DEPTH
1494
+ } from "@datrix/core";
1400
1495
  var whereError = {
1401
1496
  invalidOperator(operator, path, context) {
1402
1497
  throw new ParserError(`Invalid WHERE operator: ${operator}`, {