mirror of
https://github.com/Sea-Haven-Industries/seahaven-ap.git
synced 2026-10-03 01:03:14 +00:00
116 lines
4 KiB
TypeScript
116 lines
4 KiB
TypeScript
import { BUILD_GIT_SHA } from "./build-info.js";
|
|
|
|
export const USER_ROLES = ["admin", "ap_processor", "approver", "viewer"] as const;
|
|
|
|
export type UserRole = (typeof USER_ROLES)[number];
|
|
|
|
export function isUserRole(value: string): value is UserRole {
|
|
return (USER_ROLES as readonly string[]).includes(value);
|
|
}
|
|
|
|
const LOCAL_NODE_ENVS = new Set(["development", "test"]);
|
|
|
|
export function withLocalDevAuthBypass(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
|
|
if (env.DEV_AUTH_BYPASS !== undefined) return env;
|
|
const nodeEnv = env.NODE_ENV ?? "development";
|
|
if (!LOCAL_NODE_ENVS.has(nodeEnv)) return env;
|
|
return { ...env, DEV_AUTH_BYPASS: "true" };
|
|
}
|
|
|
|
export type ApiEnv = {
|
|
nodeEnv: string;
|
|
stage: string;
|
|
sha: string;
|
|
port: number;
|
|
databaseDriver: "postgres" | "data-api";
|
|
databaseUrl: string;
|
|
awsRegion: string;
|
|
rdsClusterArn: string;
|
|
rdsSecretArn: string;
|
|
rdsDatabase: string;
|
|
cognitoIssuer: string;
|
|
cognitoAudience: string;
|
|
cognitoDomain: string;
|
|
appOrigin: string;
|
|
originVerifySecret: string;
|
|
documentsEndpoint: string;
|
|
documentsAccessKey: string;
|
|
documentsSecretKey: string;
|
|
documentsBucket: string;
|
|
devAuthBypass: boolean;
|
|
devAuthSub: string;
|
|
devAuthEmail: string;
|
|
devAuthName: string;
|
|
devAuthRole: UserRole;
|
|
};
|
|
|
|
function required(name: string, value: string | undefined): string {
|
|
if (!value) {
|
|
throw new Error(`Missing required env var ${name}.`);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
export function loadEnv(env: NodeJS.ProcessEnv = process.env): ApiEnv {
|
|
const nodeEnv = env.NODE_ENV ?? "development";
|
|
const databaseDriver = (env.DATABASE_DRIVER ?? "postgres") as ApiEnv["databaseDriver"];
|
|
if (databaseDriver !== "postgres" && databaseDriver !== "data-api") {
|
|
throw new Error(`Invalid DATABASE_DRIVER: ${databaseDriver}`);
|
|
}
|
|
|
|
const devAuthBypass = env.DEV_AUTH_BYPASS === "true";
|
|
if (devAuthBypass && !LOCAL_NODE_ENVS.has(nodeEnv)) {
|
|
throw new Error("DEV_AUTH_BYPASS is only allowed when NODE_ENV is development or test.");
|
|
}
|
|
|
|
const rawRole = env.DEV_AUTH_ROLE ?? "admin";
|
|
if (!isUserRole(rawRole)) {
|
|
throw new Error(`Invalid DEV_AUTH_ROLE: ${rawRole}`);
|
|
}
|
|
|
|
const local = LOCAL_NODE_ENVS.has(nodeEnv);
|
|
const stage = env.STAGE?.trim() || (local ? "local" : "dev");
|
|
// SHA is inlined at image build. Runtime GIT_SHA is a local-dev convenience
|
|
// only and must not be the deployed source of truth.
|
|
const sha = BUILD_GIT_SHA || env.GIT_SHA?.trim() || "unknown";
|
|
|
|
const base: ApiEnv = {
|
|
nodeEnv,
|
|
stage,
|
|
sha,
|
|
port: Number(env.API_PORT ?? "8787"),
|
|
databaseDriver,
|
|
databaseUrl: env.DATABASE_URL ?? "postgresql://seahaven:seahaven@127.0.0.1:5432/seahaven_ap",
|
|
awsRegion: env.AWS_REGION ?? "us-east-1",
|
|
rdsClusterArn: env.RDS_CLUSTER_ARN ?? "",
|
|
rdsSecretArn: env.RDS_SECRET_ARN ?? "",
|
|
rdsDatabase: env.RDS_DATABASE ?? "seahaven_ap",
|
|
cognitoIssuer: env.COGNITO_ISSUER ?? "",
|
|
cognitoAudience: env.COGNITO_AUDIENCE ?? "",
|
|
cognitoDomain: env.COGNITO_DOMAIN?.trim() ?? "",
|
|
appOrigin: env.APP_ORIGIN?.trim() || (local ? "http://127.0.0.1:3000" : ""),
|
|
originVerifySecret: env.ORIGIN_VERIFY_SECRET?.trim() ?? "",
|
|
documentsEndpoint: env.DOCUMENTS_ENDPOINT?.trim() || env.MINIO_ENDPOINT?.trim() || "",
|
|
documentsAccessKey: env.DOCUMENTS_ACCESS_KEY?.trim() || env.MINIO_ACCESS_KEY?.trim() || "",
|
|
documentsSecretKey: env.DOCUMENTS_SECRET_KEY?.trim() || env.MINIO_SECRET_KEY?.trim() || "",
|
|
documentsBucket:
|
|
env.DOCUMENTS_BUCKET?.trim() || env.MINIO_BUCKET?.trim() || "seahaven-ap-documents",
|
|
devAuthBypass,
|
|
devAuthSub: env.DEV_AUTH_SUB ?? "seed-sub-admin",
|
|
devAuthEmail: env.DEV_AUTH_EMAIL ?? "admin@seahavenind.com",
|
|
devAuthName: env.DEV_AUTH_NAME ?? "Dev Admin",
|
|
devAuthRole: rawRole,
|
|
};
|
|
|
|
if (databaseDriver === "data-api") {
|
|
required("RDS_CLUSTER_ARN", base.rdsClusterArn);
|
|
required("RDS_SECRET_ARN", base.rdsSecretArn);
|
|
}
|
|
|
|
if (!devAuthBypass && nodeEnv !== "test") {
|
|
required("COGNITO_ISSUER", base.cognitoIssuer);
|
|
required("COGNITO_AUDIENCE", base.cognitoAudience);
|
|
}
|
|
|
|
return base;
|
|
}
|