zerobyte/app/server/lib/auth/utils/sso-context.ts
Nico 2ff6451f37
test: use better-auth built-in test plugin (#599)
test: use better-auth built-in test plugin

refactor: map auth errors server side

refactor: native trusted providers callback usage

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

## Release Notes

* **New Features**
  * Enhanced SSO authentication error messaging with specific guidance for different failure scenarios (account linking required, email verification needed, banned accounts, invite-only access).

* **Chores**
  * Updated authentication dependencies to version 1.5.0.

* **Tests**
  * Extended test coverage for SSO error code handling and authentication scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-03-01 15:10:50 +01:00

47 lines
1.2 KiB
TypeScript

import type { GenericEndpointContext } from "@better-auth/core";
const SSO_CALLBACK_PATH_SEGMENTS = ["/sso/callback/", "/sso/saml2/callback/", "/sso/saml2/sp/acs/"] as const;
const SSO_CALLBACK_PATH_PATTERN = /\/sso\/(?:callback|saml2\/callback|saml2\/sp\/acs)\/([^/]+)$/;
export function normalizeEmail(email: string): string {
return email.trim().toLowerCase();
}
export function isSsoCallbackPath(pathname: string): boolean {
return SSO_CALLBACK_PATH_SEGMENTS.some((segment) => pathname.includes(segment));
}
export function extractProviderIdFromPathname(pathname: string): string | null {
if (!isSsoCallbackPath(pathname)) {
return null;
}
const match = pathname.match(SSO_CALLBACK_PATH_PATTERN);
return match?.[1] ?? null;
}
export function extractProviderIdFromUrl(url: string): string | null {
try {
const pathname = new URL(url, "http://localhost").pathname;
return extractProviderIdFromPathname(pathname);
} catch {
return null;
}
}
export function extractProviderIdFromContext(ctx?: GenericEndpointContext | null) {
if (!ctx) {
return null;
}
if (ctx.params?.providerId) {
return ctx.params.providerId;
}
if (ctx.request?.url) {
return extractProviderIdFromUrl(ctx.request.url);
}
return null;
}