Task 3.3: Handle Google OAuth sign-in callback in src/auth.ts
- Add signIn callback: on Google sign-in, check users table by email; create new user (provider='google', provider_account_id, name/image from profile) if not found, or allow sign-in for returning users - Update jwt callback to look up DB uuid by email for Google sign-ins, so token.id is always the DB uuid rather than the Google sub ID - Mark task 3.3 as complete in tasks.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
40afd4111c
commit
a8c88f3ca2
2 changed files with 49 additions and 2 deletions
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
- [x] 3.1 `[sonnet]` Create `src/auth.ts` with Auth.js v5 config: JWT strategy, Credentials provider (email/password with bcryptjs verify), Google OAuth provider
|
||||
- [x] 3.2 `[sonnet]` Add JWT callback to embed `user.id` in token and session callback to expose `session.user.id`
|
||||
- [ ] 3.3 `[sonnet]` Handle Google OAuth sign-in callback: create user on first sign-in, find existing user on returning sign-in
|
||||
- [x] 3.3 `[sonnet]` Handle Google OAuth sign-in callback: create user on first sign-in, find existing user on returning sign-in
|
||||
- [ ] 3.4 `[haiku]` Create `src/app/api/auth/[...nextauth]/route.ts` exporting GET/POST handlers
|
||||
|
||||
## 4. Registration API
|
||||
|
|
|
|||
49
src/auth.ts
49
src/auth.ts
|
|
@ -56,10 +56,57 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
|
|||
}),
|
||||
],
|
||||
callbacks: {
|
||||
async jwt({ token, user }) {
|
||||
async signIn({ user, account, profile }) {
|
||||
// Only handle Google OAuth sign-ins here; credentials are handled in authorize()
|
||||
if (account?.provider === "google") {
|
||||
const email = profile?.email ?? user.email;
|
||||
if (!email) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [existingUser] = await db
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq(users.email, email))
|
||||
.limit(1);
|
||||
|
||||
if (!existingUser) {
|
||||
// First Google sign-in: create a new user record
|
||||
await db.insert(users).values({
|
||||
email,
|
||||
name: profile?.name ?? user.name ?? null,
|
||||
image: profile?.picture ?? (user.image ?? null),
|
||||
provider: "google",
|
||||
provider_account_id: account.providerAccountId,
|
||||
password_hash: null,
|
||||
});
|
||||
}
|
||||
// Returning Google sign-in: existing user found, allow sign-in
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
async jwt({ token, user, account }) {
|
||||
if (user) {
|
||||
// For credentials sign-in the authorize() function already returns the DB uuid as user.id
|
||||
token.id = user.id;
|
||||
}
|
||||
|
||||
// For Google sign-in, user.id is the Google sub ID, not our DB uuid.
|
||||
// Look up the DB record by email to get the correct uuid.
|
||||
if (account?.provider === "google" && token.email) {
|
||||
const [dbUser] = await db
|
||||
.select({ id: users.id })
|
||||
.from(users)
|
||||
.where(eq(users.email, token.email))
|
||||
.limit(1);
|
||||
|
||||
if (dbUser) {
|
||||
token.id = dbUser.id;
|
||||
}
|
||||
}
|
||||
|
||||
return token;
|
||||
},
|
||||
async session({ session, token }) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue