feat: add Google OAuth login with USER role and pending approval flow

- Add GET /api/auth/google and GET /api/auth/callback/google routes with CSRF state protection and account linking via googleId
- Add getPublicOrigin() for dynamic redirect_uri (supports reverse proxy via X-Forwarded-Proto)
- Add USER role to schema (default for new Google sign-ins), make password optional, add googleId and image fields
- Role-based redirect after login: USER → /profile, ADMIN/DEVELOPER → /dashboard
- Profile page shows pending approval alert for USER role
- Dashboard redirects USER role back to profile
- Login page shows specific error messages per OAuth error code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 15:06:13 +08:00
parent 9d80eb3b85
commit 94724a5081
9 changed files with 219 additions and 21 deletions

View File

@@ -1,13 +1,14 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useNavigate } from '@tanstack/react-router'
export type Role = | 'ADMIN' | 'DEVELOPER'
export type Role = 'USER' | 'ADMIN' | 'DEVELOPER'
export interface User {
id: string
name: string
email: string
role: Role
image?: string | null
}
async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
@@ -41,7 +42,7 @@ export function useLogin() {
}),
onSuccess: (data) => {
queryClient.setQueryData(['auth', 'session'], data)
navigate({ to: '/dashboard' })
navigate({ to: data.user.role === 'USER' ? '/profile' : '/dashboard' })
},
})
}