File

src/shared/utils/webhook/webhook.service.ts

Description

Service for handling webhooks in the application.

Index

Methods

Constructor

constructor(httpService: HttpService, sessionService: SessionService, sessionLogger: SessionLoggerService)

Constructor for WebhookService.

Parameters :
Name Type Optional
httpService HttpService No
sessionService SessionService No
sessionLogger SessionLoggerService No

Methods

sendWebhook
sendWebhook(values: literal type)

Sends a webhook with the optional provided credentials, return the response data.

Parameters :
Name Type Optional
values literal type No
Returns : any
Async sendWebhookNotification
sendWebhookNotification(session: Session, logContext: SessionLogContext, notification: Notification)

Sends a webhook notification for a session.

Parameters :
Name Type Optional
session Session No
logContext SessionLogContext No
notification Notification No
Returns : any
import { HttpService } from "@nestjs/axios";
import { Injectable } from "@nestjs/common";
import { firstValueFrom } from "rxjs";
import {
    Notification,
    Session,
} from "../../../session/entities/session.entity";
import { SessionService } from "../../../session/session.service";
import { SessionLoggerService } from "../logger/session-logger.service";
import { SessionLogContext } from "../logger/session-logger-context";
import { WebhookConfig } from "./webhook.dto";

/**
 * Response from a webhook to receive credentials.
 */
export class WebhookResponse {
    [key: string]: Record<string, any>;
}

/**
 * Service for handling webhooks in the application.
 */
@Injectable()
export class WebhookService {
    /**
     * Constructor for WebhookService.
     * @param httpService
     * @param sessionService
     * @param sessionLogger
     */
    constructor(
        private httpService: HttpService,
        private sessionService: SessionService,
        private sessionLogger: SessionLoggerService,
    ) {}

    /**
     * Sends a webhook with the optional provided credentials, return the response data.
     */
    sendWebhook(values: {
        webhook: WebhookConfig;
        logContext: SessionLogContext;
        session: Session;
        credentials?: any[];
        expectResponse: boolean;
    }) {
        const headers: Record<string, string> = {};

        if (values.webhook.auth && values.webhook.auth.type === "apiKey") {
            headers[values.webhook.auth.config.headerName] =
                values.webhook.auth.config.value;
        }
        this.sessionLogger.logSession(values.logContext, "Sending webhook", {
            webhookUrl: values.webhook.url,
            authType: values.webhook.auth?.type || "none",
        });

        return firstValueFrom(
            this.httpService.post(
                values.webhook.url,
                {
                    credentials: values.credentials,
                    session: values.session.id,
                },
                {
                    headers,
                },
            ),
        ).then(
            async (webhookResponse) => {
                this.sessionLogger.logSession(
                    values.logContext,
                    "Webhook sent successfully",
                    {
                        responseStatus: webhookResponse.status,
                        hasResponseData: !!webhookResponse.data,
                    },
                );

                //check if a redirect URI is passed, we either expect a redirect or claims, but never both.
                if (webhookResponse.data?.redirectUri) {
                    //TODO: do we need to do something with it?
                } else if (webhookResponse.data && values.expectResponse) {
                    //TODO: update this for presentation during issuance
                    //session.credentialPayload!.credentialClaims!["id"].claims = webhookResponse.data;
                    //store received webhook response
                    await this.sessionService.add(values.session.id, {
                        credentialPayload: values.session.credentialPayload,
                    });
                }

                return webhookResponse.data;
            },
            (err) => {
                this.sessionLogger.logSessionError(
                    values.logContext,
                    err,
                    "Error sending webhook",
                    {
                        webhookUrl: values.webhook.url,
                    },
                );
                throw new Error(`Error sending webhook: ${err.message || err}`);
            },
        );
    }

    /**
     * Sends a webhook notification for a session.
     * @param session
     * @param logContext
     * @param notification
     */
    async sendWebhookNotification(
        session: Session,
        logContext: SessionLogContext,
        notification: Notification,
    ) {
        const headers: Record<string, string> = {};
        const webhook = session.notifyWebhook!;

        if (webhook.auth && webhook.auth.type === "apiKey") {
            headers[webhook.auth.config.headerName] = webhook.auth.config.value;
        }
        this.sessionLogger.logSession(
            logContext,
            "Sending webhook notification",
            {
                webhookUrl: webhook.url,
                authType: webhook.auth?.type || "none",
            },
        );

        await firstValueFrom(
            this.httpService.post(
                webhook.url,
                {
                    notification,
                    session: session.id,
                },
                {
                    headers,
                },
            ),
        ).then(
            (webhookResponse) => {
                //TODO: update notification status based on response
                this.sessionLogger.logSession(
                    logContext,
                    "Webhook notification sent successfully",
                    {
                        responseStatus: webhookResponse.status,
                        hasResponseData: !!webhookResponse.data,
                    },
                );
            },
            (err) => {
                this.sessionLogger.logSessionError(
                    logContext,
                    err,
                    "Error sending webhook",
                    {
                        webhookUrl: webhook.url,
                    },
                );
                throw new Error(`Error sending webhook: ${err.message || err}`);
            },
        );
    }
}

results matching ""

    No results matching ""