Parse backend environment, expose more settings
This commit is contained in:
@@ -2,10 +2,11 @@ import cors from "@elysiajs/cors";
|
||||
import { staticPlugin } from "@elysiajs/static";
|
||||
import { swagger } from "@elysiajs/swagger";
|
||||
import { AttachmentId, PieceId, RepertoireId, RequestId, SessionId, Sha256_Bin, Sha256_Hex } from "common";
|
||||
import { Effect, Option, pipe } from "effect";
|
||||
import { Effect, Option, pipe, Redacted } from "effect";
|
||||
import { Elysia, error, t } from "elysia";
|
||||
import { sql } from "kysely";
|
||||
import { CLIENT_ID, EXTERNAL_OAUTH_CONFIGURATION, getUser, INTERNAL_OAUTH_CONFIGURATION, makeAuthorizationUrl, REDIRECT_URI, revalidateTokens } from "./auth";
|
||||
import { EXTERNAL_OAUTH_CONFIGURATION, getUser, INTERNAL_OAUTH_CONFIGURATION, makeAuthorizationUrl, REDIRECT_URI, revalidateTokens } from "./auth";
|
||||
import { config } from "./config";
|
||||
import * as Db from "./database";
|
||||
import * as Model from "./model";
|
||||
import { DbFromInstance } from "./services/db";
|
||||
@@ -30,9 +31,9 @@ const app = new Elysia()
|
||||
},
|
||||
}))
|
||||
|
||||
.use(cors({ origin: process.env.NODE_ENV === "production" ? false : "localhost:5173" }))
|
||||
.use(cors({ origin: config.NODE_ENV === "production" ? false : "localhost:5173" }))
|
||||
|
||||
.decorate("db", await Db.initDatabase(process.env.DB_PATH))
|
||||
.decorate("db", await Db.initDatabase(config.DB_PATH))
|
||||
|
||||
.resolve(async ({ db, cookie }) => {
|
||||
await db
|
||||
@@ -201,12 +202,12 @@ const app = new Elysia()
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
"client_id": CLIENT_ID,
|
||||
"client_id": config.CLIENT_ID,
|
||||
"code": code,
|
||||
"redirect_uri": REDIRECT_URI,
|
||||
"grant_type": "authorization_code",
|
||||
"code_verifier": codeVerifier.value,
|
||||
"client_secret": process.env.CLIENT_SECRET!,
|
||||
"client_secret": Redacted.value(config.CLIENT_SECRET),
|
||||
}).toString(),
|
||||
});
|
||||
|
||||
@@ -229,7 +230,7 @@ const app = new Elysia()
|
||||
.execute();
|
||||
}
|
||||
|
||||
return redirect(process.env.NODE_ENV === "production" ? "https://music.renati.me/" : "http://localhost:5173/", 303) as unknown as void;
|
||||
return redirect(config.NODE_ENV === "production" ? "https://music.renati.me/" : "http://localhost:5173/", 303) as unknown as void;
|
||||
}, {
|
||||
response: {
|
||||
303: t.Void(),
|
||||
@@ -859,5 +860,5 @@ const app = new Elysia()
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
app.listen(process.env.PORT || 3000);
|
||||
app.listen(config.PORT);
|
||||
export type App = typeof app;
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import { UserId } from "common";
|
||||
import { DateTime, Duration, Effect, Option, pipe } from "effect";
|
||||
import { DateTime, Duration, Effect, Option, pipe, Redacted } from "effect";
|
||||
import { constant } from "effect/Function";
|
||||
import { config } from "./config";
|
||||
import * as Model from "./model";
|
||||
import { Db } from "./services/db";
|
||||
import { Session } from "./services/session";
|
||||
|
||||
export const TENANT_ID = "0817c403-92e4-4648-a9aa-f688ffc5f97a";
|
||||
export const TENANT_SUBDOMAIN = "chkvoxastra";
|
||||
|
||||
export const CLIENT_ID = "e5948f7d-187b-44f9-80cd-63ffda86f9be";
|
||||
export const OAUTH_SCOPE = "email offline_access openid profile https://graph.microsoft.com/User.Read.All";
|
||||
|
||||
export const REDIRECT_URI = process.env.NODE_ENV === "production" ? "https://music.renati.me/api/v1/login" : "http://localhost:3000/api/v1/login";
|
||||
export const REDIRECT_URI = config.NODE_ENV === "production" ? "https://music.renati.me/api/v1/login" : "http://localhost:3000/api/v1/login";
|
||||
|
||||
export const EXPIRATION_BUFFER = Duration.seconds(10);
|
||||
|
||||
@@ -21,13 +17,13 @@ export interface OAuthConfiguration {
|
||||
}
|
||||
|
||||
export const INTERNAL_OAUTH_CONFIGURATION: OAuthConfiguration = Object.freeze<OAuthConfiguration>({
|
||||
authorizationEndpoint: `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/authorize`,
|
||||
tokenEndpoint: `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token`,
|
||||
authorizationEndpoint: `https://login.microsoftonline.com/${config.TENANT_ID}/oauth2/v2.0/authorize`,
|
||||
tokenEndpoint: `https://login.microsoftonline.com/${config.TENANT_ID}/oauth2/v2.0/token`,
|
||||
});
|
||||
|
||||
export const EXTERNAL_OAUTH_CONFIGURATION: OAuthConfiguration = Object.freeze<OAuthConfiguration>({
|
||||
authorizationEndpoint: `https://${TENANT_SUBDOMAIN}.ciamlogin.com/${TENANT_ID}/oauth2/v2.0/authorize`,
|
||||
tokenEndpoint: `https://${TENANT_SUBDOMAIN}.ciamlogin.com/${TENANT_ID}/oauth2/v2.0/token`,
|
||||
authorizationEndpoint: `https://${config.TENANT_SUBDOMAIN}.ciamlogin.com/${config.TENANT_ID}/oauth2/v2.0/authorize`,
|
||||
tokenEndpoint: `https://${config.TENANT_SUBDOMAIN}.ciamlogin.com/${config.TENANT_ID}/oauth2/v2.0/token`,
|
||||
});
|
||||
|
||||
export namespace makeAuthorizationUrl {
|
||||
@@ -60,7 +56,7 @@ export const makeAuthorizationUrl = Effect.fn("makeAuthorizationUrl")(
|
||||
const { authorizationEndpoint } = external ? EXTERNAL_OAUTH_CONFIGURATION : INTERNAL_OAUTH_CONFIGURATION;
|
||||
|
||||
const url = new URL(authorizationEndpoint);
|
||||
url.searchParams.set("client_id", CLIENT_ID);
|
||||
url.searchParams.set("client_id", config.CLIENT_ID);
|
||||
url.searchParams.set("response_type", "code");
|
||||
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
||||
url.searchParams.set("scope", OAUTH_SCOPE);
|
||||
@@ -132,10 +128,10 @@ export const revalidateTokens = Effect.fn("revaildateTokens")(
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
"client_id": CLIENT_ID,
|
||||
"client_id": config.CLIENT_ID,
|
||||
"grant_type": "refresh_token",
|
||||
"refresh_token": refreshTokenValue,
|
||||
"client_secret": process.env.CLIENT_SECRET!,
|
||||
"client_secret": Redacted.value(config.CLIENT_SECRET),
|
||||
}).toString(),
|
||||
}));
|
||||
|
||||
|
||||
33
packages/backend/src/config.ts
Normal file
33
packages/backend/src/config.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { pipe, Schema } from "effect";
|
||||
import { constant } from "effect/Function";
|
||||
|
||||
/* NOTE I know "effect/Config" exists, but I also don't care. This works for me. */
|
||||
|
||||
export const Config = Schema.Struct({
|
||||
CLIENT_ID: Schema.UUID,
|
||||
CLIENT_SECRET: pipe(
|
||||
Schema.String,
|
||||
Schema.Redacted,
|
||||
),
|
||||
DB_PATH: pipe(
|
||||
Schema.String,
|
||||
Schema.optional,
|
||||
),
|
||||
NODE_ENV: pipe(
|
||||
Schema.Literal("development", "production"),
|
||||
Schema.optionalWith({ default: constant("development" as const) }),
|
||||
),
|
||||
PORT: pipe(
|
||||
Schema.NumberFromString,
|
||||
Schema.optionalWith({ default: constant(3000) }),
|
||||
),
|
||||
TENANT_ID: Schema.UUID,
|
||||
TENANT_SUBDOMAIN: Schema.String,
|
||||
});
|
||||
|
||||
export type Config = typeof Config.Type;
|
||||
|
||||
export const config = pipe(
|
||||
process.env,
|
||||
Schema.decodeUnknownSync(Config),
|
||||
);
|
||||
Reference in New Issue
Block a user