diff --git a/AGENTS.md b/AGENTS.md index 2d66844..eb0198a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -88,7 +88,26 @@ Biome is used (not ESLint). Config in `biome.json`: - `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL` - Auth core - `APP_BASE_URL` - Frontend URL for trusted origins - `CORS_ORIGIN` - Frontend URL for CORS policy +- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` - Google OAuth (see below) **Frontend** (`apps/frontend/.env`): - `VITE_*` prefix required (Vite embeds these at build time) - `VITE_API_BASE_URL` - Backend URL (default: http://localhost:3000) + +## Google OAuth + +To enable login with Google: + +1. Create OAuth credentials in Google Cloud Console: + - Application type: Web application + - Authorized redirect URI: `{BETTER_AUTH_URL}/api/auth/callback/google` + +2. Add env vars to `.env.example`: + ``` + GOOGLE_CLIENT_ID=your-google-client-id + GOOGLE_CLIENT_SECRET=your-google-client-secret + ``` + +3. The backend configures `socialProviders.google` automatically. + +4. Frontend uses `authClient.signIn.social({ provider: 'google', callbackURL: 'http://localhost:5173' })`. diff --git a/apps/backend/.env.example b/apps/backend/.env.example index 31461ae..1dceb75 100644 --- a/apps/backend/.env.example +++ b/apps/backend/.env.example @@ -12,3 +12,7 @@ SMTP_PORT=587 SMTP_USER=user@example.com SMTP_PASS=your-smtp-password SMTP_FROM=Playzer + +# Google OAuth +GOOGLE_CLIENT_ID=your-google-client-id +GOOGLE_CLIENT_SECRET=your-google-client-secret diff --git a/apps/backend/src/lib/auth.ts b/apps/backend/src/lib/auth.ts index 14ec802..83b70f7 100644 --- a/apps/backend/src/lib/auth.ts +++ b/apps/backend/src/lib/auth.ts @@ -17,7 +17,21 @@ export const auth = betterAuth({ emailAndPassword: { enabled: true, }, - trustedOrigins: [process.env.APP_BASE_URL ?? 'http://localhost:5173'], + socialProviders: { + google: { + clientId: process.env.GOOGLE_CLIENT_ID!, + clientSecret: process.env.GOOGLE_CLIENT_SECRET!, + }, + }, + advanced: { + generateUsername: async (data) => { + return `user_${Date.now()}`; + }, + }, + trustedOrigins: [ + process.env.APP_BASE_URL ?? 'http://localhost:5173', + process.env.BETTER_AUTH_URL ?? 'http://localhost:3000', + ], plugins: [openAPI()], }); diff --git a/apps/frontend/src/features/login/login-page.tsx b/apps/frontend/src/features/login/login-page.tsx index 5b4c7b5..425bcb9 100644 --- a/apps/frontend/src/features/login/login-page.tsx +++ b/apps/frontend/src/features/login/login-page.tsx @@ -1,6 +1,7 @@ import { Button } from '@/components/ui/button'; import { Field, FieldError, FieldLabel } from '@/components/ui/field'; import { Input } from '@/components/ui/input'; +import { authClient } from '@/lib/api-client'; import { useAuth } from '@/lib/auth'; import { zodResolver } from '@hookform/resolvers/zod'; import { Link, useNavigate } from '@tanstack/react-router'; @@ -48,6 +49,21 @@ export function LoginPage({ redirectTo = '/' }: LoginPageProps) { } }; + const handleGoogleSignIn = async () => { + setSubmitError(null); + + try { + await authClient.signIn.social({ + provider: 'google', + callbackURL: redirectTo.startsWith('http') + ? redirectTo + : `http://localhost:5173${redirectTo}`, + }); + } catch { + setSubmitError('No pudimos iniciar sesión con Google.'); + } + }; + return (
@@ -56,6 +72,37 @@ export function LoginPage({ redirectTo = '/' }: LoginPageProps) { Ingresá con tu cuenta para acceder a Home.

+ + +
+
+ +
+
+ O +
+
+
Email