Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(auth): preserve app unlock state after app restart #75

Merged
merged 12 commits into from
Dec 26, 2024
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ can [become a sponsor on GitHub](https://github.com/sponsors/tsutsu3), or

Run these commands as needed whenever you update the images.

1. Run ``flutter clean``
2. Run ``dart run flutter_launcher_icons`
3. Run ``dart run flutter_native_splash:create``
1. Run ``dart run flutter_launcher_icons`
2. Run ``dart run flutter_native_splash:create``

#### Android

Expand Down
2 changes: 1 addition & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ analyzer:
errors:
invalid_annotation_target: ignore
exclude:
- test/**
- test/**/*.mocks.dart
- lib/**/*.g.dart
- lib/screens/settings/about/about.dart

Expand Down
1 change: 1 addition & 0 deletions android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
</manifest>
2 changes: 2 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<application
android:label="Pi-hole client"
android:name="${applicationName}"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package io.github.tsutsu3.pi_hole_client

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity;

class MainActivity: FlutterActivity()
class MainActivity: FlutterFragmentActivity()
3 changes: 0 additions & 3 deletions android/app/src/main/res/mipmap-anydpi-v26/launcher_icon.xml

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions android/app/src/profile/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
</manifest>
2 changes: 2 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,7 @@
<true/>
<key>UIStatusBarHidden</key>
<false/>
<key>NSFaceIDUsageDescription</key>
<string>Why is my app authenticating using face id?</string>
</dict>
</plist>
4 changes: 3 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ void main() async {
configProvider.setBiometricsSupport(canAuthenticateWithBiometrics);

if (canAuthenticateWithBiometrics &&
availableBiometrics.contains(BiometricType.fingerprint) == false &&
!availableBiometrics.contains(BiometricType.fingerprint) &&
!availableBiometrics.contains(BiometricType.strong) &&
!availableBiometrics.contains(BiometricType.weak) &&
dbRepository.appConfig.useBiometricAuth == 1) {
await configProvider.setUseBiometrics(false);
}
Expand Down
34 changes: 29 additions & 5 deletions lib/repository/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class DatabaseRepository {
///
/// Throws:
/// - [Exception] if the initialization fails or the database cannot be accessed.
Future<void> initialize() async {
final piHoleClientData = await loadDb();
Future<void> initialize({String? path}) async {
final piHoleClientData = await loadDb(path: path);
_servers = piHoleClientData.servers;
_appConfig = piHoleClientData.appConfig;
_dbInstance = piHoleClientData.dbInstance;
Expand All @@ -69,6 +69,10 @@ class DatabaseRepository {
/// This method is responsible for initializing or opening the database,
/// ensuring that necessary tables exist, and fetching the required data.
///
/// Parameters:
/// - [path]: The path to the database file. If not provided, the default
/// path 'pi_hole_client.db' will be used.
///
/// Returns:
/// - A `Future` that resolves to a [PiHoleClientData] object containing:
/// - `servers`: A list of server configurations from the database.
Expand All @@ -77,12 +81,12 @@ class DatabaseRepository {
///
/// Throws:
/// - [Exception] if the database cannot be initialized or data cannot be retrieved.
Future<PiHoleClientData> loadDb() async {
Future<PiHoleClientData> loadDb({String? path}) async {
List<ServerDbData>? servers;
AppDbData? appConfig;

Database db = await openDatabase(
'pi_hole_client.db',
path ?? 'pi_hole_client.db',
version: 1,
onCreate: (Database db, int version) async {
await db.execute('''
Expand Down Expand Up @@ -140,7 +144,7 @@ class DatabaseRepository {

// Load sensitive data from secure storage
final passCode = await _secureStorage.getValue('passCode');
AppDbData.withSecrets(appConfig!, passCode);
appConfig = AppDbData.withSecrets(appConfig!, passCode);

// _secureStorage.readAll()
logger.d((await _secureStorage.readAll()).toString());
Expand Down Expand Up @@ -175,6 +179,21 @@ class DatabaseRepository {
);
}

/// Closes the database connection.
///
/// This method closes the database connection and releases any resources
///
/// Returns:
/// - A `Future` that resolves to `true` if the operation is successful.
Future<bool> closeDb() async {
try {
await _dbInstance.close();
return true;
} catch (e) {
return false;
}
}

/// Saves a new server entry into the database.
///
/// This method adds a new server record to the 'servers' table in the database.
Expand Down Expand Up @@ -486,6 +505,11 @@ class DatabaseRepository {
}) async {
try {
if (column == 'passCode') {
if (value == null) {
await _secureStorage.deleteValue('passCode');
return true;
}

await _secureStorage.saveValue('passCode', value.toString());
return true;
}
Expand Down
5 changes: 4 additions & 1 deletion lib/repository/secure_storage.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class SecureStorageRepository {
final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
final FlutterSecureStorage _secureStorage;

SecureStorageRepository({FlutterSecureStorage? secureStorage})
: _secureStorage = secureStorage ?? const FlutterSecureStorage();

// Save a value securely
Future<void> saveValue(String key, String value) async {
Expand Down
Loading
Loading