Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"nodemon": "^3.1.7",
"pino-pretty": "^13.0.0",
"prettier": "^3.3.3",
"ts-jest": "29.2.5",
"ts-jest": "=29.4.6",
"ts-node": "^10.9.2",
"ts-prune": "^0.10.3",
"typescript": "^5.6.3",
Expand Down
23 changes: 11 additions & 12 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import Stripe from 'stripe';
import fastifyCors from '@fastify/cors';
import Fastify, { FastifyInstance } from 'fastify';
import { AppConfig } from './config';
import controller from './controller/payments.controller';
import objStorageController from './controller/object-storage.controller';
import businessController from './controller/business.controller';
import { paymentsController } from './controller/payments.controller';
import { objectStorageController } from './controller/object-storage.controller';
import { businessController } from './controller/business.controller';
import { productsController } from './controller/products.controller';
import checkoutController from './controller/checkout.controller';
import customerController from './controller/customer.controller';
import { checkoutController } from './controller/checkout.controller';
import { customerController } from './controller/customer.controller';
import controllerMigration from './controller-migration';
import CacheService from './services/cache.service';
import { PaymentService } from './services/payment.service';
Expand Down Expand Up @@ -57,15 +57,14 @@ export async function buildApp({

registerErrorHandler(fastify);

fastify.register(controller(paymentService, usersService, config, cacheService, licenseCodesService, tiersService));
fastify.register(objStorageController(paymentService), { prefix: '/object-storage' });
fastify.register(businessController(paymentService, usersService, tiersService, config), { prefix: '/business' });
fastify.register(
productsController(productsService, userFeaturesOverridesService, usersService, cacheService, config),
{
prefix: '/products',
},
paymentsController(paymentService, usersService, config, cacheService, licenseCodesService, tiersService),
);
fastify.register(objectStorageController(paymentService), { prefix: '/object-storage' });
fastify.register(businessController(paymentService, usersService, tiersService, config), { prefix: '/business' });
fastify.register(productsController(productsService, cacheService, config), {
prefix: '/products',
});
fastify.register(checkoutController(usersService, paymentService), { prefix: '/checkout' });
fastify.register(customerController(usersService, paymentService, cacheService), { prefix: '/customer' });
fastify.register(
Expand Down
19 changes: 3 additions & 16 deletions src/controller/business.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,19 @@ import {
} from '../services/payment.service';
import { UserNotFoundError, UsersService } from '../services/users.service';
import { assertUser } from '../utils/assertUser';
import fastifyJwt from '@fastify/jwt';
import fastifyLimit from '@fastify/rate-limit';
import Stripe from 'stripe';
import { TiersService } from '../services/tiers.service';
import { Service } from '../core/users/Tier';
import { withAuth } from '../plugins/withAuth.plugin';

export default function (
export function businessController(
paymentService: PaymentService,
usersService: UsersService,
tiersService: TiersService,
config: AppConfig,
) {
return async function (fastify: FastifyInstance) {
fastify.register(fastifyJwt, { secret: config.JWT_SECRET });
fastify.register(fastifyLimit, {
max: 1000,
timeWindow: '1 minute',
});
fastify.addHook('onRequest', async (request, reply) => {
try {
await request.jwtVerify();
} catch (err) {
request.log.warn(`JWT verification failed with error: ${(err as Error).message}`);
reply.status(401).send();
}
});
await withAuth(fastify, { secret: config.JWT_SECRET });

fastify.patch<{ Body: { workspaceId: string; subscriptionId: string; workspaceUpdatedSeats: number } }>(
'/subscription',
Expand Down
32 changes: 4 additions & 28 deletions src/controller/checkout.controller.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,20 @@
import { FastifyInstance } from 'fastify';
import Stripe from 'stripe';
import jwt from 'jsonwebtoken';
import fastifyJwt from '@fastify/jwt';
import fastifyRateLimit from '@fastify/rate-limit';

import { UsersService } from '../services/users.service';
import { PaymentIntent, PaymentService } from '../services/payment.service';
import { BadRequestError, ForbiddenError, UnauthorizedError } from '../errors/Errors';
import { BadRequestError, ForbiddenError } from '../errors/Errors';
import config from '../config';
import { fetchUserStorage } from '../utils/fetchUserStorage';
import { getAllowedCurrencies, isValidCurrency } from '../utils/currency';
import { signUserToken } from '../utils/signUserToken';
import { verifyRecaptcha } from '../utils/verifyRecaptcha';
import { withAuth } from '../plugins/withAuth.plugin';

export default function (usersService: UsersService, paymentsService: PaymentService) {
export function checkoutController(usersService: UsersService, paymentsService: PaymentService) {
return async function (fastify: FastifyInstance) {
fastify.register(fastifyJwt, { secret: config.JWT_SECRET });
fastify.register(fastifyRateLimit, {
max: 1000,
timeWindow: '1 minute',
});

fastify.addHook('onRequest', async (request) => {
const skipAuth = request.routeOptions?.config?.skipAuth;
const allowAnonymous = request.routeOptions?.config?.allowAnonymous;

if (skipAuth) {
return;
}

try {
await request.jwtVerify();
} catch (err) {
if (allowAnonymous) {
return;
}
request.log.warn(`JWT verification failed with error: ${(err as Error).message}`);
throw new UnauthorizedError();
}
});
await withAuth(fastify, { secret: config.JWT_SECRET });

/**
* @deprecated This Endpoint has been deprecated, use `POST /customer` instead
Expand Down
25 changes: 7 additions & 18 deletions src/controller/customer.controller.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
import { FastifyInstance } from 'fastify';
import fastifyJwt from '@fastify/jwt';
import fastifyRateLimit from '@fastify/rate-limit';

import { UsersService } from '../services/users.service';
import { UnauthorizedError } from '../errors/Errors';
import config from '../config';
import CacheService from '../services/cache.service';
import { PaymentService } from '../services/payment.service';
import Stripe from 'stripe';
import { withAuth } from '../plugins/withAuth.plugin';

export default function (usersService: UsersService, paymentService: PaymentService, cacheService: CacheService) {
export function customerController(
usersService: UsersService,
paymentService: PaymentService,
cacheService: CacheService,
) {
return async function (fastify: FastifyInstance) {
fastify.register(fastifyJwt, { secret: config.JWT_SECRET });
fastify.register(fastifyRateLimit, {
max: 1000,
timeWindow: '1 minute',
});

fastify.addHook('onRequest', async (request) => {
try {
await request.jwtVerify();
} catch (err) {
request.log.warn(`JWT verification failed with error: ${(err as Error).message}`);
throw new UnauthorizedError();
}
});
await withAuth(fastify, { secret: config.JWT_SECRET });

fastify.get(
'/redeemed-promotion-codes',
Expand Down
10 changes: 5 additions & 5 deletions src/controller/gateway.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { FastifyInstance } from 'fastify';
import { AppConfig } from '../config';
import { UsersService } from '../services/users.service';
import fastifyJwt from '@fastify/jwt';
import fastifyLimit from '@fastify/rate-limit';
import { NotFoundError, UnauthorizedError } from '../errors/Errors';
import Logger from '../Logger';
import CacheService from '../services/cache.service';
import { Service } from '../core/users/Tier';
import { User } from '../core/users/User';
import { UserFeaturesOverridesService } from '../services/userFeaturesOverride.service';
import { withAuth } from '../plugins/withAuth.plugin';

interface GatewayControllerPayload {
cacheService: CacheService;
Expand All @@ -24,13 +24,13 @@ export function gatewayController({
config,
}: GatewayControllerPayload) {
return async function (fastify: FastifyInstance) {
fastify.register(fastifyJwt, {
await withAuth(fastify, {
jwtOptions: {
algorithms: ['RS256'],
},
secret: {
public: Buffer.from(config.PAYMENTS_GATEWAY_PUBLIC_SECRET, 'base64').toString('utf-8'),
},
verify: {
algorithms: ['RS256'],
},
});

fastify.register(fastifyLimit, {
Expand Down
29 changes: 3 additions & 26 deletions src/controller/object-storage.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { FastifyInstance } from 'fastify';
import jwt from 'jsonwebtoken';
import fastifyJwt from '@fastify/jwt';
import fastifyRateLimit from '@fastify/rate-limit';

import {
CustomerNotFoundError,
Expand All @@ -12,36 +10,15 @@ import {
import { ForbiddenError, UnauthorizedError } from '../errors/Errors';
import config from '../config';
import Stripe from 'stripe';
import { withAuth } from '../plugins/withAuth.plugin';

function signUserToken(customerId: string) {
return jwt.sign({ customerId }, config.JWT_SECRET);
}

export default function (paymentService: PaymentService) {
export function objectStorageController(paymentService: PaymentService) {
return async function (fastify: FastifyInstance) {
fastify.register(fastifyJwt, { secret: config.JWT_SECRET });
fastify.register(fastifyRateLimit, {
max: 1000,
timeWindow: '1 minute',
});

fastify.addHook('onRequest', async (request) => {
const skipAuth = request.routeOptions?.config?.skipAuth;
const allowAnonymous = request.routeOptions?.config?.allowAnonymous;

if (skipAuth) {
return;
}
try {
await request.jwtVerify();
} catch (err) {
if (allowAnonymous) {
return;
}
request.log.warn(`JWT verification failed with error: ${(err as Error).message}`);
throw new UnauthorizedError();
}
});
await withAuth(fastify, { secret: config.JWT_SECRET });

fastify.get<{
Querystring: { email: string; customerName: string; country: string; postalCode: string; companyVatId?: string };
Expand Down
Loading
Loading