You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
6.4 KiB

import {
AUTH_HTTP_METHODS,
AUTH_ROUTE_PATHS
} from '$libs/auth/consts';
import {
authJson,
authRouteNotFound,
protectAuthHandler,
toAuthRequestLike,
verifyAuthRequestCsrf,
type AuthHandlerEngine,
type AuthRouteRequest
} from './handler-runtime.ts';
import type {
AuthEmailVerificationCompleteInput,
AuthEmailVerificationRequestInput,
AuthPasswordResetCompleteInput,
AuthPasswordResetRequestInput,
AuthSignInPasswordInput,
AuthSignUpPasswordInput
} from '$libs/auth/types';
export interface AuthRouteHandlers {
readonly current: (input: AuthRouteRequest) => Promise<Response>;
readonly csrf: (input: AuthRouteRequest) => Promise<Response>;
readonly signUpPassword: (input: AuthRouteRequest) => Promise<Response>;
readonly signInPassword: (input: AuthRouteRequest) => Promise<Response>;
readonly signOut: (input: AuthRouteRequest) => Promise<Response>;
readonly signOutGlobal: (input: AuthRouteRequest) => Promise<Response>;
readonly requestEmailVerification: (input: AuthRouteRequest) => Promise<Response>;
readonly completeEmailVerification: (input: AuthRouteRequest) => Promise<Response>;
readonly requestPasswordReset: (input: AuthRouteRequest) => Promise<Response>;
readonly completePasswordReset: (input: AuthRouteRequest) => Promise<Response>;
readonly handle: (input: AuthRouteRequest) => Promise<Response>;
}
export type { AuthRouteRequest } from './handler-runtime.ts';
export function createAuthRouteHandlers(engine: AuthHandlerEngine): AuthRouteHandlers {
async function current(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () =>
authJson(
await engine.current({ tenantId: input.tenantId, request: toAuthRequestLike(input.request) })
)
);
}
async function csrf(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
const result = await engine.issueCsrf({ tenantId: input.tenantId });
return authJson(
{ token: result.token, expiresAt: result.expiresAt },
{ cookies: [result.cookie] }
);
});
}
async function signUpPassword(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
const body = (await input.request.json()) as Omit<AuthSignUpPasswordInput, 'tenantId'>;
return authJson(await engine.signUpPassword({ ...body, tenantId: input.tenantId }));
});
}
async function signInPassword(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
const body = (await input.request.json()) as Omit<AuthSignInPasswordInput, 'tenantId'>;
return authJson(await engine.signInPassword({ ...body, tenantId: input.tenantId }));
});
}
async function signOut(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
return authJson(
await engine.signOut({ tenantId: input.tenantId, request: toAuthRequestLike(input.request) })
);
});
}
async function signOutGlobal(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
return authJson(
await engine.signOutGlobal({
tenantId: input.tenantId,
request: toAuthRequestLike(input.request)
})
);
});
}
async function requestEmailVerification(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
const body = (await input.request.json()) as Omit<
AuthEmailVerificationRequestInput,
'tenantId'
>;
return authJson(await engine.requestEmailVerification({ ...body, tenantId: input.tenantId }));
});
}
async function completeEmailVerification(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
const body = (await input.request.json()) as Omit<
AuthEmailVerificationCompleteInput,
'tenantId'
>;
return authJson(
await engine.completeEmailVerification({ ...body, tenantId: input.tenantId })
);
});
}
async function requestPasswordReset(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
const body = (await input.request.json()) as Omit<AuthPasswordResetRequestInput, 'tenantId'>;
return authJson(await engine.requestPasswordReset({ ...body, tenantId: input.tenantId }));
});
}
async function completePasswordReset(input: AuthRouteRequest): Promise<Response> {
return protectAuthHandler(async () => {
await verifyAuthRequestCsrf(engine, input);
const body = (await input.request.json()) as Omit<AuthPasswordResetCompleteInput, 'tenantId'>;
return authJson(await engine.completePasswordReset({ ...body, tenantId: input.tenantId }));
});
}
async function handle(input: AuthRouteRequest): Promise<Response> {
const pathname = new URL(input.request.url).pathname;
const method = input.request.method;
if (pathname === AUTH_ROUTE_PATHS.CURRENT && method === AUTH_HTTP_METHODS.GET)
return current(input);
if (pathname === AUTH_ROUTE_PATHS.CSRF && method === AUTH_HTTP_METHODS.GET) return csrf(input);
if (pathname === AUTH_ROUTE_PATHS.SIGN_UP_PASSWORD && method === AUTH_HTTP_METHODS.POST)
return signUpPassword(input);
if (pathname === AUTH_ROUTE_PATHS.SIGN_IN_PASSWORD && method === AUTH_HTTP_METHODS.POST)
return signInPassword(input);
if (pathname === AUTH_ROUTE_PATHS.SIGN_OUT && method === AUTH_HTTP_METHODS.POST)
return signOut(input);
if (pathname === AUTH_ROUTE_PATHS.SIGN_OUT_GLOBAL && method === AUTH_HTTP_METHODS.POST)
return signOutGlobal(input);
if (pathname === AUTH_ROUTE_PATHS.EMAIL_VERIFY_REQUEST && method === AUTH_HTTP_METHODS.POST)
return requestEmailVerification(input);
if (pathname === AUTH_ROUTE_PATHS.EMAIL_VERIFY_COMPLETE && method === AUTH_HTTP_METHODS.POST)
return completeEmailVerification(input);
if (pathname === AUTH_ROUTE_PATHS.PASSWORD_RESET_REQUEST && method === AUTH_HTTP_METHODS.POST)
return requestPasswordReset(input);
if (pathname === AUTH_ROUTE_PATHS.PASSWORD_RESET_COMPLETE && method === AUTH_HTTP_METHODS.POST)
return completePasswordReset(input);
return authRouteNotFound();
}
return {
current,
csrf,
signUpPassword,
signInPassword,
signOut,
signOutGlobal,
requestEmailVerification,
completeEmailVerification,
requestPasswordReset,
completePasswordReset,
handle
};
}

Powered by TurnKey Linux.