Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/api/v2/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { PrismaModule } from "@/modules/prisma/prisma.module";
import { RedisModule } from "@/modules/redis/redis.module";
import { RedisService } from "@/modules/redis/redis.service";
import { VercelWebhookController } from "@/vercel-webhook.controller";
import { getEnv } from "@/env";

@Module({
imports: [
Expand All @@ -35,7 +36,7 @@ import { VercelWebhookController } from "@/vercel-webhook.controller";

RedisModule,
BullModule.forRoot({
redis: `${process.env.REDIS_URL}${process.env.NODE_ENV === "production" ? "?tls=true" : ""}`,
redis: `${getEnv("REDIS_URL")}${getEnv("NODE_ENV", "development") === "production" ? "?tls=true" : ""}`,
}),
ThrottlerModule.forRootAsync({
imports: [RedisModule],
Expand Down
7 changes: 4 additions & 3 deletions apps/api/v2/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import { TRPCExceptionFilter } from "./filters/trpc-exception.filter";
import { HttpExceptionFilter } from "@/filters/http-exception.filter";
import { PrismaExceptionFilter } from "@/filters/prisma-exception.filter";
import { ZodExceptionFilter } from "@/filters/zod-exception.filter";
import { getEnv } from "@/env";

const logger: Logger = new Logger("Bootstrap");

export const bootstrap = (app: NestExpressApplication): NestExpressApplication => {
try {
if (!process.env.VERCEL) {
if (!getEnv("VERCEL", "")) {
app.enableShutdownHooks();
}
app.enableVersioning({
Expand Down Expand Up @@ -76,8 +77,8 @@ export const bootstrap = (app: NestExpressApplication): NestExpressApplication =
app.useGlobalFilters(new CalendarServiceExceptionFilter());
app.use(cookieParser());

if (process?.env?.API_GLOBAL_PREFIX) {
app.setGlobalPrefix(process?.env?.API_GLOBAL_PREFIX);
if (getEnv("API_GLOBAL_PREFIX", "")) {
app.setGlobalPrefix(getEnv("API_GLOBAL_PREFIX"));
}

return app;
Expand Down
2 changes: 1 addition & 1 deletion apps/api/v2/src/config/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const loadConfig = (): AppConfig => {
const apiPort = Number(getEnv("API_PORT", "5555"));
const apiUrl = getEnv("API_URL", "http://localhost");
let portSuffix = "";
if (process.env.API_PORT && env === "development") {
if (getEnv("API_PORT", "") && env === "development") {
portSuffix = `:${apiPort}`;
}

Expand Down
2 changes: 1 addition & 1 deletion apps/api/v2/src/instrument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getEnv } from "@/env";
import * as Sentry from "@sentry/nestjs";
import { nodeProfilingIntegration } from "@sentry/profiling-node";

if (process.env.SENTRY_DSN) {
if (getEnv("SENTRY_DSN", "")) {
// Ensure to call this before requiring any other modules!
Sentry.init({
dsn: getEnv("SENTRY_DSN"),
Expand Down
5 changes: 3 additions & 2 deletions apps/api/v2/src/lib/logger.bridge.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable, Logger as NestLogger, Scope } from "@nestjs/common";
import type { Logger as TsLogger } from "tslog";
import { getEnv } from "@/env";

// 1. Define an interface for the settings
interface IMyLoggerSettings {
Expand Down Expand Up @@ -38,8 +39,8 @@ export class Logger

// Define default settings
private static readonly defaultSettings: IMyLoggerSettings = {
minLevel: process?.env?.LOGGER_BRIDGE_LOG_LEVEL
? Number(process.env.LOGGER_BRIDGE_LOG_LEVEL)
minLevel: getEnv("LOGGER_BRIDGE_LOG_LEVEL", "")
? Number(getEnv("LOGGER_BRIDGE_LOG_LEVEL", ""))
: LogLevel.INFO, // Default to INFO level
displayTimestamp: true,
logFormat: "pretty",
Expand Down
11 changes: 6 additions & 5 deletions apps/api/v2/src/lib/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { WinstonTransport as AxiomTransport } from "@axiomhq/winston";
import type { LoggerOptions } from "winston";
import { format, transports as Transports, config } from "winston";
import type Transport from "winston-transport";
import { getEnv } from "@/env";

const formattedTimestamp = format.timestamp({
format: "YYYY-MM-DD HH:mm:ss.SSS",
Expand All @@ -22,23 +23,23 @@ const WINSTON_PROD_FORMAT = format.combine(format.errors({ stack: true }), forma
export const logLevels = config.npm.levels;

export const loggerConfig = (): LoggerOptions => {
const isProduction = process.env.NODE_ENV === "production";
const isProduction = getEnv("NODE_ENV", "development") === "production";

const transports: Transport[] = [];
transports.push(new Transports.Console());

if (!!process.env.AXIOM_TOKEN && !!process.env.AXIOM_DATASET) {
if (!!getEnv("AXIOM_TOKEN", "") && !!getEnv("AXIOM_DATASET", "")) {
transports.push(
new AxiomTransport({
token: process.env.AXIOM_TOKEN,
dataset: process.env.AXIOM_DATASET,
token: getEnv("AXIOM_TOKEN"),
dataset: getEnv("AXIOM_DATASET"),
})
);
}

return {
levels: logLevels,
level: process.env.LOG_LEVEL ?? "info",
level: getEnv("LOG_LEVEL", "info"),
format: isProduction ? WINSTON_PROD_FORMAT : WINSTON_DEV_FORMAT,
transports,
exceptionHandlers: transports,
Expand Down
5 changes: 3 additions & 2 deletions apps/api/v2/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import { AppModule } from "./app.module";
import { bootstrap } from "./bootstrap";
import { loggerConfig } from "./lib/logger";
import type { AppConfig } from "@/config/type";
import { getEnv } from "@/env";

if (process.env.NODE_ENV === "production") {
if (getEnv("NODE_ENV", "development") === "production") {
process.env.TRIGGER_VERSION = TRIGGER_VERSION;
}
const logger: Logger = new Logger("App");
Expand Down Expand Up @@ -52,7 +53,7 @@ class NestServer {
// -----------------------------------------------------------------------------
// LOCAL DEVELOPMENT STARTUP
// -----------------------------------------------------------------------------
if (!process.env.VERCEL) {
if (!getEnv("VERCEL", "")) {
run().catch((error: Error) => {
logger.error("Failed to start Cal Platform API", { error: error.stack });
process.exit(1);
Expand Down
5 changes: 3 additions & 2 deletions apps/api/v2/src/middleware/app.redirects.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Injectable, NestMiddleware } from "@nestjs/common";
import { Request, Response } from "express";
import { getEnv } from "@/env";

@Injectable()
export class RedirectsMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => void) {
if (process.env.DOCS_URL && (req.url.startsWith("/v2/docs") || req.url.startsWith("/docs"))) {
return res.redirect(process.env.DOCS_URL);
if (getEnv("DOCS_URL", "") && (req.url.startsWith("/v2/docs") || req.url.startsWith("/docs"))) {
return res.redirect(getEnv("DOCS_URL"));
}
next();
}
Expand Down
3 changes: 2 additions & 1 deletion apps/api/v2/src/modules/stripe/stripe.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type { Prisma, Credential, User } from "@calcom/prisma/client";
import { stripeKeysResponseSchema } from "./utils/stripeDataSchemas";

import stringify = require("qs-stringify");
import { getEnv } from "@/env";

export type OAuthCallbackState = {
accessToken: string;
Expand Down Expand Up @@ -68,7 +69,7 @@ export class StripeService {
email: userEmail,
first_name: userName || undefined,
/** We need this so E2E don't fail for international users */
country: process.env.NEXT_PUBLIC_IS_E2E ? "US" : undefined,
country: getEnv("NEXT_PUBLIC_IS_E2E", "") ? "US" : undefined,
},
redirect_uri: this.redirectUri,
state: JSON.stringify(state),
Expand Down
3 changes: 2 additions & 1 deletion apps/api/v2/src/modules/stripe/utils/newStripeInstance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Stripe from "stripe";
import { getEnv } from "@/env";

const stripeApiKey = process.env.STRIPE_API_KEY || "";
const stripeApiKey = getEnv("STRIPE_API_KEY", "");
export const stripeInstance = new Stripe(stripeApiKey, {
apiVersion: "2020-08-27",
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SUCCESS_STATUS, APPLE_CALENDAR_TYPE, APPLE_CALENDAR_ID } from "@calcom/
import { symmetricEncrypt, symmetricDecrypt } from "@calcom/platform-libraries";
import { BuildCalendarService } from "@calcom/platform-libraries/app-store";
import type { Credential } from "@calcom/prisma/client";
import { getEnv } from "@/env";

@Injectable()
export class AppleCalendarService implements CredentialSyncCalendarApp {
Expand Down Expand Up @@ -75,7 +76,7 @@ export class AppleCalendarService implements CredentialSyncCalendarApp {
const hasCalendarWithGivenCredentials = existingAppleCalendarCredentials.find(
(calendarCredential: Credential) => {
const decryptedKey = JSON.parse(
symmetricDecrypt(calendarCredential.key as string, process.env.CALENDSO_ENCRYPTION_KEY || "")
symmetricDecrypt(calendarCredential.key as string, getEnv("CALENDSO_ENCRYPTION_KEY", ""))
);

if (decryptedKey.username === username) {
Expand All @@ -97,7 +98,7 @@ export class AppleCalendarService implements CredentialSyncCalendarApp {
if (!!hasCalendarWithGivenCredentials && !hasMatchingUsernameAndPassword) {
await this.credentialRepository.upsertUserAppCredential(
APPLE_CALENDAR_TYPE,
symmetricEncrypt(JSON.stringify({ username, password }), process.env.CALENDSO_ENCRYPTION_KEY || ""),
symmetricEncrypt(JSON.stringify({ username, password }), getEnv("CALENDSO_ENCRYPTION_KEY", "")),
userId,
hasCalendarWithGivenCredentials.id
);
Expand All @@ -113,7 +114,7 @@ export class AppleCalendarService implements CredentialSyncCalendarApp {
type: APPLE_CALENDAR_TYPE,
key: symmetricEncrypt(
JSON.stringify({ username, password }),
process.env.CALENDSO_ENCRYPTION_KEY || ""
getEnv("CALENDSO_ENCRYPTION_KEY", "")
),
userId: userId,
teamId: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Injectable } from "@nestjs/common";
import { SUCCESS_STATUS, ICS_CALENDAR_TYPE, ICS_CALENDAR } from "@calcom/platform-constants";
import { symmetricEncrypt } from "@calcom/platform-libraries";
import { BuildIcsFeedCalendarService } from "@calcom/platform-libraries/app-store";
import { getEnv } from "@/env";

@Injectable()
export class IcsFeedService implements ICSFeedCalendarApp {
Expand All @@ -33,7 +34,7 @@ export class IcsFeedService implements ICSFeedCalendarApp {
ICS_CALENDAR,
key: symmetricEncrypt(
JSON.stringify({ urls, skipWriting: readonly }),
process.env.CALENDSO_ENCRYPTION_KEY || ""
getEnv("CALENDSO_ENCRYPTION_KEY", "")
),
userId: userId,
teamId: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Injectable, NotFoundException, BadRequestException } from "@nestjs/comm

import { generateHashedLink, isLinkExpired } from "@calcom/platform-libraries/private-links";
import { CreatePrivateLinkInput, PrivateLinkOutput, UpdatePrivateLinkInput } from "@calcom/platform-types";
import { getEnv } from "@/env";

@Injectable()
export class PrivateLinksService {
Expand All @@ -33,7 +34,7 @@ export class PrivateLinksService {
id: created.link,
eventTypeId,
isExpired: isLinkExpired(created as any),
bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${created.link}`,
bookingUrl: `${getEnv("NEXT_PUBLIC_WEBAPP_URL", "https://cal.com")}/d/${created.link}`,
expiresAt: created.expiresAt ?? null,
maxUsageCount: (created as any).maxUsageCount ?? null,
usageCount: (created as any).usageCount ?? 0,
Expand All @@ -54,7 +55,7 @@ export class PrivateLinksService {
id: l.link,
eventTypeId,
isExpired: isLinkExpired(l as any),
bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${l.link}`,
bookingUrl: `${getEnv("NEXT_PUBLIC_WEBAPP_URL", "https://cal.com")}/d/${l.link}`,
expiresAt: l.expiresAt ?? null,
maxUsageCount: l.maxUsageCount ?? null,
usageCount: l.usageCount ?? 0,
Expand Down Expand Up @@ -85,7 +86,7 @@ export class PrivateLinksService {
id: updated.link,
eventTypeId,
isExpired: isLinkExpired(updated as any),
bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${updated.link}`,
bookingUrl: `${getEnv("NEXT_PUBLIC_WEBAPP_URL", "https://cal.com")}/d/${updated.link}`,
expiresAt: updated.expiresAt ?? null,
maxUsageCount: updated.maxUsageCount ?? null,
usageCount: updated.usageCount ?? 0,
Expand Down
2 changes: 1 addition & 1 deletion apps/api/v2/src/swagger/generate-swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function generateSwaggerForApp(app: NestExpressApplication<Server>)
spawnSync("node", [biomeBin, "format", "--write", docsOutputFile], { stdio: "inherit" });
}

if (!process.env.DOCS_URL) {
if (!getEnv("DOCS_URL", "")) {
SwaggerModule.setup("docs", app, document, {
customCss: ".swagger-ui .topbar { display: none }",
});
Expand Down
5 changes: 3 additions & 2 deletions apps/api/v2/src/vercel-webhook.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { ApiExcludeController } from "@nestjs/swagger";
import { VercelWebhookGuard } from "./vercel-webhook.guard";
import { API_VERSIONS_VALUES } from "@/lib/api-versions";
import { getEnv } from "@/env";

interface VercelWebhookPayload {
type?: string;
Expand Down Expand Up @@ -50,7 +51,7 @@ export class VercelWebhookController {
}

// biome-ignore lint/style/noProcessEnv: Environment variable access required for trigger.dev API
const TRIGGER_VERSION = process.env.TRIGGER_VERSION;
const TRIGGER_VERSION = getEnv("TRIGGER_VERSION");

if (!TRIGGER_VERSION) {
this.logger.error("TRIGGER_VERSION is not defined");
Expand All @@ -66,7 +67,7 @@ export class VercelWebhookController {

private async promoteTriggerDeployment(version: string, maxRetries: number = 3): Promise<void> {
// biome-ignore lint/style/noProcessEnv: Environment variable access required for trigger.dev API
const triggerSecretKey = process.env.TRIGGER_SECRET_KEY;
const triggerSecretKey = getEnv("TRIGGER_SECRET_KEY");

const url = `https://api.trigger.dev/api/v1/deployments/${version}/promote`;

Expand Down
3 changes: 2 additions & 1 deletion apps/api/v2/src/vercel-webhook.guard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as crypto from "node:crypto";
import { CanActivate, ExecutionContext, Injectable, Logger, UnauthorizedException } from "@nestjs/common";
import { getEnv } from "@/env";

@Injectable()
export class VercelWebhookGuard implements CanActivate {
Expand All @@ -9,7 +10,7 @@ export class VercelWebhookGuard implements CanActivate {
const request = context.switchToHttp().getRequest();
const signature = request.headers["x-vercel-signature"];
// biome-ignore lint/style/noProcessEnv: Environment variable access required for webhook secret
const webhookSecret = process.env.VERCEL_PROMOTE_WEBHOOK_SECRET;
const webhookSecret = getEnv("VERCEL_PROMOTE_WEBHOOK_SECRET");

if (!webhookSecret) {
this.logger.error("VERCEL_PROMOTE_WEBHOOK_SECRET is not defined");
Expand Down