Files
calendar/packages/features/auth/lib/getServerSession.ts
T
Alex van AndelandGitHub d25c043046 chore: Remove all avatar/logo references (#14532)
* chore: Remove all avatar/logo references

* Updated user profile to only use avatarUrl

* fix: minor style issue

* chore: Remove redundant includeTeamLogo

* fix: Use right avatar default in event type list

* fix: placeholder avatar team profile, target

* chore: Add logoUrl/avatarUrl to JWT

* fix: Bunch of org avatar issues, fix members list

* Fix logoUrl on org pages

* More type fixes

* Hopefully final type fixes

* Another round of type fixes

* fix: UserForm ts

* fix: Handle as return types, not input types

* fix: Remove profile and add avatarUrl

* fix: notFound as const

* fix: Seeder avatarUrl params

* revert: Migration changes for easier recovery

* fix: Add explicit type to builder as avatar is now set

* Add logoUrl to unpublished entity

* Avatar test out of scope here

* fix: Use the new avatarUrl after save

* chore: Removed getOrgAvatarUrl/getTeamAvatarUrl

* fix: Update sidebar image immediately after change

* Unable to safe unnamed user, so default

* fix: Unpublished page, add organization test

* Add more tests
2024-04-18 21:54:16 -07:00

132 lines
3.5 KiB
TypeScript

import { LRUCache } from "lru-cache";
import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next";
import type { AuthOptions, Session } from "next-auth";
import { getToken } from "next-auth/jwt";
import checkLicense from "@calcom/features/ee/common/server/checkLicense";
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { UserRepository } from "@calcom/lib/server/repository/user";
import prisma from "@calcom/prisma";
const log = logger.getSubLogger({ prefix: ["getServerSession"] });
/**
* Stores the session in memory using the stringified token as the key.
*
*/
const CACHE = new LRUCache<string, Session>({ max: 1000 });
/**
* This is a slimmed down version of the `getServerSession` function from
* `next-auth`.
*
* Instead of requiring the entire options object for NextAuth, we create
* a compatible session using information from the incoming token.
*
* The downside to this is that we won't refresh sessions if the users
* token has expired (30 days). This should be fine as we call `/auth/session`
* frequently enough on the client-side to keep the session alive.
*/
export async function getServerSession(options: {
req: NextApiRequest | GetServerSidePropsContext["req"];
res?: NextApiResponse | GetServerSidePropsContext["res"];
authOptions?: AuthOptions;
}) {
const { req, authOptions: { secret } = {} } = options;
const token = await getToken({
req,
secret,
});
log.debug("Getting server session", safeStringify({ token }));
if (!token || !token.email || !token.sub) {
log.debug("Couldnt get token");
return null;
}
const cachedSession = CACHE.get(JSON.stringify(token));
if (cachedSession) {
log.debug("Returning cached session", safeStringify(cachedSession));
return cachedSession;
}
const userFromDb = await prisma.user.findUnique({
where: {
email: token.email.toLowerCase(),
},
});
if (!userFromDb) {
log.debug("No user found");
return null;
}
const hasValidLicense = await checkLicense(prisma);
let upId = token.upId;
if (!upId) {
upId = `usr-${userFromDb.id}`;
}
if (!upId) {
log.error("No upId found for session", { userId: userFromDb.id });
return null;
}
const user = await UserRepository.enrichUserWithTheProfile({
user: userFromDb,
upId,
});
const session: Session = {
hasValidLicense,
expires: new Date(typeof token.exp === "number" ? token.exp * 1000 : Date.now()).toISOString(),
user: {
id: user.id,
name: user.name,
username: user.username,
email: user.email,
emailVerified: user.emailVerified,
email_verified: user.emailVerified !== null,
role: user.role,
image: getUserAvatarUrl({
avatarUrl: user.avatarUrl,
}),
belongsToActiveTeam: token.belongsToActiveTeam,
org: token.org,
locale: user.locale ?? undefined,
profile: user.profile,
},
profileId: token.profileId,
upId,
};
if (token?.impersonatedBy?.id) {
const impersonatedByUser = await prisma.user.findUnique({
where: {
id: token.impersonatedBy.id,
},
select: {
id: true,
role: true,
},
});
if (impersonatedByUser) {
session.user.impersonatedBy = {
id: impersonatedByUser?.id,
role: impersonatedByUser.role,
};
}
}
CACHE.set(JSON.stringify(token), session);
log.debug("Returned session", safeStringify(session));
return session;
}