Skip to content

Commit 13f0d44

Browse files
authored
Fixed process.env.NEXT_PUBLIC_... not loaded after docker build (stack-auth#420)
1 parent 9d21b9d commit 13f0d44

File tree

14 files changed

+92
-20
lines changed

14 files changed

+92
-20
lines changed

apps/dashboard/.eslintrc.cjs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ module.exports = {
1414
message:
1515
"Importing useRouter from next/navigation or next/router is not allowed. Use our custom useRouter instead.",
1616
},
17-
],
18-
patterns: [
1917
{
2018
group: ["next/link"],
2119
message:
@@ -26,6 +24,10 @@ module.exports = {
2624
],
2725
"no-restricted-syntax": [
2826
...defaults.rules["no-restricted-syntax"].filter(e => typeof e !== "object" || !e.message.includes("yupXyz")),
27+
{
28+
selector: "MemberExpression[object.name='process'][property.name='env'][parent.property.name=/^NEXT_PUBLIC_/]",
29+
message: "Direct access to process.env.NEXT_PUBLIC_* is not allowed. Use getPublicEnvVar() instead."
30+
}
2931
],
3032
},
3133
};

apps/dashboard/sentry.client.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The config you add here will be used whenever a users loads a page in their browser.
33
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
44

5+
import { getPublicEnvVar } from "@/lib/env";
56
import * as Sentry from "@sentry/nextjs";
67
import { getBrowserCompatibilityReport } from "@stackframe/stack-shared/dist/utils/browser-compat";
78
import { sentryBaseConfig } from "@stackframe/stack-shared/dist/utils/sentry";
@@ -10,7 +11,7 @@ import { nicify } from "@stackframe/stack-shared/dist/utils/strings";
1011
Sentry.init({
1112
...sentryBaseConfig,
1213

13-
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
14+
dsn: getPublicEnvVar('NEXT_PUBLIC_SENTRY_DSN'),
1415

1516
enabled: process.env.NODE_ENV !== "development" && !process.env.CI,
1617

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/auth-methods/providers.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { FormDialog } from "@/components/form-dialog";
33
import { InputField, SwitchField } from "@/components/form-fields";
44
import { SettingIconButton, SettingSwitch } from "@/components/settings";
5+
import { getPublicEnvVar } from "@/lib/env";
56
import { AdminProject } from "@stackframe/stack";
67
import { yupBoolean, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
78
import { sharedProviders } from "@stackframe/stack-shared/dist/utils/oauth";
@@ -109,7 +110,7 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
109110
Redirect URL for the OAuth provider settings
110111
</Label>
111112
<Typography type="footnote">
112-
<InlineCode>{`${process.env.NEXT_PUBLIC_STACK_API_URL}/api/v1/auth/oauth/callback/${props.id}`}</InlineCode>
113+
<InlineCode>{`${getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL')}/api/v1/auth/oauth/callback/${props.id}`}</InlineCode>
113114
</Typography>
114115
</div>}
115116

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/project-settings/page-client.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { InputField, SwitchField } from "@/components/form-fields";
33
import { StyledLink } from "@/components/link";
44
import { FormSettingCard, SettingCard, SettingSwitch, SettingText } from "@/components/settings";
5+
import { getPublicEnvVar } from "@/lib/env";
56
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActionDialog, Alert, Button, Typography } from "@stackframe/stack-ui";
67
import * as yup from "yup";
78
import { PageLayout } from "../page-layout";
@@ -31,7 +32,7 @@ export default function PageClient() {
3132
</SettingText>
3233

3334
<SettingText label="JWKS URL">
34-
{`${process.env.NEXT_PUBLIC_STACK_API_URL}/api/v1/projects/${project.id}/.well-known/jwks.json`}
35+
{`${getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL')}/api/v1/projects/${project.id}/.well-known/jwks.json`}
3536
</SettingText>
3637
</SettingCard>
3738
<FormSettingCard

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/[endpointId]/page-client.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
"use client";
22

33
import { SettingCard, SettingSwitch } from "@/components/settings";
4+
import { getPublicEnvVar } from "@/lib/env";
45
import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises";
56
import { Alert, Badge, Button, Checkbox, CopyButton, Label, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
67
import { ChevronLeft, ChevronRight } from "lucide-react";
7-
import { useEffect, useMemo, useState } from "react";
8-
import { SvixProvider, useEndpoint, useEndpointFunctions, useEndpointMessageAttempts, useEndpointSecret, useSvix } from "svix-react";
8+
import { useMemo, useState } from "react";
9+
import { SvixProvider, useEndpoint, useEndpointFunctions, useEndpointMessageAttempts, useEndpointSecret } from "svix-react";
910
import { PageLayout } from "../../page-layout";
1011
import { useAdminApp } from "../../use-admin-app";
1112
import { getSvixResult } from "../utils";
@@ -187,7 +188,7 @@ export default function PageClient(props: { endpointId: string }) {
187188
<SvixProvider
188189
token={svixTokenUpdated}
189190
appId={stackAdminApp.projectId}
190-
options={{ serverUrl: process.env.NEXT_PUBLIC_STACK_SVIX_SERVER_URL }}
191+
options={{ serverUrl: getPublicEnvVar('NEXT_PUBLIC_STACK_SVIX_SERVER_URL') }}
191192
>
192193
<PageInner endpointId={props.endpointId} />
193194
</SvixProvider>

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/webhooks/page-client.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
"use client";
22

33
import { SmartFormDialog } from "@/components/form-dialog";
4+
import { useRouter } from "@/components/router";
45
import { SettingCard } from "@/components/settings";
6+
import { getPublicEnvVar } from "@/lib/env";
57
import { urlSchema } from "@stackframe/stack-shared/dist/schema-fields";
68
import { ActionCell, ActionDialog, Alert, Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Typography } from "@stackframe/stack-ui";
7-
import { useRouter } from "next/navigation";
89
import { useState } from "react";
910
import { SvixProvider, useEndpoints, useSvix } from "svix-react";
1011
import * as yup from "yup";
@@ -183,7 +184,7 @@ export default function PageClient() {
183184
key={updateCounter}
184185
token={svixToken}
185186
appId={stackAdminApp.projectId}
186-
options={{ serverUrl: process.env.NEXT_PUBLIC_STACK_SVIX_SERVER_URL }}
187+
options={{ serverUrl: getPublicEnvVar('NEXT_PUBLIC_STACK_SVIX_SERVER_URL') }}
187188
>
188189
<Endpoints updateFn={() => setUpdateCounter(x => x + 1)} />
189190
</SvixProvider>

apps/dashboard/src/app/(main)/integrations/neon/projects/transfer/confirm/page-client.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
"use client";
22

33
import { Logo } from "@/components/logo";
4+
import { useRouter } from "@/components/router";
45
import { useStackApp, useUser } from "@stackframe/stack";
56
import { wait } from "@stackframe/stack-shared/dist/utils/promises";
67
import { Button, Card, CardContent, CardFooter, CardHeader, Input, Typography } from "@stackframe/stack-ui";
78
import Image from "next/image";
8-
import { useRouter, useSearchParams } from "next/navigation";
9+
import { useSearchParams } from "next/navigation";
910
import NeonLogo from "../../../../../../../../public/neon.png";
1011

1112
export const stackAppInternalsSymbol = Symbol.for("StackAuth--DO-NOT-USE-OR-YOU-WILL-BE-FIRED--StackAppInternals");

apps/dashboard/src/app/layout.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { RouterProvider } from '@/components/router';
33
import { SiteLoadingIndicatorDisplay } from '@/components/site-loading-indicator';
44
import { StyleLink } from '@/components/style-link';
55
import { ThemeProvider } from '@/components/theme-provider';
6+
import { getPublicEnvVar } from '@/lib/env';
67
import { cn } from '@/lib/utils';
78
import { stackServerApp } from '@/stack';
89
import { StackProvider, StackTheme } from '@stackframe/stack';
@@ -23,7 +24,7 @@ import './globals.css';
2324
import { CSPostHogProvider, UserIdentity } from './providers';
2425

2526
export const metadata: Metadata = {
26-
metadataBase: new URL(process.env.NEXT_PUBLIC_STACK_API_URL || ''),
27+
metadataBase: new URL(getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL') || ''),
2728
title: {
2829
default: 'Stack Auth Dashboard',
2930
template: '%s | Stack Auth',
@@ -32,12 +33,12 @@ export const metadata: Metadata = {
3233
openGraph: {
3334
title: 'Stack Auth Dashboard',
3435
description: 'Stack Auth is the open-source Auth0 alternative, and the fastest way to add authentication to your web app.',
35-
images: [`${process.env.NEXT_PUBLIC_STACK_API_URL}/open-graph-image.png`]
36+
images: [`${getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL')}/open-graph-image.png`]
3637
},
3738
twitter: {
3839
title: 'Stack Auth Dashboard',
3940
description: 'Stack Auth is the open-source Auth0 alternative, and the fastest way to add authentication to your web app.',
40-
images: [`${process.env.NEXT_PUBLIC_STACK_API_URL}/open-graph-image.png`]
41+
images: [`${getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL')}/open-graph-image.png`]
4142
},
4243
};
4344

apps/dashboard/src/app/providers.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
'use client';
2+
import { getPublicEnvVar } from '@/lib/env';
23
import { useStackApp, useUser } from '@stackframe/stack';
34
import posthog from 'posthog-js';
45
import { PostHogProvider } from 'posthog-js/react';
56
import { Suspense, useEffect, useState } from 'react';
67

78
if (typeof window !== 'undefined') {
8-
const postHogKey = process.env.NEXT_PUBLIC_POSTHOG_KEY ?? "phc_vIUFi0HzHo7oV26OsaZbUASqxvs8qOmap1UBYAutU4k";
9+
const postHogKey = getPublicEnvVar('NEXT_PUBLIC_POSTHOG_KEY') ?? "phc_vIUFi0HzHo7oV26OsaZbUASqxvs8qOmap1UBYAutU4k";
910
if (postHogKey.length > 5) {
1011
posthog.init(postHogKey, {
1112
api_host: "/consume",

apps/dashboard/src/components/env-keys.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getPublicEnvVar } from "@/lib/env";
12
import { Button, CopyField, Tabs, TabsContent, TabsList, TabsTrigger } from "@stackframe/stack-ui";
23

34
export default function EnvKeys(props: {
@@ -7,7 +8,7 @@ export default function EnvKeys(props: {
78
superSecretAdminKey?: string,
89
}) {
910
const envFileContent = Object.entries({
10-
NEXT_PUBLIC_STACK_API_URL: process.env.NEXT_PUBLIC_STACK_API_URL === "https://api.stack-auth.com" ? undefined : process.env.NEXT_PUBLIC_STACK_API_URL,
11+
NEXT_PUBLIC_STACK_API_URL: getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL') === "https://api.stack-auth.com" ? undefined : getPublicEnvVar('NEXT_PUBLIC_STACK_API_URL'),
1112
NEXT_PUBLIC_STACK_PROJECT_ID: props.projectId,
1213
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY: props.publishableClientKey,
1314
STACK_SECRET_SERVER_KEY: props.secretServerKey,

0 commit comments

Comments
 (0)