Files
drop/server/api/v1/client/auth/initiate.post.ts
DecDuck b72e1ef7a4 Code-based authorization for Drop clients (#145)
* feat: code-based authorization

* fix: final touches

* fix: require session on code fetch endpoint

* feat: better error handling

* refactor: move auth send to client handler

* fix: lint
2025-08-01 13:11:56 +10:00

72 lines
2.0 KiB
TypeScript

import { type } from "arktype";
import { readDropValidatedBody, throwingArktype } from "~/server/arktype";
import type {
CapabilityConfiguration,
InternalClientCapability,
} from "~/server/internal/clients/capabilities";
import capabilityManager, {
validCapabilities,
} from "~/server/internal/clients/capabilities";
import clientHandler, { AuthMode } from "~/server/internal/clients/handler";
import { parsePlatform } from "~/server/internal/utils/parseplatform";
const ClientAuthInitiate = type({
name: "string",
platform: "string",
capabilities: "object",
mode: type.valueOf(AuthMode).default(AuthMode.Callback),
}).configure(throwingArktype);
export default defineEventHandler(async (h3) => {
const body = await readDropValidatedBody(h3, ClientAuthInitiate);
const platformRaw = body.platform;
const capabilities: Partial<CapabilityConfiguration> =
body.capabilities ?? {};
const platform = parsePlatform(platformRaw);
if (!platform)
throw createError({
statusCode: 400,
statusMessage: "Invalid or unsupported platform",
});
const capabilityIterable = Object.entries(capabilities) as Array<
[InternalClientCapability, object]
>;
if (
capabilityIterable.length > 0 &&
capabilityIterable
.map(([capability]) => validCapabilities.find((v) => capability == v))
.filter((e) => e).length == 0
)
throw createError({
statusCode: 400,
statusMessage: "Invalid capabilities.",
});
if (
capabilityIterable.length > 0 &&
capabilityIterable.filter(
([capability, configuration]) =>
!capabilityManager.validateCapabilityConfiguration(
capability,
configuration,
),
).length > 0
)
throw createError({
statusCode: 400,
statusMessage: "Invalid capability configuration.",
});
const result = await clientHandler.initiate({
name: body.name,
platform,
capabilities,
mode: body.mode,
});
return result;
});