πŸ“„ SKILL.md

← Vault

name: doccorretor-gmail-oauth

description: Gmail OAuth integration for DocCorretor (TanStack Start + Supabase) β€” OAuth flow, callback pattern, and known pitfalls.


Gmail OAuth β€” DocCorretor Pattern

Overview

Full Gmail OAuth integration using Google OAuth 2.0 with refresh tokens, stored in Supabase.

TanStack Start server-side callback + frontend redirect pattern.

Architecture

`

Frontend (admin.tsx)

β†’ getGmailAuthUrl() [server fn]

β†’ window.open(url, "_blank") ← opens Google consent in new tab

β†’ on return: /admin?gmail_connected=1 or ?gmail_error=...

Callback (gmail-oauth-callback.ts)

β†’ exchanges code at https://oauth2.googleapis.com/token

β†’ gets user email via https://www.googleapis.com/oauth2/v2/userinfo

β†’ validates user via Supabase JWT (state param)

β†’ upserts into gmail_connections table

β†’ Response.redirect() to /admin?gmail_connected=1

gmail.functions.ts

β†’ sendGmailWithAttachments: uses stored refresh_token to get access_token,

then sends via Gmail API with base64 attachments

`

Files

No code changes needed β€” App Password SMTP is already implemented. Just direct user to use it.


Known Pitfalls

Google blocks headless browsers

Google OAuth returns "This browser or app may not be secure" in headless/automated browsers.

Fix: Use App Password SMTP instead (no OAuth, no browser needed).

Anonymous auth may be disabled

Supabase Auth can have anonymous sign-ins disabled ("anonymous_users": false).

Fix: OAuth flow uses the user's actual session token as state, not anonymous auth.

Missing GOOGLE env vars

.env often missing GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET, GOOGLE_REDIRECT_URI.

Fix: Add them β€” they are NOT in the original Lovable-generated .env.

Node 18 ESM build breaks

@lovable.dev/vite-tanstack-config β†’ lovable-tagger fails with Node 18 (ESM module resolution error).

Fix: use Node 20 via /root/.nvm/versions/node/v20.20.2/bin/node

`bash

cd /var/www/documentos/deploy-vps-nodejs/app

/root/.nvm/versions/node/v20.20.2/bin/node node_modules/vite/bin/vite.js build

`

Server default is Node 18 β€” always switch before building.

RLS blocks insert/update on app_settings

RLS policies on app_settings table block write operations from the app's anon key.

Fix: Use Supabase Management API with service role key for database operations:

`bash

curl -X POST 'https://api.supabase.com/v1/projects/dauftiqcvgaydddoxqhh/query' \

-H 'apikey: ' \

-H 'Content-Type: application/json' \

-d '{"sql": "INSERT INTO public.app_settings (key, value) VALUES (...)"}'

`

Supabase project ref in .env

DocCorretor and ComercialRS share the same Supabase Cloud project (dauftiqcvgaydddoxqhh).

The .env had wrong ref (lzoiuxulhnvtmadoymrb). Fix to dauftiqcvgaydddoxqhh if tables are empty.

Anonymous auth may be disabled

If user previously authorized but refresh_token is missing: refresh_token: Unknown error.

Google only returns refresh_token on FIRST consent or after revoking access at myaccount.google.com/permissions.

Fix: User must revoke prior access, then re-authorize.

Google Cloud Console Setup

1. Go to https://console.cloud.google.com/apis/credentials

2. Select project (or create new)

3. Create OAuth 2.0 Client ID (Web application type)

4. Add Authorized redirect URI: https://documentos.rochasalesseguros.com.br/api/public/gmail-oauth-callback

5. Enable Gmail API at https://console.cloud.google.com/apis/library/gmail.googleapis.com

6. Scopes needed: https://www.googleapis.com/auth/gmail.send, https://www.googleapis.com/auth/userinfo.email