diff --git a/package-lock.json b/package-lock.json index 7d119b5c..a944efa1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitfinex/bfx-report", - "version": "5.2.0", + "version": "5.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitfinex/bfx-report", - "version": "5.2.0", + "version": "5.2.1", "license": "Apache-2.0", "dependencies": { "@bitfinex/bfx-facs-deflate": "git+https://github.com/bitfinexcom/bfx-facs-deflate.git", diff --git a/package.json b/package.json index e6637d33..bbfac92c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitfinex/bfx-report", - "version": "5.2.0", + "version": "5.2.1", "description": "Reporting tool", "main": "worker.js", "engines": { diff --git a/workers/loc.api/di/app.deps.js b/workers/loc.api/di/app.deps.js index 699ebe3e..f3af548b 100644 --- a/workers/loc.api/di/app.deps.js +++ b/workers/loc.api/di/app.deps.js @@ -185,7 +185,8 @@ module.exports = ({ TYPES.ProcessorQueue, TYPES.AggregatorQueue, TYPES.WriteDataToStream, - TYPES.PdfWriter + TYPES.PdfWriter, + TYPES.I18next ] )) bind(TYPES.Aggregator).toConstantValue( diff --git a/workers/loc.api/queue/processor.js b/workers/loc.api/queue/processor.js index 60866a31..ed44a73d 100644 --- a/workers/loc.api/queue/processor.js +++ b/workers/loc.api/queue/processor.js @@ -15,17 +15,36 @@ const { createUniqueFileName } = require('./helpers') -const { isAuthError } = require('../helpers') +const { + isAuthError, + getTranslator +} = require('../helpers') +const TRANSLATION_NAMESPACES = require( + '../i18next/translation.namespaces' +) const processReportFile = async (deps, args) => { const { data, filePath, - streamSet + streamSet, + isUnauth } = args - const write = data?.isUnauth - ? 'Your file could not be completed, please try again' + const language = data?.args?.params?.language + const translate = getTranslator( + { i18next: deps.i18next }, + { + lng: language, + ns: TRANSLATION_NAMESPACES.PDF + } + ) + const defaultUnauthMsg = 'Your file could not be completed, please try again' + const unauthMsg = translate(defaultUnauthMsg, { + prop: 'template.errorMessage' + }) + const write = isUnauth + ? unauthMsg : data const writable = createWriteStream(filePath) @@ -36,8 +55,8 @@ const processReportFile = async (deps, args) => { .createPDFStream({ jobData: data, pdfCustomTemplateName: data?.pdfCustomTemplateName, - language: data?.args?.params.language, - isError: data?.isUnauth + language, + isError: isUnauth }) streamSet.add(pdfStream) @@ -85,7 +104,8 @@ module.exports = ( processorQueue, aggregatorQueue, writeDataToStream, - pdfWriter + pdfWriter, + i18next ) => { processorQueue.on('completed', (result) => { aggregatorQueue.addJob({ @@ -159,12 +179,14 @@ module.exports = ( await processReportFile( { writeDataToStream, - pdfWriter + pdfWriter, + i18next }, { data, filePath, - streamSet + streamSet, + isUnauth } ) } @@ -190,12 +212,14 @@ module.exports = ( processorQueue.emit('error:unlink', job) } - job.done(err) - if (isAuthError(err)) { + job.done() processorQueue.emit('error:auth', job) + + return } + job.done(err) processorQueue.emit('error:base', err, job) } finally { for (const stream of streamSet) { diff --git a/workers/loc.api/queue/write-data-to-stream/auth-token-manager.js b/workers/loc.api/queue/write-data-to-stream/auth-token-manager.js new file mode 100644 index 00000000..e66db2a4 --- /dev/null +++ b/workers/loc.api/queue/write-data-to-stream/auth-token-manager.js @@ -0,0 +1,89 @@ +'use strict' + +const { AuthError } = require('../../errors') + +const regenerateAuthToken = async (auth, deps) => { + const { authToken } = auth ?? {} + + if ( + !authToken || + typeof authToken !== 'string' + ) { + return auth + } + + const { + rService, + getDataFromApi + } = deps ?? {} + + try { + const opts = { + ttl: 60 * 60, + writePermission: false + } + + const res = await getDataFromApi({ + getData: (s, args) => rService._generateToken(args, opts), + args: { auth }, + callerName: 'REPORT_FILE_WRITER', + eNetErrorAttemptsTimeframeMin: 10 / 60, + eNetErrorAttemptsTimeoutMs: 1000, + shouldNotInterrupt: true + }) + + const [authToken] = Array.isArray(res) ? res : [null] + + if (!authToken) { + throw new AuthError() + } + + return { authToken } + } catch (err) { + throw new AuthError({ + data: { + isAuthTokenGenerationError: true, + rootMessage: err.toString() + } + }) + } +} + +const invalidateAuthToken = async (auth, deps) => { + const { authToken } = auth ?? {} + + if ( + !authToken || + typeof authToken !== 'string' + ) { + return + } + + const { + rService, + getDataFromApi + } = deps ?? {} + + try { + await getDataFromApi({ + getData: (s, args) => rService._invalidateAuthToken(args), + args: { auth, params: { authToken } }, + callerName: 'REPORT_FILE_WRITER', + eNetErrorAttemptsTimeframeMin: 10 / 60, + eNetErrorAttemptsTimeoutMs: 1000, + shouldNotInterrupt: true + }) + } catch (err) { + throw new AuthError({ + data: { + isAuthTokenInvalidationError: true, + rootMessage: err.toString() + } + }) + } +} + +module.exports = { + regenerateAuthToken, + invalidateAuthToken +} diff --git a/workers/loc.api/queue/write-data-to-stream/index.js b/workers/loc.api/queue/write-data-to-stream/index.js index 864f97a8..4ca0a945 100644 --- a/workers/loc.api/queue/write-data-to-stream/index.js +++ b/workers/loc.api/queue/write-data-to-stream/index.js @@ -12,6 +12,10 @@ const { write, progress } = require('./helpers') +const { + regenerateAuthToken, + invalidateAuthToken +} = require('./auth-token-manager') module.exports = ( rService, @@ -36,8 +40,15 @@ module.exports = ( const propName = jobData.propNameForPagination const formatSettings = jobData.formatSettings + const auth = await regenerateAuthToken( + jobData?.args?.auth, + { + rService, + getDataFromApi + } + ) const _args = { - auth: { ...jobData?.args?.auth }, + auth, params: omitExtraParamFieldsForReportExport(jobData?.args?.params) } @@ -48,7 +59,7 @@ module.exports = ( const getSymbols = rService.getSymbols.bind(rService) const symbols = (await getDataFromApi({ getData: getSymbols, - args: { auth: { ...jobData?.args?.auth } }, + args: { auth }, callerName: 'REPORT_FILE_WRITER', shouldNotInterrupt: true })) ?? {} @@ -176,4 +187,12 @@ module.exports = ( currIterationArgs.params.end = lastItem[propName] - 1 } } + + await invalidateAuthToken( + auth, + { + rService, + getDataFromApi + } + ) }