Skip to content
Source
Sign inSign up

EnvironmentAuthPolicy.ts

64 lines2.2 KB

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