@absolutejs/auth 0.60.0 → 0.62.0

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/server.js CHANGED
@@ -6141,6 +6141,15 @@ init_constants();
6141
6141
  init_crypto();
6142
6142
  import { Elysia as Elysia11, t as t8 } from "elysia";
6143
6143
 
6144
+ // src/csrf.ts
6145
+ var isTrustedOrigin = (request, trustedOrigins) => {
6146
+ if (trustedOrigins === undefined || trustedOrigins.length === 0) {
6147
+ return true;
6148
+ }
6149
+ const origin = request.headers.get("origin");
6150
+ return origin !== null && trustedOrigins.includes(origin);
6151
+ };
6152
+
6144
6153
  // src/credentials/import.ts
6145
6154
  init_crypto();
6146
6155
  var normalizeEmail = (email) => email.trim().toLowerCase();
@@ -6329,6 +6338,8 @@ var evaluatePassword = async (password, policy = {}) => {
6329
6338
  var isPasswordCompromised = (password) => isPasswordBreached(password);
6330
6339
 
6331
6340
  // src/credentials/login.ts
6341
+ var dummyPasswordHashPromise;
6342
+ var dummyPasswordHash = () => dummyPasswordHashPromise ??= hashPassword("absolutejs-auth-timing-equalizer");
6332
6343
  var credentialsLogin = ({
6333
6344
  authSessionStore,
6334
6345
  checkBreachesOnLogin,
@@ -6343,7 +6354,8 @@ var credentialsLogin = ({
6343
6354
  passwordVerifier,
6344
6355
  rehashOnLogin = false,
6345
6356
  requireEmailVerification = false,
6346
- sessionDurationMs = DEFAULT_CREDENTIAL_SESSION_TTL_MS
6357
+ sessionDurationMs = DEFAULT_CREDENTIAL_SESSION_TTL_MS,
6358
+ trustedOrigins
6347
6359
  }) => new Elysia11().use(sessionStore()).post(loginRoute, async ({
6348
6360
  body: { email, password },
6349
6361
  cookie: { user_session_id },
@@ -6351,6 +6363,9 @@ var credentialsLogin = ({
6351
6363
  status,
6352
6364
  store: { session, unregisteredSession }
6353
6365
  }) => withSpan("auth.credentials.login", undefined, async (span) => {
6366
+ if (!isTrustedOrigin(request, trustedOrigins)) {
6367
+ return status("Forbidden", "Request origin is not allowed");
6368
+ }
6354
6369
  const headerBag = {};
6355
6370
  request.headers.forEach((value, key) => {
6356
6371
  headerBag[key] = value;
@@ -6370,7 +6385,13 @@ var credentialsLogin = ({
6370
6385
  const credential = await credentialStore.getCredentialByEmail(normalizedEmail);
6371
6386
  const user = await getUserByEmail(normalizedEmail);
6372
6387
  const verifyHash = passwordVerifier ?? verifyPassword;
6373
- const passwordValid = credential === undefined ? false : await verifyHash(password, credential.passwordHash);
6388
+ let passwordValid;
6389
+ if (credential === undefined) {
6390
+ await verifyPassword(password, await dummyPasswordHash());
6391
+ passwordValid = false;
6392
+ } else {
6393
+ passwordValid = await verifyHash(password, credential.passwordHash);
6394
+ }
6374
6395
  if (!credential || !user || credential.status !== "active" || !passwordValid) {
6375
6396
  await lockoutGuard?.recordFailure(normalizedEmail);
6376
6397
  await onCredentialsLoginError?.({
@@ -6502,19 +6523,26 @@ var credentialsRegister = ({
6502
6523
  credentialStore,
6503
6524
  onCreateCredentialUser,
6504
6525
  onCredentialsLoginSuccess,
6526
+ onExistingAccount,
6505
6527
  onRegistrationSuccess,
6506
6528
  onSendEmail,
6507
6529
  passwordPolicy,
6508
6530
  registerRoute = "/auth/register",
6509
6531
  requireEmailVerification = false,
6532
+ revealRegistrationConflicts = false,
6510
6533
  sessionDurationMs = DEFAULT_CREDENTIAL_SESSION_TTL_MS,
6534
+ trustedOrigins,
6511
6535
  verificationTokenDurationMs = DEFAULT_VERIFICATION_TOKEN_TTL_MS
6512
6536
  }) => new Elysia13().use(sessionStore()).post(registerRoute, async ({
6513
6537
  body: { email, password, ...extraFields },
6514
6538
  cookie: { user_session_id },
6539
+ request,
6515
6540
  status,
6516
6541
  store: { session }
6517
6542
  }) => withSpan("auth.credentials.register", undefined, async () => {
6543
+ if (!isTrustedOrigin(request, trustedOrigins)) {
6544
+ return status("Forbidden", "Request origin is not allowed");
6545
+ }
6518
6546
  const normalizedEmail = email.trim().toLowerCase();
6519
6547
  if (!normalizedEmail.includes("@")) {
6520
6548
  return status("Bad Request", "A valid email is required");
@@ -6528,7 +6556,13 @@ var credentialsRegister = ({
6528
6556
  }
6529
6557
  const existing = await credentialStore.getCredentialByEmail(normalizedEmail);
6530
6558
  if (existing) {
6531
- return status("Conflict", "Email is already registered");
6559
+ if (revealRegistrationConflicts) {
6560
+ return status("Conflict", "Email is already registered");
6561
+ }
6562
+ await onExistingAccount?.({ email: normalizedEmail });
6563
+ return status("Created", {
6564
+ status: "verification_required"
6565
+ });
6532
6566
  }
6533
6567
  const created = await onCreateCredentialUser({
6534
6568
  ...extraFields,
@@ -38319,6 +38353,9 @@ var buildAuthApplications = async (configuration) => {
38319
38353
  await webhookDispatch?.(event);
38320
38354
  }
38321
38355
  }) : undefined;
38356
+ if (auditEmit === undefined) {
38357
+ console.warn("[@absolutejs/auth] No audit sink configured (pass `audit` or `webhooks`). " + "Privileged flows (impersonation, role/permission changes, sign-out) will " + "run WITHOUT an audit trail.");
38358
+ }
38322
38359
  const lockoutGuard = lockout ? createLockoutGuard(lockout) : undefined;
38323
38360
  const resolvedAgentAuth = agentAuth === undefined ? undefined : {
38324
38361
  ...agentAuth,
@@ -38712,5 +38749,5 @@ export {
38712
38749
  VerificationProviderError
38713
38750
  };
38714
38751
 
38715
- //# debugId=F11B818E3AEEB74B64756E2164756E21
38752
+ //# debugId=E5516A34918E793A64756E2164756E21
38716
38753
  //# sourceMappingURL=server.js.map