host context

This commit is contained in:
Max Peintner
2025-01-16 09:50:25 +01:00
parent c3ba56870f
commit 18dbffc02d
4 changed files with 106 additions and 31 deletions

View File

@@ -31,6 +31,7 @@ export async function createSessionAndUpdateCookie(
checks: Checks,
challenges: RequestChallenges | undefined,
authRequestId: string | undefined,
lifetime?: Duration,
): Promise<Session> {
const host = (await headers()).get("host");
@@ -42,6 +43,7 @@ export async function createSessionAndUpdateCookie(
host,
checks,
challenges,
lifetime,
});
if (createdSession) {

View File

@@ -23,9 +23,16 @@ export async function continueWithSession({
authRequestId,
...session
}: Session & { authRequestId?: string }) {
const loginSettings = await getLoginSettings(
session.factors?.user?.organizationId,
);
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
const loginSettings = await getLoginSettings({
host,
organization: session.factors?.user?.organizationId,
});
const url =
authRequestId && session.id && session.factors?.user
@@ -99,7 +106,7 @@ export async function updateSession(options: UpdateSessionCommand) {
challenges.webAuthN.domain = hostname;
}
const loginSettings = await getLoginSettings(organization);
const loginSettings = await getLoginSettings({ host, organization });
const lifetime = checks?.webAuthN
? loginSettings?.multiFactorCheckLifetime // TODO different lifetime for webauthn u2f/passkey
@@ -122,9 +129,10 @@ export async function updateSession(options: UpdateSessionCommand) {
// if password, check if user has MFA methods
let authMethods;
if (checks && checks.password && session.factors?.user?.id) {
const response = await listAuthenticationMethodTypes(
session.factors.user.id,
);
const response = await listAuthenticationMethodTypes({
host,
userId: session.factors.user.id,
});
if (response.authMethodTypes && response.authMethodTypes.length) {
authMethods = response.authMethodTypes;
}
@@ -143,11 +151,21 @@ type ClearSessionOptions = {
};
export async function clearSession(options: ClearSessionOptions) {
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
const { sessionId } = options;
const session = await getSessionCookieById({ sessionId });
const deletedSession = await deleteSession(session.id, session.token);
const deletedSession = await deleteSession({
host,
sessionId: session.id,
sessionToken: session.token,
});
if (deletedSession) {
return removeSessionFromCookie(session);
@@ -159,12 +177,19 @@ type CleanupSessionCommand = {
};
export async function cleanupSession({ sessionId }: CleanupSessionCommand) {
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
const sessionCookie = await getSessionCookieById({ sessionId });
const deleteResponse = await deleteSession(
sessionCookie.id,
sessionCookie.token,
);
const deleteResponse = await deleteSession({
host,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
});
if (!deleteResponse) {
throw new Error("Could not delete session");

View File

@@ -19,6 +19,12 @@ type VerifyU2FCommand = {
};
export async function addU2F(command: RegisterU2FCommand) {
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
const sessionCookie = await getSessionCookieById({
sessionId: command.sessionId,
});
@@ -28,16 +34,11 @@ export async function addU2F(command: RegisterU2FCommand) {
}
const session = await getSession({
host,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
});
const host = (await headers()).get("host");
if (!host) {
return { error: "Could not get domain" };
}
const [hostname, port] = host.split(":");
if (!hostname) {
@@ -50,10 +51,16 @@ export async function addU2F(command: RegisterU2FCommand) {
return { error: "Could not get session" };
}
return registerU2F(userId, hostname);
return registerU2F({ host, userId, domain: hostname });
}
export async function verifyU2F(command: VerifyU2FCommand) {
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
let passkeyName = command.passkeyName;
if (!!!passkeyName) {
const headersList = await headers();
@@ -69,6 +76,7 @@ export async function verifyU2F(command: VerifyU2FCommand) {
});
const session = await getSession({
host,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
});
@@ -79,12 +87,12 @@ export async function verifyU2F(command: VerifyU2FCommand) {
return { error: "Could not get session" };
}
const req = create(VerifyU2FRegistrationRequestSchema, {
const request = create(VerifyU2FRegistrationRequestSchema, {
u2fId: command.u2fId,
publicKeyCredential: command.publicKeyCredential,
tokenName: passkeyName,
userId,
});
return verifyU2FRegistration(req);
return verifyU2FRegistration({ host, request });
}

View File

@@ -31,11 +31,25 @@ type VerifyUserByEmailCommand = {
};
export async function sendVerification(command: VerifyUserByEmailCommand) {
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
const verifyResponse = command.isInvite
? await verifyInviteCode(command.userId, command.code).catch(() => {
? await verifyInviteCode({
host,
userId: command.userId,
verificationCode: command.code,
}).catch(() => {
return { error: "Could not verify invite" };
})
: await verifyEmail(command.userId, command.code).catch(() => {
: await verifyEmail({
host,
userId: command.userId,
verificationCode: command.code,
}).catch(() => {
return { error: "Could not verify email" };
});
@@ -63,6 +77,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
}
session = await getSession({
host,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
}).then((response) => {
@@ -75,7 +90,10 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
return { error: "Could not create session for user" };
}
const userResponse = await getUserByID(session?.factors?.user?.id);
const userResponse = await getUserByID({
host,
userId: session?.factors?.user?.id,
});
if (!userResponse?.user) {
return { error: "Could not load user" };
@@ -83,7 +101,7 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
user = userResponse.user;
} else {
const userResponse = await getUserByID(command.userId);
const userResponse = await getUserByID({ host, userId: command.userId });
if (!userResponse || !userResponse.user) {
return { error: "Could not load user" };
@@ -119,9 +137,15 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
return { error: "Could not load user" };
}
const loginSettings = await getLoginSettings(user.details?.resourceOwner);
const loginSettings = await getLoginSettings({
host,
organization: user.details?.resourceOwner,
});
const authMethodResponse = await listAuthenticationMethodTypes(user.userId);
const authMethodResponse = await listAuthenticationMethodTypes({
host,
userId: user.userId,
});
if (!authMethodResponse || !authMethodResponse.authMethodTypes) {
return { error: "Could not load possible authenticators" };
@@ -230,6 +254,12 @@ export type SendVerificationRedirectWithoutCheckCommand = {
export async function sendVerificationRedirectWithoutCheck(
command: SendVerificationRedirectWithoutCheckCommand,
) {
const host = (await headers()).get("host");
if (!host || typeof host !== "string") {
throw new Error("No host found");
}
if (!("loginName" in command || "userId" in command)) {
return { error: "No userId, nor loginname provided" };
}
@@ -250,6 +280,7 @@ export async function sendVerificationRedirectWithoutCheck(
}
session = await getSession({
host,
sessionId: sessionCookie.id,
sessionToken: sessionCookie.token,
}).then((response) => {
@@ -262,7 +293,10 @@ export async function sendVerificationRedirectWithoutCheck(
return { error: "Could not create session for user" };
}
const userResponse = await getUserByID(session?.factors?.user?.id);
const userResponse = await getUserByID({
host,
userId: session?.factors?.user?.id,
});
if (!userResponse?.user) {
return { error: "Could not load user" };
@@ -270,7 +304,7 @@ export async function sendVerificationRedirectWithoutCheck(
user = userResponse.user;
} else if ("userId" in command) {
const userResponse = await getUserByID(command.userId);
const userResponse = await getUserByID({ host, userId: command.userId });
if (!userResponse?.user) {
return { error: "Could not load user" };
@@ -306,7 +340,10 @@ export async function sendVerificationRedirectWithoutCheck(
return { error: "Could not load user" };
}
const authMethodResponse = await listAuthenticationMethodTypes(user.userId);
const authMethodResponse = await listAuthenticationMethodTypes({
host,
userId: user.userId,
});
if (!authMethodResponse || !authMethodResponse.authMethodTypes) {
return { error: "Could not load possible authenticators" };
@@ -328,7 +365,10 @@ export async function sendVerificationRedirectWithoutCheck(
return { redirect: `/authenticator/set?${params}` };
}
const loginSettings = await getLoginSettings(user.details?.resourceOwner);
const loginSettings = await getLoginSettings({
host,
organization: user.details?.resourceOwner,
});
// redirect to mfa factor if user has one, or redirect to set one up
const mfaFactorCheck = checkMFAFactors(