mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-15 01:01:26 +00:00
Compare commits
229 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c59554f7bb | ||
|
|
11c66e8df7 | ||
|
|
c49bf0f146 | ||
|
|
e74bd91879 | ||
|
|
89d9249a08 | ||
|
|
013fff1223 | ||
|
|
fd9d27215e | ||
|
|
7315b59a6d | ||
|
|
884c6f6bdd | ||
|
|
c5367db971 | ||
|
|
8bb451261e | ||
|
|
de4c7d47e5 | ||
|
|
b4fe63c966 | ||
|
|
ed45182b6c | ||
|
|
afd2d74c90 | ||
|
|
4bcf01270a | ||
|
|
64466df6b8 | ||
|
|
db9bd49dd9 | ||
|
|
4ed4a3e3e5 | ||
|
|
ad73b2f31d | ||
|
|
227b322b8a | ||
|
|
ccf2e60390 | ||
|
|
1104c1067a | ||
|
|
83d2c39080 | ||
|
|
446caff901 | ||
|
|
90537caee7 | ||
|
|
25dea8ebe6 | ||
|
|
4a7d2907c8 | ||
|
|
7f3af0c7f6 | ||
|
|
e6e04078fa | ||
|
|
e3f6b5f812 | ||
|
|
f3461f7da4 | ||
|
|
94518ede99 | ||
|
|
0fa041da85 | ||
|
|
daa4f3a568 | ||
|
|
fc6f7d184c | ||
|
|
e50c949b62 | ||
|
|
349349e057 | ||
|
|
4b36a1219f | ||
|
|
6533ba7367 | ||
|
|
7f9c9a7df6 | ||
|
|
afda8a4981 | ||
|
|
153f9b485c | ||
|
|
b9e91115b4 | ||
|
|
2d29b1a76f | ||
|
|
f62a5ed74b | ||
|
|
7fe7e1f5bf | ||
|
|
a4d9703cf4 | ||
|
|
c9a3a775cc | ||
|
|
e7cac42d5d | ||
|
|
983e7d973b | ||
|
|
a84ac94701 | ||
|
|
4761c58265 | ||
|
|
682e762a5a | ||
|
|
c3ada43abb | ||
|
|
9a71782fff | ||
|
|
2f4c12a89e | ||
|
|
2b79c58577 | ||
|
|
1d3c62e2c7 | ||
|
|
17166c45ac | ||
|
|
f758388063 | ||
|
|
8767564977 | ||
|
|
59f47116f0 | ||
|
|
8fac541024 | ||
|
|
1ba21b531a | ||
|
|
daad48d5af | ||
|
|
8eedc62fbe | ||
|
|
d65442f042 | ||
|
|
216513405a | ||
|
|
f4c0bc29ed | ||
|
|
d1ce0362b4 | ||
|
|
4497fb160e | ||
|
|
5bffa28cdb | ||
|
|
14c5693594 | ||
|
|
53c6045cca | ||
|
|
16d441ec44 | ||
|
|
fa053ac3df | ||
|
|
e78a064af6 | ||
|
|
644e38f49e | ||
|
|
3b38049d71 | ||
|
|
c199d1cb3b | ||
|
|
164a4de6de | ||
|
|
f64455d8fb | ||
|
|
8b1d2101db | ||
|
|
22a37699ea | ||
|
|
44f92cfb26 | ||
|
|
27c10080d6 | ||
|
|
2067c5a33b | ||
|
|
fc5ed9ecc0 | ||
|
|
5e956c50c2 | ||
|
|
5110b35690 | ||
|
|
499960b3ec | ||
|
|
f6479ddf24 | ||
|
|
5d8b016e5f | ||
|
|
2bf2f2b616 | ||
|
|
1089e90ebf | ||
|
|
9fee4afd2a | ||
|
|
7ad9b10138 | ||
|
|
fb6e4f0c15 | ||
|
|
6c5f3cb72c | ||
|
|
581b16e354 | ||
|
|
d74248ff63 | ||
|
|
698ac639e9 | ||
|
|
5a086f52b5 | ||
|
|
54b7f3c842 | ||
|
|
94b9813c50 | ||
|
|
b00ee4740a | ||
|
|
78cffe2f60 | ||
|
|
9d15a7664d | ||
|
|
f5ecf846f2 | ||
|
|
a9444182bb | ||
|
|
191d9473c0 | ||
|
|
8089bcd0d0 | ||
|
|
5d8457cbdd | ||
|
|
f623b1ee7e | ||
|
|
c546f3363b | ||
|
|
8a1ec1d073 | ||
|
|
81307b6d75 | ||
|
|
50fa8e0608 | ||
|
|
626a692d63 | ||
|
|
c9b9eee564 | ||
|
|
edc308ccd1 | ||
|
|
ad214691f9 | ||
|
|
acf11da202 | ||
|
|
94eb1e365b | ||
|
|
414ccad8fb | ||
|
|
e57e5358c4 | ||
|
|
e24719ed19 | ||
|
|
e21525ce2e | ||
|
|
9a14cfc674 | ||
|
|
9af9362a7b | ||
|
|
4d4a93746d | ||
|
|
4280112eab | ||
|
|
638e1e562d | ||
|
|
321bd2ff8c | ||
|
|
323a884718 | ||
|
|
5bdfffd151 | ||
|
|
cb6b77318d | ||
|
|
6fcec26eea | ||
|
|
feb9fb689e | ||
|
|
0178ca4080 | ||
|
|
4ddb6b73bd | ||
|
|
da845c6941 | ||
|
|
c30a28aae0 | ||
|
|
5305c5a631 | ||
|
|
b0d2dcbff3 | ||
|
|
5c1364792e | ||
|
|
abf8392baa | ||
|
|
034a70d473 | ||
|
|
79f2863f24 | ||
|
|
f1ef506e2b | ||
|
|
8c9d75fe57 | ||
|
|
d00d77b747 | ||
|
|
fbeeaa4c93 | ||
|
|
00f5d433da | ||
|
|
115a4216ee | ||
|
|
403d469dff | ||
|
|
ddf112bdfa | ||
|
|
2ade07da75 | ||
|
|
e6a0339878 | ||
|
|
2b0c2cf90a | ||
|
|
2afd8d0988 | ||
|
|
f2bda6b5f9 | ||
|
|
0bb1bf81ec | ||
|
|
bf8d5ed09f | ||
|
|
e9f6854df8 | ||
|
|
6d47f28634 | ||
|
|
225332bd4f | ||
|
|
354225bf1e | ||
|
|
8c84720e24 | ||
|
|
0d4f373311 | ||
|
|
1da535e89c | ||
|
|
941b4e3652 | ||
|
|
dd1af8cd78 | ||
|
|
27ea29ab9d | ||
|
|
a699a794a9 | ||
|
|
cd6b1cf129 | ||
|
|
7d2c4992af | ||
|
|
968e8f51e4 | ||
|
|
6a21d24687 | ||
|
|
cba6ed9875 | ||
|
|
72fdc8f536 | ||
|
|
41336cca13 | ||
|
|
322907bbcd | ||
|
|
1f8df6fead | ||
|
|
6e085b783d | ||
|
|
59dddd3f4c | ||
|
|
d6bbcfbbc1 | ||
|
|
4de6b83e2f | ||
|
|
90cbb0c5f6 | ||
|
|
7260d7f9f8 | ||
|
|
c39c4be1cd | ||
|
|
6f9b3e31e7 | ||
|
|
0a0dde3f47 | ||
|
|
e27e303c01 | ||
|
|
ef54b685f6 | ||
|
|
0370fd5848 | ||
|
|
119d18d699 | ||
|
|
8322633b14 | ||
|
|
2f32fc5c16 | ||
|
|
7c44c4f194 | ||
|
|
bbb663f9d2 | ||
|
|
fdb4a2fb5c | ||
|
|
0a4684133d | ||
|
|
0d5e518af3 | ||
|
|
d47ab43fcf | ||
|
|
19a711d12b | ||
|
|
bf2db55d00 | ||
|
|
885975e099 | ||
|
|
79b3274074 | ||
|
|
7c86e5e39a | ||
|
|
e1cc61037e | ||
|
|
1ae951126a | ||
|
|
6bb8c0d4e7 | ||
|
|
087b6162ed | ||
|
|
f9e8031acb | ||
|
|
ebd767595b | ||
|
|
6231c5b8b3 | ||
|
|
a3b8297e23 | ||
|
|
6715ff9f5f | ||
|
|
8c5325511c | ||
|
|
895614353e | ||
|
|
676c507a50 | ||
|
|
5f4fd92b1d | ||
|
|
8191a7dae6 | ||
|
|
756672258d | ||
|
|
fb6f7072d4 | ||
|
|
aa95ad40c0 | ||
|
|
ba3667ab51 |
76
.github/actions/win-sign-action/action.yml
vendored
Normal file
76
.github/actions/win-sign-action/action.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: 'Windows Code Signing'
|
||||
description: 'Sign files on Windows with the Azure Trusted Signing'
|
||||
inputs:
|
||||
base-dir:
|
||||
description: 'Absolute path to the base directory to search for files'
|
||||
required: true
|
||||
recursive:
|
||||
description: 'Whether to search recursively in subdirectories'
|
||||
required: false
|
||||
default: 'false'
|
||||
file-extensions:
|
||||
description: 'List of file extensions to sign, separated by comma'
|
||||
required: true
|
||||
default: 'exe,dll,ps1'
|
||||
description:
|
||||
description: 'Signature description'
|
||||
required: true
|
||||
default: 'Cryptomator'
|
||||
url:
|
||||
description: 'Signature URL'
|
||||
required: false
|
||||
default: 'https://cryptomator.org'
|
||||
append-signature:
|
||||
description: 'Whether to append the signature to existing signatures'
|
||||
required: false
|
||||
default: 'false'
|
||||
tenant-id:
|
||||
description: 'Azure Tenant ID'
|
||||
required: true
|
||||
client-id:
|
||||
description: 'Azure Client ID'
|
||||
required: true
|
||||
client-secret:
|
||||
description: 'Azure Client Secret'
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Generate, mask, and output the input secrets
|
||||
id: set-secrets
|
||||
run: |
|
||||
echo "::add-mask::${{ inputs.tenant-id }}"
|
||||
echo "::add-mask::${{ inputs.client-id }}"
|
||||
echo "::add-mask::${{ inputs.client-secret }}"
|
||||
echo "tenant-id=${{ inputs.tenant-id }}" >> "$GITHUB_OUTPUT"
|
||||
echo "client-id=${{ inputs.client-id }}" >> "$GITHUB_OUTPUT"
|
||||
echo "client-secret=${{ inputs.client-secret }}" >> "$GITHUB_OUTPUT"
|
||||
shell: bash
|
||||
- name: Sign DLLs with Azure Trusted Signing
|
||||
uses: azure/trusted-signing-action@fc390cf8ed0f14e248a542af1d838388a47c7a7c # v0.5.10
|
||||
with:
|
||||
files-folder: ${{ inputs.base-dir }}
|
||||
files-folder-filter: ${{ inputs.file-extensions }}
|
||||
files-folder-recurse: ${{ inputs.recursive }}
|
||||
append-signature: ${{ inputs.append-signature }}
|
||||
description: ${{ inputs.description }}
|
||||
description-url: ${{ inputs.url }}
|
||||
azure-tenant-id: ${{ steps.set-secrets.outputs.tenant-id }}
|
||||
azure-client-id: ${{ steps.set-secrets.outputs.client-id }}
|
||||
azure-client-secret: ${{ steps.set-secrets.outputs.client-secret }}
|
||||
trusted-signing-account-name: cryptomatorSigning
|
||||
certificate-profile-name: production
|
||||
endpoint: https://weu.codesigning.azure.net/
|
||||
timestamp-rfc3161: http://timestamp.acs.microsoft.com
|
||||
timestamp-digest: SHA256
|
||||
exclude-environment-credential: false
|
||||
exclude-workload-identity-credential: true
|
||||
exclude-managed-identity-credential: true
|
||||
exclude-shared-token-cache-credential: true
|
||||
exclude-visual-studio-credential: true
|
||||
exclude-visual-studio-code-credential: true
|
||||
exclude-azure-cli-credential: true
|
||||
exclude-azure-powershell-credential: true
|
||||
exclude-azure-developer-cli-credential: true
|
||||
exclude-interactive-browser-credential: true
|
||||
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -53,6 +53,4 @@ updates:
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
labels:
|
||||
- "misc:ci"
|
||||
- "*"
|
||||
115
.github/workflows/appimage.yml
vendored
115
.github/workflows/appimage.yml
vendored
@@ -8,16 +8,24 @@ on:
|
||||
version:
|
||||
description: 'Version'
|
||||
required: false
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
paths:
|
||||
- '.github/workflows/appimage.yml'
|
||||
- 'dist/linux/appimage/**'
|
||||
- 'dist/linux/common/**'
|
||||
- 'dist/linux/resources/**'
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: '23.0.2'
|
||||
JAVA_VERSION: '24.0.1+9'
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
uses: ./.github/workflows/get-version.yml
|
||||
with:
|
||||
version: ${{ inputs.version }}
|
||||
version: ${{ inputs.version }} #okay if not defined
|
||||
|
||||
build:
|
||||
name: Build AppImage
|
||||
@@ -29,22 +37,21 @@ jobs:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
appimage-suffix: x86_64
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-x64_bin-jmods.zip'
|
||||
openjfx-sha: '063baebc6922e4a89c94b9dfb7a4f53e59e8d6fec400d4e670b31bc2ab324dec'
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-x64_bin-jmods.zip'
|
||||
openjfx-sha: '96e520f48610d8ffb94ca30face1f11ffe8a977ddc1c4ff80b1a9e9f048bd94e'
|
||||
- os: ubuntu-24.04-arm
|
||||
appimage-suffix: aarch64
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-aarch64_bin-jmods.zip'
|
||||
openjfx-sha: '9bbedaeae1590b69e2b22237bda310936df33e344dbc243bea2e86acaab3a0d8'
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-aarch64_bin-jmods.zip'
|
||||
openjfx-sha: '9ad4ca7b769ca4ee6419f1e99143dd6ff812f8be4fddb46a7d7cacbeea148af4'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
check-latest: true
|
||||
cache: 'maven'
|
||||
|
||||
- name: Download OpenJFX jmods
|
||||
id: download-jmods
|
||||
run: |
|
||||
@@ -61,26 +68,34 @@ jobs:
|
||||
POM_JFX_VERSION=${POM_JFX_VERSION#*@}
|
||||
POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
|
||||
|
||||
if [ $POM_JFX_VERSION -ne $JMOD_VERSION_AMD64 ]; then
|
||||
if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
|
||||
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION})"
|
||||
exit 1
|
||||
fi
|
||||
- name: Set version
|
||||
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
||||
- name: Run maven
|
||||
run: mvn -B clean package -Plinux -DskipTests -Djavafx.platform=linux
|
||||
run: mvn -B clean package -Plinux -DskipTests
|
||||
- name: Patch target dir
|
||||
run: |
|
||||
cp LICENSE.txt target
|
||||
cp target/cryptomator-*.jar target/mods
|
||||
- name: Run jlink with help option
|
||||
id: jep-493-check
|
||||
run: |
|
||||
JMOD_PATHS="openjfx-jmods"
|
||||
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||
fi
|
||||
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||
- name: Run jlink
|
||||
#Remark: no compression is applied for improved build compression later (here appimage)
|
||||
run: >
|
||||
${JAVA_HOME}/bin/jlink
|
||||
--verbose
|
||||
--output runtime
|
||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler
|
||||
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler
|
||||
--strip-native-commands
|
||||
--no-header-files
|
||||
--no-man-pages
|
||||
@@ -101,7 +116,7 @@ jobs:
|
||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
||||
--java-options "--enable-preview"
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
|
||||
--java-options "-Xss5m"
|
||||
--java-options "-Xmx256m"
|
||||
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
|
||||
@@ -117,6 +132,7 @@ jobs:
|
||||
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\""
|
||||
--java-options "-Dcryptomator.buildNumber=\"appimage-${{ needs.get-version.outputs.revNum }}\""
|
||||
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\""
|
||||
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log"
|
||||
--resource-dir dist/linux/resources
|
||||
- name: Patch Cryptomator.AppDir
|
||||
run: |
|
||||
@@ -152,14 +168,14 @@ jobs:
|
||||
- name: Build AppImage
|
||||
run: >
|
||||
./squashfs-root/AppRun Cryptomator.AppDir cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.appimage-suffix }}.AppImage
|
||||
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${{ matrix.appimage-suffix }}.AppImage.zsync'
|
||||
-u "gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${{ matrix.appimage-suffix }}.AppImage.zsync"
|
||||
--sign --sign-key=615D449FE6E6A235
|
||||
- name: Create detached GPG signatures
|
||||
run: |
|
||||
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage
|
||||
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator-*.AppImage.zsync
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: appimage-${{ matrix.appimage-suffix }}
|
||||
path: |
|
||||
@@ -169,7 +185,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
- name: Publish AppImage on GitHub Releases
|
||||
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||
with:
|
||||
fail_on_unmatched_files: true
|
||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||
@@ -177,3 +193,68 @@ jobs:
|
||||
cryptomator-*.AppImage
|
||||
cryptomator-*.zsync
|
||||
cryptomator-*.asc
|
||||
|
||||
create-aur-bin-pr:
|
||||
name: Create PR for aur-bin repo
|
||||
needs: [build, get-version]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' && needs.get-version.outputs.versionType == 'stable'
|
||||
steps:
|
||||
- name: Download AppImages
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
path: downloads/
|
||||
merge-multiple: true
|
||||
- name: Compute sha256 hash of AppImages
|
||||
id: checksums
|
||||
run: |
|
||||
X64_SHA256=$(sha256sum downloads/cryptomator-*-x86_64.AppImage | cut -d ' ' -f1)
|
||||
echo "x64-sha256sum=${X64_SHA256}" >> "$GITHUB_OUTPUT"
|
||||
AARCH64_SHA256=$(sha256sum downloads/cryptomator-*-aarch64.AppImage | cut -d ' ' -f1)
|
||||
echo "aarch64-sha256sum=${AARCH64_SHA256}" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
repository: 'cryptomator/aur-bin'
|
||||
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install makepkg pacman-package-manager
|
||||
- name: Checkout release branch
|
||||
run: |
|
||||
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
||||
- name: Update build file
|
||||
run: |
|
||||
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
|
||||
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
|
||||
sed -i -e "s|^sha256sums_x86_64=.*$|sha256sums_x86_64=('${{ steps.checksums.outputs.x64-sha256sum }}'|" PKGBUILD
|
||||
sed -i -e "s|^sha256sums_aarch64=.*$|sha256sums_aarch64=('${{ steps.checksums.outputs.aarch64-sha256sum}}'|" PKGBUILD
|
||||
makepkg --printsrcinfo > .SRCINFO
|
||||
- name: Commit and push
|
||||
run: |
|
||||
git config user.name "${{ github.actor }}"
|
||||
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
|
||||
git config push.autoSetupRemote true
|
||||
git stage .
|
||||
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
|
||||
git push
|
||||
- name: Create pull request
|
||||
id: create-pr
|
||||
run: |
|
||||
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
|
||||
URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
|
||||
echo "PR_URL=$URL" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Slack Notification
|
||||
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_USERNAME: 'Cryptobot'
|
||||
SLACK_ICON: false
|
||||
SLACK_ICON_EMOJI: ':bot:'
|
||||
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||
SLACK_TITLE: "AUR-bin release PR for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
|
||||
SLACK_MESSAGE: "See <${{ steps.create-pr.outputs.PR_URL }}|PR> on how to proceed."
|
||||
SLACK_FOOTER: false
|
||||
MSG_MINIMAL: true
|
||||
|
||||
95
.github/workflows/aur.yml
vendored
Normal file
95
.github/workflows/aur.yml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
name: Create PR for AUR
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Release tag'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
uses: ./.github/workflows/get-version.yml
|
||||
with:
|
||||
version: ${{ inputs.tag }}
|
||||
tarball:
|
||||
name: Determines tarball url and compute checksum
|
||||
runs-on: ubuntu-latest
|
||||
needs: [get-version]
|
||||
if: github.event_name == 'workflow_dispatch' || needs.get-version.outputs.versionType == 'stable'
|
||||
env:
|
||||
INPUT_TAG: ${{ inputs.tag }}
|
||||
outputs:
|
||||
url: ${{ steps.url.outputs.url}}
|
||||
sha256: ${{ steps.sha256.outputs.sha256}}
|
||||
steps:
|
||||
- name: Determine tarball url
|
||||
id: url
|
||||
run: |
|
||||
URL="";
|
||||
if [[ -n "${INPUT_TAG}" ]]; then
|
||||
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${INPUT_TAG}.tar.gz"
|
||||
else
|
||||
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz"
|
||||
fi
|
||||
echo "url=${URL}" >> "$GITHUB_OUTPUT"
|
||||
- name: Download source tarball and compute checksum
|
||||
id: sha256
|
||||
run: |
|
||||
curl --silent --fail-with-body -L -H "Accept: application/vnd.github+json" ${{ steps.url.outputs.url }} --output cryptomator.tar.gz
|
||||
TARBALL_SHA256=$(sha256sum cryptomator.tar.gz | cut -d ' ' -f1)
|
||||
echo "sha256=${TARBALL_SHA256}" >> "$GITHUB_OUTPUT"
|
||||
aur:
|
||||
name: Create PR for AUR
|
||||
runs-on: ubuntu-latest
|
||||
needs: [tarball, get-version]
|
||||
env:
|
||||
AUR_PR_URL: tbd
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
repository: 'cryptomator/aur'
|
||||
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install makepkg pacman-package-manager
|
||||
- name: Checkout release branch
|
||||
run: |
|
||||
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
||||
- name: Update build file
|
||||
run: |
|
||||
sed -i -e 's|^pkgver=.*$|pkgver=${{ needs.get-version.outputs.semVerStr }}|' PKGBUILD
|
||||
sed -i -e 's|^pkgrel=.*$|pkgrel=1|' PKGBUILD
|
||||
sed -i -e "s|^sha256sums=.*$|sha256sums=('${{ needs.tarball.outputs.sha256 }}'|" PKGBUILD
|
||||
makepkg --printsrcinfo > .SRCINFO
|
||||
- name: Commit and push
|
||||
run: |
|
||||
git config user.name "${{ github.actor }}"
|
||||
git config user.email "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
|
||||
git config push.autoSetupRemote true
|
||||
git stage .
|
||||
git commit -m "Prepare release ${{needs.get-version.outputs.semVerStr}}"
|
||||
git push
|
||||
- name: Create pull request
|
||||
run: |
|
||||
printf "> [!IMPORTANT]\n> Todos:\n> - [ ] Update build instructions\n> - [ ] Check for JDK update\n> - [ ] Check for JFX update" > pr_body.md
|
||||
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
|
||||
echo "AUR_PR_URL=$PR_URL" >> "$GITHUB_ENV"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Slack Notification
|
||||
if: github.event_name == 'release'
|
||||
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_USERNAME: 'Cryptobot'
|
||||
SLACK_ICON: false
|
||||
SLACK_ICON_EMOJI: ':bot:'
|
||||
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||
SLACK_TITLE: "AUR release PR created for ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} created."
|
||||
SLACK_MESSAGE: "See <${{ env.AUR_PR_URL }}|PR> on how to proceed."
|
||||
SLACK_FOOTER: false
|
||||
MSG_MINIMAL: true
|
||||
18
.github/workflows/av-whitelist.yml
vendored
18
.github/workflows/av-whitelist.yml
vendored
@@ -30,16 +30,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
fileName: ${{ steps.extractName.outputs.fileName}}
|
||||
env:
|
||||
INPUT_URL: ${{ inputs.url }}
|
||||
steps:
|
||||
- name: Extract file name
|
||||
id: extractName
|
||||
run: |
|
||||
url="${{ inputs.url }}"
|
||||
url="${INPUT_URL}"
|
||||
echo "fileName=${url##*/}" >> $GITHUB_OUTPUT
|
||||
- name: Download file
|
||||
run: curl --remote-name ${{ inputs.url }} -L -o ${{steps.extractName.outputs.fileName}}
|
||||
run: curl --remote-name ${INPUT_URL} -L -o ${{steps.extractName.outputs.fileName}}
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: ${{ steps.extractName.outputs.fileName }}
|
||||
path: ${{ steps.extractName.outputs.fileName }}
|
||||
@@ -51,12 +53,12 @@ jobs:
|
||||
if: github.event_name == 'workflow_call' || inputs.kaspersky
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
name: ${{ needs.download-file.outputs.fileName }}
|
||||
path: upload
|
||||
- name: Upload to Kaspersky
|
||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||
uses: SamKirkland/FTP-Deploy-Action@a51268f67f6605236975928ae28b0f7e9971d50a # v4.6.3
|
||||
with:
|
||||
protocol: ftps
|
||||
server: allowlist.kaspersky-labs.com
|
||||
@@ -71,12 +73,12 @@ jobs:
|
||||
if: github.event_name == 'workflow_call' || inputs.avast
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
name: ${{ needs.download-file.outputs.fileName }}
|
||||
path: upload
|
||||
- name: Upload to Avast
|
||||
uses: wlixcc/SFTP-Deploy-Action@v1.2.5
|
||||
- name: Upload to Avast
|
||||
uses: wlixcc/SFTP-Deploy-Action@a5ccb9c6211a94cc59404f0fdb2a9936a6dfee64 # v1.2.6
|
||||
with:
|
||||
server: whitelisting.avast.com
|
||||
port: 22
|
||||
|
||||
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
@@ -2,12 +2,16 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build.yml'
|
||||
- 'pom.xml'
|
||||
- 'src/**'
|
||||
pull_request_target:
|
||||
types: [labeled]
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: 23
|
||||
JAVA_VERSION: 24
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -18,14 +22,14 @@ jobs:
|
||||
name: Compile and Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
cache: 'maven'
|
||||
- name: Cache SonarCloud packages
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
@@ -33,7 +37,7 @@ jobs:
|
||||
- name: Build and Test
|
||||
run: >
|
||||
xvfb-run
|
||||
mvn -B verify -Djavafx.platform=linux
|
||||
mvn -B verify
|
||||
jacoco:report
|
||||
org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
|
||||
-Pcoverage
|
||||
@@ -45,7 +49,7 @@ jobs:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
- name: Draft a release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||
with:
|
||||
draft: true
|
||||
discussion_category_name: releases
|
||||
|
||||
6
.github/workflows/check-jdk-updates.yml
vendored
6
.github/workflows/check-jdk-updates.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
JDK_VERSION: '23.0.1+11'
|
||||
JDK_VERSION: '24.0.1+9'
|
||||
JDK_VENDOR: temurin
|
||||
RUNTIME_VERSION_HELPER: >
|
||||
public class Test {
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
run: echo 'JDK_MAJOR_VERSION=${{ env.JDK_VERSION }}'.substring(0,20) >> "$env:GITHUB_ENV"
|
||||
shell: pwsh
|
||||
- name: Checkout latest JDK ${{ env.JDK_MAJOR_VERSION }}
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
java-version: ${{ env.JDK_MAJOR_VERSION}}
|
||||
distribution: ${{ env.JDK_VENDOR }}
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
}
|
||||
- name: Notify
|
||||
if: steps.determine.outputs.UPDATE_AVAILABLE == 'true'
|
||||
uses: rtCamp/action-slack-notify@v2
|
||||
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_USERNAME: 'Cryptobot'
|
||||
|
||||
72
.github/workflows/debian.yml
vendored
72
.github/workflows/debian.yml
vendored
@@ -5,55 +5,68 @@ on:
|
||||
inputs:
|
||||
semver:
|
||||
description: 'SemVer String (e.g. 1.7.0-beta1)'
|
||||
required: true
|
||||
ppaver:
|
||||
description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1'
|
||||
required: true
|
||||
dput:
|
||||
description: 'Upload to PPA'
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
paths:
|
||||
- '.github/workflows/debian.yml'
|
||||
- 'dist/linux/debian/**'
|
||||
- 'dist/linux/common/**'
|
||||
- 'dist/linux/resources/**'
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: '23.0.2+7'
|
||||
COFFEELIBS_JDK: 23
|
||||
COFFEELIBS_JDK_VERSION: '23.0.2+7-0ppa1'
|
||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-x64_bin-jmods.zip'
|
||||
OPENJFX_JMODS_AMD64_HASH: '063baebc6922e4a89c94b9dfb7a4f53e59e8d6fec400d4e670b31bc2ab324dec'
|
||||
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_linux-aarch64_bin-jmods.zip'
|
||||
OPENJFX_JMODS_AARCH64_HASH: '9bbedaeae1590b69e2b22237bda310936df33e344dbc243bea2e86acaab3a0d8'
|
||||
JAVA_VERSION: '24.0.1+9'
|
||||
COFFEELIBS_JDK: 24
|
||||
COFFEELIBS_JDK_VERSION: '24.0.1+9-0ppa3'
|
||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-x64_bin-jmods.zip'
|
||||
OPENJFX_JMODS_AMD64_HASH: '96e520f48610d8ffb94ca30face1f11ffe8a977ddc1c4ff80b1a9e9f048bd94e'
|
||||
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_linux-aarch64_bin-jmods.zip'
|
||||
OPENJFX_JMODS_AARCH64_HASH: '9ad4ca7b769ca4ee6419f1e99143dd6ff812f8be4fddb46a7d7cacbeea148af4'
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
uses: ./.github/workflows/get-version.yml
|
||||
with:
|
||||
version: ${{ inputs.semver }} #okay if not defined
|
||||
|
||||
build:
|
||||
name: Build Debian Package
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [get-version]
|
||||
env:
|
||||
INPUT_PPAVER: ${{ inputs.ppaver }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- id: versions
|
||||
name: Get version information
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- id: deb-version
|
||||
name: Determine deb-version
|
||||
run: |
|
||||
SEM_VER_STR="${{ inputs.semver }}"
|
||||
SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
|
||||
REVCOUNT=`git rev-list --count HEAD`
|
||||
echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT
|
||||
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
|
||||
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
|
||||
if [ -n "${INPUT_PPAVER}" ]; then
|
||||
echo "debVersion=${INPUT_PPAVER}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "debVersion=${{needs.get-version.outputs.semVerStr}}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Install build tools
|
||||
run: |
|
||||
sudo add-apt-repository ppa:coffeelibs/openjdk
|
||||
sudo apt-get update
|
||||
sudo apt-get install debhelper devscripts dput coffeelibs-jdk-${{ env.COFFEELIBS_JDK }}=${{ env.COFFEELIBS_JDK_VERSION }}
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
check-latest: true
|
||||
cache: 'maven'
|
||||
- name: Run maven
|
||||
run: mvn -B clean package -Plinux -Djavafx.platform=linux -DskipTests
|
||||
run: mvn -B clean package -Plinux -DskipTests
|
||||
- name: Download OpenJFX jmods
|
||||
id: download-jmods
|
||||
run: |
|
||||
@@ -94,7 +107,7 @@ jobs:
|
||||
cp -r jmods pkgdir
|
||||
cp -r dist/linux/common/ pkgdir
|
||||
cp target/cryptomator-*.jar pkgdir/mods
|
||||
tar -cJf cryptomator_${{ inputs.ppaver }}.orig.tar.xz -C pkgdir .
|
||||
tar -cJf cryptomator_${{ steps.deb-version.outputs.debVersion }}.orig.tar.xz -C pkgdir .
|
||||
- name: Patch and rename pkgdir
|
||||
run: |
|
||||
cp -r dist/linux/debian/ pkgdir
|
||||
@@ -103,12 +116,12 @@ jobs:
|
||||
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules
|
||||
envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
|
||||
find . -name "*.jar" >> pkgdir/debian/source/include-binaries
|
||||
mv pkgdir cryptomator_${{ inputs.ppaver }}
|
||||
mv pkgdir cryptomator_${{ steps.deb-version.outputs.debVersion }}
|
||||
env:
|
||||
SEMVER_STR: ${{ steps.versions.outputs.semVerStr }}
|
||||
VERSION_NUM: ${{ steps.versions.outputs.semVerNum }}
|
||||
REVISION_NUM: ${{ steps.versions.outputs.revNum }}
|
||||
PPA_VERSION: ${{ inputs.ppaver }}-0ppa1
|
||||
SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }}
|
||||
VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }}
|
||||
REVISION_NUM: ${{ needs.get-version.outputs.revNum }}
|
||||
PPA_VERSION: ${{ steps.deb-version.outputs.debVersion }}-0ppa1
|
||||
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
|
||||
run: |
|
||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||
@@ -118,17 +131,18 @@ jobs:
|
||||
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||
- name: debuild
|
||||
run: |
|
||||
(sleep 8m; gpg --batch --quiet --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign README.md) &
|
||||
debuild -S -sa -d
|
||||
debuild -b -sa -d
|
||||
env:
|
||||
DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
|
||||
DEBSIGN_KEYID: 615D449FE6E6A235
|
||||
working-directory: cryptomator_${{ inputs.ppaver }}
|
||||
working-directory: cryptomator_${{ steps.deb-version.outputs.debVersion }}
|
||||
- name: Create detached GPG signatures
|
||||
run: |
|
||||
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: linux-deb-package
|
||||
path: |
|
||||
@@ -140,7 +154,7 @@ jobs:
|
||||
cryptomator_*_amd64.deb
|
||||
cryptomator_*.asc
|
||||
- name: Publish on PPA
|
||||
if: inputs.dput
|
||||
if: inputs.dput && inputs.ppaver != ''
|
||||
run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
|
||||
# If ref is a tag, also upload to GitHub Releases:
|
||||
- name: Publish Debian package on GitHub Releases
|
||||
|
||||
7
.github/workflows/dependency-check.yml
vendored
7
.github/workflows/dependency-check.yml
vendored
@@ -7,12 +7,13 @@ on:
|
||||
|
||||
jobs:
|
||||
check-dependencies:
|
||||
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@v1
|
||||
uses: skymatic/workflows/.github/workflows/run-dependency-check.yml@1074588008ae3326a2221ea451783280518f0366 # v3.0.1
|
||||
with:
|
||||
runner-os: 'ubuntu-latest'
|
||||
java-distribution: 'temurin'
|
||||
java-version: 23
|
||||
check-command: 'mvn -B validate -Pdependency-check -Djavafx.platform=linux'
|
||||
java-version: 24
|
||||
secrets:
|
||||
nvd-api-key: ${{ secrets.NVD_API_KEY }}
|
||||
ossindex-username: ${{ secrets.OSSINDEX_USERNAME }}
|
||||
ossindex-token: ${{ secrets.OSSINDEX_API_TOKEN }}
|
||||
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
4
.github/workflows/dl-stats.yml
vendored
4
.github/workflows/dl-stats.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- name: Get download count of latest releases
|
||||
id: get-stats
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
with:
|
||||
script: |
|
||||
const query = `query($owner:String!, $name:String!) {
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
INTERVAL: 900
|
||||
JSON_DATA: ${{ steps.get-stats.outputs.result }}
|
||||
- name: Upload Results
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
uses: fjogeleit/http-request-action@1297c6fc63a79b147d1676540a3fd9d2e37817c5 # v1.16.5
|
||||
with:
|
||||
url: 'https://graphite-us-central1.grafana.net/metrics'
|
||||
method: 'POST'
|
||||
|
||||
6
.github/workflows/error-db.yml
vendored
6
.github/workflows/error-db.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
- name: Query Discussion Data
|
||||
if: github.event_name == 'discussion_comment' || github.event_name == 'discussion' && github.event.action != 'deleted'
|
||||
id: query-data
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
with:
|
||||
script: |
|
||||
const query = `query ($owner: String!, $name: String!, $discussionNumber: Int!) {
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
return await github.graphql(query, variables)
|
||||
- name: Get Gist
|
||||
id: get-gist
|
||||
uses: andymckay/get-gist-action@master
|
||||
uses: andymckay/get-gist-action@cf3bc8164af24126f7e5979eb6d3dc0c12309bd1 # not_tagged
|
||||
with:
|
||||
gistURL: https://gist.github.com/cryptobot/accba9fb9555e7192271b85606f97230
|
||||
- name: Merge Error Code Data
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
env:
|
||||
DISCUSSION: ${{ steps.query-data.outputs.result }}
|
||||
- name: Patch Gist
|
||||
uses: exuanbo/actions-deploy-gist@v1
|
||||
uses: exuanbo/actions-deploy-gist@47697fceaeea2006a90594ee24eb9cd0a1121ef8 # v1.1.4
|
||||
with:
|
||||
token: ${{ secrets.CRYPTOBOT_GIST_TOKEN }}
|
||||
gist_id: accba9fb9555e7192271b85606f97230
|
||||
|
||||
17
.github/workflows/flathub.yml
vendored
17
.github/workflows/flathub.yml
vendored
@@ -26,13 +26,10 @@ jobs:
|
||||
- name: Determine tarball url
|
||||
id: url
|
||||
run: |
|
||||
URL="";
|
||||
if [[ -n "${{ inputs.tag }}" ]]; then
|
||||
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ inputs.tag }}.tar.gz"
|
||||
else
|
||||
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${{ github.event.release.tag_name }}.tar.gz"
|
||||
fi
|
||||
URL="https://github.com/cryptomator/cryptomator/archive/refs/tags/${TAG}.tar.gz"
|
||||
echo "url=${URL}" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
TAG: ${{ inputs.tag || github.event.release.tag_name}}
|
||||
- name: Download source tarball and compute checksum
|
||||
id: sha512
|
||||
run: |
|
||||
@@ -46,10 +43,10 @@ jobs:
|
||||
env:
|
||||
FLATHUB_PR_URL: tbd
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
repository: 'flathub/org.cryptomator.Cryptomator'
|
||||
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
||||
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Checkout release branch
|
||||
run: |
|
||||
git checkout -b release/${{ needs.get-version.outputs.semVerStr }}
|
||||
@@ -72,9 +69,9 @@ jobs:
|
||||
PR_URL=$(gh pr create --title "Release ${{ needs.get-version.outputs.semVerStr }}" --body-file pr_body.md)
|
||||
echo "FLATHUB_PR_URL=$PR_URL" >> "$GITHUB_ENV"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Slack Notification
|
||||
uses: rtCamp/action-slack-notify@v2
|
||||
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||
if: github.event_name == 'release'
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
|
||||
14
.github/workflows/get-version.yml
vendored
14
.github/workflows/get-version.yml
vendored
@@ -23,7 +23,7 @@ on:
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: 23
|
||||
JAVA_VERSION: 24
|
||||
|
||||
jobs:
|
||||
determine-version:
|
||||
@@ -35,11 +35,11 @@ jobs:
|
||||
revNum: ${{ steps.versions.outputs.revNum }}
|
||||
type: ${{ steps.versions.outputs.type}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
@@ -49,8 +49,8 @@ jobs:
|
||||
run: |
|
||||
if [[ $GITHUB_REF =~ refs/tags/[0-9]+\.[0-9]+\.[0-9]+.* ]]; then
|
||||
SEM_VER_STR=${GITHUB_REF##*/}
|
||||
elif [[ "${{ inputs.version }}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then
|
||||
SEM_VER_STR="${{ inputs.version }}"
|
||||
elif [[ "${VERSION_STRING}" =~ [0-9]+\.[0-9]+\.[0-9]+.* ]]; then
|
||||
SEM_VER_STR="${VERSION_STRING}"
|
||||
else
|
||||
SEM_VER_STR=`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`
|
||||
fi
|
||||
@@ -70,7 +70,9 @@ jobs:
|
||||
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
|
||||
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
|
||||
echo "type=${TYPE}" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
VERSION_STRING: ${{ inputs.version }}
|
||||
- name: Validate Version
|
||||
uses: skymatic/semver-validation-action@v3
|
||||
uses: skymatic/semver-validation-action@7a6ae1c9e121540d11c9c7e4e667c83d583aa153 # v3.0.0
|
||||
with:
|
||||
version: ${{ steps.versions.outputs.semVerStr }}
|
||||
68
.github/workflows/mac-dmg-x64.yml
vendored
68
.github/workflows/mac-dmg-x64.yml
vendored
@@ -2,20 +2,29 @@ name: Build macOS .dmg for x64
|
||||
|
||||
#######################################
|
||||
# STOP! DO NOT EDIT THIS FILE!
|
||||
#
|
||||
#
|
||||
# It is a copy of mac-dmg.yml with tiny adjustements (mainly lines 42 to 47)
|
||||
# It was made necessary, since Github does not offer free macos intel runners for macos 15 and above.
|
||||
# This workflow can only be triggered by a release.
|
||||
#
|
||||
#
|
||||
#######################################
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version'
|
||||
required: false
|
||||
notarize:
|
||||
description: 'Notarize'
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: '23.0.2+7'
|
||||
JAVA_VERSION: '24.0.1+9'
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
@@ -35,12 +44,12 @@ jobs:
|
||||
architecture: x64
|
||||
output-suffix: x64
|
||||
fuse-lib: macFUSE
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_osx-x64_bin-jmods.zip'
|
||||
openjfx-sha: '5e6c65c065eea22430c0eab36f37a5985eb8ad99e19e8772262021740d338f68'
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_osx-x64_bin-jmods.zip'
|
||||
openjfx-sha: '0eba73fb28a24c845175d16fa2f8c081c936ce6de1be9b79eb6119fa32e53d52'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
@@ -70,19 +79,27 @@ jobs:
|
||||
- name: Set version
|
||||
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
||||
- name: Run maven
|
||||
run: mvn -B -Djavafx.platform=mac clean package -Pmac -DskipTests
|
||||
run: mvn -B clean package -Pmac -DskipTests
|
||||
- name: Patch target dir
|
||||
run: |
|
||||
cp LICENSE.txt target
|
||||
cp target/cryptomator-*.jar target/mods
|
||||
- name: Run jlink with help option
|
||||
id: jep-493-check
|
||||
run: |
|
||||
JMOD_PATHS="openjfx-jmods"
|
||||
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||
fi
|
||||
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||
- name: Run jlink
|
||||
#Remark: no compression is applied for improved build compression later (here dmg)
|
||||
run: >
|
||||
${JAVA_HOME}/bin/jlink
|
||||
--verbose
|
||||
--output runtime
|
||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||
--strip-native-commands
|
||||
--no-header-files
|
||||
--no-man-pages
|
||||
@@ -103,7 +120,7 @@ jobs:
|
||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
||||
--java-options "--enable-preview"
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac"
|
||||
--java-options "-Xss5m"
|
||||
--java-options "-Xmx256m"
|
||||
--java-options "-Dfile.encoding=\"utf-8\""
|
||||
@@ -133,9 +150,23 @@ jobs:
|
||||
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
|
||||
REVISION_NO: ${{ needs.get-version.outputs.revNum }}
|
||||
PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
|
||||
- name: Build and install DockTilePlugin
|
||||
env:
|
||||
DERIVED_DATA_PATH: dist/mac/DockTilePlugin/build
|
||||
run: |
|
||||
xcodebuild -project dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj \
|
||||
-scheme DockTilePlugin \
|
||||
-configuration Release \
|
||||
-destination "platform=macOS,arch=x86_64" \
|
||||
-derivedDataPath ${DERIVED_DATA_PATH} \
|
||||
-quiet \
|
||||
clean build
|
||||
mkdir -p Cryptomator.app/Contents/PlugIns
|
||||
cp -R ${DERIVED_DATA_PATH}/Build/Products/Release/Cryptomator.docktileplugin Cryptomator.app/Contents/PlugIns/
|
||||
rm -rf ${DERIVED_DATA_PATH}
|
||||
- name: Generate license for dmg
|
||||
run: >
|
||||
mvn -B -Djavafx.platform=mac license:add-third-party
|
||||
mvn -B license:add-third-party
|
||||
-Dlicense.thirdPartyFilename=license.rtf
|
||||
-Dlicense.outputDirectory=dist/mac/dmg/resources
|
||||
-Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl
|
||||
@@ -223,9 +254,14 @@ jobs:
|
||||
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
|
||||
env:
|
||||
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
|
||||
- name: Codesign .dmg
|
||||
run: |
|
||||
codesign -s ${CODESIGN_IDENTITY} --timestamp Cryptomator-*.dmg
|
||||
env:
|
||||
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||
- name: Notarize .dmg
|
||||
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
|
||||
uses: cocoalibs/xcode-notarization-action@v1
|
||||
uses: cocoalibs/xcode-notarization-action@5cf433d494b6fa26504b574c591f4dd120388846 # v1.0.3
|
||||
with:
|
||||
app-path: 'Cryptomator-*.dmg'
|
||||
apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
|
||||
@@ -246,7 +282,7 @@ jobs:
|
||||
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
|
||||
continue-on-error: true
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: dmg-${{ matrix.output-suffix }}
|
||||
path: |
|
||||
@@ -255,7 +291,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
- name: Publish dmg on GitHub Releases
|
||||
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||
with:
|
||||
fail_on_unmatched_files: true
|
||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||
|
||||
60
.github/workflows/mac-dmg.yml
vendored
60
.github/workflows/mac-dmg.yml
vendored
@@ -13,10 +13,16 @@ on:
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
paths:
|
||||
- '.github/workflows/mac-dmg.yml'
|
||||
- 'dist/mac/**'
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: '23.0.2+7'
|
||||
JAVA_VERSION: '24.0.1+9'
|
||||
|
||||
jobs:
|
||||
get-version:
|
||||
@@ -36,12 +42,12 @@ jobs:
|
||||
architecture: aarch64
|
||||
output-suffix: arm64
|
||||
fuse-lib: FUSE-T
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.2/openjfx-23.0.2_osx-aarch64_bin-jmods.zip'
|
||||
openjfx-sha: 'c690cc642a3924cf56622951f478ba57aec9ce09063761f800c3319331bed3fc'
|
||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_osx-aarch64_bin-jmods.zip'
|
||||
openjfx-sha: '13f8c0513c40c95881479fbcf0465a29a60217393fb0656f5e4eab78a9442fba'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
@@ -71,19 +77,27 @@ jobs:
|
||||
- name: Set version
|
||||
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
||||
- name: Run maven
|
||||
run: mvn -B -Djavafx.platform=mac clean package -Pmac -DskipTests
|
||||
run: mvn -B clean package -Pmac -DskipTests
|
||||
- name: Patch target dir
|
||||
run: |
|
||||
cp LICENSE.txt target
|
||||
cp target/cryptomator-*.jar target/mods
|
||||
- name: Run jlink with help option
|
||||
id: jep-493-check
|
||||
run: |
|
||||
JMOD_PATHS="openjfx-jmods"
|
||||
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||
fi
|
||||
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||
- name: Run jlink
|
||||
#Remark: no compression is applied for improved build compression later (here dmg)
|
||||
run: >
|
||||
${JAVA_HOME}/bin/jlink
|
||||
--verbose
|
||||
--output runtime
|
||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||
--strip-native-commands
|
||||
--no-header-files
|
||||
--no-man-pages
|
||||
@@ -104,7 +118,7 @@ jobs:
|
||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
||||
--java-options "--enable-preview"
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac"
|
||||
--java-options "-Xss5m"
|
||||
--java-options "-Xmx256m"
|
||||
--java-options "-Dfile.encoding=\"utf-8\""
|
||||
@@ -121,6 +135,7 @@ jobs:
|
||||
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Library/Application Support/Cryptomator/mnt\""
|
||||
--java-options "-Dcryptomator.showTrayIcon=true"
|
||||
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ needs.get-version.outputs.revNum }}\""
|
||||
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log"
|
||||
--mac-package-identifier org.cryptomator
|
||||
--resource-dir dist/mac/resources
|
||||
- name: Patch Cryptomator.app
|
||||
@@ -134,9 +149,23 @@ jobs:
|
||||
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
|
||||
REVISION_NO: ${{ needs.get-version.outputs.revNum }}
|
||||
PROVISIONING_PROFILE_BASE64: ${{ secrets.MACOS_PROVISIONING_PROFILE_BASE64 }}
|
||||
- name: Build and install DockTilePlugin
|
||||
env:
|
||||
DERIVED_DATA_PATH: dist/mac/DockTilePlugin/build
|
||||
run: |
|
||||
xcodebuild -project dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj \
|
||||
-scheme DockTilePlugin \
|
||||
-configuration Release \
|
||||
-destination "platform=macOS,arch=arm64" \
|
||||
-derivedDataPath ${DERIVED_DATA_PATH} \
|
||||
-quiet \
|
||||
clean build
|
||||
mkdir -p Cryptomator.app/Contents/PlugIns
|
||||
cp -R ${DERIVED_DATA_PATH}/Build/Products/Release/Cryptomator.docktileplugin Cryptomator.app/Contents/PlugIns/
|
||||
rm -rf ${DERIVED_DATA_PATH}
|
||||
- name: Generate license for dmg
|
||||
run: >
|
||||
mvn -B -Djavafx.platform=mac license:add-third-party
|
||||
mvn -B license:add-third-party
|
||||
-Dlicense.thirdPartyFilename=license.rtf
|
||||
-Dlicense.outputDirectory=dist/mac/dmg/resources
|
||||
-Dlicense.fileTemplate=dist/mac/dmg/resources/licenseTemplate.ftl
|
||||
@@ -224,9 +253,14 @@ jobs:
|
||||
Cryptomator-${VERSION_NO}-${{ matrix.output-suffix }}.dmg dmg
|
||||
env:
|
||||
VERSION_NO: ${{ needs.get-version.outputs.semVerNum }}
|
||||
- name: Codesign .dmg
|
||||
run: |
|
||||
codesign -s ${CODESIGN_IDENTITY} --timestamp Cryptomator-*.dmg
|
||||
env:
|
||||
CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||
- name: Notarize .dmg
|
||||
if: startsWith(github.ref, 'refs/tags/') || inputs.notarize
|
||||
uses: cocoalibs/xcode-notarization-action@v1
|
||||
uses: cocoalibs/xcode-notarization-action@5cf433d494b6fa26504b574c591f4dd120388846 # v1.0.3
|
||||
with:
|
||||
app-path: 'Cryptomator-*.dmg'
|
||||
apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
|
||||
@@ -247,7 +281,7 @@ jobs:
|
||||
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
|
||||
continue-on-error: true
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: dmg-${{ matrix.output-suffix }}
|
||||
path: |
|
||||
@@ -256,7 +290,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
- name: Publish dmg on GitHub Releases
|
||||
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||
with:
|
||||
fail_on_unmatched_files: true
|
||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||
|
||||
2
.github/workflows/no-response.yml
vendored
2
.github/workflows/no-response.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
|
||||
with:
|
||||
days-before-stale: 14
|
||||
days-before-close: 0
|
||||
|
||||
4
.github/workflows/post-publish.yml
vendored
4
.github/workflows/post-publish.yml
vendored
@@ -19,14 +19,14 @@ jobs:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||
- name: Publish asc on GitHub Releases
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||
with:
|
||||
fail_on_unmatched_files: true
|
||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||
files: |
|
||||
cryptomator-*.tar.gz.asc
|
||||
- name: Slack Notification
|
||||
uses: rtCamp/action-slack-notify@v2
|
||||
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_USERNAME: 'Cryptobot'
|
||||
|
||||
9
.github/workflows/pullrequest.yml
vendored
9
.github/workflows/pullrequest.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'temurin'
|
||||
JAVA_VERSION: 23
|
||||
JAVA_VERSION: 24
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -15,13 +15,12 @@ jobs:
|
||||
test:
|
||||
name: Compile and Test
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
cache: 'maven'
|
||||
- name: Build and Test
|
||||
run: xvfb-run mvn -B clean install jacoco:report -Pcoverage -Djavafx.platform=linux
|
||||
run: xvfb-run mvn -B clean install jacoco:report -Pcoverage
|
||||
8
.github/workflows/release-check.yml
vendored
8
.github/workflows/release-check.yml
vendored
@@ -19,9 +19,9 @@ jobs:
|
||||
name: Validate commits pushed to release/hotfix branch to fulfill release requirements
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
- name: Cache NVD DB
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ~/.m2/repository/org/owasp/dependency-check-data/
|
||||
key: dependency-check-${{ github.run_id }}
|
||||
@@ -60,6 +60,6 @@ jobs:
|
||||
- name: Run org.owasp:dependency-check plugin
|
||||
id: dependency-check
|
||||
continue-on-error: true
|
||||
run: mvn -B verify -Pdependency-check -DskipTests -Djavafx.platform=linux
|
||||
run: mvn -B verify -Pdependency-check -DskipTests
|
||||
env:
|
||||
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
|
||||
with:
|
||||
days-before-stale: 365
|
||||
days-before-close: 90
|
||||
|
||||
341
.github/workflows/win-exe.yml
vendored
341
.github/workflows/win-exe.yml
vendored
@@ -8,18 +8,24 @@ on:
|
||||
version:
|
||||
description: 'Version'
|
||||
required: false
|
||||
isDebug:
|
||||
description: 'Build debug version with console output'
|
||||
sign:
|
||||
description: 'Sign binaries'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
paths:
|
||||
- '.github/workflows/win-exe.yml'
|
||||
- 'dist/win/**'
|
||||
|
||||
|
||||
env:
|
||||
JAVA_DIST: 'zulu'
|
||||
JAVA_VERSION: '23.0.2+7'
|
||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_windows-x64_bin-jmods.zip'
|
||||
OPENJFX_JMODS_AMD64_HASH: 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
|
||||
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
|
||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/25/openjfx-25_windows-x64_bin-jmods.zip'
|
||||
OPENJFX_JMODS_AMD64_HASH: 'c8eb9fd039b00e0020cf6c3db8ed7876bf3ee4d27860aa697a247b83b8296ae7'
|
||||
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
|
||||
WINFSP_MSI_HASH: '073a70e00f77423e34bed98b86e600def93393ba5822204fac57a29324db9f7a'
|
||||
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
||||
|
||||
defaults:
|
||||
@@ -34,33 +40,46 @@ jobs:
|
||||
|
||||
build-msi:
|
||||
name: Build .msi Installer
|
||||
runs-on: windows-latest
|
||||
needs: [get-version]
|
||||
env:
|
||||
LOOPBACK_ALIAS: 'cryptomator-vault'
|
||||
WIN_CONSOLE_FLAG: ''
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [ get-version ]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: x64
|
||||
os: windows-latest
|
||||
java-dist: 'zulu'
|
||||
java-version: '24.0.1+9'
|
||||
java-package: 'jdk'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
distribution: ${{ matrix.java-dist }}
|
||||
java-version: ${{ matrix.java-version }}
|
||||
java-package: ${{ matrix.java-package }}
|
||||
check-latest: true
|
||||
cache: 'maven'
|
||||
- name: Install wix and extensions
|
||||
run: |
|
||||
dotnet tool install --global wix --version 6.0.0
|
||||
wix.exe extension add WixToolset.UI.wixext/6.0.0 --global
|
||||
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
|
||||
- name: Download and extract JavaFX jmods from Gluon
|
||||
if: matrix.arch == 'x64'
|
||||
#In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
|
||||
run: |
|
||||
curl --output jfxjmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
|
||||
if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
|
||||
curl --output openjfx-jmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
|
||||
if(!(Get-FileHash -Path openjfx-jmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
|
||||
throw "Wrong checksum of JMOD archive downloaded from ${{ env.OPENJFX_JMODS_AMD64 }}.";
|
||||
}
|
||||
Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
|
||||
Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
|
||||
Expand-Archive -Path openjfx-jmods.zip -DestinationPath openjfx-jmods
|
||||
Get-ChildItem -Path openjfx-jmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
|
||||
shell: pwsh
|
||||
- name: Ensure major jfx version in pom and in jmods is the same
|
||||
if: matrix.arch == 'x64'
|
||||
run: |
|
||||
JMOD_VERSION_AMD64=$(jmod describe jfxjmods/javafx.base.jmod | head -1)
|
||||
JMOD_VERSION_AMD64=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
|
||||
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
|
||||
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
|
||||
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
|
||||
@@ -72,29 +91,34 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
- name: Set version
|
||||
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
||||
run: mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
||||
- name: Run maven
|
||||
run: mvn -B clean package -Pwin -DskipTests -Djavafx.platform=win
|
||||
run: mvn -B clean package -Pwin -DskipTests
|
||||
- name: Patch target dir
|
||||
run: |
|
||||
cp LICENSE.txt target
|
||||
cp target/cryptomator-*.jar target/mods
|
||||
- name: Run jlink with help option
|
||||
id: jep-493-check
|
||||
run: |
|
||||
JMOD_PATHS="openjfx-jmods"
|
||||
if ! $(${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"); then
|
||||
JMOD_PATHS="${JAVA_HOME}/jmods;${JMOD_PATHS}"
|
||||
fi
|
||||
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||
- name: Run jlink
|
||||
#Remark: no compression is applied for improved build compression later (here msi)
|
||||
# Remark: no compression is applied for improved build compression later (here msi)
|
||||
run: >
|
||||
${JAVA_HOME}/bin/jlink
|
||||
--verbose
|
||||
--output runtime
|
||||
--module-path "jfxjmods;${JAVA_HOME}/jmods"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.mscapi,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.crypto.mscapi,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||
--strip-native-commands
|
||||
--no-header-files
|
||||
--no-man-pages
|
||||
--strip-debug
|
||||
--compress zip-0
|
||||
- name: Change win-console flag if debug is active
|
||||
if: ${{ inputs.isDebug }}
|
||||
run: echo "WIN_CONSOLE_FLAG=--win-console" >> $GITHUB_ENV
|
||||
- name: Run jpackage
|
||||
run: >
|
||||
${JAVA_HOME}/bin/jpackage
|
||||
@@ -110,7 +134,7 @@ jobs:
|
||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
||||
--java-options "--enable-preview"
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
|
||||
--java-options "-Xss5m"
|
||||
--java-options "-Xmx256m"
|
||||
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
|
||||
@@ -122,30 +146,24 @@ jobs:
|
||||
--java-options "-Dcryptomator.p12Path=\"@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12\""
|
||||
--java-options "-Dcryptomator.ipcSocketPath=\"@{localappdata}/Cryptomator/ipc.socket\""
|
||||
--java-options "-Dcryptomator.mountPointsDir=\"@{userhome}/Cryptomator\""
|
||||
--java-options "-Dcryptomator.loopbackAlias=\"${{ env.LOOPBACK_ALIAS }}\""
|
||||
--java-options "-Dcryptomator.loopbackAlias=\"cryptomator-vault\""
|
||||
--java-options "-Dcryptomator.showTrayIcon=true"
|
||||
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
|
||||
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
|
||||
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
|
||||
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
|
||||
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=\"@{appdata}/Cryptomator/windowsHelloKeychain.json\""
|
||||
--java-options "-Dcryptomator.disableUpdateCheck=false"
|
||||
--java-options "-XX:ErrorFile=C:/cryptomator/cryptomator_crash.log"
|
||||
--resource-dir dist/win/resources
|
||||
--icon dist/win/resources/Cryptomator.ico
|
||||
${WIN_CONSOLE_FLAG}
|
||||
--add-launcher "Cryptomator (Debug)=dist/win/debug-launcher.properties"
|
||||
- name: Patch Application Directory
|
||||
run: |
|
||||
cp dist/win/contrib/* appdir/Cryptomator
|
||||
- name: Set LOOPBACK_ALIAS in patchWebDAV.bat
|
||||
shell: pwsh
|
||||
run: |
|
||||
$patchScript = "appdir\Cryptomator\patchWebDAV.bat"
|
||||
try {
|
||||
(Get-Content $patchScript ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"${{ env.LOOPBACK_ALIAS}}`"" | Set-Content $patchScript
|
||||
} catch {
|
||||
Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
|
||||
exit 1
|
||||
}
|
||||
- name: Fix permissions
|
||||
run: attrib -r appdir/Cryptomator/Cryptomator.exe
|
||||
run: |
|
||||
attrib -r appdir/Cryptomator/Cryptomator.exe
|
||||
attrib -r "appdir/Cryptomator/Cryptomator (Debug).exe"
|
||||
shell: pwsh
|
||||
- name: Extract jars with DLLs for Codesigning
|
||||
shell: pwsh
|
||||
@@ -170,16 +188,27 @@ jobs:
|
||||
New-Item -Path appdir/jpackage-jmod -ItemType Directory
|
||||
& $env:JAVA_HOME\bin\jmod.exe extract --dir jpackage-jmod "${env:JAVA_HOME}\jmods\jdk.jpackage.jmod"
|
||||
Get-ChildItem -Recurse -Path "jpackage-jmod" -File wixhelper.dll | Select-Object -Last 1 | Copy-Item -Destination "appdir"
|
||||
- name: Codesign
|
||||
uses: skymatic/code-sign-action@v3
|
||||
- name: Sign DLLs with Azure Trusted Signing
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: ./.github/actions/win-sign-action
|
||||
with:
|
||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
||||
description: Cryptomator
|
||||
timestampUrl: 'http://timestamp.digicert.com'
|
||||
folder: appdir
|
||||
base-dir: ${{ github.workspace }}\appdir
|
||||
recursive: true
|
||||
append-signature: true
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
- name: Sign DLLs with Actalis CodeSigner
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f # no specific version
|
||||
with:
|
||||
base-dir: 'appdir'
|
||||
file-extensions: 'dll,exe,ps1'
|
||||
recursive: true
|
||||
sign-description: 'Cryptomator'
|
||||
sign-url: 'https://cryptomator.org'
|
||||
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
|
||||
password: ${{ secrets.WIN_CODESIGN_PW }}
|
||||
- name: Replace DLLs inside jars with signed ones
|
||||
shell: pwsh
|
||||
run: |
|
||||
@@ -196,7 +225,7 @@ jobs:
|
||||
}
|
||||
- name: Generate license for MSI
|
||||
run: >
|
||||
mvn -B license:add-third-party "-Djavafx.platform=win"
|
||||
mvn -B license:add-third-party
|
||||
"-Dlicense.thirdPartyFilename=license.rtf"
|
||||
"-Dlicense.outputDirectory=dist/win/resources"
|
||||
"-Dlicense.fileTemplate=dist/win/resources/licenseTemplate.ftl"
|
||||
@@ -228,17 +257,18 @@ jobs:
|
||||
env:
|
||||
JP_WIXWIZARD_RESOURCES: ${{ github.workspace }}/dist/win/resources # requires abs path, used in resources/main.wxs
|
||||
JP_WIXHELPER_DIR: ${{ github.workspace }}\appdir
|
||||
- name: Codesign MSI
|
||||
uses: skymatic/code-sign-action@v3
|
||||
- name: Sign MSI with Azure Trusted Signing
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: ./.github/actions/win-sign-action
|
||||
with:
|
||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
||||
description: Cryptomator Installer
|
||||
timestampUrl: 'http://timestamp.digicert.com'
|
||||
folder: installer
|
||||
- name: Add possible alpha/beta tags to installer name
|
||||
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi
|
||||
base-dir: ${{ github.workspace }}\installer
|
||||
file-extensions: msi
|
||||
description: 'Cryptomator Installer'
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
- name: Add possible alpha/beta tags and architecture to installer name
|
||||
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.arch }}.msi
|
||||
- name: Create detached GPG signature with key 615D449FE6E6A235
|
||||
run: |
|
||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||
@@ -247,9 +277,9 @@ jobs:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: msi
|
||||
name: msi-${{ matrix.arch }}
|
||||
path: |
|
||||
Cryptomator-*.msi
|
||||
Cryptomator-*.asc
|
||||
@@ -257,26 +287,42 @@ jobs:
|
||||
|
||||
build-exe:
|
||||
name: Build .exe installer
|
||||
runs-on: windows-latest
|
||||
needs: [get-version, build-msi]
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [ get-version, build-msi ]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: x64
|
||||
os: windows-latest
|
||||
executable-suffix: x64
|
||||
java-dist: 'zulu'
|
||||
java-version: '24.0.1+9'
|
||||
java-package: 'jdk'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
- name: Install wix and extensions
|
||||
run: |
|
||||
dotnet tool install --global wix --version 6.0.0
|
||||
wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global
|
||||
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
|
||||
- name: Download .msi
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
name: msi
|
||||
name: msi-${{ matrix.arch }}
|
||||
path: dist/win/bundle/resources
|
||||
- name: Strip version info from msi file name
|
||||
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
|
||||
- uses: actions/setup-java@v4
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: ${{ env.JAVA_DIST }}
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
distribution: ${{ matrix.java-dist }}
|
||||
java-version: ${{ matrix.java-version }}
|
||||
java-package: ${{ matrix.java-package }}
|
||||
check-latest: true
|
||||
cache: 'maven'
|
||||
- name: Generate license for exe
|
||||
run: >
|
||||
mvn -B license:add-third-party "-Djavafx.platform=win"
|
||||
mvn -B license:add-third-party
|
||||
"-Dlicense.thirdPartyFilename=license.rtf"
|
||||
"-Dlicense.fileTemplate=dist/win/bundle/resources/licenseTemplate.ftl"
|
||||
"-Dlicense.outputDirectory=dist/win/bundle/resources"
|
||||
@@ -287,60 +333,83 @@ jobs:
|
||||
shell: pwsh
|
||||
- name: Download WinFsp
|
||||
run: |
|
||||
curl --output dist/win/bundle/resources/winfsp.msi -L ${{ env.WINFSP_MSI }}
|
||||
curl --output $env:WINFSP_PATH -L ${{ env.WINFSP_MSI }}
|
||||
$computedHash = (Get-FileHash -Path $env:WINFSP_PATH -Algorithm SHA256).Hash.ToLower()
|
||||
if ($computedHash -ne "${{ env.WINFSP_MSI_HASH }}") {
|
||||
throw "Checksum mismatch for $env:WINFSP_PATH (expected ${{ env.WINFSP_MSI_HASH }}, got $computedHash)."
|
||||
}
|
||||
env:
|
||||
WINFSP_PATH: 'dist/win/bundle/resources/winfsp.msi'
|
||||
shell: pwsh
|
||||
- name: Download Legacy-WinFsp uninstaller
|
||||
run: |
|
||||
curl --output dist/win/bundle/resources/winfsp-uninstaller.exe -L ${{ env.WINFSP_UNINSTALLER }}
|
||||
shell: pwsh
|
||||
- name: Compile to wixObj file
|
||||
- name: Create Wix Burn bundle
|
||||
working-directory: dist/win
|
||||
run: >
|
||||
"${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
|
||||
-ext WixBalExtension
|
||||
-ext WixUtilExtension
|
||||
-out dist/win/bundle/
|
||||
-dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
||||
-dBundleVendor="Skymatic GmbH"
|
||||
-dBundleCopyright="(C) 2016 - 2025 Skymatic GmbH"
|
||||
-dAboutUrl="https://cryptomator.org"
|
||||
-dHelpUrl="https://cryptomator.org/contact"
|
||||
-dUpdateUrl="https://cryptomator.org/downloads/"
|
||||
- name: Create executable with linker
|
||||
run: >
|
||||
"${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
|
||||
-ext WixBalExtension
|
||||
-ext WixUtilExtension
|
||||
-out installer/unsigned/Cryptomator-Installer.exe
|
||||
wix build
|
||||
-define BundleName="Cryptomator"
|
||||
-define BundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
|
||||
-define BundleVendor="Skymatic GmbH"
|
||||
-define BundleCopyright="(C) 2016 - 2025 Skymatic GmbH"
|
||||
-define AboutUrl="https://cryptomator.org"
|
||||
-define HelpUrl="https://cryptomator.org/contact"
|
||||
-define UpdateUrl="https://cryptomator.org/downloads/"
|
||||
-ext "WixToolset.Util.wixext"
|
||||
-ext "WixToolset.BootstrapperApplications.wixext"
|
||||
./bundle/bundleWithWinfsp.wxs
|
||||
-out "../../installer/unsigned/Cryptomator-Installer.exe"
|
||||
- name: Detach burn engine in preparation to sign
|
||||
run: >
|
||||
"${WIX}/bin/insignia.exe"
|
||||
-ib installer/unsigned/Cryptomator-Installer.exe
|
||||
-o tmp/engine.exe
|
||||
- name: Codesign burn engine
|
||||
uses: skymatic/code-sign-action@v3
|
||||
wix burn detach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe
|
||||
- name: Sign WiX burn engine with Azure Trusted Signing
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: ./.github/actions/win-sign-action
|
||||
with:
|
||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
||||
description: Cryptomator Installer
|
||||
timestampUrl: 'http://timestamp.digicert.com'
|
||||
folder: tmp
|
||||
base-dir: ${{ github.workspace }}\tmp
|
||||
file-extensions: exe
|
||||
append-signature: true
|
||||
description: 'Cryptomator Bundle Installer'
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
- name: Sign burn engine with Actalis CodeSigner
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f # no specific version
|
||||
with:
|
||||
base-dir: 'tmp'
|
||||
file-extensions: 'exe'
|
||||
sign-description: 'Cryptomator Bundle Installer'
|
||||
sign-url: 'https://cryptomator.org'
|
||||
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
|
||||
password: ${{ secrets.WIN_CODESIGN_PW }}
|
||||
- name: Reattach signed burn engine to installer
|
||||
run : >
|
||||
"${WIX}/bin/insignia.exe"
|
||||
-ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe
|
||||
-o installer/Cryptomator-Installer.exe
|
||||
- name: Codesign EXE
|
||||
uses: skymatic/code-sign-action@v3
|
||||
run: >
|
||||
wix burn reattach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe -o installer/Cryptomator-Installer.exe
|
||||
- name: Sign EXE installer with Azure Trusted Signing
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: ./.github/actions/win-sign-action
|
||||
with:
|
||||
certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }}
|
||||
password: ${{ secrets.WIN_CODESIGN_P12_PW }}
|
||||
certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A
|
||||
description: Cryptomator Installer
|
||||
timestampUrl: 'http://timestamp.digicert.com'
|
||||
folder: installer
|
||||
base-dir: ${{ github.workspace }}\installer
|
||||
file-extensions: exe
|
||||
append-signature: true
|
||||
description: 'Cryptomator Bundle Installer'
|
||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||
client-id: ${{ secrets.AZURE_CLIENT_ID }}
|
||||
client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
- name: Sign installer with Actalis CodeSigner
|
||||
if: inputs.sign || github.event_name == 'release'
|
||||
uses: skymatic/workflows/.github/actions/win-sign-action@450e322ff2214d0be0b079b63343c894f3ef735f # no specific version
|
||||
with:
|
||||
base-dir: 'installer'
|
||||
file-extensions: 'exe'
|
||||
sign-description: 'Cryptomator Bundle Installer'
|
||||
sign-url: 'https://cryptomator.org'
|
||||
username: ${{ secrets.WIN_CODESIGN_USERNAME }}
|
||||
password: ${{ secrets.WIN_CODESIGN_PW }}
|
||||
- name: Add possible alpha/beta tags to installer name
|
||||
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.exe
|
||||
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.executable-suffix }}.exe
|
||||
- name: Create detached GPG signature with key 615D449FE6E6A235
|
||||
run: |
|
||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||
@@ -349,9 +418,9 @@ jobs:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: exe
|
||||
name: exe-${{ matrix.executable-suffix }}
|
||||
path: |
|
||||
Cryptomator-*.exe
|
||||
Cryptomator-*.asc
|
||||
@@ -361,39 +430,39 @@ jobs:
|
||||
name: Publish installers to the github release
|
||||
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-msi, build-exe]
|
||||
needs: [ build-msi, build-exe ]
|
||||
outputs:
|
||||
download-url-msi: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
|
||||
download-url-exe: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
|
||||
download-url-msi-x64: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
|
||||
download-url-exe-x64: ${{ fromJSON(steps.publish.outputs.assets)[2].browser_download_url }}
|
||||
steps:
|
||||
- name: Download installers
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
merge-multiple: true
|
||||
- name: Publish .msi on GitHub Releases
|
||||
- name: Publish installers on GitHub Releases
|
||||
id: publish
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
||||
with:
|
||||
fail_on_unmatched_files: true
|
||||
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
|
||||
# do not change ordering of filelist, required for correct job output
|
||||
files: |
|
||||
*.msi
|
||||
*.exe
|
||||
*x64.msi
|
||||
*x64.exe
|
||||
*.asc
|
||||
|
||||
allowlist-msi:
|
||||
allowlist-msi-x64:
|
||||
uses: ./.github/workflows/av-whitelist.yml
|
||||
needs: [publish]
|
||||
needs: [ publish ]
|
||||
with:
|
||||
url: ${{ needs.publish.outputs.download-url-msi }}
|
||||
url: ${{ needs.publish.outputs.download-url-msi-x64 }}
|
||||
secrets: inherit
|
||||
|
||||
allowlist-exe:
|
||||
allowlist-exe-x64:
|
||||
uses: ./.github/workflows/av-whitelist.yml
|
||||
needs: [publish, allowlist-msi]
|
||||
needs: [ publish, allowlist-msi-x64 ]
|
||||
with:
|
||||
url: ${{ needs.publish.outputs.download-url-exe }}
|
||||
url: ${{ needs.publish.outputs.download-url-exe-x64 }}
|
||||
secrets: inherit
|
||||
|
||||
notify-winget:
|
||||
@@ -403,14 +472,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Slack Notification
|
||||
uses: rtCamp/action-slack-notify@v2
|
||||
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
|
||||
env:
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
SLACK_USERNAME: 'Cryptobot'
|
||||
SLACK_ICON: false
|
||||
SLACK_ICON_EMOJI: ':bot:'
|
||||
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||
SLACK_TITLE: "MSI of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
|
||||
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release to winget>."
|
||||
SLACK_TITLE: "MSI packages of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
|
||||
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release them to winget>."
|
||||
SLACK_FOOTER: false
|
||||
MSG_MINIMAL: true
|
||||
MSG_MINIMAL: true
|
||||
|
||||
8
.github/workflows/winget.yml
vendored
8
.github/workflows/winget.yml
vendored
@@ -16,12 +16,12 @@ jobs:
|
||||
run: |
|
||||
gh repo sync cryptomator/winget-pkgs -b master --force
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
- name: Submit package
|
||||
uses: vedantmgoyal2009/winget-releaser@main
|
||||
uses: vedantmgoyal2009/winget-releaser@19e706d4c9121098010096f9c495a70a7518b30f # no_specific_version
|
||||
with:
|
||||
identifier: Cryptomator.Cryptomator
|
||||
version: ${{ inputs.tag }}
|
||||
release-tag: ${{ inputs.tag }}
|
||||
installers-regex: '\.msi$'
|
||||
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
||||
installers-regex: '-x64\.msi$'
|
||||
token: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -8,7 +8,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="23" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_24" project-jdk-name="25" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/runConfigurations/Cryptomator_Linux.xml
generated
2
.idea/runConfigurations/Cryptomator_Linux.xml
generated
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="cryptomator" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="cryptomator" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator-Dev/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator-Dev/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator-Dev/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator-Dev/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
|
||||
2
.idea/runConfigurations/Cryptomator_Windows.xml
generated
2
.idea/runConfigurations/Cryptomator_Windows.xml
generated
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="cryptomator" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator" -Dcryptomator.pluginDir="@{appdata}/Cryptomator/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator" -Dcryptomator.pluginDir="@{appdata}/Cryptomator/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.integrationsWin.windowsHelloKeychainPaths="@{appdata}/Cryptomator/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator/windowsHelloKeychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="cryptomator" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator-Dev" -Dcryptomator.pluginDir="@{appdata}/Cryptomator-Dev/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
|
||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator-Dev" -Dcryptomator.pluginDir="@{appdata}/Cryptomator-Dev/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.integrationsWin.windowsHelloKeychainPaths="@{appdata}/Cryptomator-Dev/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/windowsHelloKeychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
|
||||
2
.idea/runConfigurations/Cryptomator_macOS.xml
generated
2
.idea/runConfigurations/Cryptomator_macOS.xml
generated
@@ -5,7 +5,7 @@
|
||||
</envs>
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="cryptomator" />
|
||||
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
|
||||
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</envs>
|
||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||
<module name="cryptomator" />
|
||||
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator-Dev" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Library/Application Support/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
|
||||
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator-Dev" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Library/Application Support/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
|
||||
@@ -78,7 +78,7 @@ For more information on the security details visit [cryptomator.org](https://doc
|
||||
|
||||
### Dependencies
|
||||
|
||||
* JDK 23 (e.g. temurin, zulu)
|
||||
* JDK 24 (e.g. temurin, zulu)
|
||||
* Maven 3
|
||||
|
||||
### Run Maven
|
||||
|
||||
27
dist/linux/appimage/build.sh
vendored
27
dist/linux/appimage/build.sh
vendored
@@ -12,23 +12,23 @@ command -v unzip >/dev/null 2>&1 || { echo >&2 "unzip not found."; exit 1; }
|
||||
|
||||
VERSION=$(mvn -f ../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout)
|
||||
SEMVER_STR=${VERSION}
|
||||
CPU_ARCH=$(uname -p)
|
||||
CPU_ARCH=$(uname -m)
|
||||
|
||||
if [[ ! "${CPU_ARCH}" =~ x86_64|aarch64 ]]; then echo "Platform ${CPU_ARCH} not supported"; exit 1; fi
|
||||
|
||||
mvn -f ../../../pom.xml versions:set -DnewVersion=${SEMVER_STR}
|
||||
|
||||
# compile
|
||||
mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests -Djavafx.platform=linux
|
||||
mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests
|
||||
cp ../../../LICENSE.txt ../../../target
|
||||
cp ../../../target/cryptomator-*.jar ../../../target/mods
|
||||
|
||||
JAVAFX_VERSION=23.0.2
|
||||
JAVAFX_VERSION=25
|
||||
JAVAFX_ARCH="x64"
|
||||
JAVAFX_JMODS_SHA256='063baebc6922e4a89c94b9dfb7a4f53e59e8d6fec400d4e670b31bc2ab324dec'
|
||||
JAVAFX_JMODS_SHA256='96e520f48610d8ffb94ca30face1f11ffe8a977ddc1c4ff80b1a9e9f048bd94e'
|
||||
if [ "${CPU_ARCH}" = "aarch64" ]; then
|
||||
JAVAFX_ARCH="aarch64"
|
||||
JAVAFX_JMODS_SHA256='9bbedaeae1590b69e2b22237bda310936df33e344dbc243bea2e86acaab3a0d8'
|
||||
JAVAFX_JMODS_SHA256='951c52481af0ec5885b06f1ebaa8a10da7e8ea23c5e1ef3e2f6f11fa1b3a7ce1'
|
||||
fi
|
||||
|
||||
# download javaFX jmods
|
||||
@@ -51,12 +51,18 @@ if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
|
||||
fi
|
||||
|
||||
|
||||
# add runtime
|
||||
# create runtime
|
||||
## check for JEP 493
|
||||
JMOD_PATHS="openjfx-jmods"
|
||||
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||
fi
|
||||
## create runtime image
|
||||
${JAVA_HOME}/bin/jlink \
|
||||
--verbose \
|
||||
--output runtime \
|
||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
||||
--module-path "${JMOD_PATHS}" \
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
||||
--strip-native-commands \
|
||||
--no-header-files \
|
||||
--no-man-pages \
|
||||
@@ -75,7 +81,7 @@ ${JAVA_HOME}/bin/jpackage \
|
||||
--name Cryptomator \
|
||||
--vendor "Skymatic GmbH" \
|
||||
--java-options "--enable-preview" \
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
||||
--java-options "-Xss5m" \
|
||||
--java-options "-Xmx256m" \
|
||||
@@ -92,6 +98,7 @@ ${JAVA_HOME}/bin/jpackage \
|
||||
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" \
|
||||
--java-options "-Dcryptomator.buildNumber=\"appimage-${REVISION_NO}\"" \
|
||||
--java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\"" \
|
||||
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log" \
|
||||
--resource-dir ../resources
|
||||
|
||||
# transform AppDir
|
||||
@@ -122,7 +129,7 @@ chmod +x /tmp/appimagetool.AppImage
|
||||
/tmp/appimagetool.AppImage \
|
||||
Cryptomator.AppDir \
|
||||
cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage \
|
||||
-u 'gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync'
|
||||
-u "gh-releases-zsync|cryptomator|cryptomator|latest|cryptomator-*-${CPU_ARCH}.AppImage.zsync"
|
||||
|
||||
echo ""
|
||||
echo "Done. AppImage successfully created: cryptomator-${SEMVER_STR}-${CPU_ARCH}.AppImage"
|
||||
|
||||
@@ -83,6 +83,15 @@
|
||||
</content_rating>
|
||||
|
||||
<releases>
|
||||
<release date="2025-11-12" version="1.18.0">
|
||||
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.18.0</url>
|
||||
</release>
|
||||
<release date="2025-07-08" version="1.17.1">
|
||||
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.1</url>
|
||||
</release>
|
||||
<release date="2025-06-24" version="1.17.0">
|
||||
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.17.0</url>
|
||||
</release>
|
||||
<release date="2025-05-15" version="1.16.2">
|
||||
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.2</url>
|
||||
</release>
|
||||
|
||||
2
dist/linux/debian/changelog
vendored
2
dist/linux/debian/changelog
vendored
@@ -1,4 +1,4 @@
|
||||
cryptomator (${PPA_VERSION}) focal; urgency=low
|
||||
cryptomator (${PPA_VERSION}) jammy; urgency=low
|
||||
|
||||
* Full changelog can be found on https://github.com/cryptomator/cryptomator/releases
|
||||
|
||||
|
||||
4
dist/linux/debian/control
vendored
4
dist/linux/debian/control
vendored
@@ -2,7 +2,7 @@ Source: cryptomator
|
||||
Maintainer: Cryptobot <releases@cryptomator.org>
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>=10), coffeelibs-jdk-23 (>= 23.0.2+7-0ppa1), libgtk-3-0, libxxf86vm1, libgl1
|
||||
Build-Depends: debhelper (>=10), coffeelibs-jdk-24 (>= 24.0.1+9-0ppa3), libgtk-3-0 (>= 3.20.0), libxxf86vm1, libgl1
|
||||
Standards-Version: 4.5.0
|
||||
Homepage: https://cryptomator.org
|
||||
Vcs-Git: https://github.com/cryptomator/cryptomator.git
|
||||
@@ -12,7 +12,7 @@ Package: cryptomator
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, fuse3
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, fuse3, libgtk-3-0 (>= 3.20.0)
|
||||
Recommends: gvfs-backends, gvfs-fuse, gnome-keyring
|
||||
XB-AppName: Cryptomator
|
||||
XB-Category: Utility;Security;FileTools;
|
||||
|
||||
6
dist/linux/debian/rules
vendored
6
dist/linux/debian/rules
vendored
@@ -4,7 +4,7 @@
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
JAVA_HOME = /usr/lib/jvm/java-23-coffeelibs
|
||||
JAVA_HOME = /usr/lib/jvm/java-24-coffeelibs
|
||||
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
|
||||
ifeq ($(DEB_BUILD_ARCH),amd64)
|
||||
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
|
||||
@@ -28,7 +28,7 @@ override_dh_auto_build:
|
||||
$(JAVA_HOME)/bin/jlink \
|
||||
--output runtime \
|
||||
--module-path "${JMODS_PATH}" \
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
||||
--strip-native-commands \
|
||||
--no-header-files \
|
||||
--no-man-pages \
|
||||
@@ -44,7 +44,7 @@ override_dh_auto_build:
|
||||
--name cryptomator \
|
||||
--vendor "Skymatic GmbH" \
|
||||
--java-options "--enable-preview" \
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
||||
--java-options "-Xss5m" \
|
||||
--java-options "-Xmx256m" \
|
||||
|
||||
1
dist/mac/.gitignore
vendored
1
dist/mac/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
embedded.provisionprofile
|
||||
xcuserdata/
|
||||
|
||||
19
dist/mac/DockTilePlugin/CryptomatorDockTilePlugin.swift
vendored
Normal file
19
dist/mac/DockTilePlugin/CryptomatorDockTilePlugin.swift
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// CryptomatorDockTilePlugin.swift
|
||||
// Integrations
|
||||
//
|
||||
// Created by Tobias Hagemann on 22.09.25.
|
||||
// Copyright © 2025 Cryptomator. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
|
||||
class CryptomatorDockTilePlugin: NSObject, NSDockTilePlugIn {
|
||||
func setDockTile(_ dockTile: NSDockTile?) {
|
||||
guard let dockTile = dockTile, let image = Bundle(for: Self.self).image(forResource: "Cryptomator") else {
|
||||
return
|
||||
}
|
||||
dockTile.contentView = NSImageView(image: image)
|
||||
dockTile.display()
|
||||
}
|
||||
}
|
||||
314
dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj/project.pbxproj
vendored
Normal file
314
dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj/project.pbxproj
vendored
Normal file
@@ -0,0 +1,314 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 77;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
74E08DE12E8584DE007E665C /* CryptomatorDockTilePlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74E08DE02E85847E007E665C /* CryptomatorDockTilePlugin.swift */; };
|
||||
74E08DED2E858532007E665C /* Cryptomator.icns in Resources */ = {isa = PBXBuildFile; fileRef = 74E08DEC2E858532007E665C /* Cryptomator.icns */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
74E08DD92E858467007E665C /* Cryptomator.docktileplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cryptomator.docktileplugin; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
74E08DE02E85847E007E665C /* CryptomatorDockTilePlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptomatorDockTilePlugin.swift; sourceTree = "<group>"; };
|
||||
74E08DEC2E858532007E665C /* Cryptomator.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Cryptomator.icns; path = ../resources/Cryptomator.icns; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
74E08DD62E858467007E665C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
74E08DD02E858467007E665C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
74E08DE02E85847E007E665C /* CryptomatorDockTilePlugin.swift */,
|
||||
74E08DEC2E858532007E665C /* Cryptomator.icns */,
|
||||
74E08DDA2E858467007E665C /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
74E08DDA2E858467007E665C /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
74E08DD92E858467007E665C /* Cryptomator.docktileplugin */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
74E08DD82E858467007E665C /* DockTilePlugin */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 74E08DDD2E858467007E665C /* Build configuration list for PBXNativeTarget "DockTilePlugin" */;
|
||||
buildPhases = (
|
||||
74E08DD52E858467007E665C /* Sources */,
|
||||
74E08DD62E858467007E665C /* Frameworks */,
|
||||
74E08DD72E858467007E665C /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = DockTilePlugin;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = DockTilePlugin;
|
||||
productReference = 74E08DD92E858467007E665C /* Cryptomator.docktileplugin */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
74E08DD12E858467007E665C /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastUpgradeCheck = 2600;
|
||||
ORGANIZATIONNAME = Cryptomator;
|
||||
TargetAttributes = {
|
||||
74E08DD82E858467007E665C = {
|
||||
CreatedOnToolsVersion = 26.0.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 74E08DD42E858467007E665C /* Build configuration list for PBXProject "DockTilePlugin" */;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 74E08DD02E858467007E665C;
|
||||
minimizedProjectReferenceProxies = 1;
|
||||
preferredProjectObjectVersion = 77;
|
||||
productRefGroup = 74E08DDA2E858467007E665C /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
74E08DD82E858467007E665C /* DockTilePlugin */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
74E08DD72E858467007E665C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74E08DED2E858532007E665C /* Cryptomator.icns in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
74E08DD52E858467007E665C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74E08DE12E8584DE007E665C /* CryptomatorDockTilePlugin.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
74E08DDB2E858467007E665C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = YZQJQUHA3L;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
74E08DDC2E858467007E665C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = YZQJQUHA3L;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.5;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
74E08DDE2E858467007E665C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Cryptomator. All rights reserved.";
|
||||
INFOPLIST_KEY_NSPrincipalClass = CryptomatorDockTilePlugin;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cryptomator.DockTilePlugin;
|
||||
PRODUCT_NAME = Cryptomator;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
WRAPPER_EXTENSION = docktileplugin;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
74E08DDF2E858467007E665C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Cryptomator. All rights reserved.";
|
||||
INFOPLIST_KEY_NSPrincipalClass = CryptomatorDockTilePlugin;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.cryptomator.DockTilePlugin;
|
||||
PRODUCT_NAME = Cryptomator;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
WRAPPER_EXTENSION = docktileplugin;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
74E08DD42E858467007E665C /* Build configuration list for PBXProject "DockTilePlugin" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
74E08DDB2E858467007E665C /* Debug */,
|
||||
74E08DDC2E858467007E665C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
74E08DDD2E858467007E665C /* Build configuration list for PBXNativeTarget "DockTilePlugin" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
74E08DDE2E858467007E665C /* Debug */,
|
||||
74E08DDF2E858467007E665C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 74E08DD12E858467007E665C /* Project object */;
|
||||
}
|
||||
7
dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
vendored
Normal file
7
dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
67
dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj/xcshareddata/xcschemes/DockTilePlugin.xcscheme
vendored
Normal file
67
dist/mac/DockTilePlugin/DockTilePlugin.xcodeproj/xcshareddata/xcschemes/DockTilePlugin.xcscheme
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "2600"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "74E08DD82E858467007E665C"
|
||||
BuildableName = "Cryptomator.docktileplugin"
|
||||
BlueprintName = "DockTilePlugin"
|
||||
ReferencedContainer = "container:DockTilePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "74E08DD82E858467007E665C"
|
||||
BuildableName = "Cryptomator.docktileplugin"
|
||||
BlueprintName = "DockTilePlugin"
|
||||
ReferencedContainer = "container:DockTilePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
38
dist/mac/dmg/build.sh
vendored
38
dist/mac/dmg/build.sh
vendored
@@ -32,15 +32,15 @@ REVISION_NO=`git rev-list --count HEAD`
|
||||
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
|
||||
FUSE_LIB="FUSE-T"
|
||||
|
||||
JAVAFX_VERSION=23.0.2
|
||||
JAVAFX_VERSION=25
|
||||
JAVAFX_ARCH="undefined"
|
||||
JAVAFX_JMODS_SHA256="undefined"
|
||||
if [ "$(machine)" = "arm64e" ]; then
|
||||
JAVAFX_ARCH="aarch64"
|
||||
JAVAFX_JMODS_SHA256="c690cc642a3924cf56622951f478ba57aec9ce09063761f800c3319331bed3fc"
|
||||
JAVAFX_JMODS_SHA256="13f8c0513c40c95881479fbcf0465a29a60217393fb0656f5e4eab78a9442fba"
|
||||
else
|
||||
JAVAFX_ARCH="x64"
|
||||
JAVAFX_JMODS_SHA256="5e6c65c065eea22430c0eab36f37a5985eb8ad99e19e8772262021740d338f68"
|
||||
JAVAFX_JMODS_SHA256="0eba73fb28a24c845175d16fa2f8c081c936ce6de1be9b79eb6119fa32e53d52"
|
||||
fi
|
||||
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
|
||||
|
||||
@@ -71,15 +71,21 @@ if [ "${POM_JFX_VERSION}" -ne "${JMOD_VERSION}" ]; then
|
||||
fi
|
||||
|
||||
# compile
|
||||
mvn -B -Djavafx.platform=mac -f../../../pom.xml clean package -DskipTests -Pmac
|
||||
mvn -B -f../../../pom.xml clean package -DskipTests -Pmac
|
||||
cp ../../../LICENSE.txt ../../../target
|
||||
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
|
||||
|
||||
# add runtime
|
||||
# create runtime
|
||||
## check for JEP 493
|
||||
JMOD_PATHS="openjfx-jmods"
|
||||
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||
fi
|
||||
## create custom runtime
|
||||
${JAVA_HOME}/bin/jlink \
|
||||
--output runtime \
|
||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,java.compiler \
|
||||
--module-path "${JMOD_PATHS}" \
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,java.compiler \
|
||||
--strip-native-commands \
|
||||
--no-header-files \
|
||||
--no-man-pages \
|
||||
@@ -100,7 +106,7 @@ ${JAVA_HOME}/bin/jpackage \
|
||||
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
|
||||
--app-version "${VERSION_NO}" \
|
||||
--java-options "--enable-preview" \
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac" \
|
||||
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac" \
|
||||
--java-options "-Xss5m" \
|
||||
--java-options "-Xmx256m" \
|
||||
--java-options "-Dfile.encoding=\"utf-8\"" \
|
||||
@@ -109,6 +115,7 @@ ${JAVA_HOME}/bin/jpackage \
|
||||
--java-options "-Dsun.java2d.metal=true" \
|
||||
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
|
||||
--java-options "-Dcryptomator.logDir=\"@{userhome}/Library/Logs/${APP_NAME}\"" \
|
||||
--java-options "-XX:ErrorFile=/cryptomator/cryptomator_crash.log" \
|
||||
--java-options "-Dcryptomator.pluginDir=\"@{userhome}/Library/Application Support/${APP_NAME}/Plugins\"" \
|
||||
--java-options "-Dcryptomator.settingsPath=\"@{userhome}/Library/Application Support/${APP_NAME}/settings.json\"" \
|
||||
--java-options "-Dcryptomator.ipcSocketPath=\"@{userhome}/Library/Application Support/${APP_NAME}/ipc.socket\"" \
|
||||
@@ -126,8 +133,21 @@ sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" ${APP_NAME}.app/
|
||||
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
|
||||
cp ../embedded.provisionprofile ${APP_NAME}.app/Contents/
|
||||
|
||||
# build and install dock tile plugin
|
||||
echo "Building and installing Cryptomator.docktileplugin..."
|
||||
DERIVED_DATA_PATH=../DockTilePlugin/build
|
||||
xcodebuild -project ../DockTilePlugin/DockTilePlugin.xcodeproj \
|
||||
-scheme DockTilePlugin \
|
||||
-configuration Release \
|
||||
-derivedDataPath ${DERIVED_DATA_PATH} \
|
||||
-quiet \
|
||||
clean build
|
||||
mkdir -p ${APP_NAME}.app/Contents/PlugIns
|
||||
cp -R ${DERIVED_DATA_PATH}/Build/Products/Release/Cryptomator.docktileplugin ${APP_NAME}.app/Contents/PlugIns/
|
||||
rm -rf ${DERIVED_DATA_PATH}
|
||||
|
||||
# generate license
|
||||
mvn -B -Djavafx.platform=mac -f../../../pom.xml license:add-third-party \
|
||||
mvn -B -f../../../pom.xml license:add-third-party \
|
||||
-Dlicense.thirdPartyFilename=license.rtf \
|
||||
-Dlicense.outputDirectory=dist/mac/dmg/resources \
|
||||
-Dlicense.fileTemplate=resources/licenseTemplate.ftl \
|
||||
|
||||
3
dist/mac/resources/Info.plist
vendored
3
dist/mac/resources/Info.plist
vendored
@@ -116,5 +116,8 @@
|
||||
<!-- allow utilization of integrated GPU, see https://developer.apple.com/library/mac/qa/qa1734/_index.html -->
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
<!-- register dock tile plugin -->
|
||||
<key>NSDockTilePlugIn</key>
|
||||
<string>Cryptomator.docktileplugin</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
3
dist/win/.gitignore
vendored
3
dist/win/.gitignore
vendored
@@ -4,7 +4,8 @@ installer
|
||||
*.wixobj
|
||||
*.pdb
|
||||
*.msi
|
||||
*Debug.properties
|
||||
*.exe
|
||||
*.jmod
|
||||
resources/jfxJmods.zip
|
||||
license.rtf
|
||||
license.rtf
|
||||
|
||||
6
dist/win/build.bat
vendored
6
dist/win/build.bat
vendored
@@ -11,6 +11,10 @@ SET HELP_URL="https://cryptomator.org/contact/"
|
||||
SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
|
||||
SET LOOPBACK_ALIAS="cryptomator-vault"
|
||||
|
||||
:: read clean parameter from command line
|
||||
SET CLEAN=0
|
||||
IF "%~1"=="clean" SET CLEAN=1
|
||||
|
||||
pwsh -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
|
||||
-AppName %APPNAME%^
|
||||
-MainJarGlob "%MAIN_JAR_GLOB%"^
|
||||
@@ -22,4 +26,4 @@ pwsh -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
|
||||
-HelpUrl "%HELP_URL%"^
|
||||
-UpdateUrl "%UPDATE_URL%"^
|
||||
-LoopbackAlias "%LOOPBACK_ALIAS%"^
|
||||
-Clean 1
|
||||
-Clean %CLEAN%
|
||||
238
dist/win/build.ps1
vendored
238
dist/win/build.ps1
vendored
@@ -9,39 +9,63 @@ Param(
|
||||
[Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
|
||||
[Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
|
||||
[Parameter(Mandatory, HelpMessage="Please provide an alias for localhost")][string] $LoopbackAlias,
|
||||
[bool] $clean
|
||||
[bool] $clean = $false # if true, cleans up previous build artifacts
|
||||
)
|
||||
|
||||
# ============================
|
||||
# Function Definitions Section
|
||||
# ============================
|
||||
|
||||
function Main {
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress bar, which slows down downloads to a few bytes/s
|
||||
|
||||
# check preconditions
|
||||
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
|
||||
{
|
||||
Write-Host "Unable to find git.exe in your PATH (try: choco install git)"
|
||||
Write-Error "Unable to find git.exe in your PATH (try: choco install git)"
|
||||
exit 1
|
||||
}
|
||||
if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
|
||||
{
|
||||
Write-Host "Unable to find mvn.cmd in your PATH (try: choco install maven)"
|
||||
Write-Error "Unable to find mvn.cmd in your PATH (try: choco install maven)"
|
||||
exit 1
|
||||
}
|
||||
if ((Get-Command 'wix' -ErrorAction SilentlyContinue) -eq $null)
|
||||
{
|
||||
Write-Error 'Unable to find wix in your PATH (try: dotnet tool install --global wix --version 6.0.0)'
|
||||
exit 1
|
||||
}
|
||||
$wixExtensions = & wix.exe extension list --global | Out-String
|
||||
if ($wixExtensions -notmatch 'WixToolset.UI.wixext') {
|
||||
Write-Error 'Wix UI extension missing. Please install it with: wix.exe extension add WixToolset.UI.wixext/6.0.0 --global)'
|
||||
exit 1
|
||||
}
|
||||
if ($wixExtensions -notmatch 'WixToolset.Util.wixext') {
|
||||
Write-Error 'Wix Util extension missing. Please install it with: wix.exe extension add WixToolset.Util.wixext/6.0.0 --global)'
|
||||
exit 1
|
||||
}
|
||||
if ($wixExtensions -notmatch 'WixToolset.BootstrapperApplications.wixext') {
|
||||
Write-Error 'Wix Bootstrapper extension missing. Please install it with: wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global)'
|
||||
exit 1
|
||||
}
|
||||
|
||||
$buildDir = Split-Path -Parent $PSCommandPath
|
||||
$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
|
||||
$semVerNo = $version -replace '(\d+\.\d+\.\d+).*','$1'
|
||||
$revisionNo = $(git rev-list --count HEAD)
|
||||
|
||||
Write-Output "`$version=$version"
|
||||
Write-Output "`$semVerNo=$semVerNo"
|
||||
Write-Output "`$revisionNo=$revisionNo"
|
||||
Write-Output "`$buildDir=$buildDir"
|
||||
Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
|
||||
Write-Host "`$version=$version"
|
||||
Write-Host "`$semVerNo=$semVerNo"
|
||||
Write-Host "`$revisionNo=$revisionNo"
|
||||
Write-Host "`$buildDir=$buildDir"
|
||||
Write-Host "`$Env:JAVA_HOME=$Env:JAVA_HOME"
|
||||
|
||||
$copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor"
|
||||
|
||||
# compile
|
||||
&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin "-Djavafx.platform=win"
|
||||
&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin
|
||||
Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
|
||||
|
||||
# add runtime
|
||||
@@ -50,43 +74,102 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
|
||||
Remove-Item -Path $runtimeImagePath -Force -Recurse
|
||||
}
|
||||
|
||||
## download jfx jmods
|
||||
$javaFxVersion='23.0.2'
|
||||
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
|
||||
$javaFxJmodsSHA256 = 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
|
||||
$javaFxJmods = '.\resources\jfxJmods.zip'
|
||||
if( !(Test-Path -Path $javaFxJmods) ) {
|
||||
Write-Output "Downloading ${javaFxJmodsUrl}..."
|
||||
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
|
||||
## download jfx jmods for X64, while they are part of the Arm64 JDK
|
||||
$archCode = (Get-CimInstance Win32_Processor).Architecture
|
||||
$archName = switch ($archCode) {
|
||||
9 { "x64" }
|
||||
12 { "ARM64" }
|
||||
default { "WMI Win32_Processor.Architecture code ($archCode)" }
|
||||
}
|
||||
|
||||
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
|
||||
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
|
||||
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
|
||||
, actual: $jmodsChecksumActual"
|
||||
exit 1;
|
||||
switch ($archName) {
|
||||
'ARM64' {
|
||||
$javafxBaseJmod = Join-Path $Env:JAVA_HOME "jmods\javafx.base.jmod"
|
||||
if (!(Test-Path $javafxBaseJmod)) {
|
||||
Write-Error "JavaFX module not found in JDK. Please ensure a JDK with JavaFX (including jmods) is installed."
|
||||
exit 1
|
||||
}
|
||||
|
||||
$jmodPaths = "$Env:JAVA_HOME/jmods"
|
||||
}
|
||||
'x64' {
|
||||
$javaFxVersion='25'
|
||||
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
|
||||
$javaFxJmodsSHA256 = 'c8eb9fd039b00e0020cf6c3db8ed7876bf3ee4d27860aa697a247b83b8296ae7'
|
||||
$javaFxJmods = '.\resources\jfxJmods.zip'
|
||||
|
||||
if( !(Test-Path -Path $javaFxJmods) ) {
|
||||
Write-Host "Downloading ${javaFxJmodsUrl}..."
|
||||
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
|
||||
}
|
||||
|
||||
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
|
||||
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
|
||||
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
|
||||
, actual: $jmodsChecksumActual"
|
||||
exit 1;
|
||||
}
|
||||
|
||||
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
|
||||
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
|
||||
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
|
||||
|
||||
$jmodPaths="$buildDir/resources/javafx-jmods";
|
||||
}
|
||||
default {
|
||||
Write-Error "Unsupported architecture: $arch"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
|
||||
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
|
||||
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
|
||||
|
||||
## create custom runtime
|
||||
### check for JEP 493
|
||||
if ((& "$Env:JAVA_HOME\bin\jlink" --help | Select-String -Pattern "Linking from run-time image enabled" -SimpleMatch | Measure-Object).Count -eq 0 ) {
|
||||
$jmodPaths="$Env:JAVA_HOME/jmods;" + $jmodPaths;
|
||||
}
|
||||
|
||||
### create runtime
|
||||
& "$Env:JAVA_HOME\bin\jlink" `
|
||||
--verbose `
|
||||
--output runtime `
|
||||
--module-path "$Env:JAVA_HOME/jmods;$buildDir/resources/javafx-jmods" `
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,jdk.crypto.mscapi,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
|
||||
--module-path $jmodPaths `
|
||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.crypto.mscapi,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
|
||||
--strip-native-commands `
|
||||
--no-header-files `
|
||||
--no-man-pages `
|
||||
--strip-debug `
|
||||
--compress "zip-0" #do not compress to have improved msi compression
|
||||
--compress "zip-0" #do not compress and use msi compression
|
||||
|
||||
$appPath = ".\$AppName"
|
||||
if ($clean -and (Test-Path -Path $appPath)) {
|
||||
Remove-Item -Path $appPath -Force -Recurse
|
||||
}
|
||||
|
||||
|
||||
$javaOptions = @(
|
||||
"--java-options", "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
|
||||
"--java-options", "-Xss5m"
|
||||
"--java-options", "-Xmx256m"
|
||||
"--java-options", "-Dcryptomator.appVersion=`"$semVerNo`""
|
||||
"--java-options", "-Dfile.encoding=`"utf-8`""
|
||||
"--java-options", "-Djava.net.useSystemProxies=true"
|
||||
"--java-options", "-Dcryptomator.logDir=`"@{localappdata}/$AppName`""
|
||||
"--java-options", "-XX:ErrorFile=`"C:/cryptomator/cryptomator_crash.log`""
|
||||
"--java-options", "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`""
|
||||
"--java-options", "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`""
|
||||
"--java-options", "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`""
|
||||
"--java-options", "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`""
|
||||
"--java-options", "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`""
|
||||
"--java-options", "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`""
|
||||
"--java-options", "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`""
|
||||
"--java-options", "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`""
|
||||
"--java-options", "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=`"@{appdata}/$AppName/windowsHelloKeychain.json`""
|
||||
"--java-options", "-Dcryptomator.showTrayIcon=true"
|
||||
"--java-options", "-Dcryptomator.buildNumber=`"msi-$revisionNo`""
|
||||
"--java-options", "-Dcryptomator.disableUpdateCheck=false"
|
||||
)
|
||||
|
||||
|
||||
# create app dir
|
||||
& "$Env:JAVA_HOME\bin\jpackage" `
|
||||
--verbose `
|
||||
@@ -99,30 +182,19 @@ if ($clean -and (Test-Path -Path $appPath)) {
|
||||
--name $AppName `
|
||||
--vendor $Vendor `
|
||||
--copyright $copyright `
|
||||
--java-options "--enable-preview" `
|
||||
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
|
||||
--java-options "-Xss5m" `
|
||||
--java-options "-Xmx256m" `
|
||||
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
|
||||
--app-version "$semVerNo.$revisionNo" `
|
||||
--java-options "-Dfile.encoding=`"utf-8`"" `
|
||||
--java-options "-Djava.net.useSystemProxies=true" `
|
||||
--java-options "-Dcryptomator.logDir=`"@{localappdata}/$AppName`"" `
|
||||
--java-options "-Dcryptomator.pluginDir=`"@{appdata}/$AppName/Plugins`"" `
|
||||
--java-options "-Dcryptomator.settingsPath=`"@{appdata}/$AppName/settings.json;@{userhome}/AppData/Roaming/$AppName/settings.json`"" `
|
||||
--java-options "-Dcryptomator.ipcSocketPath=`"@{localappdata}/$AppName/ipc.socket`"" `
|
||||
--java-options "-Dcryptomator.p12Path=`"@{appdata}/$AppName/key.p12;@{userhome}/AppData/Roaming/$AppName/key.p12`"" `
|
||||
--java-options "-Dcryptomator.mountPointsDir=`"@{userhome}/$AppName`"" `
|
||||
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
|
||||
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
|
||||
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
|
||||
--java-options "-Dcryptomator.showTrayIcon=true" `
|
||||
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
|
||||
--resource-dir resources `
|
||||
--icon resources/$AppName.ico
|
||||
--icon resources/$AppName.ico `
|
||||
--add-launcher "${AppName} (Debug)=$buildDir\debug-launcher.properties" `
|
||||
@javaOptions
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "jpackage Appimage failed with exit code $LASTEXITCODE"
|
||||
return 1;
|
||||
}
|
||||
|
||||
#Create RTF license for msi
|
||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
|
||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party `
|
||||
"-Dlicense.thirdPartyFilename=license.rtf" `
|
||||
"-Dlicense.fileTemplate=$buildDir\resources\licenseTemplate.ftl" `
|
||||
"-Dlicense.outputDirectory=$buildDir\resources\" `
|
||||
@@ -134,14 +206,7 @@ if ($clean -and (Test-Path -Path $appPath)) {
|
||||
# patch app dir
|
||||
Copy-Item "contrib\*" -Destination "$AppName"
|
||||
attrib -r "$AppName\$AppName.exe"
|
||||
# patch batch script to set hostfile
|
||||
$webDAVPatcher = "$AppName\patchWebDAV.bat"
|
||||
try {
|
||||
(Get-Content $webDAVPatcher ) -replace '::REPLACE ME', "SET LOOPBACK_ALIAS=`"$LoopbackAlias`"" | Set-Content $webDAVPatcher
|
||||
} catch {
|
||||
Write-Host "Failed to set LOOPBACK_ALIAS for patchWebDAV.bat"
|
||||
exit 1
|
||||
}
|
||||
attrib -r "$AppName\${AppName} (Debug).exe"
|
||||
|
||||
# create .msi
|
||||
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
|
||||
@@ -166,8 +231,13 @@ $Env:JP_WIXHELPER_DIR = "."
|
||||
--about-url $AboutUrl `
|
||||
--file-associations resources/FAvaultFile.properties
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "jpackage MSI failed with exit code $LASTEXITCODE"
|
||||
return 1;
|
||||
}
|
||||
|
||||
#Create RTF license for bundle
|
||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
|
||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party `
|
||||
"-Dlicense.thirdPartyFilename=license.rtf" `
|
||||
"-Dlicense.fileTemplate=$buildDir\bundle\resources\licenseTemplate.ftl" `
|
||||
"-Dlicense.outputDirectory=$buildDir\bundle\resources\" `
|
||||
@@ -177,24 +247,54 @@ $Env:JP_WIXHELPER_DIR = "."
|
||||
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
|
||||
|
||||
# download Winfsp
|
||||
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
|
||||
Write-Output "Downloading ${winfspMsiUrl}..."
|
||||
$winfspMsiUrl= 'https://github.com/winfsp/winfsp/releases/download/v2.1/winfsp-2.1.25156.msi'
|
||||
$winfspMsiHash = '073A70E00F77423E34BED98B86E600DEF93393BA5822204FAC57A29324DB9F7A'
|
||||
Write-Host "Downloading ${winfspMsiUrl}..."
|
||||
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
|
||||
$computedHash = $(Get-FileHash -Path '.\bundle\resources\winfsp.msi' -Algorithm SHA256).Hash
|
||||
if (! $computedHash.Equals($winfspMsiHash)) {
|
||||
Write-Error -Category InvalidData -CategoryActivity "Data integrity check failed" -Message @"
|
||||
Downloaded Winfsp Installer does not match stored SHA256 checksum.
|
||||
Expected: $winfspMsiHash
|
||||
Actual: $computedHash
|
||||
"@
|
||||
exit 1
|
||||
}
|
||||
|
||||
# download legacy-winfsp uninstaller
|
||||
$winfspUninstaller= 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
||||
Write-Output "Downloading ${winfspUninstaller}..."
|
||||
Write-Host "Downloading ${winfspUninstaller}..."
|
||||
Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
|
||||
|
||||
# copy MSI to bundle resources
|
||||
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi"
|
||||
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi" -Force
|
||||
|
||||
# create bundle including winfsp
|
||||
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -ext WixUtilextension -out bundle\ `
|
||||
-dBundleVersion="$semVerNo.$revisionNo" `
|
||||
-dBundleVendor="$Vendor" `
|
||||
-dBundleCopyright="$copyright" `
|
||||
-dAboutUrl="$AboutUrl" `
|
||||
-dHelpUrl="$HelpUrl" `
|
||||
-dUpdateUrl="$UpdateUrl"
|
||||
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -ext WixUtilextension -out installer\$AppName-Installer.exe
|
||||
& wix build `
|
||||
-define BundleName="$AppName" `
|
||||
-define BundleVersion="$semVerNo.$revisionNo" `
|
||||
-define BundleVendor="$Vendor" `
|
||||
-define BundleCopyright="$copyright" `
|
||||
-define AboutUrl="$AboutUrl" `
|
||||
-define HelpUrl="$HelpUrl" `
|
||||
-define UpdateUrl="$UpdateUrl" `
|
||||
-ext "WixToolset.Util.wixext" `
|
||||
-ext "WixToolset.BootstrapperApplications.wixext" `
|
||||
.\bundle\bundleWithWinfsp.wxs `
|
||||
-out "installer\$AppName-Installer.exe"
|
||||
|
||||
Write-Host "Created EXE installer .\installer\$AppName-Installer.exe"
|
||||
return 0;
|
||||
}
|
||||
|
||||
# ============================
|
||||
# Script Execution Starts Here
|
||||
# ============================
|
||||
if ($clean) {
|
||||
Write-Host "Cleaning up previous build artifacts..."
|
||||
Remove-Item -Path ".\runtime" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
|
||||
Remove-Item -Path ".\$AppName" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
|
||||
Remove-Item -Path ".\installer" -Force -Recurse -ErrorAction Ignore -ProgressAction SilentlyContinue
|
||||
}
|
||||
return Main
|
||||
|
||||
|
||||
104
dist/win/bundle/bundleWithWinfsp.wxs
vendored
104
dist/win/bundle/bundleWithWinfsp.wxs
vendored
@@ -1,66 +1,52 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/bundle.html-->
|
||||
<!-- Attributes explicitly not used:
|
||||
Condition - the single msi files have their own install conditions, no need to copy them here
|
||||
-->
|
||||
|
||||
<Bundle Name="Cryptomator" UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b" Version="$(var.BundleVersion)" Manufacturer="$(var.BundleVendor)"
|
||||
AboutUrl="$(var.AboutUrl)" HelpUrl="$(var.HelpUrl)" UpdateUrl="$(var.UpdateUrl)" Copyright="$(var.BundleCopyright)" IconSourceFile="bundle\resources\Cryptomator.ico">
|
||||
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
|
||||
<ns0:Wix xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
<ns0:Bundle Name="$(var.BundleName)"
|
||||
UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b"
|
||||
Version="$(var.BundleVersion)"
|
||||
Manufacturer="$(var.BundleVendor)"
|
||||
AboutUrl="$(var.AboutUrl)"
|
||||
HelpUrl="$(var.HelpUrl)"
|
||||
UpdateUrl="$(var.UpdateUrl)"
|
||||
Copyright="$(var.BundleCopyright)"
|
||||
IconSourceFile="bundle\resources\Cryptomator.ico">
|
||||
|
||||
<!-- detect outdated WinFsp installations -->
|
||||
<util:ProductSearch
|
||||
Variable="InstalledLegacyWinFspVersion"
|
||||
Result="version"
|
||||
UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B"/>
|
||||
<util:ProductSearch Variable="InstalledLegacyWinFspVersion" Result="version" UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B" />
|
||||
|
||||
<!-- for definition of the standard themes, see https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/-->
|
||||
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
|
||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/bal/wixstandardbootstrapperapplication.html -->
|
||||
<!-- Possible Attributes: LaunchTarget -->
|
||||
<bal:WixStandardBootstrapperApplication
|
||||
LicenseFile="bundle\resources\license.rtf"
|
||||
ShowVersion="yes"
|
||||
SuppressOptionsUI="yes"
|
||||
ThemeFile="bundle\customBootstrapperTheme.xml"
|
||||
LocalizationFile="bundle\customBootstrapperTheme.wxl"
|
||||
LogoFile="bundle\resources\logo.png"/>
|
||||
<Payload SourceFile="bundle\resources\logoSide.png" />
|
||||
</BootstrapperApplicationRef>
|
||||
<ns0:BootstrapperApplication>
|
||||
<bal:WixStandardBootstrapperApplication LicenseFile="bundle\resources\license.rtf" ShowVersion="yes"
|
||||
SuppressOptionsUI="yes"
|
||||
Theme="rtfLargeLicense"
|
||||
ThemeFile="bundle\resources\customBootstrapperTheme.xml"
|
||||
LocalizationFile="bundle\resources\customBootstrapperTheme.wxl"
|
||||
LogoSideFile="bundle\resources\logoSide.png"
|
||||
LogoFile="bundle\resources\logo.png"
|
||||
LaunchTarget="[ProgramFiles64Folder]\$(var.BundleName)\$(var.BundleName).exe" />
|
||||
<ns0:Payload SourceFile="bundle\resources\logoSide.png"/>
|
||||
<!-- Required due to https://github.com/wixtoolset/issues/issues/8104 -->
|
||||
<ns0:Payload Name="Cryptobot.ico" SourceFile="bundle\resources\Cryptomator.ico"/>
|
||||
</ns0:BootstrapperApplication>
|
||||
|
||||
<Chain>
|
||||
<ExePackage Cache="yes" PerMachine="yes" Permanent="no"
|
||||
SourceFile="resources\winfsp-uninstaller.exe"
|
||||
DisplayName="Removing outdated WinFsp Driver"
|
||||
Description="Executable to remove old winfsp"
|
||||
DetectCondition="false"
|
||||
InstallCondition="(InstalledLegacyWinFspVersion <> v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))">
|
||||
<CommandLine Condition="WixBundleUILevel <= 3" InstallArgument="-q -l "[WixBundleLog].winfsp-uninstaller.log"" RepairArgument="-q" UninstallArgument="-s" />
|
||||
<ns0:Variable Name="DISABLEUPDATECHECK" bal:Overridable="yes" Type="string" Value="false"/>
|
||||
|
||||
<ns0:Chain>
|
||||
<ns0:ExePackage Cache="keep" PerMachine="yes" Permanent="no" SourceFile="bundle\resources\winfsp-uninstaller.exe" DisplayName="Removing outdated WinFsp Driver" Description="Executable to remove old winfsp" DetectCondition="false" InstallCondition="(InstalledLegacyWinFspVersion <> v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))" UninstallArguments="">
|
||||
<ns0:CommandLine Condition="WixBundleUILevel <= 3" InstallArgument="-q -l "[WixBundleLog].winfsp-uninstaller.log"" RepairArgument="-q" UninstallArgument="-s" />
|
||||
<!-- XML allows line breaks in attributes, hence keep the line breaks here -->
|
||||
<CommandLine Condition="WixBundleUILevel > 3" InstallArgument="-l "[WixBundleLog].winfsp-uninstaller.log" -t "Cryptomator Installer" -m "Cryptomator requires a newer version of the WinFsp driver. The installer will now uninstall WinFsp, possibly reboot, and afterwards proceed with the installation.
|
||||
<ns0:CommandLine Condition="WixBundleUILevel > 3" InstallArgument="-l "[WixBundleLog].winfsp-uninstaller.log" -t "Cryptomator Installer" -m "Cryptomator requires a newer version of the WinFsp driver. The installer will now uninstall WinFsp, possibly reboot, and afterwards proceed with the installation.
|
||||
|
||||
Do you want to continue?"" RepairArgument="-q" UninstallArgument="-s" />
|
||||
<ExitCode Behavior="success" Value="0"/>
|
||||
<ExitCode Behavior="success" Value="1"/>
|
||||
<ExitCode Behavior="error" Value="2"/>
|
||||
<ExitCode Behavior="error" Value="3"/>
|
||||
<ExitCode Behavior="forceReboot" Value="4"/>
|
||||
<ExitCode Behavior="success" Value="5"/>
|
||||
</ExePackage>
|
||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html-->
|
||||
<MsiPackage
|
||||
SourceFile="resources\Cryptomator.msi"
|
||||
CacheId="cryptomator-bundle-cryptomator"
|
||||
DisplayInternalUI="no"
|
||||
Visible="no"/>
|
||||
<MsiPackage
|
||||
SourceFile="resources\winfsp.msi"
|
||||
CacheId="cryptomator-bundle-winfsp"
|
||||
Visible="yes"
|
||||
DisplayInternalUI="no"
|
||||
Permanent="yes"/>
|
||||
</Chain>
|
||||
</Bundle>
|
||||
</Wix>
|
||||
<ns0:ExitCode Behavior="success" Value="0" />
|
||||
<ns0:ExitCode Behavior="success" Value="1" />
|
||||
<ns0:ExitCode Behavior="error" Value="2" />
|
||||
<ns0:ExitCode Behavior="error" Value="3" />
|
||||
<ns0:ExitCode Behavior="forceReboot" Value="4" />
|
||||
<ns0:ExitCode Behavior="success" Value="5" />
|
||||
</ns0:ExePackage>
|
||||
<ns0:MsiPackage SourceFile="bundle\resources\Cryptomator.msi" CacheId="cryptomator-bundle-cryptomator" Visible="no">
|
||||
<ns0:MsiProperty Name="DISABLEUPDATECHECK" Value="[DISABLEUPDATECHECK]"/>
|
||||
</ns0:MsiPackage>
|
||||
<ns0:MsiPackage SourceFile="bundle\resources\winfsp.msi" CacheId="cryptomator-bundle-winfsp" Visible="yes" Permanent="yes" />
|
||||
</ns0:Chain>
|
||||
</ns0:Bundle>
|
||||
</ns0:Wix>
|
||||
64
dist/win/bundle/customBootstrapperTheme.wxl
vendored
64
dist/win/bundle/customBootstrapperTheme.wxl
vendored
@@ -1,64 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||
|
||||
|
||||
<WixLocalization Culture="en-us" Language="1033" xmlns="http://schemas.microsoft.com/wix/2006/localization">
|
||||
<String Id="Caption">[WixBundleName] Setup</String>
|
||||
<String Id="Title">[WixBundleName]</String>
|
||||
<String Id="InstallHeader">Welcome</String>
|
||||
<String Id="InstallMessage">This Setup will install [WixBundleName] and additional dependencies on your computer.</String>
|
||||
<String Id="InstallVersion">Version [WixBundleVersion]</String>
|
||||
<String Id="ConfirmCancelMessage">Are you sure you want to cancel?</String>
|
||||
<String Id="ExecuteUpgradeRelatedBundleMessage">Previous version</String>
|
||||
<String Id="HelpHeader">Setup Help</String>
|
||||
<String Id="HelpText">/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
|
||||
creates a complete local copy of the bundle in directory. Install is the default.
|
||||
|
||||
/passive | /quiet - displays minimal UI with no prompts or displays no UI and
|
||||
no prompts. By default UI and all prompts are displayed.
|
||||
|
||||
/norestart - suppress any attempts to restart. By default UI will prompt before restart.
|
||||
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%.</String>
|
||||
<String Id="HelpCloseButton">&Close</String>
|
||||
<String Id="InstallLicenseLinkText">[WixBundleName] <a href="#">license terms</a>.</String>
|
||||
<String Id="InstallAcceptCheckbox">I &agree to the license terms and conditions</String>
|
||||
<String Id="InstallOptionsButton">&Options</String>
|
||||
<String Id="InstallInstallButton">&Install</String>
|
||||
<String Id="InstallCloseButton">&Close</String>
|
||||
<String Id="OptionsHeader">Setup Options</String>
|
||||
<String Id="OptionsLocationLabel">Install location:</String>
|
||||
<String Id="OptionsBrowseButton">&Browse</String>
|
||||
<String Id="OptionsOkButton">&OK</String>
|
||||
<String Id="OptionsCancelButton">&Cancel</String>
|
||||
<String Id="ProgressHeader">Setup Progress</String>
|
||||
<String Id="ProgressLabel">Processing:</String>
|
||||
<String Id="OverallProgressPackageText">Initializing...</String>
|
||||
<String Id="ProgressCancelButton">&Cancel</String>
|
||||
<String Id="ModifyHeader">Modify Setup</String>
|
||||
<String Id="ModifyRepairButton">&Repair</String>
|
||||
<String Id="ModifyUninstallButton">&Uninstall</String>
|
||||
<String Id="ModifyCloseButton">&Close</String>
|
||||
<String Id="SuccessRepairHeader">Repair Successfully Completed</String>
|
||||
<String Id="SuccessUninstallHeader">Uninstall Successfully Completed</String>
|
||||
<String Id="SuccessInstallHeader">Installation Successfully Completed</String>
|
||||
<String Id="SuccessHeader">Setup Successful</String>
|
||||
<String Id="SuccessLaunchButton">&Launch</String>
|
||||
<String Id="SuccessRestartText">You must restart your computer before you can use the software.</String>
|
||||
<String Id="SuccessRestartButton">&Restart</String>
|
||||
<String Id="SuccessCloseButton">&Close</String>
|
||||
<String Id="FailureHeader">Setup Failed</String>
|
||||
<String Id="FailureInstallHeader">Setup Failed</String>
|
||||
<String Id="FailureUninstallHeader">Uninstall Failed</String>
|
||||
<String Id="FailureRepairHeader">Repair Failed</String>
|
||||
<String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>.</String>
|
||||
<String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
|
||||
<String Id="FailureRestartButton">&Restart</String>
|
||||
<String Id="FailureCloseButton">&Close</String>
|
||||
<String Id="FilesInUseHeader">Files In Use</String>
|
||||
<String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String>
|
||||
<String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String>
|
||||
<String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String>
|
||||
<String Id="FilesInUseOkButton">&OK</String>
|
||||
<String Id="FilesInUseCancelButton">&Cancel</String>
|
||||
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
|
||||
</WixLocalization>
|
||||
91
dist/win/bundle/customBootstrapperTheme.xml
vendored
91
dist/win/bundle/customBootstrapperTheme.xml
vendored
@@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||
<!-- adjusted theme based on https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/HyperlinkSidebarTheme.xml -->
|
||||
|
||||
|
||||
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
|
||||
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
|
||||
<Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
||||
<Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
|
||||
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
|
||||
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
||||
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
|
||||
<Font Id="5" Height="-12" Weight="700" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
||||
|
||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
|
||||
<Page Name="Help">
|
||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
|
||||
<Text X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
|
||||
<Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Install">
|
||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Text X="185" Y="50" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.InstallHeader)</Text>
|
||||
<Text X="185" Y="91" Width="-11" Height="64" FontId="3" DisablePrefix="yes">#(loc.InstallMessage)</Text>
|
||||
<Richedit Name="EulaRichedit" X="185" Y="131" Width="-12" Height="-65" HexStyle="0x00800000" TabStop="yes" FontId="0" />
|
||||
<Checkbox Name="EulaAcceptCheckbox" X="185" Y="-46" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
|
||||
<Text Name="InstallVersion" X="185" Y="-11" Width="-11" Height="17" FontId="3" DisablePrefix="yes" HideWhenDisabled="yes">#(loc.InstallVersion)</Text>
|
||||
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
||||
<Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="FilesInUse">
|
||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FilesInUseHeader)</Text>
|
||||
<Text X="11" Y="121" Width="-11" Height="34" FontId="3" DisablePrefix="yes">#(loc.FilesInUseLabel)</Text>
|
||||
<Text Name="FilesInUseText" X="11" Y="150" Width="-11" Height="-86" FontId="3" DisablePrefix="yes" HexStyle="0x0000000C">A</Text>
|
||||
|
||||
<Button Name="FilesInUseCloseRadioButton" X="11" Y="-60" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseCloseRadioButton)</Button>
|
||||
<Button Name="FilesInUseDontCloseRadioButton" X="11" Y="-40" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseDontCloseRadioButton)</Button>
|
||||
|
||||
<Button Name="FilesInUseOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FilesInUseOkButton)</Button>
|
||||
<Button Name="FilesInUseCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FilesInUseCancelButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Progress">
|
||||
<Text X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
|
||||
<Text X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
|
||||
<Text Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
|
||||
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
|
||||
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Modify">
|
||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
|
||||
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
|
||||
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
||||
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Success">
|
||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Text Name="SuccessHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
|
||||
<Text Name="SuccessInstallHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessInstallHeader)</Text>
|
||||
<Text Name="SuccessRepairHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRepairHeader)</Text>
|
||||
<Text Name="SuccessUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessUninstallHeader)</Text>
|
||||
<Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
||||
<Text Name="SuccessRestartText" X="185" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
|
||||
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
|
||||
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Failure">
|
||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Text Name="FailureHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
|
||||
<Text Name="FailureInstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureInstallHeader)</Text>
|
||||
<Text Name="FailureUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureUninstallHeader)</Text>
|
||||
<Text Name="FailureRepairHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRepairHeader)</Text>
|
||||
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
||||
<Hypertext Name="FailureMessageText" X="185" Y="-80" Width="-11" Height="140" FontId="5" TabStop="yes" HideWhenDisabled="yes" />
|
||||
<Text Name="FailureRestartText" X="185" Y="-57" Width="-11" Height="80" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
|
||||
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
||||
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
|
||||
</Page>
|
||||
</Theme>
|
||||
68
dist/win/bundle/resources/customBootstrapperTheme.wxl
vendored
Normal file
68
dist/win/bundle/resources/customBootstrapperTheme.wxl
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||
|
||||
|
||||
<WixLocalization Culture="en-us" Language="1033" xmlns="http://wixtoolset.org/schemas/v4/wxl">
|
||||
<String Id="Caption" Value="[WixBundleName] Setup" />
|
||||
<String Id="Title" Value="[WixBundleName]" />
|
||||
<String Id="InstallHeader" Value="Welcome" />
|
||||
<String Id="InstallMessage" Value="Setup will install [WixBundleName] on your computer." />
|
||||
<String Id="InstallVersion" Value="Version [WixBundleVersion]" />
|
||||
<String Id="CheckingForUpdatesLabel" Value="Checking for updates" />
|
||||
<String Id="UpdateButton" Value="&Update to version [WixStdBAUpdateAvailable]" />
|
||||
<String Id="InstallVersion" Value="Version [WixBundleVersion]" />
|
||||
<String Id="ConfirmCancelMessage" Value="Are you sure you want to cancel?" />
|
||||
<String Id="ExecuteUpgradeRelatedBundleMessage" Value="Previous version" />
|
||||
<String Id="HelpHeader" Value="Setup Help" />
|
||||
<String Id="HelpText" Value="/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
 creates a complete local copy of the bundle in directory. Install is the default.

/passive | /quiet - displays minimal UI with no prompts or displays no UI and
 no prompts. By default UI and all prompts are displayed.

/norestart - suppress any attempts to restart. By default UI will prompt before restart.
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%." />
|
||||
<String Id="HelpCloseButton" Value="&Close" />
|
||||
<String Id="InstallAcceptCheckbox" Value="I &agree to the license terms and conditions" />
|
||||
<String Id="InstallOptionsButton" Value="&Options" />
|
||||
<String Id="InstallInstallButton" Value="&Install" />
|
||||
<String Id="InstallCancelButton" Value="&Cancel" />
|
||||
<String Id="OptionsHeader" Value="Setup Options" />
|
||||
<String Id="OptionsLocationLabel" Value="Install location:" />
|
||||
<String Id="OptionsBrowseButton" Value="&Browse" />
|
||||
<String Id="OptionsOkButton" Value="&OK" />
|
||||
<String Id="OptionsCancelButton" Value="&Cancel" />
|
||||
<String Id="ProgressHeader" Value="Setup Progress" />
|
||||
<String Id="ProgressLabel" Value="Processing:" />
|
||||
<String Id="OverallProgressPackageText" Value="Initializing..." />
|
||||
<String Id="ProgressCancelButton" Value="&Cancel" />
|
||||
<String Id="ModifyHeader" Value="Modify Setup" />
|
||||
<String Id="ModifyRepairButton" Value="&Repair" />
|
||||
<String Id="ModifyUninstallButton" Value="&Uninstall" />
|
||||
<String Id="ModifyCancelButton" Value="&Cancel" />
|
||||
<String Id="SuccessHeader" Value="Setup Successful" />
|
||||
<String Id="SuccessCacheHeader" Value="Cache Successfully Completed" />
|
||||
<String Id="SuccessInstallHeader" Value="Installation Successfully Completed" />
|
||||
<String Id="SuccessLayoutHeader" Value="Layout Successfully Completed" />
|
||||
<String Id="SuccessModifyHeader" Value="Modify Successfully Completed" />
|
||||
<String Id="SuccessRepairHeader" Value="Repair Successfully Completed" />
|
||||
<String Id="SuccessUninstallHeader" Value="Uninstall Successfully Completed" />
|
||||
<String Id="SuccessUnsafeUninstallHeader" Value="Uninstall Successfully Completed" />
|
||||
<String Id="SuccessLaunchButton" Value="&Launch" />
|
||||
<String Id="SuccessRestartText" Value="You must restart your computer before you can use the software." />
|
||||
<String Id="SuccessUninstallRestartText" Value="You must restart your computer to complete the removal of the software." />
|
||||
<String Id="SuccessRestartButton" Value="&Restart" />
|
||||
<String Id="SuccessCloseButton" Value="&Close" />
|
||||
<String Id="FailureHeader" Value="Setup Failed" />
|
||||
<String Id="FailureCacheHeader" Value="Cache Failed" />
|
||||
<String Id="FailureInstallHeader" Value="Setup Failed" />
|
||||
<String Id="FailureLayoutHeader" Value="Layout Failed" />
|
||||
<String Id="FailureModifyHeader" Value="Modify Failed" />
|
||||
<String Id="FailureRepairHeader" Value="Repair Failed" />
|
||||
<String Id="FailureUninstallHeader" Value="Uninstall Failed" />
|
||||
<String Id="FailureUnsafeUninstallHeader" Value="Uninstall Failed" />
|
||||
<String Id="FailureHyperlinkLogText" Value="One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>." />
|
||||
<String Id="FailureRestartText" Value="You must restart your computer to complete the rollback of the software." />
|
||||
<String Id="FailureRestartButton" Value="&Restart" />
|
||||
<String Id="FailureCloseButton" Value="&Close" />
|
||||
<String Id="FilesInUseTitle" Value="Files In Use" />
|
||||
<String Id="FilesInUseLabel" Value="The following applications are using files that need to be updated:" />
|
||||
<String Id="FilesInUseNetfxCloseRadioButton" Value="Close the &applications." />
|
||||
<String Id="FilesInUseCloseRadioButton" Value="Close the &applications and attempt to restart them." />
|
||||
<String Id="FilesInUseDontCloseRadioButton" Value="&Do not close applications. A reboot will be required." />
|
||||
<String Id="FilesInUseRetryButton" Value="&Retry" />
|
||||
<String Id="FilesInUseIgnoreButton" Value="&Ignore" />
|
||||
<String Id="FilesInUseExitButton" Value="E&xit" />
|
||||
</WixLocalization>
|
||||
133
dist/win/bundle/resources/customBootstrapperTheme.xml
vendored
Normal file
133
dist/win/bundle/resources/customBootstrapperTheme.xml
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||
|
||||
|
||||
<Theme xmlns="http://wixtoolset.org/schemas/v4/thmutil">
|
||||
<Font Id="0" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font>
|
||||
<Font Id="1" Height="-24" Weight="500" Foreground="windowtext">Segoe UI</Font>
|
||||
<Font Id="2" Height="-22" Weight="500" Foreground="graytext">Segoe UI</Font>
|
||||
<Font Id="3" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font>
|
||||
|
||||
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0" Caption="#(loc.Caption)" IconFile="Cryptobot.ico">
|
||||
<Page Name="Help">
|
||||
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||
<Label X="11" Y="80" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Label>
|
||||
<Label X="11" Y="121" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Label>
|
||||
<Button Name="HelpCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.HelpCloseButton)</Text>
|
||||
<CloseWindowAction />
|
||||
</Button>
|
||||
</Page>
|
||||
<Page Name="Loading">
|
||||
<Label X="185" Y="50" Width="-11" Height="30" FontId="2" DisablePrefix="yes" Visible="no" Name="CheckingForUpdatesLabel" />
|
||||
</Page>
|
||||
<Page Name="Install">
|
||||
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.InstallHeader)</Label>
|
||||
<Label X="185" Y="50" Width="-11" Height="64" FontId="3" DisablePrefix="yes">
|
||||
<Text Condition="WixStdBASuppressOptionsUI">#(loc.InstallMessage)</Text>
|
||||
<Text Condition="NOT WixStdBASuppressOptionsUI">#(loc.InstallMessageOptions)</Text>
|
||||
</Label>
|
||||
<Richedit Name="EulaRichedit" X="185" Y="91" Width="-12" Height="-64" HexStyle="0x00800000" TabStop="yes" FontId="0" />
|
||||
<Checkbox Name="EulaAcceptCheckbox" X="185" Y="-39" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
|
||||
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||
<Button Name="InstallUpdateButton" X="11" Y="-11" Width="200" Height="23" TabStop="yes" FontId="0" EnableCondition="WixStdBAUpdateAvailable" HideWhenDisabled="yes">#(loc.UpdateButton)</Button>
|
||||
<Button Name="OptionsButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" VisibleCondition="NOT WixStdBASuppressOptionsUI">
|
||||
<Text>#(loc.InstallOptionsButton)</Text>
|
||||
<ChangePageAction Page="Options" />
|
||||
</Button>
|
||||
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
||||
<Button Name="InstallCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.InstallCancelButton)</Text>
|
||||
<CloseWindowAction />
|
||||
</Button>
|
||||
</Page>
|
||||
<Page Name="Options">
|
||||
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||
<Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Label>
|
||||
<Label X="11" Y="121" Width="-11" Height="17" FontId="3">#(loc.OptionsLocationLabel)</Label>
|
||||
<Editbox Name="InstallFolder" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
|
||||
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">
|
||||
<Text>#(loc.OptionsBrowseButton)</Text>
|
||||
<BrowseDirectoryAction VariableName="InstallFolder" />
|
||||
</Button>
|
||||
<Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.OptionsOkButton)</Text>
|
||||
<ChangePageAction Page="Install" />
|
||||
</Button>
|
||||
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.OptionsCancelButton)</Text>
|
||||
<ChangePageAction Page="Install" Cancel="yes" />
|
||||
</Button>
|
||||
</Page>
|
||||
<Page Name="Progress">
|
||||
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||
<Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Label>
|
||||
<Label X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Label>
|
||||
<Label Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Label>
|
||||
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
|
||||
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
||||
</Page>
|
||||
<Page Name="Modify">
|
||||
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Label>
|
||||
<Label Name="InstallVersion" X="11" Y="-11" Width="-11" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||
<Button Name="ModifyUpdateButton" X="11" Y="-11" Width="200" Height="23" TabStop="yes" FontId="0" EnableCondition="WixStdBAUpdateAvailable" HideWhenDisabled="yes">#(loc.UpdateButton)</Button>
|
||||
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
|
||||
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
||||
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.ModifyCancelButton)</Text>
|
||||
<CloseWindowAction />
|
||||
</Button>
|
||||
</Page>
|
||||
<Page Name="Success">
|
||||
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">
|
||||
<Text>#(loc.SuccessHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 2">#(loc.SuccessLayoutHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 3">#(loc.SuccessUnsafeUninstallHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 4">#(loc.SuccessUninstallHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 5">#(loc.SuccessCacheHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 6">#(loc.SuccessInstallHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 7">#(loc.SuccessModifyHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 8">#(loc.SuccessRepairHeader)</Text>
|
||||
</Label>
|
||||
<Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
||||
<Label X="185" Y="-51" Width="400" Height="34" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">
|
||||
<Text>#(loc.SuccessRestartText)</Text>
|
||||
<Text Condition="WixBundleAction = 3">#(loc.SuccessUninstallRestartText)</Text>
|
||||
</Label>
|
||||
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
|
||||
<Button Name="SuccessCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.SuccessCloseButton)</Text>
|
||||
<CloseWindowAction />
|
||||
</Button>
|
||||
</Page>
|
||||
<Page Name="Failure">
|
||||
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">
|
||||
<Text>#(loc.FailureHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 2">#(loc.FailureLayoutHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 3">#(loc.FailureUnsafeUninstallHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 4">#(loc.FailureUninstallHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 5">#(loc.FailureCacheHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 6">#(loc.FailureInstallHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 7">#(loc.FailureModifyHeader)</Text>
|
||||
<Text Condition="WixBundleAction = 8">#(loc.FailureRepairHeader)</Text>
|
||||
</Label>
|
||||
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
||||
<Hypertext Name="FailureMessageText" X="185" Y="-115" Width="-11" Height="80" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
|
||||
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||
<Label X="185" Y="-57" Width="-11" Height="80" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">#(loc.FailureRestartText)</Label>
|
||||
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
||||
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||
<Text>#(loc.FailureCloseButton)</Text>
|
||||
<CloseWindowAction />
|
||||
</Button>
|
||||
</Page>
|
||||
</Window>
|
||||
</Theme>
|
||||
18
dist/win/contrib/patchUpdateCheck.bat
vendored
Normal file
18
dist/win/contrib/patchUpdateCheck.bat
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
@echo off
|
||||
:: Batch wrapper for PowerShell script to modify Cryptomator update check settings
|
||||
:: This is executed as a Custom Action during MSI installation
|
||||
:: This file must be located in the INSTALLDIR
|
||||
|
||||
set "DISABLEUPDATECHECK=%~1"
|
||||
|
||||
:: Log for debugging
|
||||
echo DISABLEUPDATECHECK=%DISABLEUPDATECHECK%
|
||||
|
||||
:: Change to INSTALLDIR
|
||||
cd %~dp0
|
||||
:: Execute the PowerShell script
|
||||
powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File ".\patchUpdateCheck.ps1"^
|
||||
-DisableUpdateCheck "%DISABLEUPDATECHECK%"
|
||||
|
||||
:: Return the exit code from PowerShell
|
||||
exit /b %ERRORLEVEL%
|
||||
58
dist/win/contrib/patchUpdateCheck.ps1
vendored
Normal file
58
dist/win/contrib/patchUpdateCheck.ps1
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# PowerShell script to modify Cryptomator.cfg to set disableUpdateCheck property
|
||||
# This script is executed as a Custom Action during MSI installation
|
||||
# If the DisableUpdateCheck parameter is set to true, it disables the update check in Cryptomator by modifying the Cryptomator.cfg file.
|
||||
# NOTE: This file must be located in the same directory as set in the MSI property INSTALLDIR
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$DisableUpdateCheck
|
||||
)
|
||||
|
||||
try {
|
||||
# Log parameters for debugging (visible in MSI verbose logs)
|
||||
Write-Host "DisableUpdateCheck: $DisableUpdateCheck"
|
||||
|
||||
# Parse DisableUpdateCheck value (handle various input formats)
|
||||
$shouldDisable = $false
|
||||
if ($DisableUpdateCheck) {
|
||||
$DisableUpdateCheck = $DisableUpdateCheck.Trim().ToLower()
|
||||
$shouldDisable = ($DisableUpdateCheck -eq 'true') -or ($DisableUpdateCheck -eq '1') -or ($DisableUpdateCheck -eq 'yes')
|
||||
}
|
||||
|
||||
Write-Host "Setting cryptomator.disableUpdateCheck to: $shouldDisable"
|
||||
if (-not $shouldDisable) {
|
||||
Write-Host 'Disable-Update-Check property is by default "false". Skipping config modification.'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Determine the .cfg file path
|
||||
$cfgDir = Join-Path $PSScriptRoot 'app'
|
||||
$cfgFiles = Get-ChildItem -Path $cfgDir -Filter '*.cfg' -File
|
||||
|
||||
if ($cfgFiles.Count -eq 0) {
|
||||
Write-Error "No .cfg file found in directory: $cfgDir"
|
||||
exit 1
|
||||
}
|
||||
|
||||
foreach ($file in $cfgFiles) {
|
||||
$cfgFile = $file.FullName
|
||||
Write-Host "Modifying configuration file: $cfgFile"
|
||||
# Read the current configuration
|
||||
$content = Get-Content $cfgFile -Raw -ErrorAction Stop
|
||||
|
||||
# Add the new option based on the property value
|
||||
# Use regular expressions substitutions to replace the property
|
||||
$searchExpression = '(?<Prefix>java-options=-Dcryptomator\.disableUpdateCheck)=false'
|
||||
$replacementExpression = '${Prefix}=true'
|
||||
$content = $content -replace $searchExpression,$replacementExpression
|
||||
|
||||
# Write the modified content back
|
||||
Set-Content -Path $cfgFile -Value $content -NoNewline
|
||||
Write-Host "Successfully updated $cfgFile"
|
||||
}
|
||||
|
||||
exit 0
|
||||
}
|
||||
catch {
|
||||
Write-Error "Error modifying configuration file: $_"
|
||||
exit 1
|
||||
}
|
||||
19
dist/win/contrib/patchWebDAV.bat
vendored
19
dist/win/contrib/patchWebDAV.bat
vendored
@@ -1,7 +1,18 @@
|
||||
@echo off
|
||||
:: Default values for Cryptomator builds
|
||||
::REPLACE ME
|
||||
:: Batch wrapper for PowerShell script to adjust Windows network settings for the Cryptomator WebDAVAdapter
|
||||
:: This is executed as a Custom Action during MSI installation
|
||||
:: This file must be located in the INSTALLDIR
|
||||
|
||||
set "LOOPBACK_ALIAS=%1"
|
||||
|
||||
:: Log for debugging
|
||||
echo LOOPBACK_ALIAS=%LOOPBACK_ALIAS%
|
||||
|
||||
:: Change to INSTALLDIR
|
||||
cd %~dp0
|
||||
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -Command .\patchWebDAV.ps1^
|
||||
-LoopbackAlias %LOOPBACK_ALIAS%
|
||||
:: Execute the PowerShell script
|
||||
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy RemoteSigned -File .\patchWebDAV.ps1^
|
||||
-LoopbackAlias %LOOPBACK_ALIAS%
|
||||
|
||||
:: Return the exit code from PowerShell
|
||||
exit /b %ERRORLEVEL%
|
||||
4
dist/win/debug-launcher.properties
vendored
Normal file
4
dist/win/debug-launcher.properties
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
win-console=true
|
||||
win-shortcut=false
|
||||
win-menu=false
|
||||
description=Debug Launcher with Console for Cryptomator
|
||||
14
dist/win/launcher.bat
vendored
14
dist/win/launcher.bat
vendored
@@ -1,14 +0,0 @@
|
||||
@echo off
|
||||
java ^
|
||||
-p "mods" ^
|
||||
-cp "libs/*" ^
|
||||
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
|
||||
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
|
||||
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
|
||||
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
|
||||
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
|
||||
-Xss20m ^
|
||||
-Xmx512m ^
|
||||
--enable-preview `
|
||||
--enable-native-access=org.cryptomator.jfuse.win `
|
||||
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
|
||||
109
dist/win/resources/customWizard.wxi
vendored
109
dist/win/resources/customWizard.wxi
vendored
@@ -1,109 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Include>
|
||||
<Fragment>
|
||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/WixUI_InstallDir.wxs with custom exit dialog-->
|
||||
<UI Id="CustomWizard">
|
||||
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
|
||||
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
|
||||
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
|
||||
|
||||
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
|
||||
<Property Id="WixUI_Mode" Value="InstallDir" />
|
||||
|
||||
<DialogRef Id="BrowseDlg" />
|
||||
<DialogRef Id="DiskCostDlg" />
|
||||
<DialogRef Id="ErrorDlg" />
|
||||
<DialogRef Id="FilesInUse" />
|
||||
<DialogRef Id="MsiRMFilesInUse" />
|
||||
<DialogRef Id="PrepareDlg" />
|
||||
<DialogRef Id="ProgressDlg" />
|
||||
<DialogRef Id="ResumeDlg" />
|
||||
<DialogRef Id="UserExit" />
|
||||
|
||||
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
|
||||
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
||||
|
||||
<!-- custom end dialogs -->
|
||||
<Publish Dialog="MyExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
|
||||
<Publish Dialog="MyFatalErrorDlg" Control="Finish" Event="EndDialog" Value="Return" Order="998">1</Publish>
|
||||
|
||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
|
||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
|
||||
|
||||
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
|
||||
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
|
||||
|
||||
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
|
||||
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
|
||||
|
||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
|
||||
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
|
||||
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
|
||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/ExitDialog.wxs with adjustments-->
|
||||
<Dialog Id="MyExitDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
|
||||
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)" />
|
||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
|
||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.ExitDialogBitmap)" />
|
||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
||||
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogDescription)" />
|
||||
|
||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" />
|
||||
<!-- TODO: localize? -->
|
||||
<Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
|
||||
<Text>We recommend for the best user experience to download and install the following third party Windows driver:</Text>
|
||||
</Control>
|
||||
<Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes">
|
||||
<Text><![CDATA[WinFsp (<a href="https://winfsp.dev/">Homepage</a>)]]></Text>
|
||||
</Control>
|
||||
</Dialog>
|
||||
|
||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/FatalError.wxs with adjustments-->
|
||||
<Dialog Id="MyFatalErrorDlg" Width="370" Height="270" Title="!(loc.FatalError_Title)">
|
||||
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)">
|
||||
<Publish Event="EndDialog" Value="Exit">1</Publish>
|
||||
</Control>
|
||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
|
||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.FatalErrorBitmap)" />
|
||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.FatalErrorTitle)" />
|
||||
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="80" Transparent="yes" NoPrefix="yes" Text="!(loc.FatalErrorDescription1) !(loc.FatalErrorDescription2)" />
|
||||
<Control Id="DescriptionReason1" Type="Text" X="135" Y="160" Width="220" Height="20" Transparent="yes" NoPrefix="yes" Hidden="yes" >
|
||||
<Text>Reason:</Text>
|
||||
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
|
||||
</Control>
|
||||
<Control Id="DescriptionReason2" Type="Text" X="135" Y="170" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Hidden="yes" >
|
||||
<Text>Application to update was still running during installation.</Text>
|
||||
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
|
||||
</Control>
|
||||
</Dialog>
|
||||
|
||||
<InstallUISequence>
|
||||
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
|
||||
<Show Dialog="MyFatalErrorDlg" Overridable="yes" OnExit="error"/>
|
||||
</InstallUISequence>
|
||||
<AdminUISequence>
|
||||
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
|
||||
<Show Dialog="MyFatalErrorDlg" Overridable="yes" OnExit="error"/>
|
||||
</AdminUISequence>
|
||||
|
||||
</UI>
|
||||
|
||||
<UIRef Id="WixUI_Common" />
|
||||
</Fragment>
|
||||
</Include>
|
||||
231
dist/win/resources/main.wxs
vendored
231
dist/win/resources/main.wxs
vendored
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<ns0:Wix xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" >
|
||||
|
||||
<?ifdef JpIsSystemWide ?>
|
||||
<?define JpInstallScope="perMachine"?>
|
||||
@@ -27,177 +26,179 @@
|
||||
<?define IconFileEncryptedData= "Cryptomator-Vault.ico" ?>
|
||||
<?define ProgIdContentType= "application/vnd.cryptomator.encrypted" ?>
|
||||
<?define CloseApplicationTarget= "cryptomator.exe" ?>
|
||||
<?define LoopbackAlias= "cryptomator-vault" ?>
|
||||
|
||||
<?include $(var.JpConfigDir)/overrides.wxi ?>
|
||||
|
||||
<Product
|
||||
Id="$(var.JpProductCode)"
|
||||
Name="$(var.JpAppName)"
|
||||
Language="$(var.JpProductLanguage)"
|
||||
Version="$(var.JpAppVersion)"
|
||||
Manufacturer="$(var.JpAppVendor)"
|
||||
UpgradeCode="$(var.JpProductUpgradeCode)">
|
||||
<ns0:Package
|
||||
Name="$(var.JpAppName)"
|
||||
Language="$(var.JpProductLanguage)"
|
||||
Version="$(var.JpAppVersion)"
|
||||
Manufacturer="$(var.JpAppVendor)"
|
||||
UpgradeCode="$(var.JpProductUpgradeCode)"
|
||||
InstallerVersion="$(var.JpInstallerVersion)"
|
||||
Compressed="$(var.JpCompressedMsi)"
|
||||
ProductCode="$(var.JpProductCode)"
|
||||
Scope="$(var.JpInstallScope)">
|
||||
|
||||
<Package
|
||||
Description="$(var.JpAppDescription)"
|
||||
Manufacturer="$(var.JpAppVendor)"
|
||||
InstallerVersion="$(var.JpInstallerVersion)"
|
||||
Compressed="$(var.JpCompressedMsi)"
|
||||
InstallScope="$(var.JpInstallScope)" Platform="x64"
|
||||
/>
|
||||
<ns0:SummaryInformation Manufacturer="$(var.JpAppVendor)" Description="$(var.JpAppDescription)"/>
|
||||
<ns0:Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
|
||||
|
||||
<Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
|
||||
|
||||
<Upgrade Id="$(var.JpProductUpgradeCode)">
|
||||
<UpgradeVersion
|
||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
|
||||
Property="JP_UPGRADABLE_FOUND"
|
||||
Maximum="$(var.JpAppVersion)"
|
||||
MigrateFeatures="yes"
|
||||
IncludeMaximum="yes" /> <!-- TODO: check if this needs to be set to yes-->
|
||||
<UpgradeVersion
|
||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
|
||||
Property="JP_DOWNGRADABLE_FOUND"
|
||||
Minimum="$(var.JpAppVersion)"
|
||||
MigrateFeatures="yes"
|
||||
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
|
||||
</Upgrade>
|
||||
<ns0:Upgrade Id="$(var.JpProductUpgradeCode)">
|
||||
<ns0:UpgradeVersion
|
||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
|
||||
Property="JP_UPGRADABLE_FOUND"
|
||||
Maximum="$(var.JpAppVersion)"
|
||||
MigrateFeatures="yes"
|
||||
IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)"/> <!-- TODO in earlier versions, this was set to yes-->
|
||||
<ns0:UpgradeVersion
|
||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
|
||||
Property="JP_DOWNGRADABLE_FOUND"
|
||||
Minimum="$(var.JpAppVersion)"
|
||||
MigrateFeatures="yes"
|
||||
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
|
||||
</ns0:Upgrade>
|
||||
|
||||
<?ifndef JpAllowUpgrades ?>
|
||||
<CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
|
||||
<ns0:CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
|
||||
<?endif?>
|
||||
<?ifndef JpAllowDowngrades ?>
|
||||
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
|
||||
<ns0:CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
|
||||
<?endif?>
|
||||
|
||||
<Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll"/>
|
||||
<CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" />
|
||||
<!-- TODO: how does this work again? -->
|
||||
<ns0:Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll" />
|
||||
<ns0:CustomAction Id="JpFindRelatedProducts" BinaryRef="JpCaDll" DllEntry="FindRelatedProductsEx" />
|
||||
|
||||
<?ifndef SkipCryptomatorLegacyCheck ?>
|
||||
<!-- Block installation if innosetup entry of Cryptomator is found -->
|
||||
<Property Id="OLDEXEINSTALLER">
|
||||
<RegistrySearch Id="InnoSetupInstallation" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Cryptomator_is1" Type="raw" Name="DisplayName" />
|
||||
</Property>
|
||||
<ns0:Property Id="OLDEXEINSTALLER">
|
||||
<ns0:RegistrySearch Id="InnoSetupInstallation" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Cryptomator_is1" Type="raw" Name="DisplayName" />
|
||||
</ns0:Property>
|
||||
<!-- TODO: localize -->
|
||||
<Condition Message="A lower version of [ProductName] is already installed. Uninstall it first and then start the setup again. Setup will now exit.">
|
||||
<![CDATA[Installed OR NOT OLDEXEINSTALLER]]>
|
||||
</Condition>
|
||||
<ns0:Launch Message="A lower version of [ProductName] is already installed. Uninstall it first and then start the setup again. Setup will now exit." Condition="Installed OR NOT OLDEXEINSTALLER" />
|
||||
<?endif?>
|
||||
<!-- Cryptomator uses UNIX Sockets, which are supported starting with Windows 10 v1803-->
|
||||
<Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
||||
<RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
||||
</Property>
|
||||
<Condition Message="This application requires Windows 10 version 1803 (build 17134) or newer.">
|
||||
<![CDATA[Installed OR (WINDOWSBUILDNUMBER >= 17134)]]>
|
||||
</Condition>
|
||||
<ns0:Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
||||
<ns0:RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
||||
</ns0:Property>
|
||||
<ns0:Launch Message="This application requires Windows 10 version 1803 (build 17134) or newer." Condition="Installed OR (WINDOWSBUILDNUMBER >= 17134)" />
|
||||
|
||||
<!-- Non-Opening ProgID -->
|
||||
<DirectoryRef Id="INSTALLDIR">
|
||||
<Component Win64="yes" Id="nonStartingProgID" >
|
||||
<File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileEncryptedData)" Name="$(var.IconFileEncryptedData)"></File>
|
||||
<ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
|
||||
<Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
|
||||
<MIME ContentType="$(var.ProgIdContentType)" Default="yes"></MIME>
|
||||
</Extension>
|
||||
<Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
|
||||
</ProgId>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<ns0:DirectoryRef Id="INSTALLDIR">
|
||||
<ns0:Component Bitness="always64" Id="nonStartingProgID" >
|
||||
<ns0:File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileEncryptedData)" Name="$(var.IconFileEncryptedData)"/>
|
||||
<ns0:ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
|
||||
<ns0:Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
|
||||
<ns0:MIME ContentType="$(var.ProgIdContentType)" Default="yes"/>
|
||||
</ns0:Extension>
|
||||
<ns0:Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
|
||||
</ns0:ProgId>
|
||||
</ns0:Component>
|
||||
</ns0:DirectoryRef>
|
||||
|
||||
<!-- Standard required root -->
|
||||
<Directory Id="TARGETDIR" Name="SourceDir"/>
|
||||
|
||||
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
|
||||
<ComponentGroupRef Id="Shortcuts"/>
|
||||
<ComponentGroupRef Id="Files"/>
|
||||
<ComponentGroupRef Id="FileAssociations"/>
|
||||
<ns0:Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
|
||||
<ns0:ComponentGroupRef Id="Shortcuts"/>
|
||||
<ns0:ComponentGroupRef Id="Files"/>
|
||||
<ns0:ComponentGroupRef Id="FileAssociations"/>
|
||||
<!-- Ref to additional ProgIDs -->
|
||||
<ComponentRef Id="nonStartingProgID" />
|
||||
</Feature>
|
||||
<ns0:ComponentRef Id="nonStartingProgID" />
|
||||
</ns0:Feature>
|
||||
|
||||
<CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
||||
<CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
|
||||
<CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
|
||||
<CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" />
|
||||
<ns0:CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
||||
<ns0:CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
|
||||
<ns0:CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
|
||||
<ns0:CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" />
|
||||
|
||||
<?ifdef JpHelpURL ?>
|
||||
<CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
|
||||
<ns0:CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
|
||||
<?endif?>
|
||||
|
||||
<?ifdef JpAboutURL ?>
|
||||
<CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
|
||||
<ns0:CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
|
||||
<?endif?>
|
||||
|
||||
<?ifdef JpUpdateURL ?>
|
||||
<CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
|
||||
<ns0:CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
|
||||
<?endif?>
|
||||
|
||||
<Property Id="WixQuietExec64CmdTimeout" Value="20" />
|
||||
<ns0:Property Id="WixQuietExec64CmdTimeout" Value="20" />
|
||||
<!-- Note for custom actions: Immediate CAs run BEFORE the files are installed, hence if you depend on installed files, the CAs must be deferred.-->
|
||||
|
||||
<!-- Property for controlling update check behavior (can be set via command line) -->
|
||||
<ns0:Property Id="DISABLEUPDATECHECK" Secure="yes" />
|
||||
|
||||
<!-- WebDAV patches -->
|
||||
<SetProperty Id="PatchWebDAV" Value=""[INSTALLDIR]patchWebDAV.bat""
|
||||
Sequence="execute" Before="PatchWebDAV" />
|
||||
<CustomAction Id="PatchWebDAV" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||
<ns0:SetProperty Id="PatchWebDAV" Value=""[INSTALLDIR]patchWebDAV.bat" "$(var.LoopbackAlias)"" Sequence="execute" Before="PatchWebDAV" />
|
||||
<ns0:CustomAction Id="PatchWebDAV" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||
|
||||
<!-- Update check configuration -->
|
||||
<ns0:SetProperty Id="PatchUpdateCheck" Value=""[INSTALLDIR]patchUpdateCheck.bat" "[DISABLEUPDATECHECK]"" Sequence="execute" Before="PatchUpdateCheck" />
|
||||
<ns0:CustomAction Id="PatchUpdateCheck" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||
|
||||
<!-- Running App detection and exit -->
|
||||
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
|
||||
<ns0:Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
|
||||
<util:CloseApplication
|
||||
Target="$(var.CloseApplicationTarget)"
|
||||
Id="Close$(var.JpAppName)"
|
||||
CloseMessage="no"
|
||||
RebootPrompt="no"
|
||||
PromptToContinue="yes"
|
||||
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
|
||||
Property="FOUNDRUNNINGAPP"
|
||||
>
|
||||
</util:CloseApplication>
|
||||
<CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
|
||||
Target="$(var.CloseApplicationTarget)"
|
||||
Id="Close$(var.JpAppName)"
|
||||
CloseMessage="no"
|
||||
RebootPrompt="no"
|
||||
PromptToContinue="yes"
|
||||
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
|
||||
Property="FOUNDRUNNINGAPP"
|
||||
/>
|
||||
<ns0:CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
|
||||
|
||||
<?ifdef JpIcon ?>
|
||||
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
|
||||
<Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
|
||||
<ns0:Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
|
||||
<ns0:Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
|
||||
<?endif?>
|
||||
|
||||
<UIRef Id="JpUI"/>
|
||||
<ns0:UIRef Id="JpUI"/>
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize">Not Installed</Custom>
|
||||
<Custom Action="JpSetARPCOMMENTS" After="CostFinalize">Not Installed</Custom>
|
||||
<Custom Action="JpSetARPCONTACT" After="CostFinalize">Not Installed</Custom>
|
||||
<Custom Action="JpSetARPSIZE" After="CostFinalize">Not Installed</Custom>
|
||||
<ns0:InstallExecuteSequence>
|
||||
<ns0:Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize" Condition="Not Installed" />
|
||||
<ns0:Custom Action="JpSetARPCOMMENTS" After="CostFinalize" Condition="Not Installed" />
|
||||
<ns0:Custom Action="JpSetARPCONTACT" After="CostFinalize" Condition="Not Installed" />
|
||||
<ns0:Custom Action="JpSetARPSIZE" After="CostFinalize" Condition="Not Installed" />
|
||||
<?ifdef JpHelpURL ?>
|
||||
<Custom Action="JpSetARPHELPLINK" After="CostFinalize">Not Installed</Custom>
|
||||
<ns0:Custom Action="JpSetARPHELPLINK" After="CostFinalize" Condition="Not Installed" />
|
||||
<?endif?>
|
||||
<?ifdef JpAboutURL ?>
|
||||
<Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize">Not Installed</Custom>
|
||||
<ns0:Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize" Condition="Not Installed" />
|
||||
<?endif?>
|
||||
<?ifdef JpUpdateURL ?>
|
||||
<Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize">Not Installed</Custom>
|
||||
<ns0:Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize" Condition="Not Installed" />
|
||||
<?endif?>
|
||||
|
||||
<?ifndef JpAllowUpgrades ?>
|
||||
<Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
|
||||
<ns0:Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts" Condition="JP_UPGRADABLE_FOUND"/>
|
||||
<?endif?>
|
||||
<?ifndef JpAllowDowngrades ?>
|
||||
<Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
|
||||
<ns0:Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts" Condition="JP_DOWNGRADABLE_FOUND" />
|
||||
<?endif?>
|
||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||
<ns0:Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||
|
||||
<!-- Check and fail if Cryptomator is running -->
|
||||
<Custom Action="WixCloseApplications" Before="InstallValidate"></Custom>
|
||||
<Custom Action="FailOnRunningApp" After="WixCloseApplications" >FOUNDRUNNINGAPP</Custom>
|
||||
<ns0:Custom Action="override Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Before="InstallValidate" />
|
||||
<ns0:Custom Action="FailOnRunningApp" After="Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Condition="FOUNDRUNNINGAPP" />
|
||||
|
||||
<RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications -->
|
||||
<ns0:RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to Wix4CloseApplications_* -->
|
||||
<!-- Skip action on uninstall -->
|
||||
<!-- TODO: don't skip action, but remove cryptomator alias from hosts file -->
|
||||
<ns0:Custom Action="PatchWebDAV" After="InstallFiles" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
|
||||
<!-- Configure update check setting if property is provided -->
|
||||
<ns0:Custom Action="PatchUpdateCheck" After="PatchWebDAV" Condition="DISABLEUPDATECHECK AND NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
|
||||
</ns0:InstallExecuteSequence>
|
||||
|
||||
<Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
|
||||
</InstallExecuteSequence>
|
||||
<ns0:InstallUISequence>
|
||||
<ns0:Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||
</ns0:InstallUISequence>
|
||||
|
||||
<InstallUISequence>
|
||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||
</InstallUISequence>
|
||||
|
||||
<WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
|
||||
<WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
|
||||
</Product>
|
||||
|
||||
</Wix>
|
||||
<ns0:WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
|
||||
<ns0:WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
|
||||
</ns0:Package>
|
||||
</ns0:Wix>
|
||||
|
||||
4
dist/win/resources/overrides.wxi
vendored
4
dist/win/resources/overrides.wxi
vendored
@@ -41,10 +41,10 @@ Media Type of the encrypted data files. Default is "application/vnd.cryptomator.
|
||||
|
||||
Close Application settings:
|
||||
- CloseApplicationTarget
|
||||
Full name of executable to be checkd in the close application util. Default is "cryptomator.exe"
|
||||
Full name of executable to be checked in the close application util. Default is "cryptomator.exe"
|
||||
|
||||
Legacy Installation settings:
|
||||
- SkipCryptomatorLegacyCheck
|
||||
Should be defined to disable checking for the inno setup installation of Cryptomator and undefined, to enable it.
|
||||
-->
|
||||
<Include/>
|
||||
<ns0:Include xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs"></ns0:Include>
|
||||
|
||||
16
dist/win/resources/ui.wxf
vendored
16
dist/win/resources/ui.wxf
vendored
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<Fragment>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"></Property>
|
||||
<WixVariable Id="WixUILicenseRtf" Value="$(var.JpLicenseRtf)"></WixVariable>
|
||||
<UI Id="JpUI">
|
||||
<UIRef Id="CustomWizard" />
|
||||
<DialogRef Id="InstallDirNotEmptyDlg"></DialogRef>
|
||||
<Publish Dialog="ShortcutPromptDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg">1</Publish>
|
||||
<Publish Dialog="ShortcutPromptDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ShortcutPromptDlg" Order="6">NOT Installed</Publish>
|
||||
<UIRef Id="CustomWizard" />
|
||||
</UI>
|
||||
</Fragment>
|
||||
<?include $(env.JP_WIXWIZARD_RESOURCES)\customWizard.wxi ?>
|
||||
</Wix>
|
||||
59
pom.xml
59
pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>cryptomator</artifactId>
|
||||
<version>1.16.2</version>
|
||||
<version>1.18.0</version>
|
||||
<name>Cryptomator Desktop App</name>
|
||||
|
||||
<organization>
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.jdk.version>23</project.jdk.version>
|
||||
<project.jdk.version>24</project.jdk.version>
|
||||
|
||||
<!-- Group IDs of jars that need to stay on the class path for now -->
|
||||
<!-- remove them, as soon they got modularized or support is dropped (i.e., WebDAV) -->
|
||||
@@ -34,58 +34,47 @@
|
||||
|
||||
<!-- cryptomator dependencies -->
|
||||
<cryptomator.cryptofs.version>2.9.0</cryptomator.cryptofs.version>
|
||||
<cryptomator.integrations.version>1.5.1</cryptomator.integrations.version>
|
||||
<cryptomator.integrations.win.version>1.3.0</cryptomator.integrations.win.version>
|
||||
<cryptomator.integrations.mac.version>1.3.2</cryptomator.integrations.mac.version>
|
||||
<cryptomator.integrations.linux.version>1.5.3</cryptomator.integrations.linux.version>
|
||||
<cryptomator.fuse.version>5.0.5</cryptomator.fuse.version>
|
||||
<cryptomator.webdav.version>2.0.10</cryptomator.webdav.version>
|
||||
<cryptomator.integrations.version>1.7.0</cryptomator.integrations.version>
|
||||
<cryptomator.integrations.win.version>1.5.1</cryptomator.integrations.win.version>
|
||||
<cryptomator.integrations.mac.version>1.4.1</cryptomator.integrations.mac.version>
|
||||
<cryptomator.integrations.linux.version>1.6.1</cryptomator.integrations.linux.version>
|
||||
<cryptomator.fuse.version>5.1.0</cryptomator.fuse.version>
|
||||
<cryptomator.webdav.version>3.0.0</cryptomator.webdav.version>
|
||||
|
||||
<!-- 3rd party dependencies -->
|
||||
<commons-lang3.version>3.17.0</commons-lang3.version>
|
||||
<dagger.version>2.56.1</dagger.version>
|
||||
<commons-lang3.version>3.19.0</commons-lang3.version>
|
||||
<dagger.version>2.57.2</dagger.version>
|
||||
<easybind.version>2.2</easybind.version>
|
||||
<jackson.version>2.18.3</jackson.version>
|
||||
<javafx.version>23.0.2</javafx.version>
|
||||
<jackson.version>2.20.0</jackson.version>
|
||||
<javafx.version>25</javafx.version>
|
||||
<jwt.version>4.5.0</jwt.version>
|
||||
<nimbus-jose.version>9.37.3</nimbus-jose.version>
|
||||
<logback.version>1.5.18</logback.version>
|
||||
<nimbus-jose.version>10.5</nimbus-jose.version>
|
||||
<logback.version>1.5.19</logback.version>
|
||||
<slf4j.version>2.0.17</slf4j.version>
|
||||
<tinyoauth2.version>0.8.1</tinyoauth2.version>
|
||||
<zxcvbn.version>1.9.0</zxcvbn.version>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<junit.jupiter.version>5.12.2</junit.jupiter.version>
|
||||
<mockito.version>5.17.0</mockito.version>
|
||||
<junit.jupiter.version>5.13.4</junit.jupiter.version>
|
||||
<mockito.version>5.20.0</mockito.version>
|
||||
<hamcrest.version>3.0</hamcrest.version>
|
||||
|
||||
<!-- build-time dependencies -->
|
||||
<jetbrains.annotations.version>26.0.2</jetbrains.annotations.version>
|
||||
<dependency-check.version>12.1.1</dependency-check.version>
|
||||
<jetbrains.annotations.version>26.0.2-1</jetbrains.annotations.version>
|
||||
<dependency-check.version>12.1.5</dependency-check.version>
|
||||
<jacoco.version>0.8.13</jacoco.version>
|
||||
<license-generator.version>2.5.0</license-generator.version>
|
||||
<license-generator.version>2.7.0</license-generator.version>
|
||||
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
|
||||
<mvn-compiler.version>3.14.0</mvn-compiler.version>
|
||||
<mvn-compiler.version>3.14.1</mvn-compiler.version>
|
||||
<mvn-resources.version>3.3.1</mvn-resources.version>
|
||||
<mvn-dependency.version>3.8.1</mvn-dependency.version>
|
||||
<mvn-surefire.version>3.5.3</mvn-surefire.version>
|
||||
<mvn-surefire.version>3.5.4</mvn-surefire.version>
|
||||
<mvn-jar.version>3.4.2</mvn-jar.version>
|
||||
|
||||
<!-- Property used by surefire to determine jacoco engine -->
|
||||
<surefire.jacoco.args></surefire.jacoco.args>
|
||||
</properties>
|
||||
|
||||
<!-- TODO: Remove once webdav version 2.0.11 is released -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>webdav-nio-adapter-servlet</artifactId>
|
||||
<version>1.2.9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- Cryptomator Libs -->
|
||||
<dependency>
|
||||
@@ -225,7 +214,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.2.2</version>
|
||||
</dependency>
|
||||
<!-- JUnit / Mockito / Hamcrest -->
|
||||
<dependency>
|
||||
@@ -255,7 +244,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.jimfs</groupId>
|
||||
<artifactId>jimfs</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -358,7 +347,7 @@
|
||||
<consoleOutputReporter>
|
||||
<disable>true</disable>
|
||||
</consoleOutputReporter>
|
||||
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar}</argLine>
|
||||
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar} --enable-native-access=javafx.graphics</argLine>
|
||||
<statelessTestsetInfoReporter
|
||||
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
|
||||
</statelessTestsetInfoReporter>
|
||||
|
||||
@@ -23,6 +23,7 @@ public class Environment {
|
||||
private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath";
|
||||
private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath";
|
||||
private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths";
|
||||
private static final String WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.windowsHelloKeychainPaths";
|
||||
private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path";
|
||||
private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir";
|
||||
private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias";
|
||||
@@ -45,6 +46,7 @@ public class Environment {
|
||||
logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME);
|
||||
logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME);
|
||||
logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME);
|
||||
logCryptomatorSystemProperty(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
|
||||
logCryptomatorSystemProperty(P12_PATH_PROP_NAME);
|
||||
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
|
||||
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
|
||||
@@ -85,6 +87,10 @@ public class Environment {
|
||||
return getPaths(KEYCHAIN_PATHS_PROP_NAME);
|
||||
}
|
||||
|
||||
public Stream<Path> getWindowsHelloKeychainPath() {
|
||||
return getPaths(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
|
||||
}
|
||||
|
||||
public Stream<Path> getP12Path() {
|
||||
return getPaths(P12_PATH_PROP_NAME);
|
||||
}
|
||||
|
||||
@@ -42,25 +42,11 @@ public class KeychainManager implements KeychainAccessProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
|
||||
storePassphrase(key, displayName, passphrase, true);
|
||||
}
|
||||
|
||||
//TODO: remove ignored parameter once the API is fixed
|
||||
@Override
|
||||
public void storePassphrase(String key, String displayName, CharSequence passphrase, boolean ignored) throws KeychainAccessException {
|
||||
try {
|
||||
lock.writeLock().lock();
|
||||
var kc = getKeychainOrFail();
|
||||
//this is the only keychain actually using the parameter
|
||||
var usesOSAuth = (kc.getClass().getName().equals("org.cryptomator.macos.keychain.TouchIdKeychainAccess"));
|
||||
kc.storePassphrase(key, displayName, passphrase, usesOSAuth);
|
||||
getKeychainOrFail().storePassphrase(key, displayName, passphrase);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_BACKUP_SUFFIX;
|
||||
|
||||
public final class BackupRestorer {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BackupRestorer.class);
|
||||
|
||||
private BackupRestorer() {}
|
||||
|
||||
public static void restoreIfBackupPresent(Path vaultPath, String filePrefix) {
|
||||
Path targetFile = vaultPath.resolve(filePrefix);
|
||||
|
||||
try (Stream<Path> files = Files.list(vaultPath)) {
|
||||
files.filter(file -> isFileMatchingPattern(file.getFileName().toString(), filePrefix))
|
||||
.max((f1, f2) -> {
|
||||
try {
|
||||
FileTime time1 = Files.getLastModifiedTime(f1);
|
||||
FileTime time2 = Files.getLastModifiedTime(f2);
|
||||
return time1.compareTo(time2);
|
||||
} catch (IOException e) {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.ifPresent(backupFile -> copyBackupFile(backupFile, targetFile));
|
||||
} catch (IOException e) {
|
||||
LOG.info("Unable to restore backup files in '{}'", vaultPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFileMatchingPattern(String fileName, String filePrefix) {
|
||||
return fileName.startsWith(filePrefix) && fileName.endsWith(MASTERKEY_BACKUP_SUFFIX);
|
||||
}
|
||||
|
||||
private static void copyBackupFile(Path backupFile, Path configPath) {
|
||||
try {
|
||||
Files.copy(backupFile, configPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
LOG.debug("Backup restored - file: '{}' path: '{}'", backupFile, configPath);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unable to copy backup file from '{}' to '{}'", backupFile, configPath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
|
||||
import static org.cryptomator.common.Constants.DEFAULT_KEY_ID;
|
||||
|
||||
public final class CryptoFsInitializer {
|
||||
|
||||
private CryptoFsInitializer() {}
|
||||
|
||||
public static void init(Path recoveryPath,
|
||||
Masterkey masterkey,
|
||||
int shorteningThreshold,
|
||||
CryptorProvider.Scheme scheme) throws IOException, CryptoException {
|
||||
|
||||
MasterkeyLoader loader = ignored -> masterkey.copy();
|
||||
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties //
|
||||
.cryptoFileSystemProperties() //
|
||||
.withCipherCombo(scheme) //
|
||||
.withKeyLoader(loader) //
|
||||
.withShorteningThreshold(shorteningThreshold) //
|
||||
.build();
|
||||
CryptoFileSystemProvider.initialize(recoveryPath, fsProps, DEFAULT_KEY_ID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.cryptofs.common.Constants.DATA_DIR_NAME;
|
||||
|
||||
public final class MasterkeyService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MasterkeyService.class);
|
||||
|
||||
private MasterkeyService() {}
|
||||
|
||||
public static void recoverFromRecoveryKey(String recoveryKey, RecoveryKeyFactory recoveryKeyFactory, Path recoveryPath, CharSequence newPassword) throws IOException {
|
||||
recoveryKeyFactory.newMasterkeyFileWithPassphrase(recoveryPath, recoveryKey, newPassword);
|
||||
}
|
||||
|
||||
public static Masterkey load(MasterkeyFileAccess masterkeyFileAccess, Path masterkeyFilePath, CharSequence password) throws IOException {
|
||||
return masterkeyFileAccess.load(masterkeyFilePath, password);
|
||||
}
|
||||
|
||||
public static CryptorProvider.Scheme validateRecoveryKeyAndDetectCombo(RecoveryKeyFactory recoveryKeyFactory, //
|
||||
Vault vault, String recoveryKey, //
|
||||
MasterkeyFileAccess masterkeyFileAccess) throws IOException, CryptoException, NoSuchElementException {
|
||||
String tmpPass = UUID.randomUUID().toString();
|
||||
try (RecoveryDirectory recoveryDirectory = RecoveryDirectory.create(vault.getPath())) {
|
||||
Path tempRecoveryPath = recoveryDirectory.getRecoveryPath();
|
||||
recoverFromRecoveryKey(recoveryKey, recoveryKeyFactory, tempRecoveryPath, tmpPass);
|
||||
Path masterkeyFilePath = tempRecoveryPath.resolve(MASTERKEY_FILENAME);
|
||||
|
||||
try (Masterkey mk = load(masterkeyFileAccess, masterkeyFilePath, tmpPass)) {
|
||||
return detect(mk, vault.getPath()).orElseThrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<CryptorProvider.Scheme> detect(Masterkey masterkey, Path vaultPath) {
|
||||
try (Stream<Path> paths = Files.walk(vaultPath.resolve(DATA_DIR_NAME))) {
|
||||
Optional<Path> c9rFile = paths //
|
||||
.filter(p -> p.toString().endsWith(".c9r")) //
|
||||
.filter(p -> !p.endsWith("dir.c9r")) //
|
||||
.findFirst();
|
||||
if (c9rFile.isEmpty()) {
|
||||
LOG.info("Unable to detect Crypto scheme: No *.c9r file found in {}", vaultPath);
|
||||
return Optional.empty();
|
||||
}
|
||||
return determineScheme(c9rFile.get(), masterkey);
|
||||
} catch (IOException e) {
|
||||
LOG.info("Unable to detect Crypto scheme: Failed to inspect vault", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<CryptorProvider.Scheme> determineScheme(Path c9rFile, Masterkey masterkey) {
|
||||
return Arrays.stream(CryptorProvider.Scheme.values()).filter(scheme -> {
|
||||
try (Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(masterkey.copy(), SecureRandom.getInstanceStrong())) {
|
||||
int headerSize = cryptor.fileHeaderCryptor().headerSize();
|
||||
|
||||
ByteBuffer headerBuf = ByteBuffer.allocate(headerSize);
|
||||
|
||||
try (FileChannel channel = FileChannel.open(c9rFile, StandardOpenOption.READ)) {
|
||||
channel.read(headerBuf, 0);
|
||||
}
|
||||
|
||||
headerBuf.flip();
|
||||
cryptor.fileHeaderCryptor().decryptHeader(headerBuf.duplicate());
|
||||
LOG.debug("Detected Crypto scheme: {}", scheme);
|
||||
return true;
|
||||
} catch (IllegalArgumentException | CryptoException e) {
|
||||
LOG.debug("Could not decrypt with scheme: {}", scheme);
|
||||
return false;
|
||||
} catch (IOException | NoSuchAlgorithmException e) {
|
||||
LOG.warn("Unable to detect Crypto scheme: Failed to decrypt .c9r file", e);
|
||||
return false;
|
||||
}
|
||||
}).findFirst();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
public enum RecoveryActionType {
|
||||
RESTORE_ALL,
|
||||
RESTORE_MASTERKEY,
|
||||
RESTORE_VAULT_CONFIG,
|
||||
RESET_PASSWORD,
|
||||
SHOW_KEY,
|
||||
CONVERT_VAULT
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public final class RecoveryDirectory implements AutoCloseable {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RecoveryDirectory.class);
|
||||
|
||||
private final Path recoveryPath;
|
||||
private final Path vaultPath;
|
||||
|
||||
private RecoveryDirectory(Path vaultPath, Path recoveryPath) {
|
||||
this.vaultPath = vaultPath;
|
||||
this.recoveryPath = recoveryPath;
|
||||
}
|
||||
|
||||
public static RecoveryDirectory create(Path vaultPath) throws IOException {
|
||||
Path tempDir = Files.createTempDirectory("cryptomator");
|
||||
return new RecoveryDirectory(vaultPath, tempDir);
|
||||
}
|
||||
|
||||
public void moveRecoveredFile(String file) throws IOException {
|
||||
Files.move(recoveryPath.resolve(file), vaultPath.resolve(file), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
private void deleteRecoveryDirectory() {
|
||||
try (var paths = Files.walk(recoveryPath)) {
|
||||
paths.sorted(Comparator.reverseOrder()).forEach(p -> {
|
||||
try {
|
||||
Files.delete(p);
|
||||
} catch (IOException e) {
|
||||
LOG.info("Unable to delete {}. Please delete it manually.", p);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to clean up recovery directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
deleteRecoveryDirectory();
|
||||
}
|
||||
|
||||
public Path getRecoveryPath() {
|
||||
return recoveryPath;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.cryptomator.common.recovery;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultComponent;
|
||||
import org.cryptomator.common.vaults.VaultConfigCache;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
|
||||
public final class VaultPreparator {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(VaultPreparator.class);
|
||||
|
||||
private VaultPreparator() {}
|
||||
|
||||
public static Vault prepareVault(Path selectedDirectory, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> mountServices, //
|
||||
ResourceBundle resourceBundle) {
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
vaultSettings.path.set(selectedDirectory);
|
||||
if (selectedDirectory.getFileName() != null) {
|
||||
vaultSettings.displayName.set(selectedDirectory.getFileName().toString());
|
||||
} else {
|
||||
vaultSettings.displayName.set(resourceBundle.getString("defaults.vault.vaultName"));
|
||||
}
|
||||
|
||||
var wrapper = new VaultConfigCache(vaultSettings);
|
||||
Vault vault = vaultComponentFactory.create(vaultSettings, wrapper, LOCKED, null).vault();
|
||||
try {
|
||||
VaultListManager.determineVaultState(vault.getPath());
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e);
|
||||
}
|
||||
|
||||
//due to https://github.com/cryptomator/cryptomator/issues/2880#issuecomment-1680313498
|
||||
var nameOfWinfspLocalMounter = "org.cryptomator.frontend.fuse.mount.WinFspMountProvider";
|
||||
if (SystemUtils.IS_OS_WINDOWS && vaultSettings.path.get().toString().contains("Dropbox") && mountServices.stream().anyMatch(s -> s.getClass().getName().equals(nameOfWinfspLocalMounter))) {
|
||||
vaultSettings.mountService.setValue(nameOfWinfspLocalMounter);
|
||||
}
|
||||
|
||||
return vault;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,8 @@ import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.NodeOrientation;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -44,7 +46,7 @@ public class Settings {
|
||||
@Deprecated // to be changed to "whatever is available" eventually
|
||||
static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : //
|
||||
SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : //
|
||||
"org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
|
||||
"org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess";
|
||||
static final String DEFAULT_QUICKACCESS_SERVICE = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.quickaccess.ExplorerQuickAccessService" : //
|
||||
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
|
||||
|
||||
@@ -75,6 +77,7 @@ public class Settings {
|
||||
public final BooleanProperty checkForUpdates;
|
||||
public final ObjectProperty<Instant> lastUpdateCheckReminder;
|
||||
public final ObjectProperty<Instant> lastSuccessfulUpdateCheck;
|
||||
public final ObjectProperty<Path> previouslyUsedVaultDirectory;
|
||||
|
||||
private Consumer<Settings> saveCmd;
|
||||
|
||||
@@ -114,6 +117,7 @@ public class Settings {
|
||||
this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
|
||||
this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck);
|
||||
this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
|
||||
this.previouslyUsedVaultDirectory = new SimpleObjectProperty<>(this, "previouslyUsedVaultDirectory", json.previouslyUsedVaultDirectory);
|
||||
|
||||
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
|
||||
|
||||
@@ -143,10 +147,16 @@ public class Settings {
|
||||
checkForUpdates.addListener(this::somethingChanged);
|
||||
lastUpdateCheckReminder.addListener(this::somethingChanged);
|
||||
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
|
||||
previouslyUsedVaultDirectory.addListener(this::somethingChanged);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void migrateLegacySettings(SettingsJson json) {
|
||||
// migrate renamed keychainAccess
|
||||
if(this.keychainProvider.getValueSafe().equals("org.cryptomator.linux.keychain.SecretServiceKeychainAccess")) {
|
||||
this.keychainProvider.setValue("org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess");
|
||||
}
|
||||
|
||||
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
|
||||
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
|
||||
this.mountService.set(switch (json.preferredVolumeImpl) {
|
||||
@@ -199,6 +209,7 @@ public class Settings {
|
||||
json.checkForUpdatesEnabled = checkForUpdates.get();
|
||||
json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
|
||||
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
|
||||
json.previouslyUsedVaultDirectory = previouslyUsedVaultDirectory.get();
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@@ -92,4 +93,7 @@ class SettingsJson {
|
||||
|
||||
@JsonProperty("quickAccessService")
|
||||
String quickAccessService = Settings.DEFAULT_QUICKACCESS_SERVICE;
|
||||
|
||||
@JsonProperty("previouslyUsedVaultDirectory")
|
||||
Path previouslyUsedVaultDirectory;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||
import org.cryptomator.event.VaultEvent;
|
||||
import org.cryptomator.integrations.mount.MountFailedException;
|
||||
import org.cryptomator.integrations.mount.Mountpoint;
|
||||
import org.cryptomator.integrations.mount.UnmountFailedException;
|
||||
@@ -35,7 +34,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
@@ -75,6 +73,7 @@ public class Vault {
|
||||
private final BooleanBinding missing;
|
||||
private final BooleanBinding needsMigration;
|
||||
private final BooleanBinding unknownError;
|
||||
private final BooleanBinding missingVaultConfig;
|
||||
private final ObjectBinding<Mountpoint> mountPoint;
|
||||
private final Mounter mounter;
|
||||
private final Settings settings;
|
||||
@@ -103,6 +102,7 @@ public class Vault {
|
||||
this.processing = Bindings.createBooleanBinding(this::isProcessing, state);
|
||||
this.unlocked = Bindings.createBooleanBinding(this::isUnlocked, state);
|
||||
this.missing = Bindings.createBooleanBinding(this::isMissing, state);
|
||||
this.missingVaultConfig = Bindings.createBooleanBinding(this::isMissingVaultConfig, state);
|
||||
this.needsMigration = Bindings.createBooleanBinding(this::isNeedsMigration, state);
|
||||
this.unknownError = Bindings.createBooleanBinding(this::isUnknownError, state);
|
||||
this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
|
||||
@@ -336,6 +336,14 @@ public class Vault {
|
||||
return state.get() == VaultState.Value.ERROR;
|
||||
}
|
||||
|
||||
public BooleanBinding missingVaultConfigProperty() {
|
||||
return missingVaultConfig;
|
||||
}
|
||||
|
||||
public boolean isMissingVaultConfig() {
|
||||
return state.get() == VaultState.Value.VAULT_CONFIG_MISSING || state.get() == VaultState.Value.ALL_MISSING;
|
||||
}
|
||||
|
||||
public ReadOnlyStringProperty displayNameProperty() {
|
||||
return vaultSettings.displayName;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class VaultConfigCache {
|
||||
private final VaultSettings settings;
|
||||
private final AtomicReference<VaultConfig.UnverifiedVaultConfig> config;
|
||||
|
||||
VaultConfigCache(VaultSettings settings) {
|
||||
public VaultConfigCache(VaultSettings settings) {
|
||||
this.settings = settings;
|
||||
this.config = new AtomicReference<>(null);
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
package org.cryptomator.common.vaults;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.recovery.BackupRestorer;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptofs.DirStructure;
|
||||
import org.cryptomator.cryptofs.migration.Migrators;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -33,8 +35,7 @@ import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.*;
|
||||
|
||||
@Singleton
|
||||
public class VaultListManager {
|
||||
@@ -65,6 +66,12 @@ public class VaultListManager {
|
||||
autoLocker.init();
|
||||
}
|
||||
|
||||
public boolean isAlreadyAdded(Path vaultPath) {
|
||||
assert vaultPath.isAbsolute();
|
||||
assert vaultPath.normalize().equals(vaultPath);
|
||||
return vaultList.stream().anyMatch(v -> vaultPath.equals(v.getPath()));
|
||||
}
|
||||
|
||||
public Vault add(Path pathToVault) throws IOException {
|
||||
Path normalizedPathToVault = pathToVault.normalize().toAbsolutePath();
|
||||
if (CryptoFileSystemProvider.checkDirStructureForVault(normalizedPathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) == DirStructure.UNRELATED) {
|
||||
@@ -104,7 +111,7 @@ public class VaultListManager {
|
||||
vaultList.addAll(vaults);
|
||||
}
|
||||
|
||||
private Optional<Vault> get(Path vaultPath) {
|
||||
public Optional<Vault> get(Path vaultPath) {
|
||||
assert vaultPath.isAbsolute();
|
||||
assert vaultPath.normalize().equals(vaultPath);
|
||||
return vaultList.stream() //
|
||||
@@ -112,57 +119,122 @@ public class VaultListManager {
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public void addVault(Vault vault) {
|
||||
Path path = vault.getPath().normalize().toAbsolutePath();
|
||||
if (!isAlreadyAdded(path)) {
|
||||
vaultList.add(vault);
|
||||
}
|
||||
}
|
||||
|
||||
private Vault create(VaultSettings vaultSettings) {
|
||||
var wrapper = new VaultConfigCache(vaultSettings);
|
||||
try {
|
||||
if (Objects.isNull(vaultSettings.lastKnownKeyLoader.get())) {
|
||||
var keyIdScheme = wrapper.get().getKeyId().getScheme();
|
||||
vaultSettings.lastKnownKeyLoader.set(keyIdScheme);
|
||||
}
|
||||
var vaultState = determineVaultState(vaultSettings.path.get());
|
||||
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
||||
wrapper.reloadConfig();
|
||||
}
|
||||
initializeLastKnownKeyLoaderIfPossible(vaultSettings, vaultState, wrapper);
|
||||
|
||||
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to determine vault state for " + vaultSettings.path.get(), e);
|
||||
LOG.warn("Failed to determine vault state for {}", vaultSettings.path.get(), e);
|
||||
return vaultComponentFactory.create(vaultSettings, wrapper, ERROR, e).vault();
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeLastKnownKeyLoaderIfPossible(VaultSettings vaultSettings, VaultState.Value vaultState, VaultConfigCache wrapper) throws IOException {
|
||||
if (vaultSettings.lastKnownKeyLoader.get() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (vaultState) {
|
||||
case LOCKED -> {
|
||||
wrapper.reloadConfig();
|
||||
vaultSettings.lastKnownKeyLoader.set(wrapper.get().getKeyId().getScheme());
|
||||
}
|
||||
case NEEDS_MIGRATION -> {
|
||||
//for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
||||
vaultSettings.lastKnownKeyLoader.set(MasterkeyFileLoadingStrategy.SCHEME);
|
||||
}
|
||||
case VAULT_CONFIG_MISSING -> {
|
||||
//Nothing to do here, since there is no config to read
|
||||
}
|
||||
case MISSING, ALL_MISSING, ERROR, PROCESSING -> {
|
||||
// no config available or not safe to load
|
||||
}
|
||||
default -> {
|
||||
if (Files.exists(vaultSettings.path.get().resolve(VAULTCONFIG_FILENAME))) {
|
||||
try {
|
||||
wrapper.reloadConfig();
|
||||
vaultSettings.lastKnownKeyLoader.set(wrapper.get().getKeyId().getScheme());
|
||||
} catch (IOException e) {
|
||||
LOG.debug("Unable to load config for {}", vaultSettings.path.get(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static VaultState.Value redetermineVaultState(Vault vault) {
|
||||
VaultState state = vault.stateProperty();
|
||||
VaultState.Value previousState = state.getValue();
|
||||
return switch (previousState) {
|
||||
case LOCKED, NEEDS_MIGRATION, MISSING -> {
|
||||
try {
|
||||
var determinedState = determineVaultState(vault.getPath());
|
||||
if (determinedState == LOCKED) {
|
||||
vault.getVaultConfigCache().reloadConfig();
|
||||
}
|
||||
state.set(determinedState);
|
||||
yield determinedState;
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to determine vault state for " + vault.getPath(), e);
|
||||
state.set(ERROR);
|
||||
vault.setLastKnownException(e);
|
||||
yield ERROR;
|
||||
}
|
||||
VaultState.Value previous = state.getValue();
|
||||
|
||||
if (previous.equals(UNLOCKED) || previous.equals(PROCESSING)) {
|
||||
return previous;
|
||||
}
|
||||
|
||||
try {
|
||||
VaultState.Value determined = determineVaultState(vault.getPath());
|
||||
|
||||
if (determined == LOCKED) {
|
||||
vault.getVaultConfigCache().reloadConfig();
|
||||
}
|
||||
case ERROR, UNLOCKED, PROCESSING -> previousState;
|
||||
};
|
||||
|
||||
state.set(determined);
|
||||
return determined;
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to (re)determine vault state for {}", vault.getPath(), e);
|
||||
vault.setLastKnownException(e);
|
||||
state.set(ERROR);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private static VaultState.Value determineVaultState(Path pathToVault) throws IOException {
|
||||
public static VaultState.Value determineVaultState(Path pathToVault) throws IOException {
|
||||
if (!Files.exists(pathToVault)) {
|
||||
return VaultState.Value.MISSING;
|
||||
return MISSING;
|
||||
}
|
||||
|
||||
VaultState.Value structureResult = checkDirStructure(pathToVault);
|
||||
|
||||
if (structureResult == LOCKED || structureResult == NEEDS_MIGRATION) {
|
||||
return structureResult;
|
||||
}
|
||||
|
||||
Path pathToVaultConfig = pathToVault.resolve(VAULTCONFIG_FILENAME);
|
||||
Path pathToMasterkey = pathToVault.resolve(MASTERKEY_FILENAME);
|
||||
|
||||
if (!Files.exists(pathToVaultConfig)) {
|
||||
BackupRestorer.restoreIfBackupPresent(pathToVault, VAULTCONFIG_FILENAME);
|
||||
}
|
||||
if (!Files.exists(pathToMasterkey)) {
|
||||
BackupRestorer.restoreIfBackupPresent(pathToVault, MASTERKEY_FILENAME);
|
||||
}
|
||||
|
||||
boolean hasConfig = Files.exists(pathToVaultConfig);
|
||||
|
||||
if (!hasConfig && !Files.exists(pathToMasterkey)) {
|
||||
return ALL_MISSING;
|
||||
}
|
||||
if (!hasConfig) {
|
||||
return VAULT_CONFIG_MISSING;
|
||||
}
|
||||
|
||||
return checkDirStructure(pathToVault);
|
||||
}
|
||||
|
||||
private static VaultState.Value checkDirStructure(Path pathToVault) throws IOException {
|
||||
return switch (CryptoFileSystemProvider.checkDirStructureForVault(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME)) {
|
||||
case VAULT -> VaultState.Value.LOCKED;
|
||||
case UNRELATED -> VaultState.Value.MISSING;
|
||||
case MAYBE_LEGACY -> Migrators.get().needsMigration(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) ? //
|
||||
VaultState.Value.NEEDS_MIGRATION //
|
||||
: VaultState.Value.MISSING;
|
||||
case VAULT -> LOCKED;
|
||||
case UNRELATED -> MISSING;
|
||||
case MAYBE_LEGACY -> Migrators.get().needsMigration(pathToVault, VAULTCONFIG_FILENAME, MASTERKEY_FILENAME) ? NEEDS_MIGRATION : MISSING;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,16 @@ public class VaultState extends ObservableValueBase<VaultState.Value> implements
|
||||
*/
|
||||
MISSING,
|
||||
|
||||
/**
|
||||
* No vault config found at the provided path
|
||||
*/
|
||||
VAULT_CONFIG_MISSING,
|
||||
|
||||
/**
|
||||
* No vault config and masterkey found at the provided path
|
||||
*/
|
||||
ALL_MISSING,
|
||||
|
||||
/**
|
||||
* Vault requires migration to a newer vault format
|
||||
*/
|
||||
|
||||
@@ -53,18 +53,26 @@ class Server implements IpcCommunicator {
|
||||
@Override
|
||||
public void listen(IpcMessageListener listener, Executor executor) {
|
||||
executor.execute(() -> {
|
||||
int errorCount = 0;
|
||||
while (serverSocketChannel.isOpen()) {
|
||||
try (var ch = serverSocketChannel.accept()) {
|
||||
while (ch.isConnected()) {
|
||||
var msg = IpcMessage.receive(ch);
|
||||
listener.handleMessage(msg);
|
||||
}
|
||||
errorCount = 0;
|
||||
} catch (AsynchronousCloseException e) {
|
||||
LOG.info("Closing server socket due to closed channel.");
|
||||
return; // serverSocketChannel closed or listener interrupted
|
||||
} catch (EOFException | ClosedChannelException e) {
|
||||
// continue with next connected client
|
||||
} catch (IOException e) {
|
||||
errorCount++;
|
||||
LOG.error("Failed to read IPC message", e);
|
||||
if(errorCount > 100) { //apparently something is broken, prevent log spam
|
||||
LOG.info("Closing server socket due to too many failed requests.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -90,6 +90,9 @@ public class LogbackConfigurator extends ContextAwareBase implements Configurato
|
||||
// configure fuse file locking logger:
|
||||
Logger fuseLocking = context.getLogger("org.cryptomator.frontend.fuse.locks");
|
||||
fuseLocking.setLevel(Level.OFF);
|
||||
//deactivate kwallet unsettling message
|
||||
Logger kdeWallet = context.getLogger("org.purejava.kwallet.freedesktop.dbus.handlers");
|
||||
kdeWallet.setLevel(Level.OFF);
|
||||
}
|
||||
return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CreateNewVaultExpertSettingsController implements FxController {
|
||||
|
||||
public static final int MAX_SHORTENING_THRESHOLD = 220;
|
||||
public static final int MIN_SHORTENING_THRESHOLD = 36;
|
||||
private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/architecture/#name-shortening";
|
||||
private static final String DOCS_NAME_SHORTENING_URL = "https://docs.cryptomator.org/security/vault/#name-shortening";
|
||||
|
||||
private final Stage window;
|
||||
private final Lazy<Application> application;
|
||||
|
||||
@@ -4,6 +4,7 @@ import dagger.Lazy;
|
||||
import org.cryptomator.common.ObservableUtil;
|
||||
import org.cryptomator.common.locationpresets.LocationPreset;
|
||||
import org.cryptomator.common.locationpresets.LocationPresetsProvider;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
@@ -38,6 +39,7 @@ import javafx.stage.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
@@ -64,6 +66,7 @@ public class CreateNewVaultLocationController implements FxController {
|
||||
private final BooleanProperty loadingPresetLocations = new SimpleBooleanProperty(false);
|
||||
private final ObservableList<Node> radioButtons;
|
||||
private final ObservableList<Node> sortedRadioButtons;
|
||||
private final Settings settings;
|
||||
|
||||
private Path customVaultPath = DEFAULT_CUSTOM_VAULT_PATH;
|
||||
|
||||
@@ -82,6 +85,7 @@ public class CreateNewVaultLocationController implements FxController {
|
||||
@FxmlScene(FxmlFile.ADDVAULT_NEW_EXPERT_SETTINGS) Lazy<Scene> chooseExpertSettingsScene, //
|
||||
ObjectProperty<Path> vaultPath, //
|
||||
@Named("vaultName") StringProperty vaultName, //
|
||||
Settings settings, //
|
||||
ExecutorService backgroundExecutor, ResourceBundle resourceBundle) {
|
||||
this.window = window;
|
||||
this.chooseNameScene = chooseNameScene;
|
||||
@@ -96,6 +100,18 @@ public class CreateNewVaultLocationController implements FxController {
|
||||
this.usePresetPath = new SimpleBooleanProperty();
|
||||
this.radioButtons = FXCollections.observableArrayList();
|
||||
this.sortedRadioButtons = radioButtons.sorted(this::compareLocationPresets);
|
||||
this.settings = settings;
|
||||
|
||||
Path previouslyUsedDirectory = settings.previouslyUsedVaultDirectory.get();
|
||||
if (previouslyUsedDirectory != null) {
|
||||
try {
|
||||
if (Files.exists(previouslyUsedDirectory) && Files.isDirectory(previouslyUsedDirectory) && isActuallyWritable(previouslyUsedDirectory)) {
|
||||
this.customVaultPath = previouslyUsedDirectory;
|
||||
}
|
||||
} catch (InvalidPathException | NullPointerException e) {
|
||||
LOG.warn("Invalid previously used vault directory path: {}", previouslyUsedDirectory, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VaultPathStatus validatePath(Path p) throws NullPointerException {
|
||||
@@ -196,6 +212,12 @@ public class CreateNewVaultLocationController implements FxController {
|
||||
@FXML
|
||||
public void next() {
|
||||
if (validVaultPath.getValue()) {
|
||||
if (this.getVaultPath() != null) {
|
||||
Path parentPath = this.getVaultPath().getParent();
|
||||
if (parentPath != null) {
|
||||
this.settings.previouslyUsedVaultDirectory.setValue(parentPath);
|
||||
}
|
||||
}
|
||||
window.setScene(chooseExpertSettingsScene.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class ReadmeGenerator {
|
||||
} else if (c <= 0xFF) {
|
||||
sb.append("\\'").append(String.format("%02X", c));
|
||||
} else if (c < 0xFFFF) {
|
||||
sb.append("\\uc1\\u").append(c);
|
||||
sb.append("\\u").append(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.ResourceBundle;
|
||||
public class PasswordStrengthUtil {
|
||||
|
||||
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length
|
||||
private static final String RESSOURCE_PREFIX = "passwordStrength.messageLabel.";
|
||||
private static final List<String> SANITIZED_INPUTS = List.of("cryptomator");
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
@@ -48,13 +47,15 @@ public class PasswordStrengthUtil {
|
||||
}
|
||||
|
||||
public String getStrengthDescription(Number score) {
|
||||
if (score.intValue() == -1) {
|
||||
return String.format(resourceBundle.getString(RESSOURCE_PREFIX + "tooShort"), minPwLength);
|
||||
} else if (resourceBundle.containsKey(RESSOURCE_PREFIX + score.intValue())) {
|
||||
return resourceBundle.getString(RESSOURCE_PREFIX + score.intValue());
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return switch (score.intValue()) {
|
||||
case -1 -> String.format(resourceBundle.getString("passwordStrength.messageLabel.tooShort"), minPwLength);
|
||||
case 0 -> resourceBundle.getString("passwordStrength.messageLabel.0");
|
||||
case 1 -> resourceBundle.getString("passwordStrength.messageLabel.1");
|
||||
case 2 -> resourceBundle.getString("passwordStrength.messageLabel.2");
|
||||
case 3 -> resourceBundle.getString("passwordStrength.messageLabel.3");
|
||||
case 4 -> resourceBundle.getString("passwordStrength.messageLabel.4");
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,9 +42,10 @@ public enum FxmlFile {
|
||||
QUIT("/fxml/quit.fxml"), //
|
||||
QUIT_FORCED("/fxml/quit_forced.fxml"), //
|
||||
RECOVERYKEY_CREATE("/fxml/recoverykey_create.fxml"), //
|
||||
RECOVERYKEY_EXPERT_SETTINGS("/fxml/recoverykey_expert_settings.fxml"), //
|
||||
RECOVERYKEY_ONBOARDING("/fxml/recoverykey_onboarding.fxml"), //
|
||||
RECOVERYKEY_RECOVER("/fxml/recoverykey_recover.fxml"), //
|
||||
RECOVERYKEY_RESET_PASSWORD("/fxml/recoverykey_reset_password.fxml"), //
|
||||
RECOVERYKEY_RESET_PASSWORD_SUCCESS("/fxml/recoverykey_reset_password_success.fxml"), //
|
||||
RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
|
||||
SHARE_VAULT("/fxml/share_vault.fxml"), //
|
||||
SIMPLE_DIALOG("/fxml/simple_dialog.fxml"), //
|
||||
|
||||
@@ -4,8 +4,10 @@ import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.cryptomator.ui.changepassword.NewPasswordController;
|
||||
import org.cryptomator.ui.changepassword.PasswordStrengthUtil;
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
@@ -20,6 +22,7 @@ import org.cryptomator.ui.recoverykey.RecoveryKeyValidateController;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.scene.Scene;
|
||||
@@ -119,8 +122,8 @@ abstract class ConvertVaultModule {
|
||||
@Provides
|
||||
@IntoMap
|
||||
@FxControllerKey(RecoveryKeyValidateController.class)
|
||||
static FxController bindRecoveryKeyValidateController(@ConvertVaultWindow Vault vault, @ConvertVaultWindow VaultConfig.UnverifiedVaultConfig vaultConfig, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory);
|
||||
static FxController provideRecoveryKeyValidateController(@ConvertVaultWindow Vault vault, @ConvertVaultWindow VaultConfig.UnverifiedVaultConfig vaultConfig, @ConvertVaultWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory, MasterkeyFileAccess masterkeyFileAccess) {
|
||||
return new RecoveryKeyValidateController(vault, vaultConfig, recoveryKey, recoveryKeyFactory, masterkeyFileAccess, new SimpleObjectProperty<>(RecoveryActionType.CONVERT_VAULT), new SimpleObjectProperty<>(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.cryptomator.ui.dialogs;
|
||||
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
import org.cryptomator.ui.common.StageFactory;
|
||||
import org.cryptomator.ui.controls.FontAwesome5Icon;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationScoped;
|
||||
@@ -19,17 +20,21 @@ public class Dialogs {
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final StageFactory stageFactory;
|
||||
private final DefaultSceneFactory sceneFactory;
|
||||
|
||||
private static final String BUTTON_KEY_CLOSE = "generic.button.close";
|
||||
|
||||
@Inject
|
||||
public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory) {
|
||||
public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory, DefaultSceneFactory sceneFactory) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.stageFactory = stageFactory;
|
||||
this.sceneFactory = sceneFactory;
|
||||
}
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Dialogs.class);
|
||||
|
||||
private SimpleDialog.Builder createDialogBuilder() {
|
||||
return new SimpleDialog.Builder(resourceBundle, stageFactory);
|
||||
return new SimpleDialog.Builder(resourceBundle, stageFactory, sceneFactory);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRemoveVaultDialog(Stage window, Vault vault, ObservableList<Vault> vaults) {
|
||||
@@ -47,6 +52,43 @@ public class Dialogs {
|
||||
});
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareContactHubVaultOwner(Stage window) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("contactHubVaultOwner.title") //
|
||||
.setMessageKey("contactHubVaultOwner.message") //
|
||||
.setDescriptionKey("contactHubVaultOwner.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRecoveryVaultAdded(Stage window, String displayName) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("recover.existing.title") //
|
||||
.setMessageKey("recover.existing.message") //
|
||||
.setDescriptionKey("recover.existing.description", displayName) //
|
||||
.setIcon(FontAwesome5Icon.CHECK)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
public SimpleDialog.Builder prepareRecoveryVaultAlreadyExists(Stage window, String displayName) {
|
||||
return createDialogBuilder().setOwner(window) //
|
||||
.setTitleKey("recover.alreadyExists.title") //
|
||||
.setMessageKey("recover.alreadyExists.message") //
|
||||
.setDescriptionKey("recover.alreadyExists.description", displayName) //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION)//
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRecoverPasswordSuccess(Stage window) {
|
||||
return createDialogBuilder()
|
||||
.setOwner(window) //
|
||||
.setTitleKey("recoveryKey.recover.title") //
|
||||
.setMessageKey("recoveryKey.recover.resetSuccess.message") //
|
||||
.setDescriptionKey("recoveryKey.recover.resetSuccess.description") //
|
||||
.setIcon(FontAwesome5Icon.CHECK)
|
||||
.setOkAction(Stage::close)
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareRemoveCertDialog(Stage window, Settings settings) {
|
||||
return createDialogBuilder() //
|
||||
.setOwner(window) //
|
||||
@@ -69,7 +111,7 @@ public class Dialogs {
|
||||
.setMessageKey("dokanySupportEnd.message") //
|
||||
.setDescriptionKey("dokanySupportEnd.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION) //
|
||||
.setOkButtonKey("generic.button.close") //
|
||||
.setOkButtonKey(BUTTON_KEY_CLOSE) //
|
||||
.setCancelButtonKey("dokanySupportEnd.preferencesBtn") //
|
||||
.setOkAction(Stage::close) //
|
||||
.setCancelAction(cancelAction);
|
||||
@@ -83,8 +125,20 @@ public class Dialogs {
|
||||
.setDescriptionKey("retryIfReadonly.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION) //
|
||||
.setOkButtonKey("retryIfReadonly.retry") //
|
||||
.setCancelButtonKey("generic.button.close") //
|
||||
.setCancelButtonKey(BUTTON_KEY_CLOSE) //
|
||||
.setOkAction(okAction) //
|
||||
.setCancelAction(Stage::close);
|
||||
}
|
||||
|
||||
public SimpleDialog.Builder prepareNoDDirectorySelectedDialog(Stage window) {
|
||||
return createDialogBuilder() //
|
||||
.setOwner(window) //
|
||||
.setTitleKey("recover.invalidSelection.title") //
|
||||
.setMessageKey("recover.invalidSelection.message") //
|
||||
.setDescriptionKey("recover.invalidSelection.description") //
|
||||
.setIcon(FontAwesome5Icon.EXCLAMATION) //
|
||||
.setOkButtonKey("generic.button.change") //
|
||||
.setOkAction(Stage::close);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.cryptomator.ui.dialogs;
|
||||
|
||||
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||
import org.cryptomator.ui.common.StageFactory;
|
||||
@@ -30,15 +31,15 @@ public class SimpleDialog {
|
||||
|
||||
FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController( //
|
||||
new SimpleDialogController(resolveText(builder.messageKey, null), //
|
||||
resolveText(builder.descriptionKey, null), //
|
||||
resolveText(builder.descriptionKey, builder.descriptionArgs), //
|
||||
builder.icon, //
|
||||
resolveText(builder.okButtonKey, null), //
|
||||
builder.cancelButtonKey != null ? resolveText(builder.cancelButtonKey, null) : null, //
|
||||
() -> builder.okAction.accept(dialogStage), //
|
||||
() -> builder.cancelAction.accept(dialogStage)), //
|
||||
Scene::new, builder.resourceBundle);
|
||||
builder.sceneFactory, builder.resourceBundle);
|
||||
|
||||
dialogStage.setScene(new Scene(loaderFactory.load(FxmlFile.SIMPLE_DIALOG.getRessourcePathString()).getRoot()));
|
||||
dialogStage.setScene(loaderFactory.createScene(FxmlFile.SIMPLE_DIALOG));
|
||||
}
|
||||
|
||||
public void showAndWait() {
|
||||
@@ -62,19 +63,22 @@ public class SimpleDialog {
|
||||
private Stage owner;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final StageFactory stageFactory;
|
||||
private final DefaultSceneFactory sceneFactory;
|
||||
private String titleKey;
|
||||
private String[] titleArgs;
|
||||
private String messageKey;
|
||||
private String descriptionKey;
|
||||
private String[] descriptionArgs;
|
||||
private String okButtonKey;
|
||||
private String cancelButtonKey;
|
||||
private FontAwesome5Icon icon;
|
||||
private Consumer<Stage> okAction = Stage::close;
|
||||
private Consumer<Stage> cancelAction = Stage::close;
|
||||
|
||||
public Builder(ResourceBundle resourceBundle, StageFactory stageFactory) {
|
||||
public Builder(ResourceBundle resourceBundle, StageFactory stageFactory, DefaultSceneFactory sceneFactory) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.stageFactory = stageFactory;
|
||||
this.sceneFactory = sceneFactory;
|
||||
}
|
||||
|
||||
public Builder setOwner(Stage owner) {
|
||||
@@ -93,8 +97,9 @@ public class SimpleDialog {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDescriptionKey(String descriptionKey) {
|
||||
public Builder setDescriptionKey(String descriptionKey, String... args) {
|
||||
this.descriptionKey = descriptionKey;
|
||||
this.descriptionArgs = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ public interface ErrorComponent {
|
||||
default Stage show() {
|
||||
Stage stage = window();
|
||||
stage.setScene(scene());
|
||||
stage.setMinWidth(420);
|
||||
stage.setMinHeight(300);
|
||||
stage.setMinWidth(450);
|
||||
stage.setMinHeight(450);
|
||||
stage.show();
|
||||
return stage;
|
||||
}
|
||||
|
||||
@@ -133,9 +133,9 @@ public class EventListCellController implements FxController {
|
||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.brokenFileNode.message"));
|
||||
eventDescription.setValue(bfe.ciphertextPath().getFileName().toString());
|
||||
if (revealService != null) {
|
||||
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, convertVaultPathToSystemPath(bfe.ciphertextPath())));
|
||||
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, bfe.ciphertextPath()));
|
||||
} else {
|
||||
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.ciphertextPath()).toString()));
|
||||
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(bfe.ciphertextPath().toString()));
|
||||
}
|
||||
addAction("eventView.entry.brokenFileNode.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.cleartextPath()).toString()));
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class EventViewController implements FxController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison method for the lru cache. During comparsion the map is accessed.
|
||||
* Comparison method for the lru cache. During comparison the map is accessed.
|
||||
* First the entries are compared by the event timestamp, then vaultId, then identifying path and lastly by class name.
|
||||
*
|
||||
* @param left an entry of a {@link FSEventBucket} and its content
|
||||
|
||||
@@ -12,6 +12,7 @@ import javax.inject.Named;
|
||||
import javafx.application.Platform;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
@@ -58,29 +59,30 @@ class AppLaunchEventHandler {
|
||||
switch (event.type()) {
|
||||
case REVEAL_APP -> appWindows.showMainWindow();
|
||||
case OPEN_FILE -> Platform.runLater(() -> {
|
||||
event.pathsToOpen().forEach(this::addOrRevealVault);
|
||||
event.pathsToOpen().forEach(this::openPotentialVault);
|
||||
});
|
||||
default -> LOG.warn("Unsupported event type: {}", event.type());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO deduplicate MainWindowController...
|
||||
private void addOrRevealVault(Path potentialVaultPath) {
|
||||
private void openPotentialVault(Path path) {
|
||||
assert Platform.isFxApplicationThread();
|
||||
try {
|
||||
final Vault v;
|
||||
if (potentialVaultPath.getFileName().toString().endsWith(CRYPTOMATOR_FILENAME_EXT)) {
|
||||
v = vaultListManager.add(potentialVaultPath.getParent());
|
||||
Path potentialVaultPath = path.getFileName().toString().endsWith(CRYPTOMATOR_FILENAME_EXT) ? path.getParent() : path;
|
||||
final Optional<Vault> v = vaultListManager.get(potentialVaultPath);
|
||||
if (v.isPresent()) {
|
||||
if (v.get().isUnlocked()) {
|
||||
vaultService.reveal(v.get());
|
||||
} else if (v.get().isLocked()) {
|
||||
appWindows.startUnlockWorkflow(v.get(), null);
|
||||
}
|
||||
} else {
|
||||
v = vaultListManager.add(potentialVaultPath);
|
||||
vaultListManager.add(potentialVaultPath);
|
||||
LOG.debug("Added vault {}", potentialVaultPath);
|
||||
}
|
||||
|
||||
if (v.isUnlocked()) {
|
||||
vaultService.reveal(v);
|
||||
}
|
||||
LOG.debug("Added vault {}", potentialVaultPath);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to add vault " + potentialVaultPath, e);
|
||||
LOG.error("Failed to add vault " + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,13 @@ import org.cryptomator.ui.lock.LockComponent;
|
||||
import org.cryptomator.ui.mainwindow.MainWindowComponent;
|
||||
import org.cryptomator.ui.preferences.PreferencesComponent;
|
||||
import org.cryptomator.ui.quit.QuitComponent;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.cryptomator.ui.sharevault.ShareVaultComponent;
|
||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
||||
import org.cryptomator.ui.unlock.UnlockComponent;
|
||||
import org.cryptomator.ui.updatereminder.UpdateReminderComponent;
|
||||
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.scene.image.Image;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -40,7 +38,8 @@ import java.io.InputStream;
|
||||
HealthCheckComponent.class, //
|
||||
UpdateReminderComponent.class, //
|
||||
ShareVaultComponent.class, //
|
||||
EventViewComponent.class})
|
||||
EventViewComponent.class, //
|
||||
RecoveryKeyComponent.class})
|
||||
abstract class FxApplicationModule {
|
||||
|
||||
private static Image createImageFromResource(String resourceName) throws IOException {
|
||||
|
||||
@@ -28,7 +28,7 @@ import static org.cryptomator.common.vaults.VaultState.Value.*;
|
||||
@FxApplicationScoped
|
||||
public class FxApplicationTerminator {
|
||||
|
||||
private static final Set<VaultState.Value> STATES_ALLOWING_TERMINATION = EnumSet.of(LOCKED, NEEDS_MIGRATION, MISSING, ERROR);
|
||||
private static final Set<VaultState.Value> STATES_ALLOWING_TERMINATION = EnumSet.of(LOCKED, NEEDS_MIGRATION, MISSING, ERROR, VAULT_CONFIG_MISSING, ALL_MISSING);
|
||||
private static final Set<VaultState.Value> STATES_PREVENT_TERMINATION = EnumSet.of(PROCESSING);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FxApplicationTerminator.class);
|
||||
|
||||
@@ -110,7 +110,7 @@ public class FxApplicationTerminator {
|
||||
} else if (settings.autoCloseVaults.get() && !preventQuitWithGracefulLock.get()) {
|
||||
var lockAllTask = vaultService.createLockAllTask(vaults.filtered(Vault::isUnlocked), false);
|
||||
lockAllTask.setOnSucceeded(event -> {
|
||||
LOG.info("Locked remaining vaults was succesful.");
|
||||
LOG.info("Locked remaining vaults was successful.");
|
||||
exitingResponse.performQuit();
|
||||
});
|
||||
lockAllTask.setOnFailed(event -> {
|
||||
|
||||
@@ -46,15 +46,16 @@ public interface KeyLoadingStrategy extends MasterkeyLoader {
|
||||
/**
|
||||
* Determines whether the provided key loader scheme corresponds to a Masterkey File Vault.
|
||||
* <p>
|
||||
* This method checks if the {@code keyLoader} parameter matches the known Masterkey File Vault scheme
|
||||
* This method checks if the {@code keyLoader} parameter starts with the known Masterkey File Vault scheme
|
||||
* {@link MasterkeyFileLoadingStrategy#SCHEME}.
|
||||
* This allows identifying not only exact matches but also variants or extended schemes based on the Masterkey scheme.
|
||||
* </p>
|
||||
*
|
||||
* @param keyLoader A string representing the key loader scheme to be checked.
|
||||
* @return {@code true} if the given key loader scheme represents a Masterkey File Vault; {@code false} otherwise.
|
||||
* @return {@code true} if the given key loader scheme starts with the Masterkey File Vault scheme; {@code false} otherwise.
|
||||
*/
|
||||
static boolean isMasterkeyFileVault(String keyLoader) {
|
||||
return MasterkeyFileLoadingStrategy.SCHEME.equals(keyLoader);
|
||||
return keyLoader.startsWith(MasterkeyFileLoadingStrategy.SCHEME);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package org.cryptomator.ui.keyloading.masterkeyfile;
|
||||
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.keyloading.KeyLoading;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
@@ -27,17 +31,41 @@ public class ChooseMasterkeyFileController implements FxController {
|
||||
private final Stage window;
|
||||
private final Vault vault;
|
||||
private final CompletableFuture<Path> result;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final ResourceBundle resourceBundle;
|
||||
|
||||
@FXML
|
||||
private CheckBox restoreInsteadCheckBox;
|
||||
@FXML
|
||||
private Button forwardButton;
|
||||
|
||||
@Inject
|
||||
public ChooseMasterkeyFileController(@KeyLoading Stage window, @KeyLoading Vault vault, CompletableFuture<Path> result, ResourceBundle resourceBundle) {
|
||||
public ChooseMasterkeyFileController(@KeyLoading Stage window, //
|
||||
@KeyLoading Vault vault, //
|
||||
CompletableFuture<Path> result, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow, //
|
||||
ResourceBundle resourceBundle) {
|
||||
this.window = window;
|
||||
this.vault = vault;
|
||||
this.result = result;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.window.setOnHiding(this::windowClosed);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
restoreInsteadCheckBox.selectedProperty().addListener((_, _, newVal) -> {
|
||||
if (newVal) {
|
||||
forwardButton.setText(resourceBundle.getString("addvaultwizard.existing.restore"));
|
||||
forwardButton.setOnAction(_ -> restoreMasterkey());
|
||||
} else {
|
||||
forwardButton.setText(resourceBundle.getString("generic.button.choose"));
|
||||
forwardButton.setOnAction(_ -> proceed());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void cancel() {
|
||||
window.close();
|
||||
@@ -47,6 +75,13 @@ public class ChooseMasterkeyFileController implements FxController {
|
||||
result.cancel(true);
|
||||
}
|
||||
|
||||
@FXML
|
||||
void restoreMasterkey() {
|
||||
Stage ownerStage = (Stage) window.getOwner();
|
||||
window.close();
|
||||
recoveryKeyWindow.create(vault, ownerStage, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_MASTERKEY)).showOnboardingDialogWindow();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void proceed() {
|
||||
LOG.trace("proceed()");
|
||||
@@ -62,7 +97,7 @@ public class ChooseMasterkeyFileController implements FxController {
|
||||
|
||||
//--- Setter & Getter ---
|
||||
|
||||
public String getDisplayName(){
|
||||
public String getDisplayName() {
|
||||
return vault.getDisplayName();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.cryptomator.ui.error.ErrorComponent;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationTerminator;
|
||||
import org.cryptomator.ui.fxapp.PrimaryStage;
|
||||
import org.cryptomator.ui.migration.MigrationComponent;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
||||
import org.cryptomator.ui.traymenu.TrayMenuComponent;
|
||||
import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
|
||||
@@ -32,7 +33,7 @@ import javafx.stage.Stage;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class})
|
||||
@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class, RecoveryKeyComponent.class})
|
||||
abstract class MainWindowModule {
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -52,7 +52,7 @@ public class VaultDetailController implements FxController {
|
||||
case LOCKED -> FontAwesome5Icon.LOCK;
|
||||
case PROCESSING -> FontAwesome5Icon.SPINNER;
|
||||
case UNLOCKED -> FontAwesome5Icon.LOCK_OPEN;
|
||||
case NEEDS_MIGRATION, MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
case NEEDS_MIGRATION, MISSING, VAULT_CONFIG_MISSING, ALL_MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
};
|
||||
} else {
|
||||
return FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
|
||||
@MainWindowScoped
|
||||
public class VaultDetailMissingVaultController implements FxController {
|
||||
@@ -23,6 +29,7 @@ public class VaultDetailMissingVaultController implements FxController {
|
||||
private final ObservableList<Vault> vaults;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final Stage window;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
@Inject
|
||||
@@ -30,11 +37,13 @@ public class VaultDetailMissingVaultController implements FxController {
|
||||
ObservableList<Vault> vaults, //
|
||||
ResourceBundle resourceBundle, //
|
||||
@MainWindow Stage window, //
|
||||
Dialogs dialogs) {
|
||||
Dialogs dialogs, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow) {
|
||||
this.vault = vault;
|
||||
this.vaults = vaults;
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.window = window;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.dialogs = dialogs;
|
||||
}
|
||||
|
||||
@@ -48,6 +57,19 @@ public class VaultDetailMissingVaultController implements FxController {
|
||||
dialogs.prepareRemoveVaultDialog(window, vault.get(), vaults).build().showAndWait();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void restoreVaultConfig() {
|
||||
if(KeyLoadingStrategy.isHubVault(vault.get().getVaultSettings().lastKnownKeyLoader.get())){
|
||||
dialogs.prepareContactHubVaultOwner(window).build().showAndWait();
|
||||
}
|
||||
else if(Files.exists(vault.get().getPath().resolve(MASTERKEY_FILENAME))){
|
||||
recoveryKeyWindow.create(vault.get(), window, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)).showOnboardingDialogWindow();
|
||||
}
|
||||
else {
|
||||
recoveryKeyWindow.create(vault.get(), window, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)).showOnboardingDialogWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void changeLocation() {
|
||||
// copied from ChooseExistingVaultController class
|
||||
|
||||
@@ -55,7 +55,7 @@ public class VaultListCellController implements FxController {
|
||||
case LOCKED -> FontAwesome5Icon.LOCK;
|
||||
case PROCESSING -> FontAwesome5Icon.SPINNER;
|
||||
case UNLOCKED -> FontAwesome5Icon.LOCK_OPEN;
|
||||
case NEEDS_MIGRATION, MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
case NEEDS_MIGRATION, MISSING, VAULT_CONFIG_MISSING, ALL_MISSING, ERROR -> FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
};
|
||||
} else {
|
||||
return FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
|
||||
@@ -20,11 +20,13 @@ import javafx.stage.Stage;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ALL_MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.NEEDS_MIGRATION;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.UNLOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.VAULT_CONFIG_MISSING;
|
||||
|
||||
@MainWindowScoped
|
||||
public class VaultListContextMenuController implements FxController {
|
||||
@@ -63,7 +65,7 @@ public class VaultListContextMenuController implements FxController {
|
||||
|
||||
this.selectedVaultState = selectedVault.flatMap(Vault::stateProperty).orElse(null);
|
||||
this.selectedVaultPassphraseStored = selectedVault.map(this::isPasswordStored).orElse(false);
|
||||
this.selectedVaultRemovable = selectedVaultState.map(EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION)::contains).orElse(false);
|
||||
this.selectedVaultRemovable = selectedVaultState.map(EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION, ALL_MISSING, VAULT_CONFIG_MISSING)::contains).orElse(false);
|
||||
this.selectedVaultUnlockable = selectedVaultState.map(LOCKED::equals).orElse(false);
|
||||
this.selectedVaultLockable = selectedVaultState.map(UNLOCKED::equals).orElse(false);
|
||||
}
|
||||
@@ -102,6 +104,12 @@ public class VaultListContextMenuController implements FxController {
|
||||
vaultService.reveal(vault);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickShareVault() {
|
||||
var vault = Objects.requireNonNull(selectedVault.get());
|
||||
appWindows.showShareVaultWindow(vault);
|
||||
}
|
||||
|
||||
// Getter and Setter
|
||||
|
||||
public ObservableValue<Boolean> selectedVaultUnlockableProperty() {
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package org.cryptomator.ui.mainwindow;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.recovery.VaultPreparator;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultComponent;
|
||||
import org.cryptomator.common.vaults.VaultListManager;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptofs.DirStructure;
|
||||
import org.cryptomator.cryptofs.common.Constants;
|
||||
import org.cryptomator.integrations.mount.MountService;
|
||||
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.VaultService;
|
||||
@@ -13,6 +18,7 @@ import org.cryptomator.ui.dialogs.Dialogs;
|
||||
import org.cryptomator.ui.fxapp.FxFSEventList;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
|
||||
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -22,6 +28,7 @@ import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
@@ -37,11 +44,14 @@ import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.Stage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
@@ -50,10 +60,12 @@ import java.util.stream.Collectors;
|
||||
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_EXT;
|
||||
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ALL_MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.MISSING;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.NEEDS_MIGRATION;
|
||||
import static org.cryptomator.common.vaults.VaultState.Value.VAULT_CONFIG_MISSING;
|
||||
|
||||
@MainWindowScoped
|
||||
public class VaultListController implements FxController {
|
||||
@@ -75,6 +87,10 @@ public class VaultListController implements FxController {
|
||||
private final ObservableValue<Double> cellSize;
|
||||
private final Dialogs dialogs;
|
||||
|
||||
private final VaultComponent.Factory vaultComponentFactory;
|
||||
private final RecoveryKeyComponent.Factory recoveryKeyWindow;
|
||||
private final List<MountService> mountServices;
|
||||
|
||||
public ListView<Vault> vaultList;
|
||||
public StackPane root;
|
||||
@FXML
|
||||
@@ -94,6 +110,9 @@ public class VaultListController implements FxController {
|
||||
FxApplicationWindows appWindows, //
|
||||
Settings settings, //
|
||||
Dialogs dialogs, //
|
||||
RecoveryKeyComponent.Factory recoveryKeyWindow, //
|
||||
VaultComponent.Factory vaultComponentFactory, //
|
||||
List<MountService> mountServices, //
|
||||
FxFSEventList fxFSEventList) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.vaults = vaults;
|
||||
@@ -105,6 +124,9 @@ public class VaultListController implements FxController {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.appWindows = appWindows;
|
||||
this.dialogs = dialogs;
|
||||
this.recoveryKeyWindow = recoveryKeyWindow;
|
||||
this.vaultComponentFactory = vaultComponentFactory;
|
||||
this.mountServices = mountServices;
|
||||
|
||||
this.emptyVaultList = Bindings.isEmpty(vaults);
|
||||
this.unreadEvents = fxFSEventList.unreadEventsProperty();
|
||||
@@ -204,6 +226,26 @@ public class VaultListController implements FxController {
|
||||
VaultListManager.redetermineVaultState(newValue);
|
||||
}
|
||||
|
||||
private Optional<Path> chooseValidVaultDirectory() {
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
File selectedDirectory;
|
||||
|
||||
do {
|
||||
selectedDirectory = directoryChooser.showDialog(mainWindow);
|
||||
if (selectedDirectory == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Path selectedPath = selectedDirectory.toPath();
|
||||
if (!Files.isDirectory(selectedPath.resolve(Constants.DATA_DIR_NAME))) {
|
||||
dialogs.prepareNoDDirectorySelectedDialog(mainWindow).build().showAndWait();
|
||||
selectedDirectory = null;
|
||||
}
|
||||
} while (selectedDirectory == null);
|
||||
|
||||
return Optional.of(selectedDirectory.toPath());
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickAddNewVault() {
|
||||
addVaultWizard.build().showAddNewVaultWizard(resourceBundle);
|
||||
@@ -214,9 +256,40 @@ public class VaultListController implements FxController {
|
||||
addVaultWizard.build().showAddExistingVaultWizard(resourceBundle);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickRecoverExistingVault() {
|
||||
Optional<Path> selectedDirectory = chooseValidVaultDirectory();
|
||||
if (selectedDirectory.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Path path = selectedDirectory.get();
|
||||
Optional<Vault> matchingVaultListEntry = vaultListManager.get(path);
|
||||
if (matchingVaultListEntry.isPresent()) {
|
||||
dialogs.prepareRecoveryVaultAlreadyExists(mainWindow, matchingVaultListEntry.get().getDisplayName()) //
|
||||
.setOkAction(Stage::close) //
|
||||
.build().showAndWait();
|
||||
return;
|
||||
}
|
||||
|
||||
Vault preparedVault = VaultPreparator.prepareVault(path, vaultComponentFactory, mountServices, resourceBundle);
|
||||
VaultListManager.redetermineVaultState(preparedVault);
|
||||
|
||||
switch (preparedVault.getState()) {
|
||||
case VAULT_CONFIG_MISSING -> recoveryKeyWindow.create(preparedVault, mainWindow, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_VAULT_CONFIG)).showOnboardingDialogWindow();
|
||||
case ALL_MISSING -> recoveryKeyWindow.create(preparedVault, mainWindow, new SimpleObjectProperty<>(RecoveryActionType.RESTORE_ALL)).showOnboardingDialogWindow();
|
||||
case LOCKED, NEEDS_MIGRATION -> {
|
||||
vaultListManager.addVault(preparedVault);
|
||||
dialogs.prepareRecoveryVaultAdded(mainWindow, preparedVault.getDisplayName()).setOkAction(Stage::close).build().showAndWait();
|
||||
}
|
||||
default -> LOG.warn("Unhandled vault state during recovery: {}", preparedVault.getState());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void pressedShortcutToRemoveVault() {
|
||||
final var vault = selectedVault.get();
|
||||
if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION).contains(vault.getState())) {
|
||||
if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION, ALL_MISSING, VAULT_CONFIG_MISSING).contains(vault.getState())) {
|
||||
dialogs.prepareRemoveVaultDialog(mainWindow, vault, vaults).build().showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class GeneralPreferencesController implements FxController {
|
||||
var keychainSettingsConverter = new ServiceToSettingsConverter<>(keychainAccessProviders);
|
||||
keychainBackendChoiceBox.getItems().addAll(keychainAccessProviders);
|
||||
keychainBackendChoiceBox.setValue(keychainSettingsConverter.fromString(settings.keychainProvider.get()));
|
||||
keychainBackendChoiceBox.setConverter(new KeychainProviderDisplayNameConverter());
|
||||
keychainBackendChoiceBox.setConverter(new NamedServiceConverter<>());
|
||||
Bindings.bindBidirectional(settings.keychainProvider, keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter);
|
||||
useKeychainCheckbox.selectedProperty().bindBidirectional(settings.useKeychain);
|
||||
keychainBackendChoiceBox.disableProperty().bind(useKeychainCheckbox.selectedProperty().not());
|
||||
@@ -106,13 +106,13 @@ public class GeneralPreferencesController implements FxController {
|
||||
var idsAndNames = settings.directories.stream().collect(Collectors.toMap(vs -> vs.id, vs -> vs.displayName.getValue()));
|
||||
if (!idsAndNames.isEmpty()) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Migrating keychain entries {} from {} to {}", idsAndNames.keySet(), oldProvider.displayName(), newProvider.displayName());
|
||||
LOG.debug("Migrating keychain entries {} from {} to {}", idsAndNames.keySet(), oldProvider.getName(), newProvider.getName());
|
||||
}
|
||||
keychainMigrations = keychainMigrations.thenRunAsync(() -> {
|
||||
try {
|
||||
KeychainManager.migrate(oldProvider, newProvider, idsAndNames);
|
||||
} catch (KeychainAccessException e) {
|
||||
LOG.warn("Failed to migrate all entries from {} to {}", oldProvider.displayName(), newProvider.displayName(), e);
|
||||
LOG.warn("Failed to migrate all entries from {} to {}", oldProvider.getName(), newProvider.getName(), e);
|
||||
}
|
||||
}, backgroundExecutor);
|
||||
}
|
||||
@@ -151,25 +151,6 @@ public class GeneralPreferencesController implements FxController {
|
||||
}
|
||||
|
||||
/* Helper classes */
|
||||
|
||||
private static class KeychainProviderDisplayNameConverter extends StringConverter<KeychainAccessProvider> {
|
||||
|
||||
@Override
|
||||
public String toString(KeychainAccessProvider provider) {
|
||||
if (provider == null) {
|
||||
return null;
|
||||
} else {
|
||||
return provider.displayName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeychainAccessProvider fromString(String string) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class NamedServiceConverter<T extends NamedServiceProvider> extends StringConverter<T> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,11 +3,13 @@ package org.cryptomator.ui.recoverykey;
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Lazy;
|
||||
import dagger.Subcomponent;
|
||||
import org.cryptomator.common.recovery.RecoveryActionType;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@@ -24,6 +26,9 @@ public interface RecoveryKeyComponent {
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER)
|
||||
Lazy<Scene> recoverScene();
|
||||
|
||||
@FxmlScene(FxmlFile.RECOVERYKEY_ONBOARDING)
|
||||
Lazy<Scene> recoverOnboardingScene();
|
||||
|
||||
default void showRecoveryKeyCreationWindow() {
|
||||
Stage stage = window();
|
||||
stage.setScene(creationScene().get());
|
||||
@@ -38,11 +43,19 @@ public interface RecoveryKeyComponent {
|
||||
stage.show();
|
||||
}
|
||||
|
||||
default void showOnboardingDialogWindow() {
|
||||
Stage stage = window();
|
||||
stage.setScene(recoverOnboardingScene().get());
|
||||
stage.sizeToScene();
|
||||
stage.show();
|
||||
}
|
||||
|
||||
@Subcomponent.Factory
|
||||
interface Factory {
|
||||
|
||||
RecoveryKeyComponent create(@BindsInstance @RecoveryKeyWindow Vault vault, @BindsInstance @Named("keyRecoveryOwner") Stage owner);
|
||||
RecoveryKeyComponent create(@BindsInstance @RecoveryKeyWindow Vault vault, //
|
||||
@BindsInstance @Named("keyRecoveryOwner") Stage owner, //
|
||||
@BindsInstance @Named("recoverType") ObjectProperty<RecoveryActionType> recoverType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user