|
| 1 | +const axios = require('axios'); |
| 2 | +const fs = require('fs'); |
| 3 | +const { messages } = require('elasticio-node'); |
| 4 | +const { Logger } = require('@elastic.io/component-commons-library'); |
| 5 | +const common = require('../common.js'); |
| 6 | +const { getSecret, refreshToken } = require('../util'); |
| 7 | + |
| 8 | +if (fs.existsSync('.env')) { |
| 9 | + // eslint-disable-next-line global-require |
| 10 | + require('dotenv').config(); |
| 11 | +} |
| 12 | + |
| 13 | +const logger = Logger.getLogger(); |
| 14 | + |
| 15 | +const SALESFORCE_VERSION = common.globalConsts.SALESFORCE_API_VERSION; |
| 16 | +const { REFRESH_TOKEN_RETRIES } = common.globalConsts; |
| 17 | + |
| 18 | +async function processAction(msg, cfg) { |
| 19 | + const { method, path, body } = msg.body; |
| 20 | + const { secretId } = cfg; |
| 21 | + let accessToken; |
| 22 | + let instanceUrl; |
| 23 | + if (secretId) { |
| 24 | + logger.debug('Trying to get access token'); |
| 25 | + try { |
| 26 | + this.logger.debug('Fetching credentials by secretId'); |
| 27 | + const { credentials } = await getSecret(this, secretId); |
| 28 | + accessToken = credentials.access_token; |
| 29 | + instanceUrl = credentials.undefined_params.instance_url; |
| 30 | + logger.debug('Access token has been received'); |
| 31 | + } catch (e) { |
| 32 | + logger.error('Got error %s while request token', e.name || ''); |
| 33 | + } |
| 34 | + } |
| 35 | + let result; |
| 36 | + let isSuccess = false; |
| 37 | + let iteration = REFRESH_TOKEN_RETRIES; |
| 38 | + |
| 39 | + do { |
| 40 | + iteration -= 1; |
| 41 | + try { |
| 42 | + logger.debug('Iteration: %s', REFRESH_TOKEN_RETRIES - iteration); |
| 43 | + logger.info('Trying to call method %s', method); |
| 44 | + const basePath = `/services/data/v${SALESFORCE_VERSION}/`; |
| 45 | + const resourcePath = (path.trim().charAt(0) === '/') ? path.trim().slice(1) : path.trim(); |
| 46 | + const rawRequestPath = `${instanceUrl}${basePath}${resourcePath}`; |
| 47 | + const lowerCasedMethod = method.toLowerCase(); |
| 48 | + const rawRequestConfig = { |
| 49 | + method: lowerCasedMethod, |
| 50 | + url: rawRequestPath, |
| 51 | + headers: { |
| 52 | + Authorization: `Bearer ${accessToken && accessToken.replace(/"|'/g, '')}`, |
| 53 | + 'Content-Type': 'application/json', |
| 54 | + }, |
| 55 | + data: body || '', |
| 56 | + }; |
| 57 | + logger.info('Raw request started'); |
| 58 | + const rawRequest = await axios(rawRequestConfig); |
| 59 | + logger.info('Raw request complete'); |
| 60 | + result = messages.newMessageWithBody(rawRequest.data); |
| 61 | + isSuccess = true; |
| 62 | + logger.info('Method %s was successfully executed', method); |
| 63 | + break; |
| 64 | + } catch (e) { |
| 65 | + logger.error('Got error %s', e.name || ''); |
| 66 | + if (e.name === 'INVALID_SESSION_ID') { |
| 67 | + try { |
| 68 | + logger.debug('Session is expired, trying to refresh token...'); |
| 69 | + accessToken = await refreshToken(this, secretId); |
| 70 | + this.logger.debug('Token is successfully refreshed'); |
| 71 | + } catch (err) { |
| 72 | + logger.error('Failed to refresh token'); |
| 73 | + } |
| 74 | + } else { |
| 75 | + throw e; |
| 76 | + } |
| 77 | + } |
| 78 | + } while (iteration > 0); |
| 79 | + |
| 80 | + if (!isSuccess) { |
| 81 | + throw new Error('Failed to fetch and/or refresh token, retries exceeded'); |
| 82 | + } |
| 83 | + return result; |
| 84 | +} |
| 85 | + |
| 86 | +module.exports.process = processAction; |
0 commit comments