* --init * -- * replace old structure with new DI * fix type * -- * moving stuff around * moving stuff around again * minor clean up * -- * resolve conflict * clea up * old schema clean up * further clean up * removing unwanted merged responsibilities * -- * improve DI and SOLID * some type fixes * --1 * clean up --cont * fix DI in facade for test * more fix * fix * checking * o.o * fix import * fix failing test --2 * fix failing test --3 * fix failing test --4 * normalization use * introduce facade container injection * uniform async telemetry spans * further improvements * replace prismock with repo mocks * ensure we don't pass prisma outside of repo * fix import * remove try catch from repo calls * async await fixes * using deps pattern * more clean up and fixes * more clean up * address feedback --1 * separation of concern * clean up * test clean up * feedback --2 * remove extra fetch * remove await * migrate _post test from prismock * fix type * -- * fix tokens path * rename AuditRepo * test --1 * update _post to integration test * fix test * fix test * test fix maybe? * -- * feedback * feedback * fixes * more feedback * NIT * use sentry and logger imports as planned * assertion in test * add missing test case * add tests for controllers and services * NITs * fix domain normalisation
94 lines
2.9 KiB
TypeScript
94 lines
2.9 KiB
TypeScript
import dayjs from "@calcom/dayjs";
|
|
import { checkIfFreeEmailDomain } from "@calcom/features/watchlist/lib/freeEmailDomainCheck/checkIfFreeEmailDomain";
|
|
import { withReporting } from "@calcom/lib/sentryWrapper";
|
|
|
|
import type { getEventTypeResponse } from "./getEventTypesFromDB";
|
|
|
|
type EventType = Pick<
|
|
getEventTypeResponse,
|
|
"metadata" | "requiresConfirmation" | "requiresConfirmationForFreeEmail"
|
|
>;
|
|
type PaymentAppData = { price: number };
|
|
|
|
export async function getRequiresConfirmationFlags({
|
|
eventType,
|
|
bookingStartTime,
|
|
userId,
|
|
paymentAppData,
|
|
originalRescheduledBookingOrganizerId,
|
|
bookerEmail,
|
|
}: {
|
|
eventType: EventType;
|
|
bookingStartTime: string;
|
|
userId: number | undefined;
|
|
paymentAppData: PaymentAppData;
|
|
originalRescheduledBookingOrganizerId: number | undefined;
|
|
bookerEmail: string;
|
|
}) {
|
|
const requiresConfirmation = await determineRequiresConfirmation(eventType, bookingStartTime, bookerEmail);
|
|
const userReschedulingIsOwner = isUserReschedulingOwner(userId, originalRescheduledBookingOrganizerId);
|
|
const isConfirmedByDefault = determineIsConfirmedByDefault(
|
|
requiresConfirmation,
|
|
paymentAppData.price,
|
|
userReschedulingIsOwner
|
|
);
|
|
|
|
return {
|
|
/**
|
|
* Organizer of the booking is rescheduling
|
|
*/
|
|
userReschedulingIsOwner,
|
|
/**
|
|
* Booking won't need confirmation to be ACCEPTED
|
|
*/
|
|
isConfirmedByDefault,
|
|
};
|
|
}
|
|
|
|
// Define the function with underscore prefix
|
|
const _determineRequiresConfirmation = async (
|
|
eventType: EventType,
|
|
bookingStartTime: string,
|
|
bookerEmail: string
|
|
): Promise<boolean> => {
|
|
let requiresConfirmation = eventType?.requiresConfirmation;
|
|
const rcThreshold = eventType?.metadata?.requiresConfirmationThreshold;
|
|
const requiresConfirmationForFreeEmail = eventType?.requiresConfirmationForFreeEmail;
|
|
|
|
if (requiresConfirmationForFreeEmail) {
|
|
requiresConfirmation = await checkIfFreeEmailDomain({ email: bookerEmail });
|
|
}
|
|
|
|
if (rcThreshold) {
|
|
const timeDifference = dayjs(dayjs(bookingStartTime).utc().format()).diff(dayjs(), rcThreshold.unit);
|
|
if (timeDifference > rcThreshold.time) {
|
|
requiresConfirmation = false;
|
|
}
|
|
}
|
|
|
|
return requiresConfirmation;
|
|
};
|
|
|
|
export const determineRequiresConfirmation = withReporting(
|
|
_determineRequiresConfirmation,
|
|
"determineRequiresConfirmation"
|
|
);
|
|
|
|
function isUserReschedulingOwner(
|
|
userId: number | undefined,
|
|
originalRescheduledBookingOrganizerId: number | undefined
|
|
): boolean {
|
|
// If the user is not the owner of the event, new booking should be always pending.
|
|
// Otherwise, an owner rescheduling should be always accepted.
|
|
// Before comparing make sure that userId is set, otherwise undefined === undefined
|
|
return !!(userId && originalRescheduledBookingOrganizerId === userId);
|
|
}
|
|
|
|
function determineIsConfirmedByDefault(
|
|
requiresConfirmation: boolean,
|
|
price: number,
|
|
userReschedulingIsOwner: boolean
|
|
): boolean {
|
|
return (!requiresConfirmation && price === 0) || userReschedulingIsOwner;
|
|
}
|