From cd8a75b316eff5bdcf87fe2ef96e37da67a04f11 Mon Sep 17 00:00:00 2001
From: Hariom Balhara <hariombalhara@gmail.com>
Date: Tue, 1 Nov 2022 12:00:08 +0530
Subject: [PATCH] Fix avatar infinite redirect (#5299)

* If due to some reason avatar URL is same as route, avoid infinite redirection by serving default

* Fix avatar reverting issue

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
---
 apps/web/pages/api/user/avatar.ts     | 11 ++++++++++-
 packages/trpc/server/createContext.ts |  3 ++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/apps/web/pages/api/user/avatar.ts b/apps/web/pages/api/user/avatar.ts
index 349b71588eb1af..7b751f41474f4a 100644
--- a/apps/web/pages/api/user/avatar.ts
+++ b/apps/web/pages/api/user/avatar.ts
@@ -1,6 +1,7 @@
 import crypto from "crypto";
 import type { NextApiRequest, NextApiResponse } from "next";
 
+import { CAL_URL, WEBAPP_URL } from "@calcom/lib/constants";
 import { getPlaceholderAvatar } from "@calcom/lib/getPlaceholderAvatar";
 import prisma from "@calcom/prisma";
 
@@ -11,6 +12,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
   const username = req.query.username as string;
   const teamname = req.query.teamname as string;
   let identity;
+  let linksToThisRoute = false;
   if (username) {
     const user = await prisma.user.findUnique({
       where: {
@@ -26,6 +28,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
       email: user?.email,
       avatar: user?.avatar,
     };
+    linksToThisRoute =
+      identity.avatar === `${CAL_URL}/${username}/avatar.png` ||
+      identity.avatar === `${WEBAPP_URL}/${username}/avatar.png`;
   } else if (teamname) {
     const team = await prisma.team.findUnique({
       where: {
@@ -40,6 +45,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
       shouldDefaultBeNameBased: true,
       avatar: team?.logo,
     };
+    linksToThisRoute =
+      identity.avatar === `${CAL_URL}/team/${teamname}/avatar.png` ||
+      identity.avatar === `${WEBAPP_URL}/team/${teamname}/avatar.png`;
   }
 
   const emailMd5 = crypto
@@ -47,7 +55,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
     .update((identity?.email as string) || "guest@example.com")
     .digest("hex");
   const img = identity?.avatar;
-  if (!img) {
+  // If image isn't set or links to this route itself, use default avatar
+  if (!img || linksToThisRoute) {
     let defaultSrc = defaultAvatarSrc({ md5: emailMd5 });
     if (identity?.shouldDefaultBeNameBased) {
       defaultSrc = getPlaceholderAvatar(null, identity.name);
diff --git a/packages/trpc/server/createContext.ts b/packages/trpc/server/createContext.ts
index 0abdc083b5ad86..6086564131c554 100644
--- a/packages/trpc/server/createContext.ts
+++ b/packages/trpc/server/createContext.ts
@@ -88,7 +88,8 @@ async function getUserFromSession({
     return null;
   }
   // This helps to prevent reaching the 4MB payload limit by avoiding base64 and instead passing the avatar url
-  if (user.avatar) user.avatar = `${CAL_URL}/${user.username}/avatar.png`;
+  // TODO: Setting avatar value to /avatar.png(which is a dynamic route) would actually reset the avatar because /avatar.png is supposed to return the value of user.avatar
+  // if (user.avatar) user.avatar = `${CAL_URL}/${user.username}/avatar.png`;
   const avatar = user.avatar || defaultAvatarSrc({ email });
 
   const locale = user.locale || getLocaleFromHeaders(req);