| 1 | import { AuthEnvironmentMaintainScope, type ServerAuthDescriptor } from "@t3tools/contracts"; |
| 2 | import * as Context from "effect/Context"; |
| 3 | import * as Effect from "effect/Effect"; |
| 4 | import * as Layer from "effect/Layer"; |
| 5 | |
| 6 | import * as ServerConfig from "../config.ts"; |
| 7 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; |
| 8 | import { isRemoteReachableHost, resolveSessionCookieName } from "./utils.ts"; |
| 9 | |
| 10 | export class EnvironmentAuthPolicy extends Context.Service< |
| 11 | EnvironmentAuthPolicy, |
| 12 | { |
| 13 | readonly getDescriptor: () => Effect.Effect<ServerAuthDescriptor>; |
| 14 | } |
| 15 | >()("t3/auth/EnvironmentAuthPolicy") {} |
| 16 | |
| 17 | /** @public Service construction is part of the canonical Effect module API. */ |
| 18 | export const make = Effect.gen(function* () { |
| 19 | const config = yield* ServerConfig.ServerConfig; |
| 20 | const serverEnvironment = yield* ServerEnvironment.ServerEnvironmentIdentity; |
| 21 | const isRemoteReachable = isRemoteReachableHost(config.host); |
| 22 | |
| 23 | const policy = |
| 24 | config.mode === "desktop" |
| 25 | ? isRemoteReachable |
| 26 | ? "remote-reachable" |
| 27 | : "desktop-managed-local" |
| 28 | : isRemoteReachable |
| 29 | ? "remote-reachable" |
| 30 | : "loopback-browser"; |
| 31 | |
| 32 | const bootstrapMethods: ServerAuthDescriptor["bootstrapMethods"] = |
| 33 | policy === "desktop-managed-local" |
| 34 | ? ["desktop-bootstrap"] |
| 35 | : config.mode === "desktop" && policy === "remote-reachable" |
| 36 | ? ["desktop-bootstrap", "one-time-token"] |
| 37 | : ["one-time-token"]; |
| 38 | |
| 39 | const descriptor: ServerAuthDescriptor = { |
| 40 | policy, |
| 41 | bootstrapMethods, |
| 42 | sessionMethods: ["browser-session-cookie", "bearer-access-token", "dpop-access-token"], |
| 43 | serverUpdateScope: AuthEnvironmentMaintainScope, |
| 44 | sessionCookieName: resolveSessionCookieName({ |
| 45 | mode: config.mode, |
| 46 | port: config.port, |
| 47 | host: config.host, |
| 48 | instanceKey: config.stateDir, |
| 49 | environmentId: yield* serverEnvironment.getEnvironmentId, |
| 50 | development: config.devUrl !== undefined, |
| 51 | }), |
| 52 | }; |
| 53 | |
| 54 | return EnvironmentAuthPolicy.of({ |
| 55 | getDescriptor: () => |
| 56 | Effect.succeed(descriptor).pipe(Effect.withSpan("EnvironmentAuthPolicy.getDescriptor")), |
| 57 | }); |
| 58 | }); |
| 59 | |
| 60 | export const layer = Layer.effect(EnvironmentAuthPolicy, make); |