From f55d467f97c858babf12ecb34aff7075bdaff458 Mon Sep 17 00:00:00 2001 From: Sonny Date: Fri, 22 Dec 2023 13:46:03 +0100 Subject: [PATCH] feat: store avatar and user name --- .../migration.sql | 3 ++ prisma/schema.prisma | 8 ++-- src/lib/user/createUser.ts | 10 +++-- src/lib/user/getUserByProfileProvider.ts | 11 ------ src/lib/user/getUserByUserProvider.ts | 11 ++++++ src/lib/user/updateUser.ts | 14 ++++--- src/pages/api/auth/[...nextauth].ts | 38 ++++++++----------- src/types/types.d.ts | 14 +++++++ 8 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 prisma/migrations/20231222122307_add_name_and_image_field/migration.sql delete mode 100644 src/lib/user/getUserByProfileProvider.ts create mode 100644 src/lib/user/getUserByUserProvider.ts diff --git a/prisma/migrations/20231222122307_add_name_and_image_field/migration.sql b/prisma/migrations/20231222122307_add_name_and_image_field/migration.sql new file mode 100644 index 0000000..f616d38 --- /dev/null +++ b/prisma/migrations/20231222122307_add_name_and_image_field/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE `user` ADD COLUMN `name` VARCHAR(191) NULL AFTER `email`, + ADD COLUMN `image` VARCHAR(191) NULL AFTER `name`; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 350c520..2d5592a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -12,9 +12,11 @@ datasource db { } model User { - id Int @id @default(autoincrement()) - google_id String @unique - email String @unique + id Int @id @default(autoincrement()) + google_id String @unique + email String @unique + name String? + image String? categories Category[] links Link[] diff --git a/src/lib/user/createUser.ts b/src/lib/user/createUser.ts index 928c0c2..c5716dd 100644 --- a/src/lib/user/createUser.ts +++ b/src/lib/user/createUser.ts @@ -1,11 +1,13 @@ +import { User } from 'next-auth'; import prisma from 'utils/prisma'; -import { Profile } from 'next-auth'; -export default async function createUser(profile: Profile) { +export default async function createUser(user: User) { return await prisma.user.create({ data: { - email: profile.email, - google_id: profile.sub, + email: user.email, + google_id: user.id, + name: user.name, + image: user.image, }, }); } diff --git a/src/lib/user/getUserByProfileProvider.ts b/src/lib/user/getUserByProfileProvider.ts deleted file mode 100644 index 0546380..0000000 --- a/src/lib/user/getUserByProfileProvider.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Profile } from 'next-auth'; -import prisma from 'utils/prisma'; - -export default async function getUserByProfileProvider(profile: Profile) { - return await prisma.user.findFirst({ - where: { - google_id: profile.sub, - email: profile.email, - }, - }); -} diff --git a/src/lib/user/getUserByUserProvider.ts b/src/lib/user/getUserByUserProvider.ts new file mode 100644 index 0000000..6e3fa3d --- /dev/null +++ b/src/lib/user/getUserByUserProvider.ts @@ -0,0 +1,11 @@ +import { User } from 'next-auth'; +import prisma from 'utils/prisma'; + +export default async function getUserByUserProvider(user: User) { + return await prisma.user.findFirst({ + where: { + google_id: user.id, + email: user.email, + }, + }); +} diff --git a/src/lib/user/updateUser.ts b/src/lib/user/updateUser.ts index bd41d68..2758946 100644 --- a/src/lib/user/updateUser.ts +++ b/src/lib/user/updateUser.ts @@ -1,15 +1,17 @@ +import { User } from 'next-auth'; import prisma from '../../utils/prisma'; -import { Profile } from 'next-auth'; -export default async function updateUser(profile: Profile) { +export default async function updateUser(user: User) { return await prisma.user.update({ where: { - email: profile.email, - google_id: profile.sub, + email: user.email, + google_id: user.id, }, data: { - email: profile.email, - google_id: profile.sub, + email: user.email, + google_id: user.id, + name: user.name, + image: user.image, }, }); } diff --git a/src/pages/api/auth/[...nextauth].ts b/src/pages/api/auth/[...nextauth].ts index 598456f..ba41785 100644 --- a/src/pages/api/auth/[...nextauth].ts +++ b/src/pages/api/auth/[...nextauth].ts @@ -1,23 +1,17 @@ import PATHS from 'constants/paths'; -import NextAuth, { NextAuthOptions, Profile } from 'next-auth'; -import GoogleProvider from 'next-auth/providers/google'; -import getUserByProfileProvider from 'lib/user/getUserByProfileProvider'; import createUser from 'lib/user/createUser'; +import getUserByUserProvider from 'lib/user/getUserByUserProvider'; import updateUser from 'lib/user/updateUser'; +import NextAuth, { NextAuthOptions, User } from 'next-auth'; +import GoogleProvider from 'next-auth/providers/google'; import prisma from 'utils/prisma'; -const authLogger = (profile: Profile, ...args: any[]) => - console.log( - '[AUTH]', - profile.email, - `(${profile.name} - ${profile.sub})`, - ...args, - ); +const authLogger = (user: User, ...args: any[]) => + console.log('[AUTH]', user.email, `(${user.name} - ${user.id})`, ...args); const redirectUser = (errorKey: string) => `${PATHS.LOGIN}?error=${errorKey}`; const checkProvider = (provider: string) => provider === 'google'; -const checkAccountDataReceived = (profile: Profile) => - !!profile?.sub && !!profile?.email; +const checkAccountDataReceived = (user: User) => !!user?.id && !!user?.email; const cookieOptions = { sameSite: 'None', @@ -47,30 +41,30 @@ export const authOptions = { }); return user ? session : undefined; }, - async signIn({ account: accountParam, profile }) { + async signIn({ account: accountParam, user }) { if (!checkProvider(accountParam.provider)) { - authLogger(profile, 'rejected : forbidden provider'); + authLogger(user, 'rejected : forbidden provider'); return redirectUser('AUTH_REQUIRED'); } - if (!checkAccountDataReceived(profile)) { - authLogger(profile, 'rejected : missing data from provider', profile); + if (!checkAccountDataReceived(user)) { + authLogger(user, 'rejected : missing data from provider', user); return redirectUser('MISSING_PROVIDER_VALUES'); } try { - const isUserExists = await getUserByProfileProvider(profile); + const isUserExists = await getUserByUserProvider(user); if (isUserExists) { - await updateUser(profile); - authLogger(profile, 'success : user updated'); + await updateUser(user); + authLogger(user, 'success : user updated'); } else { - await createUser(profile); - authLogger(profile, 'success : user created'); + await createUser(user); + authLogger(user, 'success : user created'); } return true; } catch (error) { - authLogger(profile, 'rejected : unhandled error'); + authLogger(user, 'rejected : unhandled error'); console.error(error); return redirectUser('AUTH_ERROR'); } diff --git a/src/types/types.d.ts b/src/types/types.d.ts index 64887b3..d1e20ea 100644 --- a/src/types/types.d.ts +++ b/src/types/types.d.ts @@ -1,4 +1,5 @@ import { Category, User } from '@prisma/client'; +import { Profile } from 'next-auth'; export type CategoryWithLinks = Category & { author: User; @@ -23,3 +24,16 @@ export interface Favicon { type: string; size: number; } + +export interface GoogleProfile extends Profile { + iss: string; + azp: string; + aud: string; + email_verified: boolean; + at_hash: string; + picture: string; + given_name: string; + locale: string; + iat: number; + exp: number; +}