From f79e71d4f076bd8280f2b8c93334e143cd81af01 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sun, 18 Aug 2024 21:33:39 +0100 Subject: [PATCH] Update code signing process to use new OV code-signing certificate #628 (#641) --- .github/workflows/build-electron.yml | 96 ++++++++++++++++++--- KiwixWebApp-github.jsproj | 4 +- PublisherIDs.json | 6 +- package-github.appxmanifest | 4 +- package.json | 5 +- scripts/Build-Electron.ps1 | 16 ++-- scripts/Create-DraftRelease.ps1 | 6 +- scripts/Kiwix_JS_WikiMed_Release_Body.md | 1 + scripts/Kiwix_JS_Wikivoyage_Release_Body.md | 1 + scripts/Kiwix_JS_Windows_Release_Body.md | 2 +- scripts/sign.js | 61 +++++++++++++ 11 files changed, 169 insertions(+), 33 deletions(-) create mode 100644 scripts/sign.js diff --git a/.github/workflows/build-electron.yml b/.github/workflows/build-electron.yml index 5f520c0f..e7f7f91a 100644 --- a/.github/workflows/build-electron.yml +++ b/.github/workflows/build-electron.yml @@ -9,31 +9,52 @@ on: workflow_dispatch: inputs: version: - description: Specific version to build like v9.9.9 (if empty, builds version in package.json) + description: Specific version to build like v9.9.9 without suffix (if empty, builds version in package.json) required: false default: '' target: type: choice - description: Do you wish to build for "release", "nightly", or "artefacts" for testing? Artefacts will appear under the workflow run. + description: Do you wish to build for "release", "nightly", or "artefacts" for testing? Nightly will only publish on the main branch. Artefacts will appear under the workflow run. For release, a draft release with corresponding tag must exist. required: false options: - release - nightly - artefacts default: 'artefacts' + win11only: + description: Do you wish to build only for Windows 11 (primarily for testing)? + type: choice + required: false + options: + - true + - false + default: 'false' + sign: + description: Do you wish to sign the Windows packages? + type: choice + required: false + options: + - true + - false + default: 'false' env: INPUT_VERSION: ${{ github.event.inputs.version }} INPUT_TARGET: ${{ github.event.inputs.target }} CRON_LAUNCHED: ${{ github.event.schedule }} + INPUT_SIGN: ${{ github.event.inputs.sign }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: ${{ secrets.CSC_LINK }} - CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + ESIGNER_USERNAME: ${{ secrets.ESIGNER_USER_USERNAME }} + ESIGNER_PASSWORD: ${{ secrets.ESIGNER_USER_PASSWORD }} + ESIGNER_TOTP_SECRET: ${{ secrets.ESIGNER_USER_TOTP_SECRET }} + MASTER_KEY_FILE: "C:\\Users\\runneradmin\\eSignerCKA\\master.key" + INSTALL_DIR: C:\Users\runneradmin\eSignerCKA SSH_KEY: ${{ secrets.SSH_KEY }} REF_NAME: ${{ github.ref_name }} jobs: Release_Linux: + if: github.event.inputs.win11only != 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -129,7 +150,7 @@ jobs: Release_Windows: runs-on: windows-latest env: - SIGNTOOL_PATH: "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.22000.0\\x64\\signtool.exe" + SIGNTOOL_PATH: "C:/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x86/signtool.exe" steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -176,8 +197,50 @@ jobs: Write-Host "`nError! We could not obtain the requested archive $packagedFile!`n" -ForegroundColor Red exit 1 } + + - name: Install and configure eSigner CKA and Windows SDK + if: github.event.inputs.sign == 'true' + env: + ESIGNER_URL: https://github.com/SSLcom/eSignerCKA/releases/download/v1.0.7/SSL.COM-eSigner-CKA_1.0.7.zip + run: | + Set-StrictMode -Version 'Latest' + + # Download and Unzip eSignerCKA Setup + Invoke-WebRequest -OutFile eSigner_CKA_Setup.zip "$env:ESIGNER_URL" + Expand-Archive -Force eSigner_CKA_Setup.zip + Remove-Item eSigner_CKA_Setup.zip + Move-Item -Destination “eSigner_CKA_Installer.exe” -Path “eSigner_CKA_*\*.exe” + + # Install eSignerCKA + New-Item -ItemType Directory -Force -Path ${{ env.INSTALL_DIR }} + ./eSigner_CKA_Installer.exe /CURRENTUSER /VERYSILENT /SUPPRESSMSGBOXES /DIR=”${{ env.INSTALL_DIR }}” | Out-Null + + # Disable logger + $LogConfig = Get-Content -Path ${{ env.INSTALL_DIR }}/log4net.config + $LogConfig[0] = '' + $LogConfig | Set-Content -Path ${{ env.INSTALL_DIR }}/log4net.config + + # Configure + ${{ env.INSTALL_DIR }}/eSignerCKATool.exe config -mode product -user "${{ env.ESIGNER_USERNAME }}" -pass "${{ env.ESIGNER_PASSWORD }}" -totp "${{ env.ESIGNER_TOTP_SECRET }}" -key "${{ env.MASTER_KEY_FILE }}" -r + ${{ env.INSTALL_DIR }}/eSignerCKATool.exe unload + ${{ env.INSTALL_DIR }}/eSignerCKATool.exe load + + # Find certificate + $CodeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1 + echo Certificate: $CodeSigningCert + + # Extract thumbprint and subject name + $Thumbprint = $CodeSigningCert.Thumbprint + $SubjectName = ($CodeSigningCert.Subject -replace ", ?", "`n" | ConvertFrom-StringData).CN + + ls -l ${{ env.MASTER_KEY_FILE }} + + echo "ED_SIGNTOOL_THUMBPRINT=$Thumbprint" >> $env:GITHUB_ENV + echo "ED_SIGNTOOL_SUBJECT_NAME=$SubjectName" >> $env:GITHUB_ENV + - name: Run electron builder for Win 7/8/8.1 - shell: pwsh + if: github.event.inputs.win11only != 'true' + shell: powershell run: | $GITHUB_TOKEN = $Env:GITHUB_TOKEN $INPUT_VERSION = $Env:INPUT_VERSION @@ -194,7 +257,7 @@ jobs: echo "Setting the Electron version to the latest supporting Windows 7/8/8.1 (=22.3.25)" (Get-Content ./package.json) -replace '("electron":\s+)"[\d.]+[\w\d-.]*?"', '$1"22.3.25"' | Set-Content ./package.json echo "Installing dependencies in root and dist" - npm install && cd dist && npm install && cd .. + npm install; cd dist; npm install; cd .. echo "Installed Electron version:$(npx electron --version)" echo "Building Windows 7+ 32bit NSIS package..." npm run dist-win-nsis @@ -210,13 +273,15 @@ jobs: & ./scripts/Publish-ElectronPackages.ps1 -githubonly } ./scripts/Rewrite-DraftReleaseTag.ps1 + - name: Run electron builder for Win 10/11 - shell: pwsh + shell: powershell run: | $GITHUB_TOKEN = $Env:GITHUB_TOKEN $INPUT_VERSION = $Env:INPUT_VERSION $INPUT_TARGET = $Env:INPUT_TARGET $CRON_LAUNCHED = $Env:CRON_LAUNCHED + $INPUT_SIGN = !$CRON_LAUNCHED -and [System.Convert]::ToBoolean($Env:INPUT_SIGN) $ORIGINAL_ELECTRON_VERSION = $Env:ORIGINAL_ELECTRON_VERSION echo "Restoring original Electron version: $ORIGINAL_ELECTRON_VERSION" (Get-Content ./package.json) -replace '("electron":\s+)"[\d.]+[\w\d-.]*?"', ('$1"' + $ORIGINAL_ELECTRON_VERSION + '"') | Set-Content ./package.json @@ -224,10 +289,18 @@ jobs: # Set the module type to one supported by Electron # (Get-Content ./package.json) -replace '("type":\s+)"module"', '$1"commonjs"' | Set-Content ./package.json echo "Installing dependencies in root and dist" - npm install && cd dist && npm install && cd .. + npm install; cd dist; npm install; cd .. echo "Installed Electron version:$(npx electron --version)" + # echo "Configuring and loading esigner..." + # ${{ env.INSTALL_DIR }}/eSignerCKATool.exe config -mode product -user "${{ env.ESIGNER_USERNAME }}" -pass "${{ env.ESIGNER_PASSWORD }}" -totp "${{ env.ESIGNER_TOTP_SECRET }}" -key "${{ env.MASTER_KEY_FILE }}" -r + # ${{ env.INSTALL_DIR }}/eSignerCKATool.exe unload + # ${{ env.INSTALL_DIR }}/eSignerCKATool.exe load echo "Building Windows packages..." - npm run publish + if ($INPUT_SIGN) { + npm run publish + } else { + npm run build-skipsigning + } ./scripts/Rewrite-DraftReleaseTag.ps1 - name: Build portable Electron app run: | @@ -249,6 +322,7 @@ jobs: $GITHUB_TOKEN = $Env:GITHUB_TOKEN $INPUT_VERSION = $Env:INPUT_VERSION $INPUT_TARGET = $Env:INPUT_TARGET + $INPUT_SIGN = [System.Convert]::ToBoolean($Env:INPUT_SIGN) $CRON_LAUNCHED = $Env:CRON_LAUNCHED if ($Env:REF_NAME -eq "main") { ./scripts/Publish-ElectronPackages.ps1 -portableonly @@ -268,7 +342,7 @@ jobs: dist/bld/Electron/nsis-web/*.nsis.7z Release_NWJS: - if: github.ref_name == 'main' + if: github.ref_name == 'main' && github.event.inputs.win11only != 'true' runs-on: windows-latest steps: - uses: actions/checkout@v4 diff --git a/KiwixWebApp-github.jsproj b/KiwixWebApp-github.jsproj index 71c9ca7f..1c7d42ce 100644 --- a/KiwixWebApp-github.jsproj +++ b/KiwixWebApp-github.jsproj @@ -65,7 +65,7 @@ False Always neutral - AC88CB5C77BD1D6D2ECC0849F5C200C427E0ECCA + 82B88B62A6F87FBA62B2C933D747E52EDBF0F7F6 False 1 OnApplicationRun @@ -354,4 +354,4 @@ true --> - + \ No newline at end of file diff --git a/PublisherIDs.json b/PublisherIDs.json index 5326a162..d2508ecb 100644 --- a/PublisherIDs.json +++ b/PublisherIDs.json @@ -14,7 +14,7 @@ "type": "appx", "identityName": "Kiwix.KiwixJS", "dispalyName": "Kiwix JS", - "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, C=CH", + "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, S=Canton of Vaud, C=CH", "publisherDisplayName": "Association Kiwix" } } @@ -34,7 +34,7 @@ "type": "appx", "identityName": "Kiwix.WikiMed", "displayName": "WikiMed by Kiwix", - "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, C=CH", + "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, S=Canton of Vaud, C=CH", "publisherDisplayName": "Association Kiwix" } } @@ -54,7 +54,7 @@ "type": "appx", "identityName": "Kiwix.WikivoyagebyKiwix", "displayName": "Wikivoyage by Kiwix", - "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, C=CH", + "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, S=Canton of Vaud, C=CH", "publisherDisplayName": "Association Kiwix" } } diff --git a/package-github.appxmanifest b/package-github.appxmanifest index 31afd842..2c2f744d 100644 --- a/package-github.appxmanifest +++ b/package-github.appxmanifest @@ -1,6 +1,6 @@  - + Kiwix JS @@ -54,4 +54,4 @@ - + \ No newline at end of file diff --git a/package.json b/package.json index 6fcd47bb..aea2963d 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,11 @@ "buildResources": "../electron_icons" }, "win": { + "certificateSha1": "82B88B62A6F87FBA62B2C933D747E52EDBF0F7F6", "signingHashAlgorithms": [ "sha256" ], + "rfc3161TimeStampServer": "http://ts.ssl.com", "asar": "true", "extraResources": { "from": "archives", @@ -96,7 +98,7 @@ "backgroundColor": "transparent", "displayName": "Kiwix JS", "identityName": "Kiwix.KiwixJS", - "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, C=CH", + "publisher": "CN=Association Kiwix, O=Association Kiwix, L=Lausanne, S=Canton of Vaud, C=CH", "publisherDisplayName": "Association Kiwix", "languages": "en-GB", "showNameOnTiles": "true" @@ -132,6 +134,7 @@ "dist-linux": "electron-builder build --linux --projectDir dist", "dist-linux-appimage": "electron-builder build --linux AppImage:x64 --projectDir dist", "publish": "electron-builder --projectDir dist", + "build-skipsigning": "electron-builder --projectDir dist --publish never", "postpackage-win": "(robocopy archives bld\\Electron\\kiwix-js-pwa-win32-ia32\\resources\\app\\archives\\ > null) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0", "postpackage-linux": "(robocopy archives bld\\Electron\\kiwix-js-pwa-linux-x64\\archives\\ > null) ^& IF %ERRORLEVEL% LSS 8 SET ERRORLEVEL = 0" }, diff --git a/scripts/Build-Electron.ps1 b/scripts/Build-Electron.ps1 index 95ab98bb..43c0617e 100644 --- a/scripts/Build-Electron.ps1 +++ b/scripts/Build-Electron.ps1 @@ -2,20 +2,15 @@ # because it modifies variables needed in Create-DraftRelease $base_dir = "$PSScriptRoot/../dist/bld/Electron/" -replace 'scripts/../', '' if (!$skipsigning -and !$buildstorerelease) { - # Ensure the correct $Env variables are set for code signing - DEV update these as necessary - if (!$Env:CSC_LINK) { - $Env:CSC_LINK = "$PSScriptRoot\kiwix2022.pfx" - } - if (!$Env:CSC_KEY_PASSWORD) { - $Env:CSC_KEY_PASSWORD = Get-Content -Raw "$PSScriptRoot/secret_kiwix.p12.pass" - } + $Env:INPUT_SIGN = $true if (!$Env:SIGNTOOL_PATH) { # We need to use a newer version of singtool than that provided in electron-builder $Env:SIGNTOOL_PATH = "C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe" } } else { - $Env:CSC_LINK = "" - $Env:CSC_KEY_PASSWORD = "" + $Env:INPUT_SIGN = $false + $Env:ESIGNER_USERNASME = "" + $Env:ESIGNER_PASSWORD = "" $Env:SIGNTOOL_PATH = "" } "`nSelected base_tag: $base_tag" @@ -52,6 +47,7 @@ if ($electronbuild -eq "cloud") { 'inputs' = @{ 'target' = 'release' 'version' = $release_name + 'sign' = 'true' } } | ConvertTo-Json ContentType = "application/json" @@ -132,7 +128,7 @@ if ($electronbuild -eq "local" -and (-not $portableonly)) { "`nNo existing Electron package found: building $WinInstaller..." if (-Not $dryrun) { echo "`nInstalling dependencies in dist..." - cd dist && npm install && cd .. + cd dist; npm install; cd .. echo "`nBuilding Windows packages..." if ($winonly -eq "appx") { "[Only building the appx package because -winonly appx was specified]" diff --git a/scripts/Create-DraftRelease.ps1 b/scripts/Create-DraftRelease.ps1 index cc6d7d66..1b67469d 100644 --- a/scripts/Create-DraftRelease.ps1 +++ b/scripts/Create-DraftRelease.ps1 @@ -618,11 +618,11 @@ if ($dryrun -or $buildonly -or $release.assets_url -imatch '^https:') { "`nWARNING: Signing was skipped because user specified the -skipsigning flag. Be sure the bundle is signed!" } elseif (-Not $buildstorerelease) { "Signing app package for release on GitHub..." - $pfxpwd = Get-Content -Raw $PSScriptRoot\secret_kiwix.p12.pass + $certthumb = Get-Content -Raw $PSScriptRoot\master_key_thumbprint.txt if (-Not $dryrun) { - cmd.exe /c " `"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat`" && SignTool sign /fd SHA256 /a /f `"$PSScriptRoot\kiwix2022.pfx`" /p $pfxpwd /tr http://timestamp.digicert.com /td SHA256 `"$ReleaseBundle`" " + cmd.exe /c " `"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat`" && SignTool sign /fd SHA256 /a /sha1 `"$certthumb`" /tr http://ts.ssl.com /td SHA256 `"$ReleaseBundle`" " } else { - 'cmd.exe /c " "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" && SignTool sign /fd SHA256 /a /f ' + $PSScriptRoot + '\kiwix2022.pfx /p ' + $pfxpwd + ' /tr http://timestamp.digicert.com /td SHA256 ' + $ReleaseBundle + ' "' + 'cmd.exe /c " "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" && SignTool sign /fd SHA256 /a /sha1 ' + $certthumb + ' /tr http://ts.ssl.com /td SHA256 ' + $ReleaseBundle + ' "' } } # ZIP the remaining assets diff --git a/scripts/Kiwix_JS_WikiMed_Release_Body.md b/scripts/Kiwix_JS_WikiMed_Release_Body.md index f642a4dc..41cb295a 100644 --- a/scripts/Kiwix_JS_WikiMed_Release_Body.md +++ b/scripts/Kiwix_JS_WikiMed_Release_Body.md @@ -38,6 +38,7 @@ Please choose the correct version: * For the Windows Web installer, simply download and launch. It will select the correct architecture automatically and install itself, together with a shortcut in yourshortcut menu. When you want to update the app, just install a new version over it (it will uninstall the old one for you). **Please note that the Web installer needs Web access during the installation.** If this is a problem, then use the standalone installer. * For the Windows Portable build, unzip the contents of the [WikiMed-by-Kiwix-<>-E.zip](https://github.com/kiwix/kiwix-js-pwa/releases/download/v<>-WikiMed/WikiMed-by-Kiwix-<>-E.zip) archive to any folder, or to a flash drive / thumb drive, and double click on `Start WikiMed by Kiwix` or `Start WikiMed by Kiwix.bat`, or open the `kiwix-js-pwa-win32-ia32` folder and double click on `WikiMed by Kiwix.exe`. * For Windows 7/8/8.1, due to the deprecation of Chromium on these platforms, we now only provide one option: a standalone installer built with the last version of Electron that supported Chrome on Windows 7+. This is also a 32bit package (but will run on 64bit). +* **Microsoft Defender SmartScreen warning:** If you get a Smartscreen notification when downloading an `.exe`, or on first launch of the zipped portable apps, follow instructions to "Run anyway" if you trust this site. Additionally, when you first download an `.exe` installer, you may get a warning in your downloads "Kiwix-JS-Electron isn't commonly downloaded". If you see this, click on the file and choose "Keep anyway". A second screen may then popup telling you the publisher. So long as it's kiwix, then click on "Sow more" and allow the app. If you prefer, use one of the appx versions (ending `.appx` or `.appxbundle`) as this format runs in a secure, isolated container. * **For the Linux _portable_ builds**, download and save the correct AppImage file anywhere (e.g. your Desktop), and double-click it. If it doesn’t work, open a terminal and run `chmod a+x WikiMed-by-Kiwix*.AppImage` and then `./WikiMed-by-Kiwix*.AppImage`. + On **_Debian_**, if you have issues running the AppImage on older versions of the OS, you can try adding the `--no-sandbox` switch to the command (see https://github.com/electron/electron/issues/17972#issuecomment-516957971). This is not necessary on recent versions. + On **_OpenSUSE_**, you may need to install Chrome in order to get the dependencies necessary to run the AppImage (because Electron apps run Chrome internally). With **_older_** versions of OpenSUSE, you may additionally need to use these commandline switches: `./WikiMed-by-Kiwix*.AppImage --use-gl=disabled --disable-gpu-compositing`,¹ but this is no longer necessary in recent versions. diff --git a/scripts/Kiwix_JS_Wikivoyage_Release_Body.md b/scripts/Kiwix_JS_Wikivoyage_Release_Body.md index 98bfd730..dfe8a8d9 100644 --- a/scripts/Kiwix_JS_Wikivoyage_Release_Body.md +++ b/scripts/Kiwix_JS_Wikivoyage_Release_Body.md @@ -38,6 +38,7 @@ Please choose the correct version: * For the Windows Web installer, simply download and launch. It will select the correct architecture automatically and install itself, together with a shortcut in yourshortcut menu. When you want to update the app, just install a new version over it (it will uninstall the old one for you). **Please note that the Web installer needs Web access during the installation.** If this is a problem, then use the standalone installer. * For the Windows Portable build, unzip the contents of the [Wikivoyage-by-Kiwix-<>-E.zip](https://github.com/kiwix/kiwix-js-pwa/releases/download/v<>-Wikivoyage/Wikivoyage-by-Kiwix-<>-E.zip) archive to any folder, or to a flash drive / thumb drive, and double click on `Start Wikivoyage by Kiwix` or `Start Wikivoyage by Kiwix.bat`, or open the `kiwix-js-pwa-win32-ia32` folder and double click on `Wikivoyage by Kiwix.exe`. * For Windows 7/8/8.1, due to the deprecation of Chromium on these platforms, we now only provide one option: a standalone installer built with the last version of Electron that supported Chrome on Windows 7+. This is also a 32bit package (but will run on 64bit). +* **Microsoft Defender SmartScreen warning:** If you get a Smartscreen notification when downloading an `.exe`, or on first launch of the zipped portable apps, follow instructions to "Run anyway" if you trust this site. Additionally, when you first download an `.exe` installer, you may get a warning in your downloads "Kiwix-JS-Electron isn't commonly downloaded". If you see this, click on the file and choose "Keep anyway". A second screen may then popup telling you the publisher. So long as it's kiwix, then click on "Sow more" and allow the app. If you prefer, use one of the appx versions (ending `.appx` or `.appxbundle`) as this format runs in a secure, isolated container. * **For the Linux _portable_ builds,** download and save the correct AppImage file anywhere (e.g. your Desktop), and double-click it. If it doesn’t work, open a terminal and run `chmod a+x Wikivoyage-by-Kiwix*.AppImage` and then `./Wikivoyage-by-Kiwix*.AppImage`. + On **_Debian_**, if you have issues running the AppImage on older versions of the OS, you can try adding the `--no-sandbox` switch to the command (see https://github.com/electron/electron/issues/17972#issuecomment-516957971). This is not necessary on recent versions. + On **_OpenSUSE_**, you may need to install Chrome in order to get the dependencies necessary to run the AppImage (because Electron apps run Chrome internally). With **_older_** versions of OpenSUSE, you may additionally need to use these commandline switches: `./Wikivoyage-by-Kiwix*.AppImage --use-gl=disabled --disable-gpu-compositing`,¹ but this is no longer necessary in recent versions. diff --git a/scripts/Kiwix_JS_Windows_Release_Body.md b/scripts/Kiwix_JS_Windows_Release_Body.md index 9ba73f6f..74b52b42 100644 --- a/scripts/Kiwix_JS_Windows_Release_Body.md +++ b/scripts/Kiwix_JS_Windows_Release_Body.md @@ -49,6 +49,7 @@ Please choose the correct version (those marked [**AUTO**] will self-update auto * For the Windows Web installer for Windows 10/11, simply download and launch. It will select the correct architecture automatically and install itself, together with a shortcut in your shortcut menu. It auto-updates, but if you want to update it manually, then just install a new version over it (it will uninstall the old one for you). **Please note that the Web installer needs Web access during the installation.** If this is a problem, then use the standalone installer. * For the Windows 10/11 Portable builds (64bit only), the executable version (ending `.exe`) can just be run, but it may be a bit slow to start up. For a faster experience, use one of the zipped versions: unzip the contents of the package to any folder, or to a thumb drive, and double click on `Start Kiwix JS [Electron/Windows]` or `Start Kiwix JS [Electron/Windows].bat`. * For Windows 7/8/8.1, due to the deprecation of Chromium on these platforms, we now only provide one option: a standalone installer built with the last version of Electron that supported Chrome on Windows 7+. This is also a 32bit package (but will run on 64bit). +* **Microsoft Defender SmartScreen warning:** If you get a Smartscreen notification when downloading an `.exe`, or on first launch of the zipped portable apps, follow instructions to "Run anyway" if you trust this site. Additionally, when you first download an `.exe` installer, you may get a warning in your downloads "Kiwix-JS-Electron isn't commonly downloaded". If you see this, click on the file and choose "Keep anyway". A second screen may then popup telling you the publisher. So long as it's kiwix, then click on "Sow more" and allow the app. If you prefer, use one of the appx versions (ending `.appx` or `.appxbundle`) as this format runs in a secure, isolated container. * **For the Linux _portable_ builds,** download and save the correct AppImage file anywhere (e.g. your Desktop), and double-click it. If it doesn’t work, open a terminal and run `chmod a+x Kiwix-JS-Electron*.AppImage` and then `./Kiwix-JS-Electron*.AppImage`. This version will auto-update. + On **_Debian_**, if you have issues running the AppImage on older versions of the OS, you can try adding the `--no-sandbox` switch to the command (see https://github.com/electron/electron/issues/17972#issuecomment-516957971). This is not necessary on recent versions. + On **_OpenSUSE_**, you may need to install Chrome in order to get the dependencies necessary to run the AppImage (because Electron apps run Chrome internally). With **_older_** versions of OpenSUSE, you may additionally need to use these commandline switches: `./Kiwix-JS-Electron*.AppImage --use-gl=disabled --disable-gpu-compositing`,¹ but this is no longer necessary in recent versions. @@ -56,7 +57,6 @@ Please choose the correct version (those marked [**AUTO**] will self-update auto + **_Debian/Ubuntu_**: download the correct `.deb` package. Open a terminal, `cd` to the directory containing the package, and type `sudo apt-get update` followed by `chmod a+x ./kiwix-js-electron*.deb`, then `sudo apt install ./kiwix-js-electron*.deb`. To run the app from the command line, rather than from its installed icon, simply type `kiwix-js-electron` in terminal. On **Debian**, if you receive the error `libgbm.so.1: cannot open shared object file`, please run `sudo apt install libgbm-dev`. On older versions of Debian, you may have to add `--no-sandbox` to the command line when running the app, i.e. `kiwix-js-electron --no-sandbox`. When you want to update, just install the new version, and it will install over the old version. + **_Fedora_**: download the correct `.rpm` package. You should be able to install it by opening the File manager, locating the package, and double-clicking it. Alternatively, open a terminal and `cd` to the directory with the package, and then type `sudo rpm --install ./kiwix-js-electron-*.rpm` (you may need to do `chmod a+x kiwix-js-electron-*.rpm` first). After install, you should find Kiwix JS Electron in your app list, and you can launch it from there. To upgrade, locate the newly downloaded package in terminal and type `sudo rpm --upgrade ./kiwix.js.electron-*.rpm` (ensure you specify the correct package number in place of `*` if you have more than one). If you find the app is stuck looking for an old sample package after upgrade, please just press the Reset button next to the version number at the top of Configuration. + **_OpenSUSE_**: download the correct `.rpm` package. You may get a better installation experience if you first install Chrome or another Chromium browser, as the Electron app has the same dependencies as Chrome. Then open a Terminal with superuser privileges, navigate to the directory containing the `.rpm` package, and type `zypper install kiwix-js-electron-*.rpm` (you may need to do `chmod a+x kiwix-js-electron-*.rpm` first). If you are informed about missing dependencies, try "Solution 2: break kiwix-js-electron... by ignoring some of its dependencies'. You will also be warned that the app is not signed. You can ignore this, if you trust this repository. See above for commandline switches in older versions of OpenSUSE. -* Windows (zipped apps): If you get a Windows Smartscreen notification on first launch of the zipped portable apps, follow instructions to "Run anyway" if you trust this site. If you prefer, use one of the executable versions (ending `.exe`) which are digitally signed. ¹ With many thanks to Jay Midura for documenting the switches needed for OpenSUSE. diff --git a/scripts/sign.js b/scripts/sign.js new file mode 100644 index 00000000..c0aee44b --- /dev/null +++ b/scripts/sign.js @@ -0,0 +1,61 @@ +import { execSync } from 'child_process'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export default async function (configuration) { + // Read package.json + const packageJsonPath = path.resolve(__dirname, '../package.json'); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + + // Extract rfc3161TimeStampServer and sha1 from package.json + const rfc3161TimeStampServer = packageJson.build.win.rfc3161TimeStampServer; + const sha1 = packageJson.build.win.certificateSha1; + + // Extract file to sign from configuration + const fileToSign = configuration.path; + + // Debug statement to print the file to sign + // console.log('FILE_TO_SIGN:', fileToSign); + + const signToolPath = process.env.SIGNTOOL_PATH; + const eSignerCKAPath = process.env.INSTALL_DIR + '/eSignerCKATool.exe'; + + console.log('eSigner CKA Status:'); + execSync(`"${eSignerCKAPath}" status`, { stdio: 'inherit' }); + + // Debug statements to print environment variables + // console.log('SIGNING_CERT_SHA1:', sha1); + // console.log('SIGNTOOL_PATH:', signToolPath); + + if (!fileToSign) { + console.error('No file specified to sign.'); + process.exit(1); + } + + if (!sha1) { + console.error('Signing certificate SHA1 is not set in package.json.'); + process.exit(1); + } + + if (!rfc3161TimeStampServer) { + console.error('rfc3161TimeStampServer is not set in package.json.'); + process.exit(1); + } + + const signCommand = `"${signToolPath}" sign /sha1 ${sha1} /s My /fd sha256 /tr ${rfc3161TimeStampServer} /td sha256 /csp "eSignerKSP" /d "Kiwix JS Electron" /du "https://github.com/kiwix/kiwix-js-pwa#readme" /debug "${fileToSign}"`; + + // Debug statement to print the full sign command + console.log('Sign Command:', signCommand); + + try { + execSync(signCommand, { stdio: 'inherit' }); + console.log(`Successfully signed ${fileToSign}`); + } catch (error) { + console.error(`Failed to sign ${fileToSign}`); + process.exit(1); + } +};