fix: team invite links (#10110)

This commit is contained in:
Omar López 2023-07-12 14:24:47 -07:00 committed by GitHub
parent a1f9012501
commit 9b37d65503
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 15 deletions

View File

@ -6,7 +6,6 @@ import type { SubmitHandler } from "react-hook-form";
import { FormProvider, useForm } from "react-hook-form";
import { z } from "zod";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername";
import { getOrgFullDomain } from "@calcom/features/ee/organizations/lib/orgDomains";
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
@ -83,7 +82,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
};
return (
<LicenseRequired>
<>
<div
className="bg-muted flex min-h-screen flex-col justify-center "
style={
@ -166,7 +165,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
</div>
</div>
</div>
</LicenseRequired>
</>
);
}

View File

@ -79,11 +79,12 @@ export async function getTeamWithMembers(id?: number, slug?: string, userId?: nu
...baseEventTypeSelect,
},
},
inviteToken: {
inviteTokens: {
select: {
token: true,
expires: true,
expiresInDays: true,
identifier: true,
},
},
});
@ -114,7 +115,16 @@ export async function getTeamWithMembers(id?: number, slug?: string, userId?: nu
...eventType,
metadata: EventTypeMetaDataSchema.parse(eventType.metadata),
}));
return { ...team, metadata: teamMetadataSchema.parse(team.metadata), eventTypes, members };
/** Don't leak invite tokens to the frontend */
const { inviteTokens, ...teamWithoutInviteTokens } = team;
return {
...teamWithoutInviteTokens,
/** To prevent breaking we only return non-email attached token here, if we have one */
inviteToken: inviteTokens.find((token) => token.identifier === "invite-link-for-teamId-" + team.id),
metadata: teamMetadataSchema.parse(team.metadata),
eventTypes,
members,
};
}
// also returns team

View File

@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "VerificationToken_teamId_key";

View File

@ -270,7 +270,7 @@ model Team {
parent Team? @relation("organization", fields: [parentId], references: [id], onDelete: Cascade)
children Team[] @relation("organization")
orgUsers User[] @relation("scope")
inviteToken VerificationToken?
inviteTokens VerificationToken[]
webhooks Webhook[]
timeFormat Int?
timeZone String @default("Europe/London")
@ -310,7 +310,7 @@ model VerificationToken {
expiresInDays Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
teamId Int? @unique
teamId Int?
team Team? @relation(fields: [teamId], references: [id])
@@unique([identifier, token])

View File

@ -22,7 +22,7 @@ export const createInviteHandler = async ({ ctx, input }: CreateInviteOptions) =
const token = randomBytes(32).toString("hex");
await prisma.verificationToken.create({
data: {
identifier: "",
identifier: "invite-link-for-teamId-" + teamId,
token,
expires: new Date(),
teamId,

View File

@ -26,20 +26,22 @@ export const listHandler = async ({ ctx }: ListOptions) => {
include: {
team: {
include: {
inviteToken: true,
inviteTokens: true,
},
},
},
orderBy: { role: "desc" },
});
const isOrgAdmin = !!(await isOrganisationAdmin(ctx.user.id, ctx.user?.organization?.id ?? -1)); // Org id exists here as we're inside a conditional TS complaining for some reason
const isOrgAdmin = !!(await isOrganisationAdmin(ctx.user.id, ctx.user.organization.id)); // Org id exists here as we're inside a conditional TS complaining for some reason
return membershipsWithoutParent.map(({ team, ...membership }) => ({
return membershipsWithoutParent.map(({ team: { inviteTokens, ..._team }, ...membership }) => ({
role: membership.role,
accepted: membership.accepted,
isOrgAdmin,
...team,
..._team,
/** To prevent breaking we only return non-email attached token here, if we have one */
inviteToken: inviteTokens.find((token) => token.identifier === "invite-link-for-teamId-" + _team.id),
}));
}
@ -50,7 +52,7 @@ export const listHandler = async ({ ctx }: ListOptions) => {
include: {
team: {
include: {
inviteToken: true,
inviteTokens: true,
},
},
},
@ -62,9 +64,11 @@ export const listHandler = async ({ ctx }: ListOptions) => {
const metadata = teamMetadataSchema.parse(mmship.team.metadata);
return !metadata?.isOrganization;
})
.map(({ team, ...membership }) => ({
.map(({ team: { inviteTokens, ..._team }, ...membership }) => ({
role: membership.role,
accepted: membership.accepted,
...team,
..._team,
/** To prevent breaking we only return non-email attached token here, if we have one */
inviteToken: inviteTokens.find((token) => token.identifier === "invite-link-for-teamId-" + _team.id),
}));
};