diff --git a/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts b/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts index 6f59810d13..40b81b597e 100644 --- a/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts +++ b/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts @@ -2,15 +2,34 @@ import { oauth2_v2 } from "@googleapis/oauth2"; import type { OAuth2Client } from "googleapis-common"; import logger from "@calcom/lib/logger"; +import { uploadAvatar } from "@calcom/lib/server/avatar"; import { UserRepository } from "@calcom/lib/server/repository/user"; +import { resizeBase64Image } from "@calcom/lib/server/resizeBase64Image"; export async function updateProfilePhotoGoogle(oAuth2Client: OAuth2Client, userId: number) { try { const oauth2 = new oauth2_v2.Oauth2({ auth: oAuth2Client }); const userDetails = await oauth2.userinfo.get(); - if (userDetails.data?.picture) { - await UserRepository.updateAvatar({ id: userId, avatarUrl: userDetails.data.picture }); + const avatarUrl = userDetails.data?.picture; + if (!avatarUrl) { + return; } + + // Handle base64 data + if ( + avatarUrl.startsWith("data:image/png;base64,") || + avatarUrl.startsWith("data:image/jpeg;base64,") || + avatarUrl.startsWith("data:image/jpg;base64,") + ) { + const resizedAvatarUrl = await uploadAvatar({ + avatar: await resizeBase64Image(avatarUrl), + userId, + }); + await UserRepository.updateAvatar({ id: userId, avatarUrl: resizedAvatarUrl }); + return; + } + + await UserRepository.updateAvatar({ id: userId, avatarUrl }); } catch (error) { logger.error("Error updating avatarUrl from google calendar connect", error); } diff --git a/packages/app-store/googlecalendar/api/callback.ts b/packages/app-store/googlecalendar/api/callback.ts index 9d9d545a90..85c3ba0be6 100644 --- a/packages/app-store/googlecalendar/api/callback.ts +++ b/packages/app-store/googlecalendar/api/callback.ts @@ -4,7 +4,12 @@ import type { NextApiRequest, NextApiResponse } from "next"; import GoogleCalendarService from "@calcom/app-store/googlecalendar/lib/CalendarService"; import { renewSelectedCalendarCredentialId } from "@calcom/lib/connectedCalendar"; -import { GOOGLE_CALENDAR_SCOPES, WEBAPP_URL, WEBAPP_URL_FOR_OAUTH } from "@calcom/lib/constants"; +import { + GOOGLE_CALENDAR_SCOPES, + SCOPE_USERINFO_PROFILE, + WEBAPP_URL, + WEBAPP_URL_FOR_OAUTH, +} from "@calcom/lib/constants"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import { HttpError } from "@calcom/lib/http-error"; import { defaultHandler } from "@calcom/lib/server/defaultHandler"; @@ -14,6 +19,7 @@ import { Prisma } from "@calcom/prisma/client"; import getInstalledAppPath from "../../_utils/getInstalledAppPath"; import { decodeOAuthState } from "../../_utils/oauth/decodeOAuthState"; +import { updateProfilePhotoGoogle } from "../../_utils/oauth/updateProfilePhotoGoogle"; import { getGoogleAppKeys } from "../lib/getGoogleAppKeys"; async function getHandler(req: NextApiRequest, res: NextApiResponse) { @@ -95,10 +101,9 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) { } // Only attempt to update the user's profile photo if the user has granted the required scope - // TODO: Use the avatarUrl when setting the profile picture - // if (grantedScopes.includes(SCOPE_USERINFO_PROFILE)) { - // await updateProfilePhotoGoogle(oAuth2Client, req.session.user.id); - // } + if (grantedScopes.includes(SCOPE_USERINFO_PROFILE)) { + await updateProfilePhotoGoogle(oAuth2Client, req.session.user.id); + } const selectedCalendarWhereUnique = { userId: req.session.user.id, diff --git a/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts b/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts index ae92ff9ca4..1d93cdfade 100644 --- a/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts +++ b/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts @@ -152,7 +152,12 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) } // if defined AND a base 64 string, upload and update the avatar URL - if (input.avatarUrl && input.avatarUrl.startsWith("data:image/png;base64,")) { + if ( + input.avatarUrl && + (input.avatarUrl.startsWith("data:image/png;base64,") || + input.avatarUrl.startsWith("data:image/jpeg;base64,") || + input.avatarUrl.startsWith("data:image/jpg;base64,")) + ) { data.avatarUrl = await uploadAvatar({ avatar: await resizeBase64Image(input.avatarUrl), userId: user.id, diff --git a/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts b/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts index 2e8150b7b3..ae8d6f4171 100644 --- a/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts @@ -119,7 +119,12 @@ export const updateUserHandler = async ({ ctx, input }: UpdateUserOptions) => { timeZone: input.timeZone, }; - if (input.avatar && input.avatar.startsWith("data:image/png;base64,")) { + if ( + input.avatar && + (input.avatar.startsWith("data:image/png;base64,") || + input.avatar.startsWith("data:image/jpeg;base64,") || + input.avatar.startsWith("data:image/jpg;base64,")) + ) { const avatar = await resizeBase64Image(input.avatar); data.avatarUrl = await uploadAvatar({ avatar, diff --git a/packages/trpc/server/routers/viewer/teams/create.handler.ts b/packages/trpc/server/routers/viewer/teams/create.handler.ts index 1f06448f9c..96f0e551cc 100644 --- a/packages/trpc/server/routers/viewer/teams/create.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/create.handler.ts @@ -106,7 +106,12 @@ export const createHandler = async ({ ctx, input }: CreateOptions) => { }, }); // Upload logo, create doesn't allow logo removal - if (input.logo && input.logo.startsWith("data:image/png;base64,")) { + if ( + input.logo && + (input.logo.startsWith("data:image/png;base64,") || + input.logo.startsWith("data:image/jpeg;base64,") || + input.logo.startsWith("data:image/jpg;base64,")) + ) { const logoUrl = await uploadLogo({ logo: await resizeBase64Image(input.logo), teamId: createdTeam.id, diff --git a/packages/trpc/server/routers/viewer/teams/update.handler.ts b/packages/trpc/server/routers/viewer/teams/update.handler.ts index 6b525e6b6a..75dd5d92f1 100644 --- a/packages/trpc/server/routers/viewer/teams/update.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/update.handler.ts @@ -70,7 +70,12 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => { rrTimestampBasis: input.rrTimestampBasis, }; - if (input.logo && input.logo.startsWith("data:image/png;base64,")) { + if ( + input.logo && + (input.logo.startsWith("data:image/png;base64,") || + input.logo.startsWith("data:image/jpeg;base64,") || + input.logo.startsWith("data:image/jpg;base64,")) + ) { data.logoUrl = await uploadLogo({ teamId: input.id, logo: input.logo }); } else if (typeof input.logo !== "undefined" && !input.logo) { data.logoUrl = null;