feat: avatar images

This commit is contained in:
Mythie
2024-06-27 21:50:42 +10:00
parent 5b4e6e530b
commit 22c02aac02
19 changed files with 546 additions and 47 deletions

View File

@ -0,0 +1,26 @@
import sharp from 'sharp';
import { prisma } from '@documenso/prisma';
export type GetAvatarImageOptions = {
id: string;
};
export const getAvatarImage = async ({ id }: GetAvatarImageOptions) => {
const avatarImage = await prisma.avatarImage.findFirst({
where: {
id,
},
});
if (!avatarImage) {
return null;
}
const bytes = Buffer.from(avatarImage.bytes, 'base64');
return {
contentType: 'image/jpeg',
content: await sharp(bytes).toFormat('jpeg').toBuffer(),
};
};

View File

@ -25,6 +25,7 @@ type PublicDirectLinkTemplate = Template & {
type BaseResponse = {
url: string;
name: string;
avatarImageId?: string | null;
badge?: {
type: 'Premium' | 'EarlySupporter';
since: Date;
@ -149,6 +150,7 @@ export const getPublicProfileByUrl = async ({
badge,
profile: user.profile,
url: profileUrl,
avatarImageId: user.avatarImageId,
name: user.name || '',
templates: user.Template.filter(
(template): template is PublicDirectLinkTemplate =>
@ -166,6 +168,7 @@ export const getPublicProfileByUrl = async ({
},
profile: team.profile,
url: profileUrl,
avatarImageId: team.avatarImageId,
name: team.name || '',
templates: team.templates.filter(
(template): template is PublicDirectLinkTemplate =>

View File

@ -0,0 +1,106 @@
import sharp from 'sharp';
import { prisma } from '@documenso/prisma';
import type { RequestMetadata } from '../../universal/extract-request-metadata';
export type SetAvatarImageOptions = {
userId: number;
teamId?: number | null;
bytes?: string | null;
requestMetadata?: RequestMetadata;
};
export const setAvatarImage = async ({
userId,
teamId,
bytes,
requestMetadata,
}: SetAvatarImageOptions) => {
let oldAvatarImageId: string | null = null;
const user = await prisma.user.findUnique({
where: {
id: userId,
},
include: {
avatarImage: true,
},
});
if (!user) {
throw new Error('User not found');
}
oldAvatarImageId = user.avatarImageId;
if (teamId) {
const team = await prisma.team.findFirst({
where: {
id: teamId,
members: {
some: {
userId,
},
},
},
});
if (!team) {
throw new Error('Team not found');
}
oldAvatarImageId = team.avatarImageId;
}
if (oldAvatarImageId) {
await prisma.avatarImage.delete({
where: {
id: oldAvatarImageId,
},
});
}
let newAvatarImageId: string | null = null;
if (bytes) {
const optimisedBytes = await sharp(Buffer.from(bytes, 'base64'))
.resize(512, 512)
.toFormat('jpeg', { quality: 75 })
.toBuffer();
const avatarImage = await prisma.avatarImage.create({
data: {
bytes: optimisedBytes.toString('base64'),
},
});
newAvatarImageId = avatarImage.id;
}
if (teamId) {
await prisma.team.update({
where: {
id: teamId,
},
data: {
avatarImageId: newAvatarImageId,
},
});
// TODO: Audit Logs
} else {
await prisma.user.update({
where: {
id: userId,
},
data: {
avatarImageId: newAvatarImageId,
},
});
// TODO: Audit Logs
}
return newAvatarImageId;
};