"use strict";
const core = require("@otplib/core");
const pluginCrypto = require("@otplib/plugin-crypto");
require("@otplib/plugin-thirty-two");
const crypto = require("crypto");
const user = require("./user-xjV81VA_.cjs");
const index = require("./i18n-HHdcQbuJ.cjs");
require("./createAProfileForAnExistingUser-T9XwxKw3.cjs");
require("zod");
require("./EventTypeSchema-N6iC-kdu.cjs");
require("./team-a8vvscOr.cjs");
const server = require("@trpc/server");
const index$1 = require("./email-manager-NqFEofh9.cjs");
const otplib = require("otplib");
const Sentry = require("@sentry/nextjs");
const watchlist_repository = require("./watchlist.repository-XHVXAGHR.cjs");
const totpRawCheck = (token, secret, opts = {}) => {
  const { window = [1, 0], ...rest } = opts;
  const authenticator = new core.TOTP({
    createDigest: pluginCrypto.createDigest,
    window,
    ...rest
  });
  return authenticator.check(token, secret);
};
const isEmail = (str) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
index.logger.getSubLogger({ prefix: ["inviteMember.utils"] });
function checkInputEmailIsValid(email) {
  if (!isEmail(email))
    throw new server.TRPCError({
      code: "BAD_REQUEST",
      message: `Invite failed because ${email} is not a valid email address`
    });
}
async function createNewUsersConnectToOrgIfExists({
  invitations,
  isOrg,
  teamId,
  parentId,
  autoAcceptEmailDomain,
  orgConnectInfoByUsernameOrEmail,
  isPlatformManaged,
  timeFormat,
  weekStart,
  timeZone,
  language,
  creationSource
}) {
  invitations.forEach((invitation) => checkInputEmailIsValid(invitation.usernameOrEmail));
  const createdUsers = await index.prisma.$transaction(
    async (tx) => {
      const createdUsers2 = [];
      for (let index$12 = 0; index$12 < invitations.length; index$12++) {
        const invitation = invitations[index$12];
        const { orgId, autoAccept } = orgConnectInfoByUsernameOrEmail[invitation.usernameOrEmail];
        const [emailUser, emailDomain] = invitation.usernameOrEmail.split("@");
        const [domainName, TLD] = emailDomain.split(".");
        const orgMemberUsername = emailDomain === autoAcceptEmailDomain ? index.slugify(emailUser) : index.slugify(`${emailUser}-${domainName}${isPlatformManaged ? `-${TLD}` : ""}`);
        const regularTeamMemberUsername = null;
        const isBecomingAnOrgMember = parentId || isOrg;
        const defaultAvailability = user.getAvailabilityFromSchedule(user.DEFAULT_SCHEDULE);
        const t = await index.getTranslation(language ?? "en", "common");
        const createdUser = await tx.user.create({
          data: {
            username: isBecomingAnOrgMember ? orgMemberUsername : regularTeamMemberUsername,
            email: invitation.usernameOrEmail,
            verified: true,
            invitedTo: teamId,
            isPlatformManaged: !!isPlatformManaged,
            timeFormat,
            weekStart,
            timeZone,
            creationSource,
            organizationId: orgId || null,
            // If the user is invited to a child team, they are automatically added to the parent org
            ...orgId ? {
              profiles: {
                createMany: {
                  data: [
                    {
                      uid: user.ProfileRepository.generateProfileUid(),
                      username: orgMemberUsername,
                      organizationId: orgId
                    }
                  ]
                }
              }
            } : null,
            teams: {
              create: {
                teamId,
                role: invitation.role,
                accepted: autoAccept
                // If the user is invited to a child team, they are automatically accepted
              }
            },
            ...!isPlatformManaged ? {
              schedules: {
                create: {
                  name: t("default_schedule_name"),
                  availability: {
                    createMany: {
                      data: defaultAvailability.map((schedule) => ({
                        days: schedule.days,
                        startTime: schedule.startTime,
                        endTime: schedule.endTime
                      }))
                    }
                  }
                }
              }
            } : {}
          }
        });
        if (parentId) {
          await tx.membership.create({
            data: {
              createdAt: /* @__PURE__ */ new Date(),
              teamId: parentId,
              userId: createdUser.id,
              role: index.MembershipRole.MEMBER,
              accepted: autoAccept
            }
          });
        }
        createdUsers2.push(createdUser);
      }
      return createdUsers2;
    },
    { timeout: 1e4 }
  );
  return createdUsers;
}
async function sendSignupToOrganizationEmail({
  usernameOrEmail,
  team,
  translation,
  inviterName,
  teamId,
  isOrg
}) {
  try {
    const token = crypto.randomBytes(32).toString("hex");
    await index.prisma.verificationToken.create({
      data: {
        identifier: usernameOrEmail,
        token,
        expires: new Date((/* @__PURE__ */ new Date()).setHours(168)),
        // +1 week
        team: {
          connect: {
            id: teamId
          }
        }
      }
    });
    await index$1.sendTeamInviteEmail({
      language: translation,
      from: inviterName || `${team.name}'s admin`,
      to: usernameOrEmail,
      teamName: team.name,
      joinLink: `${index.WEBAPP_URL}/signup?token=${token}&callbackUrl=/getting-started`,
      isCalcomMember: false,
      isOrg,
      parentTeamName: team?.parent?.name,
      isAutoJoin: false,
      isExistingUserMovedToOrg: false,
      // For a new user there is no prev and new links.
      prevLink: null,
      newLink: null
    });
  } catch (error) {
    index.logger.error(
      "Failed to send signup to organization email",
      index.safeStringify({
        usernameOrEmail,
        orgId: teamId
      }),
      error
    );
  }
}
function presenter(watchlistedEmail) {
  return Sentry.startSpan({ name: "checkIfEmailInWatchlist Presenter", op: "serialize" }, () => {
    return !!watchlistedEmail;
  });
}
async function checkIfEmailIsBlockedInWatchlistController(email) {
  return await Sentry.startSpan({ name: "checkIfEmailInWatchlist Controller" }, async () => {
    const lowercasedEmail = email.toLowerCase();
    const watchlistRepository = new watchlist_repository.WatchlistRepository();
    const watchlistedEmail = await watchlistRepository.getBlockedEmailInWatchlist(lowercasedEmail);
    return presenter(watchlistedEmail);
  });
}
const log = index.logger.getSubLogger({ prefix: [`[[Auth] `] });
const sendEmailVerificationByCode = async ({
  email,
  language,
  username,
  isVerifyingEmail
}) => {
  if (await checkIfEmailIsBlockedInWatchlistController(email)) {
    log.warn("Email is blocked - not sending verification email", email);
    return { ok: false, skipped: false };
  }
  const translation = await index.getTranslation(language ?? "en", "common");
  const secret = crypto.createHash("md5").update(email + process.env.CALENDSO_ENCRYPTION_KEY).digest("hex");
  otplib.totp.options = { step: 900 };
  const code = otplib.totp.generate(secret);
  await index$1.sendEmailVerificationCode({
    language: translation,
    verificationEmailCode: code,
    user: {
      email,
      name: username
    },
    isVerifyingEmail
  });
  return { ok: true, skipped: false };
};
exports.createNewUsersConnectToOrgIfExists = createNewUsersConnectToOrgIfExists;
exports.sendEmailVerificationByCode = sendEmailVerificationByCode;
exports.sendSignupToOrganizationEmail = sendSignupToOrganizationEmail;
exports.totpRawCheck = totpRawCheck;
