@@ -25,21 +25,26 @@ export const authOptions: NextAuthOptions = {
2525 } ,
2626 callbacks : {
2727 async signIn ( { user, account, profile } ) {
28- // Allow Google sign-in for any domain
29- // Also, if signing in with Google and user has no image yet, save Google's avatar as default
30- try {
31- if ( account ?. provider === "google" ) {
32- const picture = ( profile as { picture ?: string } | null | undefined ) ?. picture
33- if ( user ?. id && picture ) {
34- const existing = await prisma . user . findUnique ( { where : { id : user . id } , select : { image : true } } )
35- if ( existing && ! existing . image ) {
36- await prisma . user . update ( { where : { id : user . id } , data : { image : picture } } )
28+ // For OAuth, prevent auto-creating accounts for unknown emails.
29+ // Send them to signup with an error instead of proceeding to restricted pages.
30+ if ( account ?. provider === "google" ) {
31+ const email = ( user ?. email || ( profile as { email ?: string } | null | undefined ) ?. email || "" ) . toLowerCase ( )
32+ if ( email ) {
33+ const existing = await prisma . user . findUnique ( { where : { email } } )
34+ if ( ! existing ) {
35+ // Abort sign-in and redirect to signup with error message
36+ return "/auth/signup/organization?error=no_account"
37+ }
38+ // Best-effort: sync Google avatar for existing users lacking image
39+ try {
40+ const picture = ( profile as { picture ?: string } | null | undefined ) ?. picture
41+ if ( ! existing . image && picture ) {
42+ await prisma . user . update ( { where : { id : existing . id } , data : { image : picture } } )
3743 }
44+ } catch ( e ) {
45+ console . warn ( "signIn avatar sync failed" , e )
3846 }
3947 }
40- } catch ( e ) {
41- // Non-blocking: even if this fails, we still allow the sign-in
42- console . warn ( "signIn avatar sync failed" , e )
4348 }
4449 return true ;
4550 } ,
0 commit comments