refactor: api routes

This commit is contained in:
Max Koon
2025-11-26 12:09:12 -05:00
parent ed3e6df4d2
commit cbc220a968
15 changed files with 342 additions and 322 deletions

View File

@@ -0,0 +1,61 @@
import { AuthSchema } from "@money/shared/auth";
import { Context, Effect, Schema, Console } from "effect";
import { Authorization } from "../auth/context";
import { HttpLayerRouter, HttpServerRequest } from "@effect/platform";
export class CurrentSession extends Context.Tag("CurrentSession")<
CurrentSession,
{ readonly auth: Schema.Schema.Type<typeof AuthSchema> | null }
>() {}
export const SessionMiddleware = HttpLayerRouter.middleware<{
provides: CurrentSession;
}>()(
Effect.gen(function* () {
const auth = yield* Authorization;
return (httpEffect) =>
Effect.gen(function* () {
const request = yield* HttpServerRequest.HttpServerRequest;
const headers = { ...request.headers };
const token = yield* HttpServerRequest.schemaHeaders(
Schema.Struct({
authorization: Schema.optional(Schema.String),
}),
).pipe(
Effect.tap(Console.debug),
Effect.flatMap(({ authorization }) =>
authorization != undefined
? parseAuthorization(authorization)
: Effect.succeed(undefined),
),
);
if (token) {
headers["cookie"] = token;
}
const session = yield* auth
.use((auth) => auth.api.getSession({ headers }))
.pipe(
Effect.flatMap((s) =>
s == null ? Effect.succeed(null) : Schema.decode(AuthSchema)(s),
),
// Effect.tap((s) => Console.debug("Auth result", s)),
);
return yield* Effect.provideService(httpEffect, CurrentSession, {
auth: session,
});
});
}),
);
const parseAuthorization = (input: string) =>
Effect.gen(function* () {
const m = /^Bearer\s+(.+)$/.exec(input);
if (!m) {
return yield* Effect.fail(new Error("Invalid token"));
}
return m[1];
});