UNPKG

@fusebit-int/xero-connector

Version:
57 lines 2.85 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Service = void 0; const crypto_1 = __importDefault(require("crypto")); const superagent_1 = __importDefault(require("superagent")); const oauth_connector_1 = require("@fusebit-int/oauth-connector"); class Service extends oauth_connector_1.OAuthConnector.Service { getEventsFromPayload(ctx) { return ctx.req.body.events; } getAuthIdFromEvent(ctx, event) { return event.tenantId; } eventToString(event) { return `{\n "resourceUrl": "${event.resourceUrl}",\n "resourceId": "${event.resourceId}",\n "eventDateUtc": "${event.eventDateUtc}",\n "eventType": "${event.eventType}",\n "eventCategory": "${event.eventCategory}",\n "tenantId": "${event.tenantId}",\n "tenantType": "${event.tenantType}"\n}`; } bodyToString(body) { return `{"events":[${body.events.map((event) => this.eventToString(event)).join(',')}],"firstEventSequence": ${body.firstEventSequence},"lastEventSequence": ${body.lastEventSequence}, "entropy": "${body.entropy}"}`; } async validateWebhookEvent(ctx) { const signingSecret = ctx.state.manager.config.configuration.signingSecret; const requestSignature = ctx.req.headers['x-xero-signature']; const body = ctx.req.body; // Convert the body to a string: const bodyString = this.bodyToString(body); const calculatedSignature = crypto_1.default.createHmac('sha256', signingSecret).update(bodyString).digest('base64'); const calculatedSignatureBuffer = Buffer.from(calculatedSignature, 'utf8'); const requestSignatureBuffer = Buffer.from(requestSignature, 'utf8'); const result = crypto_1.default.timingSafeEqual(calculatedSignatureBuffer, requestSignatureBuffer); // Xero has specific requirements about the return code: it must be 401, and there must be no body. if (!result) { ctx.throw(401, { hideBody: true }); } return true; } async initializationChallenge(ctx) { if (ctx.req.body.events.length === 0 && ctx.req.body.entropy) { return true; } return false; } async getTokenAuthId(ctx, token) { // Get the connections, which contains the list of tenants, and use those as ids. const connections = await superagent_1.default .get('https://api.xero.com/connections') .set('Authorization', `Bearer ${token.access_token}`); return connections.body.map((tenant) => tenant.tenantId); } getWebhookEventType(event) { return event.eventType; } } exports.Service = Service; //# sourceMappingURL=Service.js.map