Merge commit '31f3d9778e2e9465e194007a7063cd9859c00b33' into teste2e-multiSelectQuestion
commit
64635b7bb2
|
@ -5,6 +5,7 @@ import { z } from "zod";
|
||||||
|
|
||||||
import { getSession } from "@calcom/features/auth/lib/getSession";
|
import { getSession } from "@calcom/features/auth/lib/getSession";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
|
import type { Prisma } from "@calcom/prisma/client";
|
||||||
|
|
||||||
const teamIdschema = z.object({
|
const teamIdschema = z.object({
|
||||||
teamId: z.preprocess((a) => parseInt(z.string().parse(a), 10), z.number().positive()),
|
teamId: z.preprocess((a) => parseInt(z.string().parse(a), 10), z.number().positive()),
|
||||||
|
@ -63,11 +64,75 @@ export function checkUserIdentifier(creds: Partial<Credentials>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkPermission(session: Session | null) {
|
export function checkPermission(session: Session | null) {
|
||||||
if (session?.user.role !== "ADMIN" && process.env.NEXT_PUBLIC_TEAM_IMPERSONATION === "false") {
|
if (
|
||||||
|
(session?.user.role !== "ADMIN" && process.env.NEXT_PUBLIC_TEAM_IMPERSONATION === "false") ||
|
||||||
|
!session?.user
|
||||||
|
) {
|
||||||
throw new Error("You do not have permission to do this.");
|
throw new Error("You do not have permission to do this.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getImpersonatedUser({
|
||||||
|
session,
|
||||||
|
teamId,
|
||||||
|
creds,
|
||||||
|
}: {
|
||||||
|
session: Session | null;
|
||||||
|
teamId: number | undefined;
|
||||||
|
creds: Credentials | null;
|
||||||
|
}) {
|
||||||
|
let TeamWhereClause: Prisma.MembershipWhereInput = {
|
||||||
|
disableImpersonation: false, // Ensure they have impersonation enabled
|
||||||
|
accepted: true, // Ensure they are apart of the team and not just invited.
|
||||||
|
team: {
|
||||||
|
id: teamId, // Bring back only the right team
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// If you are an admin we dont need to follow this flow -> We can just follow the usual flow
|
||||||
|
// If orgId and teamId are the same we can follow the same flow
|
||||||
|
if (session?.user.org?.id && session.user.org.id !== teamId && session?.user.role !== "ADMIN") {
|
||||||
|
TeamWhereClause = {
|
||||||
|
disableImpersonation: false,
|
||||||
|
accepted: true,
|
||||||
|
team: {
|
||||||
|
id: session.user.org.id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user who is being impersonated
|
||||||
|
const impersonatedUser = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
OR: [{ username: creds?.username }, { email: creds?.username }],
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
role: true,
|
||||||
|
name: true,
|
||||||
|
email: true,
|
||||||
|
organizationId: true,
|
||||||
|
disableImpersonation: true,
|
||||||
|
locale: true,
|
||||||
|
teams: {
|
||||||
|
where: TeamWhereClause,
|
||||||
|
select: {
|
||||||
|
teamId: true,
|
||||||
|
disableImpersonation: true,
|
||||||
|
role: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!impersonatedUser) {
|
||||||
|
throw new Error("This user does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
return impersonatedUser;
|
||||||
|
}
|
||||||
|
|
||||||
const ImpersonationProvider = CredentialsProvider({
|
const ImpersonationProvider = CredentialsProvider({
|
||||||
id: "impersonation-auth",
|
id: "impersonation-auth",
|
||||||
name: "Impersonation",
|
name: "Impersonation",
|
||||||
|
@ -85,41 +150,7 @@ const ImpersonationProvider = CredentialsProvider({
|
||||||
checkUserIdentifier(creds);
|
checkUserIdentifier(creds);
|
||||||
checkPermission(session);
|
checkPermission(session);
|
||||||
|
|
||||||
// Get user who is being impersonated
|
const impersonatedUser = await getImpersonatedUser({ session, teamId, creds });
|
||||||
const impersonatedUser = await prisma.user.findFirst({
|
|
||||||
where: {
|
|
||||||
OR: [{ username: creds?.username }, { email: creds?.username }],
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
role: true,
|
|
||||||
name: true,
|
|
||||||
email: true,
|
|
||||||
organizationId: true,
|
|
||||||
disableImpersonation: true,
|
|
||||||
locale: true,
|
|
||||||
teams: {
|
|
||||||
where: {
|
|
||||||
disableImpersonation: false, // Ensure they have impersonation enabled
|
|
||||||
accepted: true, // Ensure they are apart of the team and not just invited.
|
|
||||||
team: {
|
|
||||||
id: teamId, // Bring back only the right team
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
teamId: true,
|
|
||||||
disableImpersonation: true,
|
|
||||||
role: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check if impersonating is allowed for this user
|
|
||||||
if (!impersonatedUser) {
|
|
||||||
throw new Error("This user does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session?.user.role === "ADMIN") {
|
if (session?.user.role === "ADMIN") {
|
||||||
if (impersonatedUser.disableImpersonation) {
|
if (impersonatedUser.disableImpersonation) {
|
||||||
|
|
|
@ -321,7 +321,7 @@ export default function MemberListItem(props: Props) {
|
||||||
onSubmit={async (e) => {
|
onSubmit={async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await signIn("impersonation-auth", {
|
await signIn("impersonation-auth", {
|
||||||
username: props.member.username || props.member.email,
|
username: props.member.email,
|
||||||
teamId: props.team.id,
|
teamId: props.team.id,
|
||||||
});
|
});
|
||||||
setShowImpersonateModal(false);
|
setShowImpersonateModal(false);
|
||||||
|
|
|
@ -27,7 +27,7 @@ export function ImpersonationMemberModal(props: { state: State; dispatch: Dispat
|
||||||
onSubmit={async (e) => {
|
onSubmit={async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await signIn("impersonation-auth", {
|
await signIn("impersonation-auth", {
|
||||||
username: user.username || user.email,
|
username: user.email,
|
||||||
teamId: teamId,
|
teamId: teamId,
|
||||||
});
|
});
|
||||||
props.dispatch({
|
props.dispatch({
|
||||||
|
|
|
@ -130,14 +130,15 @@ async function getInfoForAllTeams({ ctx, input }: GetOptions) {
|
||||||
|
|
||||||
// Get total team count across all teams the user is in (for pagination)
|
// Get total team count across all teams the user is in (for pagination)
|
||||||
|
|
||||||
const totalTeamMembers =
|
const totalTeamMembers = await prisma.$queryRaw<
|
||||||
await prisma.$queryRaw<number>`SELECT COUNT(DISTINCT "userId")::integer from "Membership" WHERE "teamId" IN (${Prisma.join(
|
{
|
||||||
teamIds
|
count: number;
|
||||||
)})`;
|
}[]
|
||||||
|
>`SELECT COUNT(DISTINCT "userId")::integer from "Membership" WHERE "teamId" IN (${Prisma.join(teamIds)})`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
teamMembers,
|
teamMembers,
|
||||||
totalTeamMembers,
|
totalTeamMembers: totalTeamMembers[0].count,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue