Skip to content

Commit

Permalink
Added optional shared key authentication for BPP Webhook communication
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhishek Y committed Jun 22, 2024
1 parent adaa914 commit cb5fcf7
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
9 changes: 6 additions & 3 deletions src/controllers/bpp.request.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import * as AmqbLib from "amqplib";
import { Exception, ExceptionType } from "../models/exception.model";
import { acknowledgeACK } from "../utils/acknowledgement.utils";
import { GatewayUtils } from "../utils/gateway.utils";
import { ActionUtils } from "../utils/actions.utils";
import { RequestCache } from "../utils/cache/request.cache.utils";
import { parseRequestCache } from "../schemas/cache/request.cache.schema";
import { getSubscriberDetails } from "../utils/lookup.utils";
import { Locals } from "../interfaces/locals.interface";
import moment from "moment";
import { getConfig } from "../utils/config.utils";
Expand All @@ -19,6 +17,7 @@ import {
createTelemetryEvent,
processTelemetry
} from "../utils/telemetry.utils";
import { createBppWebhookAuthHeaderConfig } from "../utils/auth.utils";

export const bppNetworkRequestHandler = async (
req: Request,
Expand Down Expand Up @@ -92,7 +91,11 @@ export const bppNetworkRequestSettler = async (
break;
}
case ClientConfigType.webhook: {
requestCallback(requestBody);
let axios_config = {};
if (getConfig().app.useHMACForWebhook) {
axios_config = await createBppWebhookAuthHeaderConfig(requestBody);
}
requestCallback(requestBody, axios_config);
break;
}
case ClientConfigType.messageQueue: {
Expand Down
4 changes: 3 additions & 1 deletion src/schemas/configs/app.config.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ export const appConfigSchema = z.object({
mandateLayer2Config: z.boolean().optional(),
unsolicitedWebhook: z.object({
url: z.string().optional()
}).optional()
}).optional(),
useHMACForWebhook: z.boolean().optional(),
sharedKeyForWebhookHMAC: z.string().optional(),
});

export type AppConfigDataType = z.infer<typeof appConfigSchema>;
Expand Down
31 changes: 26 additions & 5 deletions src/utils/auth.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,8 @@ export const createAuthorizationHeader = async (message: any) => {
getConfig().app.privateKey || ""
);
const subscriber_id = getConfig().app.subscriberId;
const header = `Signature keyId="${subscriber_id}|${
getConfig().app.uniqueKey
}|ed25519",algorithm="ed25519",created="${created}",expires="${expires}",headers="(created) (expires) digest",signature="${signature}"`;
const header = `Signature keyId="${subscriber_id}|${getConfig().app.uniqueKey
}|ed25519",algorithm="ed25519",created="${created}",expires="${expires}",headers="(created) (expires) digest",signature="${signature}"`;
return header;
};

Expand Down Expand Up @@ -204,8 +203,30 @@ export const createAuthHeaderConfig = async (request: any) => {
timeout: getConfig().app.httpTimeout
};
logger.info(
`Axios Config for Request from ${
getConfig().app.mode + " " + getConfig().app.gateway.mode
`Axios Config for Request from ${getConfig().app.mode + " " + getConfig().app.gateway.mode
}:==>\n${JSON.stringify(axios_config)}\n\n`
);
return axios_config;
};

const createBppWebhookAuthHeader = async (request: any) => {
const sodium = _sodium;
const key = getConfig().app.sharedKeyForWebhookHMAC || "";
const keyUint8Array = sodium.from_string(key);
const messageUint8Array = sodium.from_string(JSON.stringify(request));
const hmac = sodium.crypto_auth(messageUint8Array, keyUint8Array);
return sodium.to_hex(hmac);
};

export const createBppWebhookAuthHeaderConfig = async (request: any) => {
const header = await createBppWebhookAuthHeader(request);
const axios_config = {
headers: {
authorization: header
}
};
logger.info(
`Axios Config for Request from ${getConfig().app.mode + " " + getConfig().app.gateway.mode
}:==>\n${JSON.stringify(axios_config)}\n\n`
);
return axios_config;
Expand Down
14 changes: 6 additions & 8 deletions src/utils/callback.utils.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import axios from "axios";
import axios, { AxiosRequestConfig } from "axios";
import { Exception, ExceptionType } from "../models/exception.model";
import {
BecknErrorDataType,
becknErrorSchema
BecknErrorDataType
} from "../schemas/becknError.schema";
import { requestCallbackSchema } from "../schemas/callbacks/request.callback.schema";
import { responseCallbackSchema } from "../schemas/callbacks/response.callback.schema";
import {
ClientConfigType,
WebhookClientConfigDataType
} from "../schemas/configs/client.config.schema";
import { GatewayMode } from "../schemas/configs/gateway.app.config.schema";
import { getConfig } from "./config.utils";
import logger from "./logger.utils";

async function makeClientCallback(data: any) {
async function makeClientCallback(data: any, axios_config?: AxiosRequestConfig) {
try {
if (getConfig().client.type != ClientConfigType.webhook) {
throw new Exception(
Expand All @@ -30,7 +28,7 @@ async function makeClientCallback(data: any) {
console.log(
`TMTR - ${data?.context?.message_id} - ${getConfig().app.mode}-${getConfig().app.gateway.mode} FORW EXIT: ${new Date().valueOf()}`
);
const response = await axios.post(clientConnectionConfig.url, data);
const response = await axios.post(clientConnectionConfig.url, data, axios_config || {});
logger.info(
`Response from Webhook:==>\n ${JSON.stringify(
response.data
Expand Down Expand Up @@ -88,10 +86,10 @@ export async function responseCallback(data: any) {
}
}

export async function requestCallback(data: any) {
export async function requestCallback(data: any, axios_config?: AxiosRequestConfig) {
try {
const callbackData = requestCallbackSchema.parse(data);
await makeClientCallback(callbackData);
await makeClientCallback(callbackData, axios_config);
} catch (error) {
if (error instanceof Exception) {
throw error;
Expand Down

0 comments on commit cb5fcf7

Please sign in to comment.