Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0a0c826
Refactor authentication flow to use AppSecurityService
zHd4 Jul 21, 2026
7d32f61
Migrate NotesIntegrationTest to AppSecurityService
zHd4 Jul 22, 2026
8d17ac3
Migrate ActivityBase to AppSecurityService
zHd4 Jul 22, 2026
f28804d
Migrate ExportActivity to AppSecurityService
zHd4 Jul 22, 2026
d74be6f
Migrate FilesListActivity to AppSecurityService
zHd4 Jul 22, 2026
3518cdb
Migrate FileViewerActivityBase to AppSecurityService
zHd4 Jul 22, 2026
fb644cc
Migrate KeyRecoveryActivity to AppSecurityService
zHd4 Jul 22, 2026
088a253
Migrate OpenImageActivity to AppSecurityService
zHd4 Jul 22, 2026
6a62f19
Migrate OpenNoteActivity to AppSecurityService
zHd4 Jul 22, 2026
3500303
Migrate OpenVideoActivity to AppSecurityService
zHd4 Jul 22, 2026
5b0ffc7
Simplify AppSecurityService instantiation in SetupKeyActivity
zHd4 Jul 22, 2026
91812b1
Migrate AppCloseAndroidService to AppSecurityService
zHd4 Jul 22, 2026
94b2c98
Migrate CbcToGcmKeyMigration to AppSecurityService
zHd4 Jul 22, 2026
6e57ad7
Migrate RoomIntegrationMigration to AppSecurityService
zHd4 Jul 22, 2026
458db80
Migrate ImportService to AppSecurityService
zHd4 Jul 22, 2026
cd2fa8b
Migrate ExportAndroidService to AppSecurityService
zHd4 Jul 22, 2026
a0a6ba8
Fix Javadoc of setSecrets method in AppSecurityService
zHd4 Jul 22, 2026
ce9b449
Refactor CryptoManager to replace high-level exceptions with low-leve…
zHd4 Jul 23, 2026
74ee209
Update SECURE_RANDOM initialization in CryptoManagerTest to use defau…
zHd4 Jul 23, 2026
1a7d188
Refactor CryptoManagerTest to use default key size in generateRandomB…
zHd4 Jul 23, 2026
cb1a18d
Add null check for newCryptoSecrets in setSecrets method in AppSecuri…
zHd4 Jul 23, 2026
88210c4
Add null checks to CryptoSecrets destroy and copy methods
zHd4 Jul 23, 2026
a75a22c
Expand validation tests for setSecrets in AppSecurityServiceTest
zHd4 Jul 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: MIT
*/

package app.notesr;
package app.notesr.activity;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
Expand All @@ -20,8 +20,6 @@

import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesGcmCryptor;
import app.notesr.core.security.crypto.CryptoManager;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.data.AppDatabase;
import app.notesr.data.DatabaseProvider;
import app.notesr.core.security.dto.CryptoSecrets;
Expand All @@ -31,6 +29,7 @@
import app.notesr.service.file.FileService;
import app.notesr.service.note.NoteService;
import app.notesr.core.util.FilesUtilsAdapter;
import app.notesr.service.security.AppSecurityService;
import io.bloco.faker.Faker;

import org.junit.Before;
Expand Down Expand Up @@ -58,14 +57,14 @@ public class NotesIntegrationTest {
private Note testNote;

@BeforeClass
public static void beforeAll() throws Exception {
public static void beforeAll() {
context = ApplicationProvider.getApplicationContext();

FilesUtilsAdapter filesUtils = new FilesUtils();
CryptoManager cryptoManager = CryptoManagerProvider.getInstance(context);
var appSecurityService = new AppSecurityService(context);
CryptoSecrets cryptoSecrets = getTestSecrets();

cryptoManager.setSecrets(context, cryptoSecrets);
appSecurityService.setSecrets(cryptoSecrets);

cryptor = new AesGcmCryptor(getSecretKeyFromSecrets(cryptoSecrets));
db = DatabaseProvider.getInstance(context);
Expand Down
10 changes: 6 additions & 4 deletions app/src/main/java/app/notesr/activity/ActivityBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;

import app.notesr.core.security.crypto.CryptoManager;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.service.security.AppSecurityService;

public class ActivityBase extends AppCompatActivity {

private AppSecurityService appSecurityService;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -30,6 +31,8 @@ protected void onCreate(Bundle savedInstanceState) {
int windowFlag = WindowManager.LayoutParams.FLAG_SECURE;
getWindow().setFlags(windowFlag, windowFlag);

appSecurityService = new AppSecurityService(getApplicationContext());

if (requiresSession() && !isSessionActive()) {
restartApp();
}
Expand Down Expand Up @@ -58,8 +61,7 @@ protected boolean requiresSession() {
}

private boolean isSessionActive() {
CryptoManager cryptoManager = CryptoManagerProvider.getInstance(getApplicationContext());
return cryptoManager.isConfigured();
return appSecurityService.isAuthConfigured();
}

private void restartApp() {
Expand Down
17 changes: 8 additions & 9 deletions app/src/main/java/app/notesr/activity/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@
import java.util.function.Supplier;

import app.notesr.R;
import app.notesr.core.security.crypto.CryptoManager;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.service.AndroidServiceBootstrapper;
import app.notesr.service.AndroidServiceRegistry;
import app.notesr.service.lifecycle.AppCloseAndroidService;
import app.notesr.service.lifecycle.AppCloseAndroidServiceStarter;
import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.activity.security.AuthActivity;
import app.notesr.activity.security.KeyRecoveryActivity;
import app.notesr.service.security.AppSecurityService;

public final class MainActivity extends ActivityBase {

Expand All @@ -37,10 +36,10 @@ protected void onCreate(Bundle savedInstanceState) {
new AndroidServiceBootstrapper(serviceRegistry)
.startServicesPreAuth(getApplicationContext());

var cryptoManager = CryptoManagerProvider.getInstance(getApplicationContext());
var appSecurityService = new AppSecurityService(getApplicationContext());
var intentSuppliers = getIntentSuppliers(
getApplicationContext(),
cryptoManager,
appSecurityService,
fsaResolver
);

Expand All @@ -58,22 +57,22 @@ protected boolean requiresSession() {

private List<Supplier<Intent>> getIntentSuppliers(
Context context,
CryptoManager cryptoManager,
AppSecurityService appSecurityService,
FsaResolver fsaResolver
) {
return List.of(
() -> cryptoManager.isBlocked(getApplicationContext())
() -> appSecurityService.isAppBlocked()
? new Intent(context, KeyRecoveryActivity.class)
: null,

() -> !cryptoManager.isKeyExists(getApplicationContext())
() -> !appSecurityService.isKeyExists()
? new Intent(context, StartActivity.class)
: null,

() -> !cryptoManager.isConfigured()
() -> !appSecurityService.isAuthConfigured()
? new Intent(context, AuthActivity.class)
.putExtra(AuthActivity.EXTRA_MODE,
AuthActivity.Mode.AUTHORIZATION.toString())
AuthActivity.Mode.AUTHENTICATION.toString())
: null,

() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@

import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesCryptorFactory;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.core.util.FileExifDataResolver;
import app.notesr.core.util.FilesUtils;
import app.notesr.data.DatabaseProvider;
Expand All @@ -44,6 +44,7 @@
import app.notesr.service.file.FileService;
import app.notesr.activity.note.list.NotesListActivity;
import app.notesr.service.note.NoteService;
import app.notesr.service.security.AppSecurityService;
import app.notesr.util.VersionFetcherImpl;

public final class ExportActivity extends ActivityBase {
Expand Down Expand Up @@ -75,8 +76,8 @@ protected void onCreate(Bundle savedInstanceState) {
var context = getApplicationContext();
var db = DatabaseProvider.getInstance(this);

var secrets = CryptoManagerProvider.getInstance(context).getSecrets();
var cryptor = AesCryptorFactory.createAesGcmCryptor(secrets);
AesCryptor cryptor = AesCryptorFactory.createAesGcmCryptor(
new AppSecurityService(context).getActualSecrets());

noteService = new NoteService(db);
fileService = new FileService(context, db, cryptor, new FilesUtils());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@
import app.notesr.activity.ActivityBase;
import app.notesr.activity.DialogFactory;
import app.notesr.activity.file.viewer.FileViewerActivityBase;
import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesCryptorFactory;
import app.notesr.core.security.exception.DecryptionFailedException;
import app.notesr.data.DatabaseProvider;
import app.notesr.service.file.FileService;
import app.notesr.service.note.NoteService;
import app.notesr.data.model.FileInfo;
import app.notesr.data.model.Note;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.core.util.FilesUtils;
import app.notesr.service.security.AppSecurityService;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -81,8 +82,8 @@ protected void onCreate(Bundle savedInstanceState) {
var context = getApplicationContext();
var db = DatabaseProvider.getInstance(context);

var secrets = CryptoManagerProvider.getInstance(context).getSecrets();
var cryptor = AesCryptorFactory.createAesGcmCryptor(secrets);
AesCryptor cryptor = AesCryptorFactory.createAesGcmCryptor(
new AppSecurityService(context).getActualSecrets());

fileService = new FileService(context, db, cryptor, new FilesUtils());
noteService = new NoteService(db);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@
import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.activity.file.helper.FileIOHelper;
import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesCryptorFactory;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.core.util.FilesUtils;
import app.notesr.data.DatabaseProvider;
import app.notesr.data.model.FileInfo;
import app.notesr.service.file.FileService;
import app.notesr.service.security.AppSecurityService;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -61,8 +62,8 @@ protected void onCreate(Bundle savedInstanceState) {

var context = getApplicationContext();

var secrets = CryptoManagerProvider.getInstance(context).getSecrets();
var cryptor = AesCryptorFactory.createAesGcmCryptor(secrets);
AesCryptor cryptor = AesCryptorFactory.createAesGcmCryptor(
new AppSecurityService(context).getActualSecrets());

fileService = new FileService(
context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static java.util.concurrent.Executors.newSingleThreadExecutor;

import app.notesr.activity.DialogFactory;
import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesCryptorFactory;
import app.notesr.core.util.FilesUtils;

Expand All @@ -32,7 +33,7 @@
import app.notesr.data.DatabaseProvider;
import app.notesr.core.security.exception.DecryptionFailedException;
import app.notesr.service.file.FileService;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.service.security.AppSecurityService;

public final class OpenImageActivity extends FileViewerActivityBase {

Expand Down Expand Up @@ -174,8 +175,8 @@ private FileService getFileService() {
var context = getApplicationContext();
var db = DatabaseProvider.getInstance(this);

var secrets = CryptoManagerProvider.getInstance(context).getSecrets();
var cryptor = AesCryptorFactory.createAesGcmCryptor(secrets);
AesCryptor cryptor = AesCryptorFactory.createAesGcmCryptor(
new AppSecurityService(context).getActualSecrets());

var filesUtils = new FilesUtils();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesCryptorFactory;
import app.notesr.core.security.crypto.AesGcmCryptor;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.core.security.crypto.EncryptedMediaDataSourceFactory;
import app.notesr.core.util.FilesUtils;
import app.notesr.data.DatabaseProvider;
import app.notesr.service.file.FileService;
import app.notesr.service.security.AppSecurityService;

import java.io.File;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -59,8 +59,8 @@ protected void onCreate(Bundle savedInstanceState) {
var context = getApplicationContext();
var db = DatabaseProvider.getInstance(context);

var secrets = CryptoManagerProvider.getInstance(context).getSecrets();
var cryptor = AesCryptorFactory.createAesGcmCryptor(secrets);
AesCryptor cryptor = AesCryptorFactory.createAesGcmCryptor(
new AppSecurityService(context).getActualSecrets());

fileService = new FileService(context, db, cryptor, new FilesUtils());
videoView = findViewById(R.id.video_view);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@
import app.notesr.activity.ActivityBase;
import app.notesr.activity.DialogFactory;
import app.notesr.activity.file.FilesListActivity;
import app.notesr.core.security.crypto.AesCryptor;
import app.notesr.core.security.crypto.AesCryptorFactory;
import app.notesr.data.DatabaseProvider;
import app.notesr.service.file.FileService;
import app.notesr.data.model.Note;
import app.notesr.service.note.NoteService;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.core.util.FilesUtils;
import app.notesr.service.security.AppSecurityService;
import io.noties.markwon.Markwon;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
Expand Down Expand Up @@ -95,8 +96,8 @@ protected void onCreate(Bundle savedInstanceState) {
var context = getApplicationContext();
var db = DatabaseProvider.getInstance(context);

var secrets = CryptoManagerProvider.getInstance(context).getSecrets();
var cryptor = AesCryptorFactory.createAesGcmCryptor(secrets);
AesCryptor cryptor = AesCryptorFactory.createAesGcmCryptor(
new AppSecurityService(context).getActualSecrets());

noteService = new NoteService(db);
fileService = new FileService(context, db, cryptor, new FilesUtils());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@
import app.notesr.activity.security.AuthActivity;
import app.notesr.activity.security.GenerateNewKeyAction;
import app.notesr.activity.security.LockAction;
import app.notesr.core.security.crypto.CryptoManager;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.data.AppDatabase;
import app.notesr.data.DatabaseProvider;
import app.notesr.data.model.Note;
import app.notesr.service.note.NoteService;
import app.notesr.service.security.AppSecurityService;

import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -74,10 +73,10 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_note_list);
applyInsets(findViewById(R.id.main));

CryptoManager cryptoManager = CryptoManagerProvider.getInstance(getApplicationContext());
var appSecurityService = new AppSecurityService(getApplicationContext());

lockAction = new LockAction(this, cryptoManager);
generateNewKeyAction = new GenerateNewKeyAction(this, cryptoManager);
lockAction = new LockAction(this, appSecurityService);
generateNewKeyAction = new GenerateNewKeyAction(this, appSecurityService);

noteEditorLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), getOpenNoteResultCallback());
Expand Down
13 changes: 6 additions & 7 deletions app/src/main/java/app/notesr/activity/security/AuthActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@

import app.notesr.R;
import app.notesr.activity.ActivityBase;
import app.notesr.core.security.crypto.CryptoManager;
import app.notesr.core.security.crypto.CryptoManagerProvider;
import app.notesr.core.util.SecureStringBuilder;
import app.notesr.service.security.AppSecurityService;
import lombok.AllArgsConstructor;
import lombok.Getter;

Expand All @@ -32,7 +31,7 @@ public final class AuthActivity extends ActivityBase {
@AllArgsConstructor
@Getter
public enum Mode {
AUTHORIZATION("authorization"),
AUTHENTICATION("authentication"),
CREATE_PASSWORD("create_password"),
CHANGE_PASSWORD("change_password"),
KEY_RECOVERY("key_recovery");
Expand All @@ -57,8 +56,8 @@ protected void onCreate(Bundle savedInstanceState) {
applyInsets(findViewById(R.id.main));

String mode = getIntent().getStringExtra(EXTRA_MODE);
CryptoManager cryptoManager = CryptoManagerProvider.getInstance(getApplicationContext());
extension = new AuthActivityExtension(this, cryptoManager, passwordBuilder);
var appSecurityService = new AppSecurityService(getApplicationContext());
extension = new AuthActivityExtension(this, appSecurityService, passwordBuilder);

try {
currentMode = Mode.valueOf(mode);
Expand Down Expand Up @@ -86,7 +85,7 @@ private void configure() {
Button changeLayoutButton = findViewById(R.id.changeKeyboardLayoutButton);

switch (currentMode) {
case AUTHORIZATION -> {
case AUTHENTICATION -> {
topLabel.setText(R.string.enter_access_code);
disableBackButton(this);
}
Expand Down Expand Up @@ -123,7 +122,7 @@ private void configure() {

authButton.setOnClickListener(view -> {
switch (currentMode) {
case AUTHORIZATION -> extension.authorize();
case AUTHENTICATION -> extension.authenticate();
case CREATE_PASSWORD -> extension.createPassword();
case KEY_RECOVERY -> extension.recoverKey();
case CHANGE_PASSWORD -> extension.changePassword();
Expand Down
Loading
Loading