From 1762b15a37da7158b3ba593bfb2d9218c5af7fb1 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 12:58:51 +0000 Subject: [PATCH] fix: Pages deploy step, and trim Google OAuth credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first real deploy got the Worker out and failed on Pages: wrangler-action installs its own default wrangler (3.90.0) unless told otherwise, and that rejected --functions-directory. No version of wrangler has that flag — `pages deploy` compiles ./functions from the working directory, which is already the repo root. Drop the flag and pin the action to the backend's wrangler (4.134.0). `wrangler pages functions build functions` compiles the proxy cleanly with it. Also trim GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET before use. They are pasted into `wrangler secret put` by hand, and a trailing newline or carriage return makes Google answer "The provided client secret is invalid" with nothing visibly wrong. Neither can contain whitespace. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TivKBtoj8GvfK4yeS44Vnr --- .github/workflows/deploy-cloudflare.yml | 13 +++++++++---- backend/src/routes/auth.ts | 14 ++++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy-cloudflare.yml b/.github/workflows/deploy-cloudflare.yml index 3423419..488b943 100644 --- a/.github/workflows/deploy-cloudflare.yml +++ b/.github/workflows/deploy-cloudflare.yml @@ -86,11 +86,16 @@ jobs: with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - # --functions-directory is explicit: the proxy in functions/ lives at - # the repo root, not inside dist/, and losing it would deploy a - # frontend that quietly falls back to the free tier. + # Pinned to the backend's wrangler. Left unset, the action installs + # its own default (3.90.0 at the time of writing), which is a major + # version behind and rejected the flags this step used to pass. + wranglerVersion: '4.134.0' + # No --functions-directory: wrangler has no such flag. `pages deploy` + # compiles ./functions from the working directory, which is the repo + # root here — the proxy lives there, not inside dist/, and deploying + # without it would serve a frontend that quietly falls back to the + # free tier. command: >- pages deploy dist --project-name=bottlecount --branch=main - --functions-directory=functions diff --git a/backend/src/routes/auth.ts b/backend/src/routes/auth.ts index cde71b3..9ad5c4d 100644 --- a/backend/src/routes/auth.ts +++ b/backend/src/routes/auth.ts @@ -15,15 +15,21 @@ type Bindings = { const auth = new Hono<{ Bindings: Bindings; Variables: AppVariables }>(); auth.use('/google', async (c, next) => { - if (!c.env.GOOGLE_CLIENT_ID) { + // Trimmed because these are pasted into `wrangler secret put` by hand, and a + // trailing newline or carriage return — easy to pick up from a terminal — + // makes Google reject the secret as invalid with nothing visibly wrong. + // Neither value can legitimately contain whitespace. + const clientId = c.env.GOOGLE_CLIENT_ID?.trim(); + const clientSecret = c.env.GOOGLE_CLIENT_SECRET?.trim(); + if (!clientId) { return c.json({ error: 'Missing GOOGLE_CLIENT_ID' }, 500); } - if (!c.env.GOOGLE_CLIENT_SECRET) { + if (!clientSecret) { return c.json({ error: 'Missing GOOGLE_CLIENT_SECRET' }, 500); } const handler = googleAuth({ - client_id: c.env.GOOGLE_CLIENT_ID, - client_secret: c.env.GOOGLE_CLIENT_SECRET, + client_id: clientId, + client_secret: clientSecret, scope: ['openid', 'email', 'profile'], // The redirect target is the *frontend* origin: the Pages Function at // functions/auth/google.ts proxies it straight back here, which is what