Skip to content

Commit

Permalink
Merge branch 'release/1.11.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
SailReal committed Feb 19, 2025
2 parents 0af633c + ffee91b commit e4775e3
Show file tree
Hide file tree
Showing 34 changed files with 441 additions and 234 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Cryptomator for Android is currently available in the following distribution ch
2. [Using Cryptomator's Website](https://cryptomator.org/android/)
3. [Using Cryptomator's F-Droid Repository](https://cryptomator.org/android/)
4. [Using F-Droid's Main Repository](https://f-droid.org/en/packages/org.cryptomator.lite)
5. Building from source using Gradle (instructions below)
5. [Using Accrescent](https://accrescent.app/app/org.cryptomator)
6. Building from source using Gradle (instructions below)

## Building

Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def getVersionCode = { ->
allprojects {
ext {
androidApplicationId = 'org.cryptomator'
androidVersionCode = getVersionCode()
androidVersionName = '1.11.0'
androidVersionCode = 2991 // must be getVersionCode(). only at release tag set the actual value
androidVersionName = '1.11.1'
}
repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ private Interceptor httpLoggingInterceptor(Context context) {
public String getVaultKeyJwe(UnverifiedHubVaultConfig unverifiedHubVaultConfig, String accessToken) throws BackendException {
var request = new Request.Builder().get() //
.header("Authorization", "Bearer " + accessToken) //
.header("deviceId", getHubDeviceCryptor().getDeviceId()) //
.url(unverifiedHubVaultConfig.getApiBaseUrl() + "vaults/" + unverifiedHubVaultConfig.vaultId() + "/access-token") //
.build();
try (var response = getHttpClient().newCall(request).execute()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.cryptomator.domain.exception;

public class IllegalFileNameException extends BackendException {

public IllegalFileNameException() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.cryptomator.domain.usecases;

import android.content.Context;
import android.net.Uri;

import org.cryptomator.domain.exception.BackendException;
import org.cryptomator.domain.exception.FatalBackendException;
import org.cryptomator.generator.Parameter;
import org.cryptomator.generator.UseCase;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@UseCase
public class CalculateFileHash {

private final Context context;
private final Uri uri;

CalculateFileHash(final Context context, @Parameter Uri uri) {
this.context = context;
this.uri = uri;
}

public byte[] execute() throws BackendException, FileNotFoundException {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
try (InputStream inputStream = context.getContentResolver().openInputStream(uri); //
DigestInputStream dis = new DigestInputStream(inputStream, digest)) {
byte[] buffer = new byte[4096];
while (dis.read(buffer) != -1) {
}
return digest.digest();
} catch (IOException e) {
throw new FatalBackendException(e);
}
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.cryptomator.domain.usecases;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.provider.DocumentsContract;

import org.cryptomator.domain.CloudFile;
import org.cryptomator.domain.exception.BackendException;
import org.cryptomator.domain.exception.FatalBackendException;
import org.cryptomator.domain.exception.IllegalFileNameException;
import org.cryptomator.domain.exception.NoSuchCloudFileException;
import org.cryptomator.generator.Parameter;
import org.cryptomator.generator.UseCase;
import org.cryptomator.util.file.MimeType;
import org.cryptomator.util.file.MimeTypes;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

@UseCase
public class PrepareDownloadFiles {

private final Context context;
private final MimeTypes mimeTypes;
private final List<CloudFile> filesToExport;
private final Uri parentUri;
private final ContentResolver contentResolver;
private final CloudNodeRecursiveListing cloudNodeRecursiveListing;

private List<DownloadFile> downloadFiles = new ArrayList<>();

PrepareDownloadFiles(Context context, MimeTypes mimeTypes, @Parameter List<CloudFile> filesToExport, @Parameter Uri parentUri, @Parameter CloudNodeRecursiveListing cloudNodeRecursiveListing) {
this.context = context;
this.mimeTypes = mimeTypes;
this.filesToExport = filesToExport;
this.parentUri = parentUri;
this.contentResolver = context.getContentResolver();
this.cloudNodeRecursiveListing = cloudNodeRecursiveListing;
}

List<DownloadFile> execute() throws BackendException, FileNotFoundException {
downloadFiles = prepareFilesForExport(filesToExport, parentUri);
for (CloudFolderRecursiveListing folderRecursiveListing : cloudNodeRecursiveListing.getFoldersContent()) {
prepareFolderContentForExport(folderRecursiveListing, parentUri);
}
return downloadFiles;
}

private List<DownloadFile> prepareFilesForExport(List<CloudFile> filesToExport, Uri parentUri) throws NoSuchCloudFileException, FileNotFoundException, IllegalFileNameException {
List<DownloadFile> downloadFiles = new ArrayList<>();
for (CloudFile cloudFile : filesToExport) {
DownloadFile downloadFile = createDownloadFile(cloudFile, parentUri);
downloadFiles.add(downloadFile);
}
return downloadFiles;
}

private void prepareFolderContentForExport(CloudFolderRecursiveListing folderRecursiveListing, Uri parentUri) throws FileNotFoundException, NoSuchCloudFileException, IllegalFileNameException {
Uri createdFolder = createFolder(parentUri, folderRecursiveListing.getParent().getName());
if (createdFolder != null) {
downloadFiles.addAll(prepareFilesForExport(folderRecursiveListing.getFiles(), createdFolder));
for (CloudFolderRecursiveListing childFolder : folderRecursiveListing.getFolders()) {
prepareFolderContentForExport(childFolder, createdFolder);
}
} else {
throw new FatalBackendException("Failed to create parent folder for export");
}
}

private Uri createFolder(Uri parentUri, String folderName) throws NoSuchCloudFileException {
try {
return DocumentsContract.createDocument(contentResolver, parentUri, DocumentsContract.Document.MIME_TYPE_DIR, folderName);
} catch (FileNotFoundException e) {
throw new NoSuchCloudFileException("Creating folder failed");
}
}

private DownloadFile createDownloadFile(CloudFile file, Uri documentUri) throws NoSuchCloudFileException, IllegalFileNameException {
try {
return new DownloadFile.Builder().setDownloadFile(file).setDataSink(contentResolver.openOutputStream(createNewDocumentUri(documentUri, file.getName()))).build();
} catch (FileNotFoundException e) {
throw new NoSuchCloudFileException(file.getName());
}
}

private Uri createNewDocumentUri(Uri parentUri, String fileName) throws IllegalFileNameException, NoSuchCloudFileException {
MimeType mimeType = mimeTypes.fromFilename(fileName);
if (mimeType == null) {
mimeType = MimeType.APPLICATION_OCTET_STREAM;
}
try {
Uri documentUri = DocumentsContract.createDocument(context.getContentResolver(), parentUri, mimeType.toString(), fileName);
if (documentUri == null) {
throw new IllegalFileNameException();
}
return documentUri;
} catch (FileNotFoundException e) {
throw new NoSuchCloudFileException(fileName);
}
}

}
3 changes: 2 additions & 1 deletion fastlane/release-notes-de.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- Hub-Unterstützung hinzugefügt
- Cryptomator Hub erhält nun die Geräte-ID während der Tresorschlüsselabfrage
- Potenzieller Absturz beim Öffnen großer Dateien und Exportieren großer Ordner behoben
3 changes: 2 additions & 1 deletion fastlane/release-notes-en.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- Add Hub support
- Cryptomator Hub now receives the Device ID during vault key retrieval
- Fixed potential crash when handling large files and exporting large folders
3 changes: 2 additions & 1 deletion fastlane/release-notes.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<ul>
<li>Add Hub support</li>
<li>Cryptomator Hub now receives the Device ID during vault key retrieval</li>
<li>Fixed potential crash when handling large files and exporting large folders</li>
</ul>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.cryptomator.cryptolib.api.InvalidPassphraseException
import org.cryptomator.domain.di.PerView
import org.cryptomator.domain.exception.CloudAlreadyExistsException
import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException
import org.cryptomator.domain.exception.IllegalFileNameException
import org.cryptomator.domain.exception.NetworkConnectionException
import org.cryptomator.domain.exception.NoSuchBucketException
import org.cryptomator.domain.exception.NoSuchCloudFileException
Expand Down Expand Up @@ -39,7 +40,7 @@ import timber.log.Timber
class ExceptionHandlers @Inject constructor(private val context: Context, defaultExceptionHandler: DefaultExceptionHandler) : Iterable<ExceptionHandler?> {

private val exceptionHandlers: MutableList<ExceptionHandler> = ArrayList()
private val defaultExceptionHandler: ExceptionHandler
private val defaultExceptionHandler: ExceptionHandler = defaultExceptionHandler

private fun setupHandlers() {
staticHandler(AuthenticationException::class.java, R.string.error_authentication_failed)
Expand Down Expand Up @@ -122,7 +123,6 @@ class ExceptionHandlers @Inject constructor(private val context: Context, defaul
}

init {
this.defaultExceptionHandler = defaultExceptionHandler
setupHandlers()
}
}

This file was deleted.

Loading

0 comments on commit e4775e3

Please sign in to comment.