fix: payload cleanup (#13552)
* fix: payload cleanup * Update eventType.ts * Send whitelisted fields everywhere * Removed a user select * Removed extra usage of users * Put back user field with fewer selects * Added user pick * Removed more users selects * Another select removal --------- Co-authored-by: Hariom <hariombalhara@gmail.com> Co-authored-by: Keith Williams <keithwillcode@gmail.com>
This commit is contained in:
co-authored by
Hariom
Keith Williams
parent
bba68e09a9
commit
66b5dfd796
@@ -51,7 +51,6 @@ export async function getHandler(req: NextApiRequest) {
|
||||
include: {
|
||||
customInputs: true,
|
||||
team: { select: { slug: true } },
|
||||
users: true,
|
||||
hosts: { select: { userId: true, isFixed: true } },
|
||||
owner: { select: { username: true, id: true } },
|
||||
children: { select: { id: true, userId: true } },
|
||||
|
||||
@@ -56,7 +56,6 @@ async function getHandler(req: NextApiRequest) {
|
||||
include: {
|
||||
customInputs: true,
|
||||
team: { select: { slug: true } },
|
||||
users: true,
|
||||
hosts: { select: { userId: true, isFixed: true } },
|
||||
owner: { select: { username: true, id: true } },
|
||||
children: { select: { id: true, userId: true } },
|
||||
|
||||
@@ -59,7 +59,6 @@ async function getHandler(req: NextApiRequest) {
|
||||
include: {
|
||||
customInputs: true,
|
||||
team: { select: { slug: true } },
|
||||
users: true,
|
||||
hosts: { select: { userId: true, isFixed: true } },
|
||||
owner: { select: { username: true, id: true } },
|
||||
children: { select: { id: true, userId: true } },
|
||||
|
||||
@@ -24,7 +24,12 @@ export const responseHandler = async ({ ctx, input }: ResponseHandlerOptions) =>
|
||||
id: formId,
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!form) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { OrderedResponses } from "../types/types";
|
||||
import type { Response, SerializableForm } from "../types/types";
|
||||
|
||||
export async function onFormSubmission(
|
||||
form: Ensure<SerializableForm<App_RoutingForms_Form> & { user: User }, "fields">,
|
||||
form: Ensure<SerializableForm<App_RoutingForms_Form> & { user: Pick<User, "id" | "email"> }, "fields">,
|
||||
response: Response
|
||||
) {
|
||||
const fieldResponsesByName: Record<
|
||||
|
||||
@@ -57,8 +57,6 @@ const Reschedule = async (bookingUid: string, cancellationReason: string) => {
|
||||
const event = await prisma.eventType.findFirstOrThrow({
|
||||
select: {
|
||||
title: true,
|
||||
users: true,
|
||||
schedulingType: true,
|
||||
},
|
||||
where: {
|
||||
id: bookingToReschedule.eventTypeId,
|
||||
|
||||
@@ -57,7 +57,6 @@ const Reschedule = async (bookingUid: string, cancellationReason: string) => {
|
||||
const event = await prisma.eventType.findFirstOrThrow({
|
||||
select: {
|
||||
title: true,
|
||||
users: true,
|
||||
schedulingType: true,
|
||||
},
|
||||
where: {
|
||||
|
||||
@@ -47,7 +47,7 @@ const loginWithTotp = async (user: { email: string }) =>
|
||||
|
||||
type UserTeams = {
|
||||
teams: (Membership & {
|
||||
team: Team;
|
||||
team: Pick<Team, "metadata">;
|
||||
})[];
|
||||
};
|
||||
|
||||
@@ -106,7 +106,9 @@ const providers: Provider[] = [
|
||||
throw new Error(ErrorCode.InternalServerError);
|
||||
}
|
||||
|
||||
const user = await UserRepository.findByEmailAndIncludeProfiles({ email: credentials.email });
|
||||
const user = await UserRepository.findByEmailAndIncludeProfilesAndPassword({
|
||||
email: credentials.email,
|
||||
});
|
||||
// Don't leak information about it being username or password that is invalid
|
||||
if (!user) {
|
||||
throw new Error(ErrorCode.IncorrectEmailPassword);
|
||||
@@ -273,7 +275,9 @@ if (isSAMLLoginEnabled) {
|
||||
email?: string;
|
||||
locale?: string;
|
||||
}) => {
|
||||
const user = await UserRepository.findByEmailAndIncludeProfiles({ email: profile.email || "" });
|
||||
const user = await UserRepository.findByEmailAndIncludeProfilesAndPassword({
|
||||
email: profile.email || "",
|
||||
});
|
||||
if (!user) {
|
||||
throw new Error(ErrorCode.UserNotFound);
|
||||
}
|
||||
@@ -339,7 +343,7 @@ if (isSAMLLoginEnabled) {
|
||||
}
|
||||
|
||||
const { id, firstName, lastName, email } = userInfo;
|
||||
const user = await UserRepository.findByEmailAndIncludeProfiles({ email });
|
||||
const user = await UserRepository.findByEmailAndIncludeProfilesAndPassword({ email });
|
||||
if (!user) {
|
||||
throw new Error(ErrorCode.UserNotFound);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Prisma, EventType as PrismaEventType } from "@prisma/client";
|
||||
import type { EventType as PrismaEventType } from "@prisma/client";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
@@ -22,6 +23,16 @@ type IEventType = Ensure<
|
||||
"title" | "slug" | "length"
|
||||
>;
|
||||
|
||||
const userSelect = Prisma.validator<Prisma.UserSelect>()({
|
||||
name: true,
|
||||
avatarUrl: true,
|
||||
username: true,
|
||||
id: true,
|
||||
email: true,
|
||||
locale: true,
|
||||
defaultScheduleId: true,
|
||||
});
|
||||
|
||||
export class EventTypeRepository {
|
||||
static async create(data: IEventType) {
|
||||
const {
|
||||
@@ -92,19 +103,23 @@ export class EventTypeRepository {
|
||||
// TODO: As required by getByViewHandler - Make it configurable
|
||||
team: {
|
||||
include: {
|
||||
eventTypes: true,
|
||||
eventTypes: {
|
||||
include: {
|
||||
users: { select: userSelect },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
hashedLink: true,
|
||||
users: true,
|
||||
users: { select: userSelect },
|
||||
children: {
|
||||
include: {
|
||||
users: true,
|
||||
users: { select: userSelect },
|
||||
},
|
||||
},
|
||||
hosts: {
|
||||
include: {
|
||||
user: true,
|
||||
user: { select: userSelect },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { Prisma, MembershipRole } from "@calcom/prisma/client";
|
||||
import type { MembershipRole } from "@calcom/prisma/client";
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
|
||||
import logger from "../../logger";
|
||||
import { safeStringify } from "../../safeStringify";
|
||||
@@ -14,6 +15,33 @@ type IMembership = {
|
||||
role: MembershipRole;
|
||||
};
|
||||
|
||||
const membershipSelect = Prisma.validator<Prisma.MembershipSelect>()({
|
||||
id: true,
|
||||
teamId: true,
|
||||
userId: true,
|
||||
accepted: true,
|
||||
role: true,
|
||||
disableImpersonation: true,
|
||||
});
|
||||
|
||||
const teamParentSelect = Prisma.validator<Prisma.TeamSelect>()({
|
||||
id: true,
|
||||
name: true,
|
||||
slug: true,
|
||||
logoUrl: true,
|
||||
parentId: true,
|
||||
});
|
||||
|
||||
const userSelect = Prisma.validator<Prisma.UserSelect>()({
|
||||
name: true,
|
||||
avatarUrl: true,
|
||||
username: true,
|
||||
id: true,
|
||||
email: true,
|
||||
locale: true,
|
||||
defaultScheduleId: true,
|
||||
});
|
||||
|
||||
export class MembershipRepository {
|
||||
static async create(data: IMembership) {
|
||||
return await prisma.membership.create({
|
||||
@@ -68,25 +96,33 @@ export class MembershipRepository {
|
||||
include: {
|
||||
team: {
|
||||
include: {
|
||||
members: true,
|
||||
parent: true,
|
||||
members: {
|
||||
select: membershipSelect,
|
||||
},
|
||||
parent: {
|
||||
select: teamParentSelect,
|
||||
},
|
||||
eventTypes: {
|
||||
include: {
|
||||
team: {
|
||||
include: {
|
||||
eventTypes: true,
|
||||
eventTypes: {
|
||||
include: {
|
||||
users: { select: userSelect },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
hashedLink: true,
|
||||
users: true,
|
||||
hosts: {
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
},
|
||||
users: { select: userSelect },
|
||||
children: {
|
||||
include: {
|
||||
users: true,
|
||||
users: { select: userSelect },
|
||||
},
|
||||
},
|
||||
hosts: {
|
||||
include: {
|
||||
user: { select: userSelect },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ import { v4 as uuidv4 } from "uuid";
|
||||
import { whereClauseForOrgWithSlugOrRequestedSlug } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
import type { Team } from "@calcom/prisma/client";
|
||||
import type { UpId, UserAsPersonalProfile, UserProfile } from "@calcom/types/UserProfile";
|
||||
|
||||
@@ -11,6 +12,28 @@ import logger from "../../logger";
|
||||
import { getParsedTeam } from "./teamUtils";
|
||||
import { UserRepository } from "./user";
|
||||
|
||||
const userSelect = Prisma.validator<Prisma.UserSelect>()({
|
||||
name: true,
|
||||
avatarUrl: true,
|
||||
username: true,
|
||||
id: true,
|
||||
email: true,
|
||||
locale: true,
|
||||
defaultScheduleId: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
bufferTime: true,
|
||||
});
|
||||
|
||||
const membershipSelect = Prisma.validator<Prisma.MembershipSelect>()({
|
||||
id: true,
|
||||
teamId: true,
|
||||
userId: true,
|
||||
accepted: true,
|
||||
role: true,
|
||||
disableImpersonation: true,
|
||||
});
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["repository/profile"] });
|
||||
const organizationSelect = {
|
||||
id: true,
|
||||
@@ -30,14 +53,17 @@ export class ProfileRepository {
|
||||
return uuidv4();
|
||||
}
|
||||
|
||||
private static getInheritedDataFromUser({ user }: { user: PrismaUser }) {
|
||||
private static getInheritedDataFromUser({
|
||||
user,
|
||||
}: {
|
||||
user: Pick<PrismaUser, "name" | "avatarUrl" | "startTime" | "endTime" | "bufferTime">;
|
||||
}) {
|
||||
return {
|
||||
name: user.name,
|
||||
avatarUrl: user.avatarUrl,
|
||||
startTime: user.startTime,
|
||||
endTime: user.endTime,
|
||||
bufferTime: user.bufferTime,
|
||||
avatar: user.avatar,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -233,7 +259,9 @@ export class ProfileRepository {
|
||||
organization: {
|
||||
select: organizationSelect,
|
||||
},
|
||||
user: true,
|
||||
user: {
|
||||
select: userSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -268,7 +296,9 @@ export class ProfileRepository {
|
||||
organization: {
|
||||
select: organizationSelect,
|
||||
},
|
||||
user: true,
|
||||
user: {
|
||||
select: userSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
return profile;
|
||||
@@ -313,11 +343,15 @@ export class ProfileRepository {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
user: {
|
||||
select: userSelect,
|
||||
},
|
||||
movedFromUser: true,
|
||||
organization: {
|
||||
include: {
|
||||
members: true,
|
||||
members: {
|
||||
select: membershipSelect,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -346,7 +380,9 @@ export class ProfileRepository {
|
||||
organization: whereClauseForOrgWithSlugOrRequestedSlug(orgSlug),
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
user: {
|
||||
select: userSelect,
|
||||
},
|
||||
organization: {
|
||||
select: organizationSelect,
|
||||
},
|
||||
@@ -416,7 +452,9 @@ export class ProfileRepository {
|
||||
organizationId,
|
||||
},
|
||||
include: {
|
||||
user: true,
|
||||
user: {
|
||||
select: userSelect,
|
||||
},
|
||||
organization: {
|
||||
select: organizationSelect,
|
||||
},
|
||||
@@ -434,7 +472,9 @@ export class ProfileRepository {
|
||||
organization: {
|
||||
select: organizationSelect,
|
||||
},
|
||||
user: true,
|
||||
user: {
|
||||
select: userSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!profile) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import type { z } from "zod";
|
||||
|
||||
import { whereClauseForOrgWithSlugOrRequestedSlug } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
@@ -148,12 +148,23 @@ export async function getOrg<TeamSelect extends Prisma.TeamSelect>({
|
||||
teamSelect,
|
||||
});
|
||||
}
|
||||
|
||||
const teamSelect = Prisma.validator<Prisma.TeamSelect>()({
|
||||
id: true,
|
||||
name: true,
|
||||
slug: true,
|
||||
logoUrl: true,
|
||||
parentId: true,
|
||||
metadata: true,
|
||||
});
|
||||
|
||||
export class TeamRepository {
|
||||
static async findById({ id }: { id: number }) {
|
||||
const team = await prisma.team.findUnique({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
select: teamSelect,
|
||||
});
|
||||
if (!team) {
|
||||
return null;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { whereClauseForOrgWithSlugOrRequestedSlug } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { User as UserType, Prisma } from "@calcom/prisma/client";
|
||||
import { Prisma } from "@calcom/prisma/client";
|
||||
import type { User as UserType } from "@calcom/prisma/client";
|
||||
import type { UpId, UserProfile } from "@calcom/types/UserProfile";
|
||||
|
||||
import { isOrganization } from "../../entityPermissionUtils";
|
||||
@@ -12,6 +13,54 @@ import { getParsedTeam } from "./teamUtils";
|
||||
const log = logger.getSubLogger({ prefix: ["[repository/user]"] });
|
||||
|
||||
export const ORGANIZATION_ID_UNKNOWN = "ORGANIZATION_ID_UNKNOWN";
|
||||
|
||||
const teamSelect = Prisma.validator<Prisma.TeamSelect>()({
|
||||
id: true,
|
||||
name: true,
|
||||
slug: true,
|
||||
metadata: true,
|
||||
logoUrl: true,
|
||||
});
|
||||
|
||||
const userSelect = Prisma.validator<Prisma.UserSelect>()({
|
||||
id: true,
|
||||
username: true,
|
||||
name: true,
|
||||
email: true,
|
||||
emailVerified: true,
|
||||
bio: true,
|
||||
avatar: true,
|
||||
avatarUrl: true,
|
||||
timeZone: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
weekStart: true,
|
||||
bufferTime: true,
|
||||
hideBranding: true,
|
||||
theme: true,
|
||||
createdDate: true,
|
||||
trialEndsAt: true,
|
||||
completedOnboarding: true,
|
||||
locale: true,
|
||||
timeFormat: true,
|
||||
twoFactorSecret: true,
|
||||
twoFactorEnabled: true,
|
||||
backupCodes: true,
|
||||
identityProviderId: true,
|
||||
invitedTo: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
away: true,
|
||||
allowDynamicBooking: true,
|
||||
allowSEOIndexing: true,
|
||||
receiveMonthlyDigestEmail: true,
|
||||
verified: true,
|
||||
disableImpersonation: true,
|
||||
locked: true,
|
||||
movedToProfileId: true,
|
||||
metadata: true,
|
||||
});
|
||||
|
||||
export class UserRepository {
|
||||
static async findTeamsByUserId({ userId }: { userId: UserType["id"] }) {
|
||||
const teamMemberships = await prisma.membership.findMany({
|
||||
@@ -19,7 +68,9 @@ export class UserRepository {
|
||||
userId: userId,
|
||||
},
|
||||
include: {
|
||||
team: true,
|
||||
team: {
|
||||
select: teamSelect,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -69,6 +120,7 @@ export class UserRepository {
|
||||
|
||||
return (
|
||||
await prisma.user.findMany({
|
||||
select: userSelect,
|
||||
where,
|
||||
})
|
||||
).map((user) => {
|
||||
@@ -136,7 +188,7 @@ export class UserRepository {
|
||||
return { where, profiles };
|
||||
}
|
||||
|
||||
static async findByEmailAndIncludeProfiles({ email }: { email: string }) {
|
||||
static async findByEmailAndIncludeProfilesAndPassword({ email }: { email: string }) {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
email: email.toLowerCase(),
|
||||
@@ -157,7 +209,9 @@ export class UserRepository {
|
||||
locale: true,
|
||||
teams: {
|
||||
include: {
|
||||
team: true,
|
||||
team: {
|
||||
select: teamSelect,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -179,6 +233,7 @@ export class UserRepository {
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
select: userSelect,
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
|
||||
@@ -100,7 +100,11 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
|
||||
schedulingType: SchedulingType.COLLECTIVE,
|
||||
},
|
||||
select: {
|
||||
users: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -127,7 +127,6 @@ export const requestRescheduleHandler = async ({ ctx, input }: RequestReschedule
|
||||
event = await prisma.eventType.findFirstOrThrow({
|
||||
select: {
|
||||
title: true,
|
||||
users: true,
|
||||
schedulingType: true,
|
||||
recurringEvent: true,
|
||||
},
|
||||
|
||||
@@ -32,7 +32,11 @@ export const duplicateHandler = async ({ ctx, input }: DuplicateOptions) => {
|
||||
include: {
|
||||
customInputs: true,
|
||||
schedule: true,
|
||||
users: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
team: true,
|
||||
workflows: true,
|
||||
webhooks: true,
|
||||
|
||||
@@ -20,7 +20,11 @@ export const eventOwnerProcedure = authedProcedure
|
||||
const event = await ctx.prisma.eventType.findUnique({
|
||||
where: { id: input.id },
|
||||
include: {
|
||||
users: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
team: {
|
||||
select: {
|
||||
members: {
|
||||
|
||||
@@ -29,7 +29,14 @@ export const paymentsRouter = router({
|
||||
},
|
||||
include: {
|
||||
payment: true,
|
||||
user: true,
|
||||
user: {
|
||||
select: {
|
||||
email: true,
|
||||
locale: true,
|
||||
name: true,
|
||||
timeZone: true,
|
||||
},
|
||||
},
|
||||
attendees: true,
|
||||
eventType: true,
|
||||
},
|
||||
|
||||
@@ -147,7 +147,11 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
|
||||
id: newEventTypeId,
|
||||
},
|
||||
include: {
|
||||
users: true,
|
||||
users: {
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
},
|
||||
team: {
|
||||
include: {
|
||||
members: true,
|
||||
|
||||
Reference in New Issue
Block a user