feat: configurable trusted origins
Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled

This commit is contained in:
Nicolas Meienberger 2026-01-10 13:22:57 +01:00
parent 2bb11b0d33
commit 185ce22ce9
4 changed files with 11 additions and 4 deletions

View file

@ -80,9 +80,10 @@ Zerobyte can be customized using environment variables. Below are the available
| :-------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------- | | :-------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------- |
| `PORT` | The port the web interface and API will listen on. | `4096` | | `PORT` | The port the web interface and API will listen on. | `4096` |
| `RESTIC_HOSTNAME` | The hostname used by Restic when creating snapshots. Automatically detected if a custom hostname is set in Docker. | `zerobyte` | | `RESTIC_HOSTNAME` | The hostname used by Restic when creating snapshots. Automatically detected if a custom hostname is set in Docker. | `zerobyte` |
| `TZ` | Timezone for the container (e.g., `Europe/Paris`). **Crucial for accurate backup scheduling.** | `UTC` |
| `TRUSTED_ORIGINS` | Comma-separated list of trusted origins for CORS (e.g., `http://localhost:3000,http://example.com`). | (none) |
| `LOG_LEVEL` | Logging verbosity. Options: `debug`, `info`, `warn`, `error`. | `info` | | `LOG_LEVEL` | Logging verbosity. Options: `debug`, `info`, `warn`, `error`. | `info` |
| `SERVER_IDLE_TIMEOUT` | Idle timeout for the server in seconds. | `60` | | `SERVER_IDLE_TIMEOUT` | Idle timeout for the server in seconds. | `60` |
| `TZ` | Timezone for the container (e.g., `Europe/Paris`). **Crucial for accurate backup scheduling.** | `UTC` |
### Secret References ### Secret References

View file

@ -11,12 +11,14 @@ import { convertLegacyUserOnFirstLogin } from "./auth-middlewares/convert-legacy
import { cryptoUtils } from "~/server/utils/crypto"; import { cryptoUtils } from "~/server/utils/crypto";
import { db } from "~/server/db/db"; import { db } from "~/server/db/db";
import { ensureOnlyOneUser } from "./auth-middlewares/only-one-user"; import { ensureOnlyOneUser } from "./auth-middlewares/only-one-user";
import { config } from "~/server/core/config";
export type AuthMiddlewareContext = MiddlewareContext<MiddlewareOptions, AuthContext<BetterAuthOptions>>; export type AuthMiddlewareContext = MiddlewareContext<MiddlewareOptions, AuthContext<BetterAuthOptions>>;
const createBetterAuth = (secret: string) => const createBetterAuth = (secret: string) =>
betterAuth({ betterAuth({
secret, secret,
trustedOrigins: config.trustedOrigins ?? ["*"],
hooks: { hooks: {
before: createAuthMiddleware(async (ctx) => { before: createAuthMiddleware(async (ctx) => {
await ensureOnlyOneUser(ctx); await ensureOnlyOneUser(ctx);
@ -55,9 +57,6 @@ const createBetterAuth = (secret: string) =>
}, },
}), }),
], ],
advanced: {
disableOriginCheck: true,
},
}); });
type Auth = ReturnType<typeof createBetterAuth>; type Auth = ReturnType<typeof createBetterAuth>;

View file

@ -1,5 +1,6 @@
import { Scalar } from "@scalar/hono-api-reference"; import { Scalar } from "@scalar/hono-api-reference";
import { Hono } from "hono"; import { Hono } from "hono";
import { cors } from "hono/cors";
import { logger as honoLogger } from "hono/logger"; import { logger as honoLogger } from "hono/logger";
import { secureHeaders } from "hono/secure-headers"; import { secureHeaders } from "hono/secure-headers";
import { rateLimiter } from "hono-rate-limiter"; import { rateLimiter } from "hono-rate-limiter";
@ -38,6 +39,10 @@ export const scalarDescriptor = Scalar({
export const createApp = () => { export const createApp = () => {
const app = new Hono(); const app = new Hono();
if (config.trustedOrigins) {
app.use(cors({ origin: config.trustedOrigins }));
}
if (config.environment !== "test") { if (config.environment !== "test") {
app.use(honoLogger()); app.use(honoLogger());
} }

View file

@ -32,6 +32,7 @@ const envSchema = type({
PORT: 'string.integer.parse = "4096"', PORT: 'string.integer.parse = "4096"',
MIGRATIONS_PATH: "string?", MIGRATIONS_PATH: "string?",
APP_VERSION: "string = 'dev'", APP_VERSION: "string = 'dev'",
TRUSTED_ORIGINS: "string?",
}).pipe((s) => ({ }).pipe((s) => ({
__prod__: s.NODE_ENV === "production", __prod__: s.NODE_ENV === "production",
environment: s.NODE_ENV, environment: s.NODE_ENV,
@ -41,6 +42,7 @@ const envSchema = type({
port: s.PORT, port: s.PORT,
migrationsPath: s.MIGRATIONS_PATH, migrationsPath: s.MIGRATIONS_PATH,
appVersion: s.APP_VERSION, appVersion: s.APP_VERSION,
trustedOrigins: s.TRUSTED_ORIGINS?.split(",").map((origin) => origin.trim()),
})); }));
const parseConfig = (env: unknown) => { const parseConfig = (env: unknown) => {