Files
zerobyte/app/server/modules/desktop/desktop.service.ts
Nico d24167b520 refactor(auth): mark desktop sessions with auth source (#990)
* refactor(auth): mark desktop sessions with auth source

Makes it easier to filter out on session type in backend paths that
behave differently depending on the context

* chore: fix un-used import

* fix(auth): align desktop session guards

* refactor(auth): gate desktop sessions by runtime features
2026-06-15 21:39:32 +02:00

49 lines
1.5 KiB
TypeScript

import { BadRequestError, UnauthorizedError } from "http-errors-enhanced";
import { config } from "~/server/core/config";
import { auth } from "~/server/lib/auth";
import { ensureDesktopIdentity } from "~/server/modules/desktop/bootstrap";
import { cryptoUtils } from "~/server/utils/crypto";
import type { CreateDesktopSessionBody } from "./desktop.dto";
export const DESKTOP_LAUNCH_SECRET_HEADER = "X-Zerobyte-Desktop-Launch-Secret";
export const assertDesktopRuntime = () => {
if (config.runtime !== "desktop") {
throw new BadRequestError("Desktop runtime is not enabled");
}
};
export const verifyDesktopLaunchSecret = (secret: string | undefined) => {
assertDesktopRuntime();
const expected = config.desktop.launchSecret;
if (!secret || !expected) {
throw new UnauthorizedError("Invalid desktop launch secret");
}
if (!cryptoUtils.timingSafeEqualString(secret, expected)) {
throw new UnauthorizedError("Invalid desktop launch secret");
}
};
const createDesktopSession = async (body: CreateDesktopSessionBody) => {
assertDesktopRuntime();
const user = await ensureDesktopIdentity(body);
if (!user) {
throw new Error("Failed to bootstrap desktop user");
}
const ctx = await auth.$context;
const session = await ctx.internalAdapter.createSession(user.id, false, { authSource: "desktop-session" }, true);
if (!session) {
throw new Error("Failed to create desktop session");
}
return { session, user };
};
export const desktopService = {
createDesktopSession,
};