Skip to content

Commit 967787b

Browse files
committed
feat: refine Better Auth deploy support
1 parent 21838d7 commit 967787b

6 files changed

Lines changed: 56 additions & 8 deletions

File tree

‎docs/guide/auth.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,15 @@ When auth is active, Void configures Better Auth with these conventions:
139139
- mount path: `/api/auth/*`
140140
- email/password enabled by default unless `auth.providers` is set without `"email"`
141141
- `auth.providers` can enable any built-in Better Auth social provider
142-
- deployed apps need an auth secret via `BETTER_AUTH_SECRET` or `AUTH_SECRET`
142+
- deployed apps need an auth secret via `BETTER_AUTH_SECRET`
143143
- D1/SQLite uses the app `DB` binding
144144
- PostgreSQL apps (`"database": "pg"`) use the app `HYPERDRIVE` binding
145145

146146
Auth sessions live in the same database system as the rest of the app. `AUTH_KV` is no longer used.
147147

148-
On Void Cloud, Void auto-creates `BETTER_AUTH_SECRET` for auth-enabled apps if you have not set `BETTER_AUTH_SECRET` or `AUTH_SECRET` yourself through project secrets.
148+
On Void Cloud, Void auto-creates `BETTER_AUTH_SECRET` for auth-enabled apps if you have not set `BETTER_AUTH_SECRET` yourself through project secrets.
149149

150-
Localhost dev uses a built-in fallback secret automatically. Outside the managed Void Cloud deploy flow, set `BETTER_AUTH_SECRET` or `AUTH_SECRET` yourself.
150+
Localhost dev uses a built-in fallback secret automatically. Outside the managed Void Cloud deploy flow, set `BETTER_AUTH_SECRET` yourself.
151151

152152
## Customization
153153

‎packages/void/src/cli/package.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ export function packageBuild(
133133

134134
// Build manifest from inferred bindings
135135
const manifest: DeployManifest = { version: 3, bindings: {} };
136+
if (bindings.needsAuth) manifest.auth = true;
136137
if (bindings.needsD1 || bindings.needsAuth) {
137138
if (dialect === "postgresql") {
138139
manifest.bindings.hyperdrive = ["HYPERDRIVE"];

‎packages/void/src/cli/types.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export interface WebSocketManifestMeta {
5353

5454
export interface DeployManifest {
5555
version: number;
56+
auth?: boolean;
5657
bindings: {
5758
d1?: string[];
5859
kv?: string[];

‎packages/void/src/runtime/better-auth-shared.ts‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export interface VoidAuthEnv extends Record<string, unknown> {
2323
DATABASE_URL?: string;
2424
HYPERDRIVE?: { connectionString?: string };
2525
BETTER_AUTH_SECRET?: string;
26-
AUTH_SECRET?: string;
2726
GITHUB_OAUTH_ID?: string;
2827
GITHUB_OAUTH_SECRET?: string;
2928
GOOGLE_OAUTH_ID?: string;
@@ -76,17 +75,15 @@ function resolveSecret(request: Request, env: VoidAuthEnv): string {
7675
const explicit =
7776
typeof env.BETTER_AUTH_SECRET === "string" && env.BETTER_AUTH_SECRET.length > 0
7877
? env.BETTER_AUTH_SECRET
79-
: typeof env.AUTH_SECRET === "string" && env.AUTH_SECRET.length > 0
80-
? env.AUTH_SECRET
81-
: undefined;
78+
: undefined;
8279
if (explicit) return explicit;
8380

8481
const url = new URL(request.url);
8582
if (isLocalHost(url.hostname)) {
8683
return "void-dev-better-auth-secret-1234567890";
8784
}
8885

89-
throw new Error("Missing Better Auth secret. Set BETTER_AUTH_SECRET or AUTH_SECRET.");
86+
throw new Error("Missing Better Auth secret. Set BETTER_AUTH_SECRET.");
9087
}
9188

9289
function readEnvString(env: VoidAuthEnv, ...keys: string[]): string | undefined {

‎packages/void/test/unit/better-auth.test.ts‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,34 @@ describe("resolveVoidAuthOptions", () => {
6464
),
6565
).rejects.toThrow('Missing auth credentials for provider "google"');
6666
});
67+
68+
it("requires BETTER_AUTH_SECRET outside localhost", async () => {
69+
await expect(
70+
resolveVoidAuthOptions(
71+
new Request("https://example.com/api/auth"),
72+
{
73+
AUTH_SECRET: "legacy-secret",
74+
},
75+
{
76+
dialect: "sqlite",
77+
providers: null,
78+
},
79+
{} as never,
80+
),
81+
).rejects.toThrow("Missing Better Auth secret. Set BETTER_AUTH_SECRET.");
82+
});
83+
84+
it("uses the localhost fallback when BETTER_AUTH_SECRET is missing", async () => {
85+
const { options } = await resolveVoidAuthOptions(
86+
new Request("http://localhost:3000/api/auth"),
87+
{},
88+
{
89+
dialect: "sqlite",
90+
providers: null,
91+
},
92+
{} as never,
93+
);
94+
95+
expect(options.secret).toBe("void-dev-better-auth-secret-1234567890");
96+
});
6797
});

‎packages/void/test/unit/package.test.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,25 @@ describe("packageBuild", () => {
118118
const manifest = JSON.parse(manifestRaw);
119119
expect(manifest.version).toBe(3);
120120
});
121+
122+
it("marks auth-enabled deploys in the manifest", () => {
123+
const workerDir = join(TMP, "worker");
124+
mkdirSync(workerDir, { recursive: true });
125+
writeFileSync(join(workerDir, "index.js"), "export default {}");
126+
127+
const form = packageBuild(TMP, "worker", {
128+
needsD1: false,
129+
needsKV: false,
130+
needsR2: false,
131+
needsAuth: true,
132+
needsQueues: false,
133+
needsAI: false,
134+
});
135+
136+
const manifestRaw = form.get("manifest") as string;
137+
const manifest = JSON.parse(manifestRaw);
138+
expect(manifest.auth).toBe(true);
139+
});
121140
});
122141

123142
describe("computeAssetHash", () => {

0 commit comments

Comments
 (0)