diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
index ad4099a..6e50db1 100644
--- a/.github/workflows/changelog.yml
+++ b/.github/workflows/changelog.yml
@@ -2,7 +2,7 @@ name: Changelog Generation
on:
release:
- types: [published, released]
+ types: [published]
workflow_dispatch:
jobs:
@@ -16,6 +16,7 @@ jobs:
- uses: rhysd/changelog-from-release/action@v3
with:
file: CHANGELOG.md
+ pull_request: true
github_token: ${{ secrets.GITHUB_TOKEN }}
commit_summary_template: 'update changelog for %s changes'
args: -l 2
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9e60fe6..c1426ba 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -45,5 +45,23 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
+ - name: Run lint check
+ run: bash ./gradlew lint
+
+ - name: Upload lint result
+ uses: actions/upload-artifact@v4
+ with:
+ name: lint-results-debug
+ path: BackupApp/build/reports/lint-results-debug.html
+
- name: Build the app
run: bash ./gradlew build --stacktrace
+
+ - name: Build debug apk
+ run: bash ./gradlew assembleDebug
+
+ - name: Upload debug apk
+ uses: actions/upload-artifact@v4
+ with:
+ name: debug-apk
+ path: BackupApp/build/outputs/apk/debug/*.apk
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index aa9c63f..e9d0871 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,37 @@
+# Built application files
+/*/build/
+build/*
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Gradle generated files
+.gradle/
+
+# Signing files
+.signing/
+
+# User-specific configurations
+.idea/*
*.iml
-.gradle
-/local.properties
-.idea/
-misc.xml
+
+# OS-specific files
.DS_Store
-/build
-/captures
-.externalNativeBuild
-.cxx
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# Documents
+*.pdf
+*.doc
+*.docx
+*.odt
+
+# APKs
+*.apk
/pfa.properties
+/.idea/
+/BackupApp/release
diff --git a/.gitmodules b/.gitmodules
index 3c35039..cdb3b42 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "BackupAPI"]
path = BackupAPI
url = https://github.com/SecUSo/privacy-friendly-backup-api.git
+[submodule "openpgp-api"]
+ path = openpgp-api
+ url = https://github.com/open-keychain/openpgp-api
diff --git a/BackupApp/build.gradle b/BackupApp/build.gradle
index e10153a..508f9b9 100644
--- a/BackupApp/build.gradle
+++ b/BackupApp/build.gradle
@@ -24,17 +24,17 @@ android {
applicationId "org.secuso.privacyfriendlybackup"
minSdkVersion 21
targetSdkVersion 34
- versionCode 5
- versionName "1.3.1"
+ versionCode 6
+ versionName "1.3.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments += [
- "room.schemaLocation": "$projectDir/schemas".toString(),
- "room.incremental":"true",
- "room.expandProjection":"true"
+ "room.schemaLocation" : "$projectDir/schemas".toString(),
+ "room.incremental" : "true",
+ "room.expandProjection": "true"
]
}
}
@@ -106,10 +106,10 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
// OpenPGP API
- implementation 'org.sufficientlysecure:openpgp-api:12.0'
-
+ //implementation 'org.sufficientlysecure:openpgp-api:12.0'
+ implementation(project(':openpgp-api'))
// WorkManager
- def work_version = "2.9.0"
+ def work_version = "2.9.1"
implementation "androidx.work:work-runtime:$work_version"
implementation "androidx.work:work-runtime-ktx:$work_version"
androidTestImplementation "androidx.work:work-testing:$work_version"
@@ -123,10 +123,10 @@ dependencies {
implementation "androidx.room:room-ktx:$roomVersion"
// Lifecycle
- implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3"
- implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.3'
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6"
+ implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.6'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
- implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.3'
+ implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.6'
// Preferences
def preference_version = "1.2.1"
@@ -136,7 +136,7 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
// JSON Viewer
- implementation 'com.yuyh.json:jsonviewer:1.0.6'
+ implementation 'com.github.smuyyh:JsonViewer:1.0.7'
// Retrofit for Google Drive Test
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
diff --git a/BackupApp/src/androidTest/java/org/secuso/privacyfriendlybackup/ConnectToPFATest.kt b/BackupApp/src/androidTest/java/org/secuso/privacyfriendlybackup/ConnectToPFATest.kt
deleted file mode 100644
index ad3cae4..0000000
--- a/BackupApp/src/androidTest/java/org/secuso/privacyfriendlybackup/ConnectToPFATest.kt
+++ /dev/null
@@ -1,173 +0,0 @@
-package org.secuso.privacyfriendlybackup
-
-import android.util.Log
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.work.Configuration
-import androidx.work.WorkManager
-import androidx.work.testing.SynchronousExecutor
-import androidx.work.testing.WorkManagerTestInitHelper
-
-import org.junit.Test
-import org.junit.runner.RunWith
-
-import org.junit.Assert.*
-import org.junit.Before
-import org.junit.BeforeClass
-import org.secuso.privacyfriendlybackup.api.IPFAService
-import org.secuso.privacyfriendlybackup.api.common.PfaApi.ACTION_CONNECT
-import org.secuso.privacyfriendlybackup.api.common.PfaError
-import org.secuso.privacyfriendlybackup.backupapi.PfaApiConnection
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-@RunWith(AndroidJUnit4::class)
-class ConnectToPFATest {
- val TAG = "PFABackup"
-
- val appContext = InstrumentationRegistry.getInstrumentation().targetContext
-
- @Before
- fun setUp() {
- val config = Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).build()
- WorkManagerTestInitHelper.initializeTestWorkManager(appContext, config)
- WorkManager.getInstance(appContext)
- }
-
- @Test
- fun useAppContext() {
- // Context of the app under test.
- assertEquals("org.secuso.privacyfriendlybackup", appContext.packageName)
- }
-
- @Test
- fun bindToService() {
- var testEnd = false
- var connection : PfaApiConnection? = null
- var valid = false
-
- val listener = object : PfaApiConnection.IPfaApiListener {
- override fun onBound(service: IPFAService?) {
- Log.d("$TAG ConnectToPFATest","Bound service successfully.")
- connection!!.send(ACTION_CONNECT)
- }
- override fun onError(error: PfaError) {
- Log.d("$TAG ConnectToPFATest","Error: ${error.errorMessage}")
- testEnd = true
- }
- override fun onSuccess() {
- Log.d("$TAG ConnectToPFATest","Command sent successfully.")
- connection!!.disconnect()
- valid = true
- testEnd = true
- }
- override fun onDisconnected() {
- Log.d("$TAG ConnectToPFATest","Disconnected")
- testEnd = true
- }
- }
-
- connection = PfaApiConnection(appContext, "org.secuso.example", listener)
- connection.connect()
-
- try {
- do {
- Thread.sleep(1000)
- } while(!testEnd)
- } catch (e : InterruptedException) {
- if(connection.isBound()) {
- connection.disconnect()
- }
- }
- assertTrue(valid)
- }
-
- @Test
- fun bindToServiceUnknownCommand() {
- var testEnd = false
- var connection : PfaApiConnection? = null
- var valid = false
-
- val listener = object : PfaApiConnection.IPfaApiListener {
- override fun onBound(service: IPFAService?) {
- Log.d("$TAG ConnectToPFATest","Bound service successfully.")
- connection!!.send("UNKNOWN")
- }
- override fun onError(error: PfaError) {
- Log.d("$TAG ConnectToPFATest","Error: ${error.errorMessage}")
- assertEquals(error.code, PfaError.PfaErrorCode.ACTION_ERROR)
- valid = true
- testEnd = true
- }
- override fun onSuccess() {
- Log.d("$TAG ConnectToPFATest","Command sent successfully.")
- connection!!.disconnect()
- testEnd = true
- }
- override fun onDisconnected() {
- Log.d("$TAG ConnectToPFATest","Disconnected")
- testEnd = true
- }
- }
-
- connection = PfaApiConnection(appContext, "org.secuso.example", listener)
- connection.connect()
-
- try {
- do {
- Thread.sleep(1000)
- } while(!testEnd)
- } catch (e : InterruptedException) {
- if(connection.isBound()) {
- connection.disconnect()
- }
- }
- assertTrue(valid)
- }
-
- @Test
- fun bindToServiceAPIUnsupported() {
- var testEnd = false
- var connection : PfaApiConnection? = null
- var valid = false
-
- val listener = object : PfaApiConnection.IPfaApiListener {
- override fun onBound(service: IPFAService?) {
- println("Bound service successfully.")
- connection!!.send(ACTION_CONNECT)
- }
- override fun onError(error: PfaError) {
- println("Error: ${error.errorMessage}")
- assertEquals(error.code, PfaError.PfaErrorCode.API_VERSION_UNSUPPORTED)
- valid = true
- testEnd = true
- }
- override fun onSuccess() {
- println("Command sent successfully.")
- connection!!.disconnect()
- testEnd = true
- }
- override fun onDisconnected() {
- println("Disconnected")
- testEnd = true
- }
- }
-
- connection = PfaApiConnection(appContext, "org.secuso.example", listener, 0)
- connection.connect()
-
- try {
- do {
- Thread.sleep(1000)
- } while(!testEnd)
- } catch (e : InterruptedException) {
- if(connection.isBound()) {
- connection.disconnect()
- }
- }
- assertTrue(valid)
- }
-}
\ No newline at end of file
diff --git a/BackupApp/src/main/AndroidManifest.xml b/BackupApp/src/main/AndroidManifest.xml
index 9900b86..61df407 100644
--- a/BackupApp/src/main/AndroidManifest.xml
+++ b/BackupApp/src/main/AndroidManifest.xml
@@ -27,14 +27,7 @@
-
-
-
+ tools:node="remove" />
+ if (newValue.equals(true)) {
+ ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.POST_NOTIFICATIONS), REQUEST_CODE_POST_NOTIFICATION)
+ }
+ return@setOnPreferenceChangeListener true
+ }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionActivity.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionActivity.kt
index 034c526..44aab13 100644
--- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionActivity.kt
+++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionActivity.kt
@@ -1,5 +1,6 @@
package org.secuso.privacyfriendlybackup.ui.inspection
+import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
@@ -53,6 +54,7 @@ class DataInspectionActivity : AppCompatActivity() {
}
}
+ @SuppressLint("MissingSuperCall")
override fun onBackPressed() {
finish()
}
diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionViewModel.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionViewModel.kt
index d6d67f5..3bb3d82 100644
--- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionViewModel.kt
+++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionViewModel.kt
@@ -5,7 +5,11 @@ import android.net.Uri
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
-import androidx.lifecycle.*
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager
import androidx.work.ExistingWorkPolicy
import androidx.work.WorkInfo
@@ -26,7 +30,6 @@ import org.secuso.privacyfriendlybackup.data.room.model.BackupJob
import org.secuso.privacyfriendlybackup.data.room.model.enums.BackupJobAction
import org.secuso.privacyfriendlybackup.data.room.model.enums.StorageType
import org.secuso.privacyfriendlybackup.worker.BackupJobManagerWorker
-import java.util.*
class DataInspectionViewModel(app : Application) : AndroidViewModel(app) {
val TAG : String = "DataInspectionViewModel"
@@ -147,9 +150,7 @@ class DataInspectionViewModel(app : Application) : AndroidViewModel(app) {
}
private fun setDecryptionMetaData(decryptionMetaData: DecryptionMetaData?) {
- decryptionMetaData ?: return
-
- decryptionMetaLiveData.postValue(decryptionMetaData)
+ decryptionMetaData?.let { decryptionMetaLiveData.postValue(it) }
}
private fun getUnencryptedFilename(filename: String) =
diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/worker/EncryptionWorker.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/worker/EncryptionWorker.kt
index 9f6934b..78a96f9 100644
--- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/worker/EncryptionWorker.kt
+++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/worker/EncryptionWorker.kt
@@ -1,9 +1,12 @@
package org.secuso.privacyfriendlybackup.worker
+import android.Manifest
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
import android.util.Log
+import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
@@ -387,7 +390,9 @@ class EncryptionWorker(val context: Context, params: WorkerParameters) : Corouti
}.build()
with(NotificationManagerCompat.from(context)) {
- notify(NOTIFICATION_ID, notification)
+ if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
+ notify(NOTIFICATION_ID, notification)
+ }
}
// end this worker and wait for user interaction
diff --git a/BackupApp/src/main/res/values-de/strings.xml b/BackupApp/src/main/res/values-de/strings.xml
index 1fd6454..c0aa2df 100644
--- a/BackupApp/src/main/res/values-de/strings.xml
+++ b/BackupApp/src/main/res/values-de/strings.xml
@@ -3,7 +3,7 @@
Backup
Privacy Friendly Backup
Standard
- Standard Benachrichtigungskanal
+ Standard-Benachrichtigungskanal
Suche
Alle markieren
Sortieren
@@ -11,7 +11,7 @@
Backup Übersicht
Verfügbare Apps
Verschlüsselungsoptionen
- Backup Einstellungen
+ Backup-Einstellungen
Hilfe
Über
Verschlüsselungsoptionen
@@ -20,7 +20,7 @@
Schlüssel auswählen
Verschlüsselung ist aktiviert
Daten werden unverschlüsselt gespeichert
- Tippen um Schlüssel auszuwählen
+ Tippen, um Schlüssel auszuwählen
Krypto-Anbieter auswählen
Verschlüsselungsoptionen
Sind Sie sicher, dass Sie die markierten Backups löschen möchten? Diese Operation ist permanent und kann nicht wieder rückgängig gemacht werden.
@@ -50,18 +50,18 @@
Automatische Backups
Externer Speicher
Wiederherstellen
- Fehler: Id ist nicht korrekt
+ Fehler: ID ist nicht korrekt
Exportieren
Unbekannt
Lade…
Entschlüssle…
Unbekannter Fehler.
- Ein unbekannter entschlüsselungsfehler ist aufgetreten. Bitte überprüfen Sie ob in den Verschlüsselungsoptionen der korrekte Krypto-Anbieter ausgewählt ist und der benötigte Schlüssel noch verfügbar ist.
+ Ein unbekannter Entschlüsselungsfehler ist aufgetreten. Bitte überprüfen Sie, ob in den Verschlüsselungsoptionen der korrekte Krypto-Anbieter ausgewählt ist und der benötigte Schlüssel noch verfügbar ist.
Fertig
Backup importieren
Backup importieren
Exportieren
- Datenimport Abgeschlossen
+ Datenimport abgeschlossen
Das Backup wurde erfolgreich importiert.\n App: %s \n Datum: %s
Okay
Okay
@@ -77,7 +77,7 @@
Möchten Sie dieses Backup exportieren?
Backup verschlüsseln
Durch unverschlüsseltes Speichern des Backups in den externen Speicher sind ihre Daten ungeschützt.
- Dieses Backup scheint beschädigt zu sein. Versuchen Sie ein neues Backup zu erstellen oder versuchen Sie es erneut zu importieren.
+ Dieses Backup scheint beschädigt zu sein. Versuchen Sie, ein neues Backup zu erstellen, oder versuchen Sie, es erneut zu importieren.
Ja
Nein
Importieren des Backups
@@ -88,27 +88,27 @@
Autoren:
und Mitwirkende
In Zusammenarbeit mit
- Diese App gehört zur Gruppe der Privacy Friendly Apps entwickelt von der Forschungsgruppe SECUSO am Karlsruher Institut für Technologie (KIT). Quelltext lizenziert unter GPLv3. Bilder copyright SECUSO und Google Inc.
+ Diese App gehört zur Gruppe der Privacy Friendly Apps, entwickelt von der Forschungsgruppe SECUSO am Karlsruher Institut für Technologie (KIT). Quelltext lizenziert unter GPLv3. Bilder copyright SECUSO und Google Inc.
Mehr Informationen können gefunden werden auf:
Signiert: %s
- Schlüssel ID: %s
+ Schlüssel-ID: %s
Keine Signatur
Gültig
Ungültig
Unsicher
Abgelaufen
- Wiederrufen
+ Widerrufen
Unbestätigt
Schlüssel fehlt
Es existieren zur Zeit noch keine Backups. Erstellen Sie neue Backups über die Applikationsübersicht oder importieren Sie existierende Backups.
- Zur Zeit sind keine Applikationen installiert, welche das Backup Protokoll unterstützen. Stellen Sie sicher, dass die Privacy Friendly Apps aktualisiert oder passende Apps installiert sind.
+ Zurzeit sind keine Applikationen installiert, welche das Backup-Protokoll unterstützen. Stellen Sie sicher, dass die Privacy Friendly Apps aktualisiert oder passende Apps installiert sind.
Aufmerksamkeit erforderlich
- Einstellungen für die Verschlüsselung im Hintergrund fehlen. Tippen Sie auf diese Benachrichtigung um fortzufahren.
- Was ist die Privacy Friendly Backup App?
+ Einstellungen für die Verschlüsselung im Hintergrund fehlen. Tippen Sie auf diese Benachrichtigung, um fortzufahren.
+ Was ist die Privacy-Friendly-Backup-App?
Wie funktioniert die Verschlüsselung?
- Die Privacy Friendly Backup App unterstützt Anwender beim Erstellen von Backups anderer Privacy Friendly Apps. Die Apps kommunizieren untereinander, senden und empfangen Daten, um App-Daten zu sichern und wiederherzustellen.
- Die Verschlüsselung erfolgt über einen externen Kryptographie-Anbieter. Für weitere Informationen können Sie sich die Openpgp-api ansehen, die von dieser Anwendung verwendet wird.
- Um die Verschlüsselung nutzen zu können, müssen Sie eine Kryptoanbieter-Anwendung installieren. Wir empfehlen die OpenKeyChain-Anwendung, da sie quelloffen ist und sowohl im Google Play Store als auch im f-Droid-Store verfügbar ist.
+ Die Privacy-Friendly-Backup-App unterstützt Anwender beim Erstellen von Backups anderer Privacy Friendly Apps. Die Apps kommunizieren untereinander, senden und empfangen Daten, um App-Daten zu sichern und wiederherzustellen.
+ Die Verschlüsselung erfolgt über einen externen Kryptographie-Anbieter. Für weitere Informationen können Sie sich die OpenPGP-API ansehen, die von dieser Anwendung verwendet wird.
+ Um die Verschlüsselung nutzen zu können, müssen Sie eine Kryptoanbieter-Anwendung installieren. Wir empfehlen die OpenKeyChain-Anwendung, da sie quelloffen ist und sowohl im Google Play Store als auch im F-Droid-Store verfügbar ist.
Wie viele und welche Apps werden zur Zeit unterstützt?
- Wir arbeiten stetig daran neue Apps zu unterstützten. Zur Zeit wird nur die Notizen App unterstützt.
+ Wir arbeiten stetig daran neue Apps zu unterstützen. Zurzeit wird nur die Notizen-App unterstützt.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 7e98f85..5cae6c7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,12 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = "1.9.10"
+ ext.kotlin_version = "1.9.20"
repositories {
google()
- jcenter()
+ mavenCentral()
+ maven { url 'https://jitpack.io' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.1.4'
+ classpath 'com.android.tools.build:gradle:8.6.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
@@ -22,10 +23,11 @@ plugins {
allprojects {
repositories {
google()
- jcenter()
+ mavenCentral()
+ maven { url 'https://jitpack.io' }
}
}
-task clean(type: Delete) {
+tasks.register('clean', Delete) {
delete rootProject.buildDir
}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 510e968..ee70b1d 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
diff --git a/openpgp-api b/openpgp-api
new file mode 160000
index 0000000..f91db6b
--- /dev/null
+++ b/openpgp-api
@@ -0,0 +1 @@
+Subproject commit f91db6be300e8a777c49bbcb8ad0b3a9a583ef08
diff --git a/settings.gradle b/settings.gradle
index 13d6585..4650b51 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -2,4 +2,7 @@ include ':BackupApp'
rootProject.name = "Backup"
include ':BackupAPI'
-project(':BackupAPI').projectDir = new File('BackupAPI/BackupAPI')
\ No newline at end of file
+project(':BackupAPI').projectDir = new File('BackupAPI/BackupAPI')
+
+include ':openpgp-api'
+project(':openpgp-api').projectDir = new File('openpgp-api/openpgp-api')
\ No newline at end of file