fix: build share urls from auth_url instead of localhost

docker build sets next_public_app_url to localhost; preferring it over
runtime auth_url made prod share links point at localhost:3000.
This commit is contained in:
ginnoir
2026-07-18 17:22:58 -05:00
parent d1e295165a
commit 832e7265c9
4 changed files with 14 additions and 6 deletions
+2
View File
@@ -16,7 +16,9 @@ ENV CI=true
ENV NEXT_TELEMETRY_DISABLED=1 ENV NEXT_TELEMETRY_DISABLED=1
ENV DATABASE_URL=postgres://build:build@localhost:5432/build ENV DATABASE_URL=postgres://build:build@localhost:5432/build
ENV AUTH_SECRET=build-time-placeholder ENV AUTH_SECRET=build-time-placeholder
# Build-only placeholder. Runtime public URL is AUTH_URL from stack.env — never prefer this.
ENV NEXT_PUBLIC_APP_URL=http://localhost:3000 ENV NEXT_PUBLIC_APP_URL=http://localhost:3000
ENV AUTH_URL=http://localhost:3000
COPY . . COPY . .
RUN pnpm install --offline --frozen-lockfile RUN pnpm install --offline --frozen-lockfile
RUN --mount=type=cache,id=famapp-nextjs,target=/app/.next/cache \ RUN --mount=type=cache,id=famapp-nextjs,target=/app/.next/cache \
+8
View File
@@ -0,0 +1,8 @@
/** Public origin for absolute links. AUTH_URL wins — Docker build sets NEXT_PUBLIC to localhost. */
export function getAppPublicUrl(): string {
const raw =
process.env.AUTH_URL?.trim() ||
process.env.NEXT_PUBLIC_APP_URL?.trim() ||
"http://localhost:3000";
return raw.replace(/\/$/, "");
}
+2 -3
View File
@@ -1,6 +1,7 @@
import { createHash, randomBytes } from "crypto"; import { createHash, randomBytes } from "crypto";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import type { ApiAuthContext } from "@/lib/api-auth"; import type { ApiAuthContext } from "@/lib/api-auth";
import { getAppPublicUrl } from "@/lib/app-url";
import { db } from "@/lib/db"; import { db } from "@/lib/db";
import { getEntityType, getRegistry } from "./registry"; import { getEntityType, getRegistry } from "./registry";
import { shareLinks } from "./schema"; import { shareLinks } from "./schema";
@@ -27,9 +28,7 @@ function hashToken(raw: string): string {
} }
function buildUrl(token: string): string { function buildUrl(token: string): string {
const base = return `${getAppPublicUrl()}/s/${token}`;
process.env["NEXT_PUBLIC_APP_URL"] ?? process.env["AUTH_URL"] ?? "http://localhost:3000";
return `${base}/s/${token}`;
} }
export function listShareableEntityTypes() { export function listShareableEntityTypes() {
+2 -3
View File
@@ -2,6 +2,7 @@
import { createHash, randomBytes } from "crypto"; import { createHash, randomBytes } from "crypto";
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { getAppPublicUrl } from "@/lib/app-url";
import { db } from "@/lib/db"; import { db } from "@/lib/db";
import { getCurrentSession } from "@/lib/session"; import { getCurrentSession } from "@/lib/session";
import { getEntityType } from "./registry"; import { getEntityType } from "./registry";
@@ -21,9 +22,7 @@ function hashToken(raw: string): string {
} }
function buildUrl(token: string): string { function buildUrl(token: string): string {
const base = return `${getAppPublicUrl()}/s/${token}`;
process.env["NEXT_PUBLIC_APP_URL"] ?? process.env["AUTH_URL"] ?? "http://localhost:3000";
return `${base}/s/${token}`;
} }
export async function createShareLink( export async function createShareLink(