feat: store avatar and user name

This commit is contained in:
Sonny
2023-12-22 13:46:03 +01:00
committed by Sonny
parent 115ff3e2f8
commit f55d467f97
8 changed files with 63 additions and 46 deletions

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE `user` ADD COLUMN `name` VARCHAR(191) NULL AFTER `email`,
ADD COLUMN `image` VARCHAR(191) NULL AFTER `name`;

View File

@@ -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[]

View File

@@ -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,
},
});
}

View File

@@ -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,
},
});
}

View File

@@ -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,
},
});
}

View File

@@ -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,
},
});
}

View File

@@ -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');
}

14
src/types/types.d.ts vendored
View File

@@ -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;
}