All files / src/Batch UpgatesCreateWebhooks.ts

53.33% Statements 16/30
16.66% Branches 1/6
66.66% Functions 2/3
53.33% Lines 16/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 928x 8x 8x 8x 8x   8x 8x     8x 8x   8x     8x       1x   1x 1x   1x                                                                                             1x                                      
import { ApplicationInstall } from '@orchesty/nodejs-sdk/dist/lib/Application/Database/ApplicationInstall';
import Webhook from '@orchesty/nodejs-sdk/dist/lib/Application/Database/Webhook';
import ABatchNode from '@orchesty/nodejs-sdk/dist/lib/Batch/ABatchNode';
import TopologyRunner from '@orchesty/nodejs-sdk/dist/lib/Topology/TopologyRunner';
import { HttpMethods } from '@orchesty/nodejs-sdk/dist/lib/Transport/HttpMethods';
import BatchProcessDto from '@orchesty/nodejs-sdk/dist/lib/Utils/BatchProcessDto';
import ResultCode from '@orchesty/nodejs-sdk/dist/lib/Utils/ResultCode';
import crypto from 'crypto';
import UpgatesApplication from '../UpgatesApplication';
 
export const NAME = 'upgates-create-webhooks';
const UPGATES_CREATE_WEBHOOK_ENDPOINT = 'api/v2/webhooks';
 
export default class UpgatesCreateWebhooks extends ABatchNode {
 
    public getName(): string {
        return NAME;
    }
 
    public async processAction(dto: BatchProcessDto): Promise<BatchProcessDto> {
        const app = this.getApplication<UpgatesApplication>();
 
        const webhookIndex = Number(dto.getBatchCursor('0'));
        const webhooks = app.getWebhookSubscriptions();
 
        Iif (webhooks.length > 0) {
            const appInstall = await this.getApplicationInstallFromProcess(dto);
            const repo = this.getDbClient().getRepository(Webhook);
 
            const token = this.getRandomToken();
            const requestDto = app.getRequestDto(
                dto,
                appInstall,
                HttpMethods.POST,
                UPGATES_CREATE_WEBHOOK_ENDPOINT,
                JSON.stringify({
                    name: webhooks[webhookIndex].getName(),
                    event: webhooks[webhookIndex].getName(),
                    url: TopologyRunner.getWebhookUrl(
                        webhooks[webhookIndex].getTopology(),
                        webhooks[webhookIndex].getNode(),
                        token,
                    ),
                }),
            );
 
            let res;
            try {
                res = await this.getSender().send<IResponse>(requestDto);
                const respBody = res.getJsonBody();
 
                await repo.insert(new Webhook()
                    .setWebhookId(respBody.webhook.id.toString())
                    .setUser(appInstall.getUser())
                    .setNode(webhooks[webhookIndex].getNode())
                    .setToken(token)
                    .setApplication(app.getName())
                    .setTopology(webhooks[webhookIndex].getTopology())
                    .setName(webhooks[webhookIndex].getName()));
 
                if (webhooks.length - 1 > webhookIndex) {
                    dto.setBatchCursor((webhookIndex + 1).toString());
                }
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            } catch (e) {
                appInstall.setEnabled(false);
                await this.getDbClient().getRepository(ApplicationInstall).update(appInstall);
 
                dto.setStopProcess(ResultCode.STOP_AND_FAILED, res?.getBody() ?? 'Webhook could not be registered!');
            }
        }
 
        return dto;
    }
 
    private getRandomToken(): string {
        return crypto.randomBytes(64).toString('hex');
    }
 
}
 
export interface IResponse {
    webhook: {
        id: number;
        // eslint-disable-next-line @typescript-eslint/naming-convention
        active_yn: boolean;
        name: string;
        url: string;
        event: string;
    };
}