Compare commits
1 Commits
main
...
chore/orgs
Author | SHA1 | Date |
---|---|---|
Hariom Balhara | fbcb6d56de |
|
@ -16,6 +16,10 @@ import {
|
||||||
} from "@calcom/ui";
|
} from "@calcom/ui";
|
||||||
import { Info } from "@calcom/ui/components/icon";
|
import { Info } from "@calcom/ui/components/icon";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component verifies the code for org creation as well as for Booker Email verification which both use different endpoints to verify
|
||||||
|
* TODO: We should create separate components for these two tasks, sharing whatever is needed
|
||||||
|
*/
|
||||||
export const VerifyCodeDialog = ({
|
export const VerifyCodeDialog = ({
|
||||||
isOpenDialog,
|
isOpenDialog,
|
||||||
setIsOpenDialog,
|
setIsOpenDialog,
|
||||||
|
@ -42,6 +46,7 @@ export const VerifyCodeDialog = ({
|
||||||
onChange,
|
onChange,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Used by org creation as it passes isUserSessionRequiredToVerify=true
|
||||||
const verifyCodeMutationUserSessionRequired = trpc.viewer.organizations.verifyCode.useMutation({
|
const verifyCodeMutationUserSessionRequired = trpc.viewer.organizations.verifyCode.useMutation({
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
@ -55,6 +60,7 @@ export const VerifyCodeDialog = ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Used by Booker Email verification as it passes isUserSessionRequiredToVerify=false
|
||||||
const verifyCodeMutationUserSessionNotRequired = trpc.viewer.auth.verifyCodeUnAuthenticated.useMutation({
|
const verifyCodeMutationUserSessionNotRequired = trpc.viewer.auth.verifyCodeUnAuthenticated.useMutation({
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
|
@ -2,13 +2,16 @@ import type { GetServerSidePropsContext } from "next";
|
||||||
|
|
||||||
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
||||||
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
|
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
|
||||||
|
import logger from "@calcom/lib/logger";
|
||||||
import { MembershipRole } from "@calcom/prisma/client";
|
import { MembershipRole } from "@calcom/prisma/client";
|
||||||
|
|
||||||
|
const log = logger.getChildLogger({ prefix: ["[pages/organization]"] });
|
||||||
export const getServerSideProps = async ({ req, res }: GetServerSidePropsContext) => {
|
export const getServerSideProps = async ({ req, res }: GetServerSidePropsContext) => {
|
||||||
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
|
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
|
||||||
const flags = await getFeatureFlagMap(prisma);
|
const flags = await getFeatureFlagMap(prisma);
|
||||||
// Check if organizations are enabled
|
// Check if organizations are enabled
|
||||||
if (flags["organizations"] !== true) {
|
if (flags["organizations"] !== true) {
|
||||||
|
log.warn(`"organizations" flag is not enabled`);
|
||||||
return {
|
return {
|
||||||
notFound: true,
|
notFound: true,
|
||||||
};
|
};
|
||||||
|
@ -17,6 +20,7 @@ export const getServerSideProps = async ({ req, res }: GetServerSidePropsContext
|
||||||
// Check if logged in user has an organization assigned
|
// Check if logged in user has an organization assigned
|
||||||
const session = await getServerSession({ req, res });
|
const session = await getServerSession({ req, res });
|
||||||
if (!session?.user.org?.id) {
|
if (!session?.user.org?.id) {
|
||||||
|
log.debug(`User ${session?.user.id} has no organization assigned`);
|
||||||
return {
|
return {
|
||||||
notFound: true,
|
notFound: true,
|
||||||
};
|
};
|
||||||
|
@ -32,6 +36,7 @@ export const getServerSideProps = async ({ req, res }: GetServerSidePropsContext
|
||||||
role: true,
|
role: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!membership?.role || membership?.role === MembershipRole.MEMBER) {
|
if (!membership?.role || membership?.role === MembershipRole.MEMBER) {
|
||||||
return {
|
return {
|
||||||
notFound: true,
|
notFound: true,
|
||||||
|
|
|
@ -2,6 +2,7 @@ const VERCEL_URL = process.env.NEXT_PUBLIC_VERCEL_URL ? `https://${process.env.N
|
||||||
const RAILWAY_STATIC_URL = process.env.RAILWAY_STATIC_URL ? `https://${process.env.RAILWAY_STATIC_URL}` : "";
|
const RAILWAY_STATIC_URL = process.env.RAILWAY_STATIC_URL ? `https://${process.env.RAILWAY_STATIC_URL}` : "";
|
||||||
const HEROKU_URL = process.env.HEROKU_APP_NAME ? `https://${process.env.HEROKU_APP_NAME}.herokuapp.com` : "";
|
const HEROKU_URL = process.env.HEROKU_APP_NAME ? `https://${process.env.HEROKU_APP_NAME}.herokuapp.com` : "";
|
||||||
const RENDER_URL = process.env.RENDER_EXTERNAL_URL ? `https://${process.env.RENDER_EXTERNAL_URL}` : "";
|
const RENDER_URL = process.env.RENDER_EXTERNAL_URL ? `https://${process.env.RENDER_EXTERNAL_URL}` : "";
|
||||||
|
// NODE_ENV is production even for staging/preview environents. So, we have CALCOM_ENV to override that.
|
||||||
export const CALCOM_ENV = process.env.CALCOM_ENV || process.env.NODE_ENV;
|
export const CALCOM_ENV = process.env.CALCOM_ENV || process.env.NODE_ENV;
|
||||||
export const IS_PRODUCTION = CALCOM_ENV === "production";
|
export const IS_PRODUCTION = CALCOM_ENV === "production";
|
||||||
export const IS_PRODUCTION_BUILD = process.env.NODE_ENV === "production";
|
export const IS_PRODUCTION_BUILD = process.env.NODE_ENV === "production";
|
||||||
|
|
|
@ -10,9 +10,10 @@ import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/avail
|
||||||
import {
|
import {
|
||||||
IS_TEAM_BILLING_ENABLED,
|
IS_TEAM_BILLING_ENABLED,
|
||||||
RESERVED_SUBDOMAINS,
|
RESERVED_SUBDOMAINS,
|
||||||
IS_PRODUCTION,
|
|
||||||
WEBAPP_URL,
|
WEBAPP_URL,
|
||||||
|
IS_PRODUCTION,
|
||||||
} from "@calcom/lib/constants";
|
} from "@calcom/lib/constants";
|
||||||
|
import logger from "@calcom/lib/logger";
|
||||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||||
import slugify from "@calcom/lib/slugify";
|
import slugify from "@calcom/lib/slugify";
|
||||||
import { prisma } from "@calcom/prisma";
|
import { prisma } from "@calcom/prisma";
|
||||||
|
@ -23,6 +24,7 @@ import { TRPCError } from "@trpc/server";
|
||||||
import type { TrpcSessionUser } from "../../../trpc";
|
import type { TrpcSessionUser } from "../../../trpc";
|
||||||
import type { TCreateInputSchema } from "./create.schema";
|
import type { TCreateInputSchema } from "./create.schema";
|
||||||
|
|
||||||
|
const log = logger.getChildLogger({ prefix: ["organizations.create.handler"] });
|
||||||
type CreateOptions = {
|
type CreateOptions = {
|
||||||
ctx: {
|
ctx: {
|
||||||
user: NonNullable<TrpcSessionUser>;
|
user: NonNullable<TrpcSessionUser>;
|
||||||
|
@ -121,7 +123,7 @@ export const createHandler = async ({ input, ctx }: CreateOptions) => {
|
||||||
t,
|
t,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn("Organization created: subdomain not configured and couldn't notify adminnistrators");
|
log.warn("Organization created: subdomain not configured and couldn't notify administrators");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +177,12 @@ export const createHandler = async ({ input, ctx }: CreateOptions) => {
|
||||||
|
|
||||||
return { user: { ...createOwnerOrg, password } };
|
return { user: { ...createOwnerOrg, password } };
|
||||||
} else {
|
} else {
|
||||||
if (!IS_PRODUCTION) return { checked: true };
|
if (!IS_PRODUCTION) {
|
||||||
|
log.warn(
|
||||||
|
"Being in Non Production env, organization will be created without requiring email verification. Use any digits for OTP verification"
|
||||||
|
);
|
||||||
|
return { checked: true };
|
||||||
|
}
|
||||||
const language = await getTranslation(input.language ?? "en", "common");
|
const language = await getTranslation(input.language ?? "en", "common");
|
||||||
|
|
||||||
const secret = createHash("md5")
|
const secret = createHash("md5")
|
||||||
|
|
|
@ -2,12 +2,15 @@ import { createHash } from "crypto";
|
||||||
|
|
||||||
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
|
||||||
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
import { IS_PRODUCTION } from "@calcom/lib/constants";
|
||||||
|
import logger from "@calcom/lib/logger";
|
||||||
import { totpRawCheck } from "@calcom/lib/totp";
|
import { totpRawCheck } from "@calcom/lib/totp";
|
||||||
import type { ZVerifyCodeInputSchema } from "@calcom/prisma/zod-utils";
|
import type { ZVerifyCodeInputSchema } from "@calcom/prisma/zod-utils";
|
||||||
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
|
||||||
|
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
|
const log = logger.getChildLogger({ prefix: ["verifyCode"] });
|
||||||
|
|
||||||
type VerifyCodeOptions = {
|
type VerifyCodeOptions = {
|
||||||
ctx: {
|
ctx: {
|
||||||
user: NonNullable<TrpcSessionUser>;
|
user: NonNullable<TrpcSessionUser>;
|
||||||
|
@ -21,7 +24,10 @@ export const verifyCodeHandler = async ({ ctx, input }: VerifyCodeOptions) => {
|
||||||
|
|
||||||
if (!user || !email || !code) throw new TRPCError({ code: "BAD_REQUEST" });
|
if (!user || !email || !code) throw new TRPCError({ code: "BAD_REQUEST" });
|
||||||
|
|
||||||
if (!IS_PRODUCTION) return true;
|
if (!IS_PRODUCTION) {
|
||||||
|
log.warn("Accepting any code in non-production environment");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
await checkRateLimitAndThrowError({
|
await checkRateLimitAndThrowError({
|
||||||
rateLimitingType: "core",
|
rateLimitingType: "core",
|
||||||
identifier: email,
|
identifier: email,
|
||||||
|
|
Loading…
Reference in New Issue