feat: Verify paddle webhooks

This commit is contained in:
Faruk AYDIN
2023-03-21 22:02:11 +03:00
parent 4202f963c3
commit e1d26325f3
9 changed files with 201 additions and 8 deletions

View File

@@ -59,6 +59,7 @@
"nodemailer": "6.7.0",
"oauth-1.0a": "^2.2.6",
"objection": "^3.0.0",
"paddle-sdk": "^3.3.0",
"pg": "^8.7.1",
"stripe": "^11.13.0",
"winston": "^3.7.1"

View File

@@ -40,13 +40,15 @@ app.use(
},
})
);
app.use(express.urlencoded({
extended: false,
limit: appConfig.requestBodySizeLimit,
verify(req, res, buf) {
(req as IRequest).rawBody = buf;
},
}));
app.use(
express.urlencoded({
extended: true,
limit: appConfig.requestBodySizeLimit,
verify(req, res, buf) {
(req as IRequest).rawBody = buf;
},
})
);
app.use(cors(corsOptions));
app.use('/', router);

View File

@@ -41,6 +41,7 @@ type AppConfig = {
isCloud: boolean;
paddleVendorId: number;
paddleVendorAuthCode: string;
paddlePublicKey: string;
licenseKey: string;
sentryDsn: string;
};
@@ -111,6 +112,7 @@ const appConfig: AppConfig = {
isCloud: process.env.AUTOMATISCH_CLOUD === 'true',
paddleVendorId: Number(process.env.PADDLE_VENDOR_ID),
paddleVendorAuthCode: process.env.PADDLE_VENDOR_AUTH_CODE,
paddlePublicKey: process.env.PADDLE_PUBLIC_KEY,
licenseKey: process.env.LICENSE_KEY,
sentryDsn: process.env.SENTRY_DSN,
};

View File

@@ -0,0 +1,14 @@
import { Response } from 'express';
import { IRequest } from '@automatisch/types';
import Billing from '../../helpers/billing/index.ee';
export default async (request: IRequest, response: Response) => {
const isVerified = Billing.paddleClient.verifyWebhookData(request.body);
if (!isVerified) {
return response.sendStatus(401);
}
// TODO: Handle Paddle webhooks
return response.sendStatus(200);
};

View File

@@ -1,4 +1,5 @@
import appConfig from '../../config/app';
import paddleClient from './paddle.ee';
import paddlePlans from './plans.ee';
const paddleInfo = {
@@ -7,6 +8,7 @@ const paddleInfo = {
};
const billing = {
paddleClient,
paddlePlans,
paddleInfo,
};

View File

@@ -0,0 +1,10 @@
import PaddleSDK from 'paddle-sdk';
import appConfig from '../../config/app';
const paddleClient = new PaddleSDK(
appConfig.paddleVendorId.toString(),
appConfig.paddleVendorAuthCode,
appConfig.paddlePublicKey
);
export default paddleClient;

View File

@@ -1,10 +1,12 @@
import { Router } from 'express';
import graphQLInstance from '../helpers/graphql-instance';
import webhooksRouter from './webhooks';
import paddleRouter from './paddle.ee';
const router = Router();
router.use('/graphql', graphQLInstance);
router.use('/webhooks', webhooksRouter);
router.use('/paddle', paddleRouter);
export default router;

View File

@@ -0,0 +1,19 @@
import { Response, Router, NextFunction, RequestHandler } from 'express';
import { IRequest } from '@automatisch/types';
import webhooksHandler from '../controllers/paddle/webhooks.ee';
const router = Router();
const exposeError =
(handler: RequestHandler) =>
async (req: IRequest, res: Response, next: NextFunction) => {
try {
await handler(req, res, next);
} catch (err) {
next(err);
}
};
router.post('/webhooks', exposeError(webhooksHandler));
export default router;