UNPKG

@event-inc/connections

Version:

Event Inc is a fully managed event bus lets you send and receive data across mission-critical cloud apps, databases and warehouses.

164 lines (145 loc) 4.21 kB
import { OauthConnections, OauthConnectionTypes } from '@event-inc/types'; import { makeHttpNetworkCall, matchResultAndHandleHttpError, } from '@event-inc/utils'; import { identity } from 'ramda'; import jwt_decode from 'jwt-decode'; interface OauthConnectionOptions { OAUTH_APP_CLIENT_ID: string; OAUTH_APP_CLIENT_SECRET: string; type: OauthConnections; } interface Tenants { id: string; tenantId: string; tenantType: string; tenantName: string; createdDateUtc: string; updatedDateUtc: string; authEventId: string; } []; const endpoints = { xero: 'https://identity.xero.com/connect/token', }; const deleteEndpoints = { xero: 'https://api.xero.com/connections/{connectionId}', }; export class OauthConnection { private readonly OAUTH_APP_CLIENT_ID: string; private readonly OAUTH_APP_CLIENT_SECRET: string; private readonly type: string; constructor({ OAUTH_APP_CLIENT_ID, OAUTH_APP_CLIENT_SECRET, type, }: OauthConnectionOptions) { this.OAUTH_APP_CLIENT_ID = OAUTH_APP_CLIENT_ID; this.OAUTH_APP_CLIENT_SECRET = OAUTH_APP_CLIENT_SECRET; this.type = type; } getOauthDetails = () => { switch (this.type) { case OauthConnectionTypes.Xero: return { endpoint: endpoints[this.type], headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: `Basic ${Buffer.from( `${this.OAUTH_APP_CLIENT_ID}:${this.OAUTH_APP_CLIENT_SECRET}` ).toString('base64')}`, }, sourceIntegrationDefinitionId: 'conn_def_src_MTY4ODc2MzM3ODY2OQ::OWE2NDdmYjAtZjFlMy00MWEyLTgwMTctMzVhODMxYTBkOWNi', destinationIntegrationDefinitionId: 'conn_def_dst_MTY4NjA3MDUyOTk1OA::MTgwM2E1NGItMTYxMC00NjE4LTk1NTItNjBjY2I1NmY1ZmQx', }; } }; getOauthFormData = ({ accessToken, refreshToken, }: { accessToken: string; refreshToken: string; }) => { switch (this.type) { case OauthConnectionTypes.Xero: return { XERO_REFRESH_TOKEN: refreshToken, XERO_ACCESS_TOKEN: accessToken, XERO_CLIENT_ID: this.OAUTH_APP_CLIENT_ID, XERO_CLIENT_SECRET: this.OAUTH_APP_CLIENT_SECRET, }; } }; deleteOauthConnection = async ({ connectionId, accessToken, }: { connectionId: string; accessToken: string; }) => { const deleteEndpoint = deleteEndpoints[this.type as OauthConnections]; const response = await makeHttpNetworkCall({ method: 'DELETE', url: deleteEndpoint.replace('{connectionId}', connectionId), headers: { Authorization: `Bearer ${accessToken}`, }, }); return matchResultAndHandleHttpError(response, identity); }; getTenantId = async (accessToken: string) => { switch (this.type) { case OauthConnectionTypes.Xero: const decodedToken: { authentication_event_id: string; } = jwt_decode(accessToken); const response = await makeHttpNetworkCall({ method: 'GET', url: 'https://api.xero.com/connections', headers: { Authorization: `Bearer ${accessToken}`, }, params: { authEventId: decodedToken?.authentication_event_id, }, }); let { data } = matchResultAndHandleHttpError(response, identity) as { data: Tenants[]; }; if (data?.length === 0 || data?.length > 1) { const existingTenants = await this.getAuthorizedTenants(accessToken); const tenantNames = existingTenants ?.map((item) => item.tenantName) ?.join(', '); const existingTenantsMessage = tenantNames?.length > 0 ? ` The following tenants are currently connected: ${tenantNames}.` : ''; throw new Error( `No tenant was explicitly selected on connect.${existingTenantsMessage}Ensure you disconnect and connect again with a single tenant selected.` ); } return data?.[0]?.id; } }; getAuthorizedTenants = async (accessToken: string) => { switch (this.type) { case OauthConnectionTypes.Xero: const response = await makeHttpNetworkCall({ method: 'GET', url: 'https://api.xero.com/connections', headers: { Authorization: `Bearer ${accessToken}`, }, }); const { data } = matchResultAndHandleHttpError(response, identity) as { data: Tenants[]; }; return data; } }; }