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.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`
|
- [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
|
- [ ] 3.4 `[haiku]` Create `src/app/api/auth/[...nextauth]/route.ts` exporting GET/POST handlers
|
||||||
|
|
||||||
## 4. Registration API
|
## 4. Registration API
|
||||||
|
|
|
||||||
49
src/auth.ts
49
src/auth.ts
|
|
@ -56,10 +56,57 @@ export const { handlers, auth, signIn, signOut } = NextAuth({
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
callbacks: {
|
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) {
|
if (user) {
|
||||||
|
// For credentials sign-in the authorize() function already returns the DB uuid as user.id
|
||||||
token.id = 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;
|
return token;
|
||||||
},
|
},
|
||||||
async session({ session, token }) {
|
async session({ session, token }) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue