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.
+
+
+
+