@absolutejs/auth 0.63.0 → 0.65.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.
@@ -21,6 +21,10 @@ export type CredentialEmailMessage = {
21
21
  export type CredentialsConfig<UserType> = {
22
22
  checkBreachesOnLogin?: boolean;
23
23
  credentialStore: CredentialStore;
24
+ /** When `trustedOrigins` is set, whether an untrusted Origin is REJECTED
25
+ * (default true) or merely reported via `onUntrustedOrigin` (false = a
26
+ * report-only rollout that never blocks). */
27
+ enforceTrustedOrigins?: boolean;
24
28
  getUserByEmail: (email: string) => Promise<UserType | null | undefined> | UserType | null | undefined;
25
29
  isMfaRequired?: (user: UserType, context?: {
26
30
  headers: Record<string, string | undefined>;
@@ -56,6 +60,13 @@ export type CredentialsConfig<UserType> = {
56
60
  user: UserType;
57
61
  }) => void | Promise<void>;
58
62
  onSendEmail: (message: CredentialEmailMessage) => void | Promise<void>;
63
+ /** Called on login/register when the request's Origin is not in
64
+ * `trustedOrigins`. Fires whether or not `enforceTrustedOrigins` blocks the
65
+ * request, so it can drive a report-only rollout (log/surface the Origin). */
66
+ onUntrustedOrigin?: (context: {
67
+ origin: string | null;
68
+ request: Request;
69
+ }) => void | Promise<void>;
59
70
  passwordPolicy?: PasswordPolicy;
60
71
  registerRoute?: RouteString;
61
72
  /** When true, registration creates the account but NOT a session, and login is
@@ -1,6 +1,6 @@
1
1
  import { Elysia } from 'elysia';
2
2
  import { type CredentialRouteProps } from './config';
3
- export declare const credentialsLogin: <UserType>({ authSessionStore, checkBreachesOnLogin, cookieSecure, credentialStore, getUserByEmail, isMfaRequired, lockoutGuard, loginRoute, onCredentialsLoginError, onCredentialsLoginSuccess, passwordVerifier, rehashOnLogin, requireEmailVerification, sessionDurationMs, trustedOrigins }: CredentialRouteProps<UserType>) => Elysia<"", {
3
+ export declare const credentialsLogin: <UserType>({ authSessionStore, checkBreachesOnLogin, cookieSecure, credentialStore, enforceTrustedOrigins, getUserByEmail, isMfaRequired, lockoutGuard, loginRoute, onCredentialsLoginError, onCredentialsLoginSuccess, onUntrustedOrigin, passwordVerifier, rehashOnLogin, requireEmailVerification, sessionDurationMs, trustedOrigins }: CredentialRouteProps<UserType>) => Elysia<"", {
4
4
  decorator: {};
5
5
  store: {
6
6
  session: import("..").SessionRecord<UserType>;
@@ -1,6 +1,6 @@
1
1
  import { Elysia } from 'elysia';
2
2
  import { type CredentialRouteProps } from './config';
3
- export declare const credentialsRegister: <UserType>({ authSessionStore, cookieSecure, credentialStore, onCreateCredentialUser, onCredentialsLoginSuccess, onExistingAccount, onRegistrationSuccess, onSendEmail, passwordPolicy, registerRoute, requireEmailVerification, revealRegistrationConflicts, sessionDurationMs, trustedOrigins, verificationTokenDurationMs }: CredentialRouteProps<UserType>) => Elysia<"", {
3
+ export declare const credentialsRegister: <UserType>({ authSessionStore, cookieSecure, credentialStore, enforceTrustedOrigins, onCreateCredentialUser, onCredentialsLoginSuccess, onExistingAccount, onRegistrationSuccess, onSendEmail, onUntrustedOrigin, passwordPolicy, registerRoute, requireEmailVerification, revealRegistrationConflicts, sessionDurationMs, trustedOrigins, verificationTokenDurationMs }: CredentialRouteProps<UserType>) => Elysia<"", {
4
4
  decorator: {};
5
5
  store: {
6
6
  session: import("..").SessionRecord<UserType>;
package/dist/csrf.d.ts CHANGED
@@ -1 +1,10 @@
1
1
  export declare const isTrustedOrigin: (request: Request, trustedOrigins?: readonly string[]) => boolean;
2
+ export declare const resolveOriginAllowed: ({ enforce, onUntrustedOrigin, request, trustedOrigins }: {
3
+ enforce?: boolean;
4
+ onUntrustedOrigin?: (context: {
5
+ origin: string | null;
6
+ request: Request;
7
+ }) => void | Promise<void>;
8
+ request: Request;
9
+ trustedOrigins?: readonly string[];
10
+ }) => Promise<boolean>;
package/dist/index.d.ts CHANGED
@@ -3442,6 +3442,7 @@ export { createFederatedTokenStore, getOrRefreshFederatedTokens } from './federa
3442
3442
  export type { FederatedTokenRefresher, FederatedTokenSet, FederatedTokenStore } from './federation/tokenStore';
3443
3443
  export { decodeSessionUserRecord, type AuthSessionStore, type SessionUserDecoder } from './session/types';
3444
3444
  export { isAuthIntent, isUserSessionId, isValidUser } from './typeGuards';
3445
+ export { readSessionCookie } from './session/cookieReader';
3445
3446
  export { AuthIdentityConflictError } from './errors';
3446
3447
  export { sessionStore } from './session/state';
3447
3448
  export { createInMemoryAuthSessionStore } from './session/inMemoryStore';
package/dist/index.js CHANGED
@@ -5153,6 +5153,20 @@ var isTrustedOrigin = (request, trustedOrigins) => {
5153
5153
  const origin = request.headers.get("origin");
5154
5154
  return origin !== null && trustedOrigins.includes(origin);
5155
5155
  };
5156
+ var resolveOriginAllowed = async ({
5157
+ enforce = true,
5158
+ onUntrustedOrigin,
5159
+ request,
5160
+ trustedOrigins
5161
+ }) => {
5162
+ if (isTrustedOrigin(request, trustedOrigins))
5163
+ return true;
5164
+ await onUntrustedOrigin?.({
5165
+ origin: request.headers.get("origin"),
5166
+ request
5167
+ });
5168
+ return enforce === false;
5169
+ };
5156
5170
 
5157
5171
  // src/credentials/import.ts
5158
5172
  init_crypto();
@@ -5349,12 +5363,14 @@ var credentialsLogin = ({
5349
5363
  checkBreachesOnLogin,
5350
5364
  cookieSecure,
5351
5365
  credentialStore,
5366
+ enforceTrustedOrigins,
5352
5367
  getUserByEmail,
5353
5368
  isMfaRequired,
5354
5369
  lockoutGuard,
5355
5370
  loginRoute = "/auth/login",
5356
5371
  onCredentialsLoginError,
5357
5372
  onCredentialsLoginSuccess,
5373
+ onUntrustedOrigin,
5358
5374
  passwordVerifier,
5359
5375
  rehashOnLogin = false,
5360
5376
  requireEmailVerification = false,
@@ -5367,7 +5383,12 @@ var credentialsLogin = ({
5367
5383
  status,
5368
5384
  store: { session, unregisteredSession }
5369
5385
  }) => withSpan("auth.credentials.login", undefined, async (span) => {
5370
- if (!isTrustedOrigin(request, trustedOrigins)) {
5386
+ if (!await resolveOriginAllowed({
5387
+ enforce: enforceTrustedOrigins,
5388
+ onUntrustedOrigin,
5389
+ request,
5390
+ trustedOrigins
5391
+ })) {
5371
5392
  return status("Forbidden", "Request origin is not allowed");
5372
5393
  }
5373
5394
  const headerBag = {};
@@ -5525,11 +5546,13 @@ var credentialsRegister = ({
5525
5546
  authSessionStore,
5526
5547
  cookieSecure,
5527
5548
  credentialStore,
5549
+ enforceTrustedOrigins,
5528
5550
  onCreateCredentialUser,
5529
5551
  onCredentialsLoginSuccess,
5530
5552
  onExistingAccount,
5531
5553
  onRegistrationSuccess,
5532
5554
  onSendEmail,
5555
+ onUntrustedOrigin,
5533
5556
  passwordPolicy,
5534
5557
  registerRoute = "/auth/register",
5535
5558
  requireEmailVerification = false,
@@ -5544,7 +5567,12 @@ var credentialsRegister = ({
5544
5567
  status,
5545
5568
  store: { session }
5546
5569
  }) => withSpan("auth.credentials.register", undefined, async () => {
5547
- if (!isTrustedOrigin(request, trustedOrigins)) {
5570
+ if (!await resolveOriginAllowed({
5571
+ enforce: enforceTrustedOrigins,
5572
+ onUntrustedOrigin,
5573
+ request,
5574
+ trustedOrigins
5575
+ })) {
5548
5576
  return status("Forbidden", "Request origin is not allowed");
5549
5577
  }
5550
5578
  const normalizedEmail = email.trim().toLowerCase();
@@ -24637,6 +24665,23 @@ var decodeSessionUserRecord = (value) => {
24637
24665
  throw new TypeError("Persisted session user must be an object");
24638
24666
  return value;
24639
24667
  };
24668
+ // src/session/cookieReader.ts
24669
+ var SESSION_COOKIE_NAME = "user_session_id";
24670
+ var SESSION_COOKIE_PATTERN = new RegExp(`(?:^|;\\s*)${SESSION_COOKIE_NAME}=([^;]*)`);
24671
+ var readSessionCookie = (request) => {
24672
+ const header = request.headers.get("cookie");
24673
+ if (header === null)
24674
+ return null;
24675
+ const match = header.match(SESSION_COOKIE_PATTERN);
24676
+ const value = match?.[1];
24677
+ if (value === undefined)
24678
+ return null;
24679
+ try {
24680
+ return decodeURIComponent(value);
24681
+ } catch {
24682
+ return value;
24683
+ }
24684
+ };
24640
24685
  // src/session/inMemoryStore.ts
24641
24686
  var cloneSessionData = (value) => ({
24642
24687
  ...value
@@ -37679,6 +37724,7 @@ export {
37679
37724
  resolveProviderClientConfiguration,
37680
37725
  resolvePostLogoutRedirect,
37681
37726
  resolvePermissions,
37727
+ resolveOriginAllowed,
37682
37728
  resolveOAuthTokenExpiresAt,
37683
37729
  resolveOAuthAuthorization,
37684
37730
  resolveCookieSecure,
@@ -37696,6 +37742,7 @@ export {
37696
37742
  recordLoginAttempt,
37697
37743
  readUserInfoBearer,
37698
37744
  readSessionRing,
37745
+ readSessionCookie,
37699
37746
  pushAuthorizationRequest,
37700
37747
  pruneInactiveUsers,
37701
37748
  providersFromEnv,
@@ -38100,5 +38147,5 @@ export {
38100
38147
  AGENT_CLAIM_GRANT_TYPE
38101
38148
  };
38102
38149
 
38103
- //# debugId=A719E0625663B7E664756E2164756E21
38150
+ //# debugId=1D72B0CC5FBF9E2F64756E2164756E21
38104
38151
  //# sourceMappingURL=index.js.map