diff --git a/.dockerignore b/.dockerignore index 752df873..7d350ac2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -15,6 +15,7 @@ bfx-reports-framework/config/*.json bfx-reports-framework/config/facs/*.json bfx-reports-framework/logs/*.log bfx-reports-framework/csv +bfx-reports-framework/report-files bfx-report-ui/build bfx-report-ui/bfx-report-express/logs/*.log bfx-report-ui/bfx-report-express/config/*.json diff --git a/.env.example b/.env.example index 9f778853..45b35750 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ +REPO_OWNER=bitfinexcom REPO_BRANCH=master IS_BFX_API_STAGING=0 IS_DEV_ENV=0 diff --git a/.github/workflows/build-electron-app.yml b/.github/workflows/build-electron-app.yml index e0124c7b..6f2cded9 100644 --- a/.github/workflows/build-electron-app.yml +++ b/.github/workflows/build-electron-app.yml @@ -22,6 +22,9 @@ on: isNotarizeDisabled: description: 'Is notarize disabled (true / 1)?' required: false + repoOwner: + description: 'Repository owner for auto-update' + required: false env: DOCKER_BUILDKIT: 1 @@ -36,11 +39,6 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive - - name: Set repo owner - run: | - sed -i -e \ - "s/owner: '.*'/owner: '${{ github.repository_owner }}'/g" \ - "./electron-builder-config.js" - if: github.event.inputs.version != '' name: Set release version run: | @@ -55,9 +53,16 @@ jobs: name: Use BFX API Staging for queries run: | echo "IS_BFX_API_STAGING=1" >> $GITHUB_ENV + - name: Set repository owner for auto-update + run: | + if [[ "${{ github.event.inputs.repoOwner }}" != "" ]]; then + echo "REPO_OWNER=${{ github.event.inputs.repoOwner }}" >> $GITHUB_ENV + else + echo "REPO_OWNER=${{ github.repository_owner }}" >> $GITHUB_ENV + fi - name: Cache Electron binaries id: electron-cache - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: electron-cache-v1 with: @@ -69,7 +74,7 @@ jobs: ${{ runner.os }}-build-${{ env.cache-name }}- - name: Build release id: release-builder - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 continue-on-error: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -82,14 +87,14 @@ jobs: - name: Zip Linux Unpacked build run: zip -r dist/linux-unpacked.zip dist/linux-unpacked - name: Upload Linux Unpacked build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: linux-unpacked path: dist/linux-unpacked.zip - name: Zip Win Unpacked build run: zip -r dist/win-unpacked.zip dist/win-unpacked - name: Upload Win Unpacked build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: win-unpacked path: dist/win-unpacked.zip @@ -110,11 +115,6 @@ jobs: run: | brew install gnu-sed echo "$(brew --prefix)/opt/gnu-sed/libexec/gnubin" >> $GITHUB_PATH - - name: Set repo owner - run: | - sed -i -e \ - "s/owner: '.*'/owner: '${{ github.repository_owner }}'/g" \ - "./electron-builder-config.js" - if: github.event.inputs.version != '' name: Set release version run: | @@ -133,12 +133,19 @@ jobs: name: Use BFX API Staging for queries run: | echo "IS_BFX_API_STAGING=1" >> $GITHUB_ENV - - uses: actions/setup-node@v3 + - name: Set repository owner for auto-update + run: | + if [[ "${{ github.event.inputs.repoOwner }}" != "" ]]; then + echo "REPO_OWNER=${{ github.event.inputs.repoOwner }}" >> $GITHUB_ENV + else + echo "REPO_OWNER=${{ github.repository_owner }}" >> $GITHUB_ENV + fi + - uses: actions/setup-node@v4 with: node-version: 18.17.1 - name: Cache Electron binaries id: electron-cache - uses: actions/cache@v3 + uses: actions/cache@v4 env: cache-name: electron-cache-v1 with: @@ -149,7 +156,7 @@ jobs: ${{ runner.os }}-build-${{ env.cache-name }}- - name: Build release id: release-builder - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 continue-on-error: false env: APPLE_TEAM_ID: ${{ secrets.BFX_APPLE_TEAM_ID }} @@ -175,7 +182,7 @@ jobs: - name: Zip Mac Unpacked build run: zip -r dist/mac.zip dist/mac - name: Upload Mac Unpacked build - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: mac-unpacked path: dist/mac.zip @@ -188,20 +195,20 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.17.1 - name: Install main dev deps run: npm i --development --no-audit --progress=false --force - name: Download Linux Unpacked build - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: linux-unpacked path: dist - name: Unzip Linux Unpacked build run: unzip dist/linux-unpacked.zip - name: Run tests - uses: coactions/setup-xvfb@v1.0.1 + uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a with: run: npm run e2e - name: Normalize E2E test report @@ -220,20 +227,20 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.17.1 - name: Install main dev deps run: npm i --development --no-audit --progress=false --force - name: Download Linux Unpacked build - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: win-unpacked path: dist - name: Unzip Win Unpacked build run: 7z -y x dist/win-unpacked.zip - name: Run tests - uses: coactions/setup-xvfb@v1.0.1 + uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a with: run: npm run e2e - name: Normalize E2E test report @@ -254,20 +261,20 @@ jobs: uses: actions/checkout@v4 - name: Prepare Mac runner uses: ./.github/actions/prepare-mac-runner - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.17.1 - name: Install main dev deps run: npm i --development --no-audit --progress=false --force - name: Download Mac Unpacked build - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: mac-unpacked path: dist - name: Unzip Mac Unpacked build run: unzip dist/mac.zip - name: Run tests - uses: coactions/setup-xvfb@v1.0.1 + uses: coactions/setup-xvfb@6b00cf1889f4e1d5a48635647013c0508128ee1a with: run: npm run e2e - name: Normalize E2E test report diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4154b2e..acf4b350 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 18.17.1 - name: Setup configs and install deps diff --git a/.github/workflows/e2e-test-report.yml b/.github/workflows/e2e-test-report.yml index f8d8a397..b353f0ad 100644 --- a/.github/workflows/e2e-test-report.yml +++ b/.github/workflows/e2e-test-report.yml @@ -16,6 +16,7 @@ jobs: e2e-web-page-report: name: E2E Web Page Report runs-on: ubuntu-22.04 + if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - uses: dorny/test-reporter@v1 id: linux-e2e-test-results diff --git a/.github/workflows/test-report.yml b/.github/workflows/test-report.yml index 925aaf43..107c4a83 100644 --- a/.github/workflows/test-report.yml +++ b/.github/workflows/test-report.yml @@ -16,6 +16,7 @@ jobs: web-page-report: name: Web Page Report runs-on: ubuntu-22.04 + if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - uses: dorny/test-reporter@v1 id: test-results diff --git a/CHANGELOG.md b/CHANGELOG.md index 690f9523..a4740f0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.20.0] - 2024-03-06 + +### Added + +- Added missing translations for `2FA`. PR: [bfx-report-ui#774](https://github.com/bitfinexcom/bfx-report-ui/pull/774) +- Implemented exporting to PDF support for `Ledgers` and `Tax Reports`. PRs: [bfx-report#347](https://github.com/bitfinexcom/bfx-report/pull/347), [bfx-reports-framework#352](https://github.com/bitfinexcom/bfx-reports-framework/pull/352), [bfx-report-electron#319](https://github.com/bitfinexcom/bfx-report-electron/pull/319), [bfx-ext-pdf-js#4](https://github.com/bitfinexcom/bfx-ext-pdf-js/pull/4), [bfx-report#349](https://github.com/bitfinexcom/bfx-report/pull/349), [bfx-reports-framework#354](https://github.com/bitfinexcom/bfx-reports-framework/pull/354), [bfx-report-ui#775](https://github.com/bitfinexcom/bfx-report-ui/pull/775) +- Added detection for `BFX` auth error: `ERR_AUTH_API: ERR_TOKEN_ALREADY_USED`. PR: [bfx-report#348](https://github.com/bitfinexcom/bfx-report/pull/348) +- Added improvements to the token refresh flow: stop the auth token refresh interval if catch an auth error. PR: [bfx-reports-framework#353](https://github.com/bitfinexcom/bfx-reports-framework/pull/353) +- Added option to set repo owner for auto-update in manual run. PR: [bfx-report-electron#331](https://github.com/bitfinexcom/bfx-report-electron/pull/331) + +### Changed + +- Reworked navigation for the `Movements` report according to the latest UX improvement proposals: remove tabs from wallets & movements, make movements a separate navigation item under `My History`. PR: [bfx-report-ui#771](https://github.com/bitfinexcom/bfx-report-ui/pull/771) +- Reworked navigation for the `My History` section according to the latest UX improvement proposals. PR: [bfx-report-ui#778](https://github.com/bitfinexcom/bfx-report-ui/pull/778) +- Enhanced `loading` and `no data` states representation for reports with tables. PR: [bfx-report-ui#779](https://github.com/bitfinexcom/bfx-report-ui/pull/779) +- Set `90sec` timeout for grc requests to have the same timeout as for api requests. PR: [bfx-report#351](https://github.com/bitfinexcom/bfx-report/pull/351) +- Set `90sec` timeout for `html-pdf` lib. PR: [bfx-reports-framework#355](https://github.com/bitfinexcom/bfx-reports-framework/pull/355) +- Optimized GitHub Actions Workflow for release build. PR: [bfx-report-electron#322](https://github.com/bitfinexcom/bfx-report-electron/pull/322) +- Updated Actions to use Nodejs `v20`. PR: [bfx-report-electron#323](https://github.com/bitfinexcom/bfx-report-electron/pull/323) + +### Fixed + +- Updated UI engines configuration to prevent issues. PR: [bfx-report-ui#772](https://github.com/bitfinexcom/bfx-report-ui/pull/772) +- Fixed `2FA` authorization flow according to: After the first push of the auth button, we should lock the button (till we get any response from this endpoint) to prevent sending several of the same requests. PR: [bfx-report-ui#776](https://github.com/bitfinexcom/bfx-report-ui/pull/776) +- Fixed the potential possibility of duplicated sending for correct `OTP`: it should keep btn disabled until the successful auth will be completed. PR: [bfx-report-ui#780](https://github.com/bitfinexcom/bfx-report-ui/pull/780) +- Fixed 11 `auto-update-toast:width` listeners added. PR: [bfx-report-electron#330](https://github.com/bitfinexcom/bfx-report-electron/pull/330) + ## [4.19.0] - 2024-02-14 ### Added diff --git a/Dockerfile.linux-builder b/Dockerfile.linux-builder index c0354e3a..b6cd6ced 100644 --- a/Dockerfile.linux-builder +++ b/Dockerfile.linux-builder @@ -14,6 +14,7 @@ RUN ./scripts/helpers/install-nodejs.sh ${NODE_VERSION} \ bc \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +RUN chown root:root . COPY . . diff --git a/Dockerfile.mac-builder b/Dockerfile.mac-builder index ad1ea892..020628a3 100644 --- a/Dockerfile.mac-builder +++ b/Dockerfile.mac-builder @@ -14,6 +14,7 @@ RUN ./scripts/helpers/install-nodejs.sh ${NODE_VERSION} \ bc \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +RUN chown root:root . COPY . . diff --git a/Dockerfile.ui-builder b/Dockerfile.ui-builder index 5f193211..ea9b0d63 100644 --- a/Dockerfile.ui-builder +++ b/Dockerfile.ui-builder @@ -8,6 +8,7 @@ ENV IS_DEV_ENV=${IS_DEV_ENV:-0} COPY ./scripts/helpers/install-nodejs.sh ./scripts/helpers/install-nodejs.sh RUN ./scripts/helpers/install-nodejs.sh ${NODE_VERSION} +RUN chown root:root . COPY . . diff --git a/Dockerfile.win-builder b/Dockerfile.win-builder index ee59f7ee..b4119164 100644 --- a/Dockerfile.win-builder +++ b/Dockerfile.win-builder @@ -17,6 +17,7 @@ RUN ./scripts/helpers/install-nodejs.sh ${NODE_VERSION} \ bc \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +RUN chown root:root . COPY . . diff --git a/bfx-report-ui b/bfx-report-ui index 640f4a9d..3bad3486 160000 --- a/bfx-report-ui +++ b/bfx-report-ui @@ -1 +1 @@ -Subproject commit 640f4a9d29e800fbf9f0a9a7ef31c35e85f58b46 +Subproject commit 3bad3486986d3cc5b44f7c85aa33591d55a5ab7c diff --git a/bfx-reports-framework b/bfx-reports-framework index bd237349..be1ed7b4 160000 --- a/bfx-reports-framework +++ b/bfx-reports-framework @@ -1 +1 @@ -Subproject commit bd2373497d981c13ee59f53242b601cbb14ddfca +Subproject commit be1ed7b41947675ed4bee8599fbed1dca747b80e diff --git a/docker-compose.yaml b/docker-compose.yaml index 71f96c1b..e729b589 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -28,6 +28,7 @@ services: IS_PUBLISHED: ${IS_PUBLISHED:-0} GH_TOKEN: ${GH_TOKEN:-} GITHUB_TOKEN: ${GITHUB_TOKEN:-} + REPO_OWNER: ${REPO_OWNER:-} EP_GH_IGNORE_TIME: ${EP_GH_IGNORE_TIME:-true} CURRENT_UID: ${CURRENT_UID:-"1000:1000"} volumes: @@ -52,6 +53,7 @@ services: IS_PUBLISHED: ${IS_PUBLISHED:-0} GH_TOKEN: ${GH_TOKEN:-} GITHUB_TOKEN: ${GITHUB_TOKEN:-} + REPO_OWNER: ${REPO_OWNER:-} EP_GH_IGNORE_TIME: ${EP_GH_IGNORE_TIME:-true} CURRENT_UID: ${CURRENT_UID:-"1000:1000"} volumes: @@ -76,6 +78,7 @@ services: IS_PUBLISHED: ${IS_PUBLISHED:-0} GH_TOKEN: ${GH_TOKEN:-} GITHUB_TOKEN: ${GITHUB_TOKEN:-} + REPO_OWNER: ${REPO_OWNER:-} EP_GH_IGNORE_TIME: ${EP_GH_IGNORE_TIME:-true} CURRENT_UID: ${CURRENT_UID:-"1000:1000"} volumes: diff --git a/electron-builder-config.js b/electron-builder-config.js index 0938f268..c3429703 100644 --- a/electron-builder-config.js +++ b/electron-builder-config.js @@ -12,6 +12,59 @@ const parseEnvValToBool = require( './src/helpers/parse-env-val-to-bool' ) +const electronEnvVars = { + REPO_OWNER: 'bitfinexcom' +} +let electronEnvVarsFromFile = {} + +const electronEnvFilePath = path.join( + __dirname, 'electronEnv.json' +) +const electronEnvExampleFilePath = path.join( + __dirname, 'electronEnv.json.example' +) + +let hasElectronEnv = false +let hasNewElectronEnv = false + +try { + electronEnvVarsFromFile = require(electronEnvFilePath) + Object.assign(electronEnvVars, electronEnvVarsFromFile) + hasElectronEnv = true +} catch (err) {} + +if (!hasElectronEnv) { + try { + electronEnvVarsFromFile = JSON.parse( + fs.readFileSync(electronEnvExampleFilePath, 'utf8') + ) + Object.assign(electronEnvVars, electronEnvVarsFromFile) + fs.writeFileSync( + electronEnvFilePath, + JSON.stringify(electronEnvVars, null, 2), + 'utf8' + ) + hasElectronEnv = true + } catch (err) {} +} + +if (process.env.REPO_OWNER) { + electronEnvVars.REPO_OWNER = process.env.REPO_OWNER +} +if (electronEnvVars.REPO_OWNER !== electronEnvVarsFromFile.REPO_OWNER) { + hasNewElectronEnv = true +} + +if (hasNewElectronEnv) { + try { + fs.writeFileSync( + electronEnvFilePath, + JSON.stringify(electronEnvVars, null, 2), + 'utf8' + ) + } catch (err) {} +} + let version let zippedAppImageArtifactPath let zippedMacArtifactPath @@ -88,7 +141,7 @@ module.exports = { publish: { provider: 'github', repo: 'bfx-report-electron', - owner: 'bitfinexcom', + owner: electronEnvVars.REPO_OWNER, vPrefixedTagName: true, channel: 'latest', @@ -155,6 +208,7 @@ module.exports = { '!bfx-reports-framework/*/*.sh', '!bfx-reports-framework/*.sh', '!bfx-reports-framework/.mocharc.json', + '!bfx-reports-framework/node_modules/phantomjs-prebuilt', '!**/.dockerignore', '!**/*Dockerfile*', diff --git a/electronEnv.json.example b/electronEnv.json.example index 60128780..ef13f6be 100644 --- a/electronEnv.json.example +++ b/electronEnv.json.example @@ -1,4 +1,5 @@ { "NODE_ENV": "production", - "IS_AUTO_UPDATE_DISABLED": false + "IS_AUTO_UPDATE_DISABLED": false, + "REPO_OWNER": "bitfinexcom" } diff --git a/package.json b/package.json index d0296b92..c048db90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bfx-report-electron", - "version": "4.19.0", + "version": "4.20.0", "repository": "https://github.com/bitfinexcom/bfx-report-electron", "description": "Reporting tool", "author": "bitfinex.com", diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 3862083b..27f93e1d 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -152,12 +152,12 @@ fi if [ $isAutoUpdateDisabled == 1 ]; then echo -e "\n${COLOR_YELLOW}Auto-update is turned off!${COLOR_NORMAL}" - sed -i -e \ - "s/\"IS_AUTO_UPDATE_DISABLED\": .*/\"IS_AUTO_UPDATE_DISABLED\": true/g" \ + sed -i -E -e \ + "s/\"IS_AUTO_UPDATE_DISABLED\": (false)|(true)/\"IS_AUTO_UPDATE_DISABLED\": true/g" \ "$ROOT/$ELECTRON_ENV_FILE_NAME" else - sed -i -e \ - "s/\"IS_AUTO_UPDATE_DISABLED\": .*/\"IS_AUTO_UPDATE_DISABLED\": false/g" \ + sed -i -E -e \ + "s/\"IS_AUTO_UPDATE_DISABLED\": (false)|(true)/\"IS_AUTO_UPDATE_DISABLED\": false/g" \ "$ROOT/$ELECTRON_ENV_FILE_NAME" fi diff --git a/scripts/setup.sh b/scripts/setup.sh index f8c77105..62f1f3a8 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -94,12 +94,12 @@ fi if [ $isAutoUpdateDisabled == 1 ]; then echo -e "\n${COLOR_YELLOW}Auto-update is turned off!${COLOR_NORMAL}" - sed -i -e \ - "s/\"IS_AUTO_UPDATE_DISABLED\": .*/\"IS_AUTO_UPDATE_DISABLED\": true/g" \ + sed -i -E -e \ + "s/\"IS_AUTO_UPDATE_DISABLED\": (false)|(true)/\"IS_AUTO_UPDATE_DISABLED\": true/g" \ "$ROOT/$ELECTRON_ENV_FILE_NAME" else - sed -i -e \ - "s/\"IS_AUTO_UPDATE_DISABLED\": .*/\"IS_AUTO_UPDATE_DISABLED\": false/g" \ + sed -i -E -e \ + "s/\"IS_AUTO_UPDATE_DISABLED\": (false)|(true)/\"IS_AUTO_UPDATE_DISABLED\": false/g" \ "$ROOT/$ELECTRON_ENV_FILE_NAME" fi diff --git a/server.js b/server.js index 2b1641f3..056e6fad 100644 --- a/server.js +++ b/server.js @@ -32,7 +32,7 @@ const { const { WrongPathToUserDataError, - WrongPathToUserCsvError, + WrongPathToUserReportFilesError, WrongSecretKeyError } = require('./src/errors') @@ -76,7 +76,9 @@ const allowedProcessMessagesSet = _getAllowedStatesSet({ 'RESPONSE_GET_BACKUP_FILES_METADATA', - 'RESPONSE_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE' + 'RESPONSE_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE', + + 'REQUEST_PDF_CREATION' ] }) const allowedProcessStatesSet = _getAllowedStatesSet({ @@ -92,14 +94,16 @@ const allowedProcessStatesSet = _getAllowedStatesSet({ 'REQUEST_GET_BACKUP_FILES_METADATA', - 'REQUEST_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE' + 'REQUEST_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE', + + 'RESPONSE_PDF_CREATION' ] }) ;(async () => { try { const pathToUserData = process.env.PATH_TO_USER_DATA - const pathToUserCsv = process.env.PATH_TO_USER_CSV + const pathToUserReportFiles = process.env.PATH_TO_USER_REPORT_FILES const schedulerRule = process.env.SCHEDULER_RULE const secretKey = process.env.SECRET_KEY const grape1DhtPort = process.env.GRAPE_1DHT_PORT @@ -116,8 +120,8 @@ const allowedProcessStatesSet = _getAllowedStatesSet({ if (!pathToUserData) { throw new WrongPathToUserDataError() } - if (!pathToUserCsv) { - throw new WrongPathToUserCsvError() + if (!pathToUserReportFiles) { + throw new WrongPathToUserReportFilesError() } const grape = `http://127.0.0.1:${grape2ApiPort}` @@ -162,7 +166,7 @@ const allowedProcessStatesSet = _getAllowedStatesSet({ '--isSchedulerEnabled=true', '--isElectronjsEnv=true', '--isLoggerDisabled=false', - `--csvFolder=${pathToUserCsv}`, + `--reportFolder=${pathToUserReportFiles}`, `--tempFolder=${pathToUserData}/temp`, `--logsFolder=${pathToUserData}/logs`, `--dbFolder=${pathToUserData}`, diff --git a/src/auto-updater/index.js b/src/auto-updater/index.js index 92fd97f5..178e806b 100644 --- a/src/auto-updater/index.js +++ b/src/auto-updater/index.js @@ -96,6 +96,23 @@ const _fireToast = ( WINDOW_EVENT_NAMES.CLOSED, () => closeAlert(alert) ) + const autoUpdateToastWidthHandler = (event, data) => { + alert.browserWindow?.setBounds({ + width: Math.round(data?.width ?? 0) + }) + } + const autoUpdateToastRepositionHandler = () => { + const { x, y, width } = win.getContentBounds() + const { width: alWidth } = alert.browserWindow.getContentBounds() + + const boundsOpts = { + x: (x + width) - alWidth, + y, + height + } + + alert.browserWindow.setBounds(boundsOpts) + } const bwOptions = { frame: false, @@ -155,6 +172,14 @@ const _fireToast = ( }, didClose: () => { eventHandlerCtx.removeListener() + ipcMain.removeListener( + 'auto-update-toast:width', + autoUpdateToastWidthHandler + ) + ipcMain.removeListener( + alert.uid + 'reposition', + autoUpdateToastRepositionHandler + ) didClose(alert) } @@ -169,23 +194,8 @@ const _fireToast = ( sound ) - ipcMain.on('auto-update-toast:width', (event, data) => { - alert.browserWindow?.setBounds({ - width: Math.round(data?.width ?? 0) - }) - }) - ipcMain.on(alert.uid + 'reposition', () => { - const { x, y, width } = win.getContentBounds() - const { width: alWidth } = alert.browserWindow.getContentBounds() - - const boundsOpts = { - x: (x + width) - alWidth, - y, - height - } - - alert.browserWindow.setBounds(boundsOpts) - }) + ipcMain.on('auto-update-toast:width', autoUpdateToastWidthHandler) + ipcMain.on(alert.uid + 'reposition', autoUpdateToastRepositionHandler) return res } diff --git a/src/change-reports-folder.js b/src/change-reports-folder.js index 59f2f0d1..4bdb9efc 100644 --- a/src/change-reports-folder.js +++ b/src/change-reports-folder.js @@ -2,7 +2,7 @@ const { dialog, BrowserWindow } = require('electron') -const { CSV_PATH_VERSION } = require('./const') +const { REPORT_FILES_PATH_VERSION } = require('./const') const { InvalidFilePathError, @@ -52,8 +52,8 @@ module.exports = ({ pathToUserDocuments }) => { await pauseApp() const isSaved = await getConfigsKeeperByName('main') .saveConfigs({ - csvPathVersion: CSV_PATH_VERSION, - pathToUserCsv: filePaths[0] + reportFilesPathVersion: REPORT_FILES_PATH_VERSION, + pathToUserReportFiles: filePaths[0] }) if (!isSaved) { diff --git a/src/const.js b/src/const.js index 400c7df6..df3cc2f1 100644 --- a/src/const.js +++ b/src/const.js @@ -6,7 +6,7 @@ const DB_FILE_NAME = 'db-sqlite_sync_m0.db' const DB_SHM_FILE_NAME = `${DB_FILE_NAME}-shm` const DB_WAL_FILE_NAME = `${DB_FILE_NAME}-wal` const SECRET_KEY_FILE_NAME = 'secret-key' -const CSV_PATH_VERSION = 1 +const REPORT_FILES_PATH_VERSION = 1 module.exports = { CONFIGS_FILE_NAME, @@ -15,5 +15,5 @@ module.exports = { DB_SHM_FILE_NAME, DB_WAL_FILE_NAME, SECRET_KEY_FILE_NAME, - CSV_PATH_VERSION + REPORT_FILES_PATH_VERSION } diff --git a/src/errors/index.js b/src/errors/index.js index 98a6119e..0b26dbfd 100644 --- a/src/errors/index.js +++ b/src/errors/index.js @@ -65,8 +65,8 @@ class WrongPathToUserDataError extends BaseError { } } -class WrongPathToUserCsvError extends BaseError { - constructor (message = 'ERR_WRONG_PATH_TO_USER_CSV') { +class WrongPathToUserReportFilesError extends BaseError { + constructor (message = 'ERR_WRONG_PATH_TO_USER_REPORT_FILES') { super(message) } } @@ -124,7 +124,7 @@ module.exports = { AppInitializationError, FreePortError, WrongPathToUserDataError, - WrongPathToUserCsvError, + WrongPathToUserReportFilesError, WrongSecretKeyError, ReportsFolderChangingError, SyncFrequencyChangingError, diff --git a/src/initialize-app.js b/src/initialize-app.js index 6f5d6298..763f6361 100644 --- a/src/initialize-app.js +++ b/src/initialize-app.js @@ -3,7 +3,7 @@ const { app } = require('electron') const path = require('path') -const { CSV_PATH_VERSION } = require('./const') +const { REPORT_FILES_PATH_VERSION } = require('./const') const triggerSyncAfterUpdates = require('./trigger-sync-after-updates') const triggerElectronLoad = require('./trigger-electron-load') @@ -41,6 +41,7 @@ const enforceMacOSAppLocation = require( const manageWorkerMessages = require( './manage-worker-messages' ) +const printToPDF = require('./print-to-pdf') const pathToLayouts = path.join(__dirname, 'layouts') const pathToLayoutAppInitErr = path @@ -50,52 +51,26 @@ const { rule: schedulerRule } = require( '../bfx-reports-framework/config/schedule.json' ) -const _resetCsvPath = async ( +const _resetReportFilesPath = async ( configsKeeper, opts = {} ) => { const { - pathToUserCsv, - isRelativeCsvPath + pathToUserReportFiles } = opts - // Need to use a new csv folder path for export - const storedPathToUserCsv = configsKeeper - .getConfigByName('pathToUserCsv') - const csvPathVersion = configsKeeper - .getConfigByName('csvPathVersion') - - if (csvPathVersion === CSV_PATH_VERSION) { - return - } - if ( - ( - isRelativeCsvPath && - !storedPathToUserCsv.endsWith('csv') - ) || - ( - !isRelativeCsvPath && - !storedPathToUserCsv.endsWith('bitfinex/reports') - ) || - ( - !isRelativeCsvPath && - !path.isAbsolute(storedPathToUserCsv) - ) || - ( - isRelativeCsvPath && - path.isAbsolute(storedPathToUserCsv) - ) - ) { - await configsKeeper.saveConfigs({ - csvPathVersion: CSV_PATH_VERSION, - pathToUserCsv - }) + // Need to use a new report folder path for export + const reportFilesPathVersion = configsKeeper + .getConfigByName('reportFilesPathVersion') ?? + configsKeeper.getConfigByName('csvPathVersion') // For back compatibility + if (reportFilesPathVersion === REPORT_FILES_PATH_VERSION) { return } await configsKeeper.saveConfigs({ - csvPathVersion: CSV_PATH_VERSION + reportFilesPathVersion: REPORT_FILES_PATH_VERSION, + pathToUserReportFiles }) } @@ -153,7 +128,7 @@ const _manageConfigs = (params = {}) => { pathToUserDocuments } = params - const pathToUserCsv = path.join( + const pathToUserReportFiles = path.join( pathToUserDocuments, 'bitfinex/reports' ) @@ -161,18 +136,15 @@ const _manageConfigs = (params = {}) => { const configsKeeper = configsKeeperFactory( { pathToUserData }, { - pathToUserCsv, + pathToUserReportFiles, schedulerRule, shownChangelogVer: '0.0.0', triggeredSyncAfterUpdatesVer: '0.0.0' } ) - _resetCsvPath( + _resetReportFilesPath( configsKeeper, - { - pathToUserCsv, - isRelativeCsvPath: true - } + { pathToUserReportFiles } ) } @@ -222,6 +194,8 @@ module.exports = async () => { await triggerElectronLoad(portsMap) await checkForUpdatesAndNotify() await manageChangelog() + + printToPDF() } catch (err) { await createErrorWindow(pathToLayoutAppInitErr) diff --git a/src/print-to-pdf/index.js b/src/print-to-pdf/index.js new file mode 100644 index 00000000..150b421a --- /dev/null +++ b/src/print-to-pdf/index.js @@ -0,0 +1,109 @@ +'use strict' + +const { BrowserWindow } = require('electron') +const fs = require('fs/promises') +const path = require('path') + +const ipcs = require('../ipcs') +const wins = require('../windows') + +const PROCESS_MESSAGES = require( + '../../bfx-reports-framework/workers/loc.api/process.message.manager/process.messages' +) +const PROCESS_STATES = require( + '../../bfx-reports-framework/workers/loc.api/process.message.manager/process.states' +) + +module.exports = () => { + ipcs.serverIpc.on('message', async (mess) => { + try { + if (mess?.state !== PROCESS_MESSAGES.REQUEST_PDF_CREATION) { + return + } + + const { + templateFilePath, + template = 'No data', + format = 'portrait', + orientation = 'Letter', + uid = null + } = mess?.data ?? {} + + const isTemplateFilePathUsed = ( + templateFilePath && + typeof templateFilePath === 'string' + ) + + const html = isTemplateFilePathUsed + ? await fs.readFile(templateFilePath, { encoding: 'utf8' }) + : template + + if (isTemplateFilePathUsed) { + await fs.rm(templateFilePath, { force: true, maxRetries: 3 }) + } + + const win = new BrowserWindow({ + show: false, + parent: wins.mainWindow, + webPreferences: { + nodeIntegration: true + } + }) + win.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(html)}`) + + await new Promise((resolve, reject) => { + win.webContents.on('did-finish-load', resolve) + win.webContents.on('did-fail-load', (e, code, err) => { + reject(err) + }) + }) + const buffer = await win.webContents.printToPDF({ + landscape: format !== 'portrait', + pageSize: orientation, + margins: { + top: 0, + bottom: 0, + left: 0, + right: 0 + }, + displayHeaderFooter: true, + footerTemplate: `\ + + Page from +` + }) + + if (isTemplateFilePathUsed) { + const { dir, name } = path.parse(templateFilePath) + const pdfFilePath = path.format({ dir, name, ext: '.pdf' }) + + await fs.writeFile(pdfFilePath, buffer) + + ipcs.serverIpc.send({ + state: PROCESS_STATES.RESPONSE_PDF_CREATION, + data: { pdfFilePath, uid } + }) + + return + } + + ipcs.serverIpc.send({ + state: PROCESS_STATES.RESPONSE_PDF_CREATION, + data: { buffer, uid } + }) + } catch (err) { + ipcs.serverIpc.send({ + state: PROCESS_STATES.RESPONSE_PDF_CREATION, + data: { err, uid: mess?.data?.uid ?? null } + }) + + console.error(err) + } + }) +} diff --git a/src/run-server.js b/src/run-server.js index 741881b4..03b785d1 100644 --- a/src/run-server.js +++ b/src/run-server.js @@ -28,8 +28,8 @@ module.exports = ({ const env = { ...process.env, PATH_TO_USER_DATA: pathToUserData, - PATH_TO_USER_CSV: mainConfsKeeper - .getConfigByName('pathToUserCsv'), + PATH_TO_USER_REPORT_FILES: mainConfsKeeper + .getConfigByName('pathToUserReportFiles'), SCHEDULER_RULE: mainConfsKeeper .getConfigByName('schedulerRule'), SECRET_KEY: secretKey,