[mob][photos] moved funtions to lockscreen_setting.dart from configuration.dart

This commit is contained in:
Aman Raj Singh Mourya
2024-06-26 14:02:27 +05:30
parent 3fe0faff6a
commit 59b132edf8
11 changed files with 161 additions and 125 deletions

View File

@@ -5,7 +5,6 @@ import "dart:io";
import 'package:bip39/bip39.dart' as bip39;
import "package:flutter/services.dart";
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import "package:flutter_sodium/flutter_sodium.dart";
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:photos/core/constants.dart';
@@ -35,6 +34,7 @@ import 'package:photos/services/search_service.dart';
import 'package:photos/services/sync_service.dart';
import 'package:photos/utils/crypto_util.dart';
import 'package:photos/utils/file_uploader.dart';
import "package:photos/utils/lockscreen_setting.dart";
import 'package:photos/utils/validator_util.dart';
import "package:photos/utils/wakelock_util.dart";
import 'package:shared_preferences/shared_preferences.dart';
@@ -60,7 +60,7 @@ class Configuration {
// keyShouldKeepDeviceAwake is used to determine whether the device screen
// should be kept on while the app is in foreground.
static const keyShouldKeepDeviceAwake = "should_keep_device_awake";
static const keyShouldShowLockScreen = "should_show_lock_screen";
static const keyShowSystemLockScreen = "should_show_lock_screen";
static const keyHasSelectedAnyBackupFolder =
"has_selected_any_folder_for_backup";
static const lastTempFolderClearTimeKey = "last_temp_folder_clear_time";
@@ -86,7 +86,7 @@ class Configuration {
late FlutterSecureStorage _secureStorage;
late String _tempDocumentsDirPath;
late String _thumbnailCacheDirectory;
final LockscreenSetting _lockscreenSetting = LockscreenSetting.instance;
// 6th July 22: Remove this after 3 months. Hopefully, active users
// will migrate to newer version of the app, where shared media is stored
// on appSupport directory which OS won't clean up automatically
@@ -154,80 +154,6 @@ class Configuration {
}
}
static Uint8List generateSalt() {
return Sodium.randombytesBuf(Sodium.cryptoPwhashSaltbytes);
}
Future<void> setPin(String userPin) async {
await _secureStorage.delete(key: saltKey);
final salt = generateSalt();
final hash = cryptoPwHash({
"password": utf8.encode(userPin),
"salt": salt,
"opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
"memLimit": Sodium.cryptoPwhashMemlimitInteractive,
});
final String saltPin = base64Encode(salt);
final String hashedPin = base64Encode(hash);
await _secureStorage.write(key: saltKey, value: saltPin);
await _secureStorage.write(key: pin, value: hashedPin);
await _secureStorage.delete(key: password);
return;
}
Future<Uint8List?> getSalt() async {
final String? salt = await _secureStorage.read(key: saltKey);
if (salt == null) return null;
return base64Decode(salt);
}
Future<String?> getPin() async {
return _secureStorage.read(key: pin);
}
Future<void> setPassword(String pass) async {
await _secureStorage.delete(key: saltKey);
final salt = generateSalt();
final hash = cryptoPwHash({
"password": utf8.encode(pass),
"salt": salt,
"opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
"memLimit": Sodium.cryptoPwhashMemlimitInteractive,
});
final String saltPassword = base64Encode(salt);
final String hashPassword = base64Encode(hash);
await _secureStorage.write(key: saltKey, value: saltPassword);
await _secureStorage.write(key: password, value: hashPassword);
await _secureStorage.delete(key: pin);
return;
}
Future<String?> getPassword() async {
return _secureStorage.read(key: password);
}
Future<void> removePinAndPassword() async {
await _secureStorage.delete(key: saltKey);
await _secureStorage.delete(key: pin);
await _secureStorage.delete(key: password);
}
Future<bool> isPinSet() async {
return await _secureStorage.containsKey(key: pin);
}
Future<bool> isPasswordSet() async {
return await _secureStorage.containsKey(key: password);
}
// _cleanUpStaleFiles deletes all files in the temp directory that are older
// than kTempFolderDeletionTimeBuffer except the the temp encrypted files for upload.
// Those file are deleted by file uploader after the upload is complete or those
@@ -697,16 +623,22 @@ class Configuration {
}
}
bool shouldShowLockScreen() {
if (_preferences.containsKey(keyShouldShowLockScreen)) {
return _preferences.getBool(keyShouldShowLockScreen)!;
Future<bool> shouldShowLockScreen() async {
final bool isPin = await _lockscreenSetting.isPinSet();
final bool isPass = await _lockscreenSetting.isPasswordSet();
return isPin || isPass || shouldShowSystemLockScreen();
}
bool shouldShowSystemLockScreen() {
if (_preferences.containsKey(keyShowSystemLockScreen)) {
return _preferences.getBool(keyShowSystemLockScreen)!;
} else {
return false;
}
}
Future<void> setShouldShowLockScreen(bool value) {
return _preferences.setBool(keyShouldShowLockScreen, value);
Future<void> setSystemLockScreen(bool value) {
return _preferences.setBool(keyShowSystemLockScreen, value);
}
void setVolatilePassword(String volatilePassword) {

View File

@@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import "package:flutter/rendering.dart";
import "package:flutter_displaymode/flutter_displaymode.dart";
import "package:flutter_secure_storage/flutter_secure_storage.dart";
import 'package:logging/logging.dart';
import "package:media_kit/media_kit.dart";
import 'package:path_provider/path_provider.dart';
@@ -53,6 +54,7 @@ import 'package:photos/utils/crypto_util.dart';
import "package:photos/utils/email_util.dart";
import 'package:photos/utils/file_uploader.dart';
import 'package:photos/utils/local_settings.dart';
import "package:photos/utils/lockscreen_setting.dart";
import 'package:shared_preferences/shared_preferences.dart';
final _logger = Logger("main");
@@ -94,7 +96,7 @@ Future<void> _runInForeground(AdaptiveThemeMode? savedThemeMode) async {
builder: (args) =>
EnteApp(_runBackgroundTask, _killBGTask, locale, savedThemeMode),
lockScreen: const LockScreen(),
enabled: Configuration.instance.shouldShowLockScreen(),
enabled: await Configuration.instance.shouldShowLockScreen(),
locale: locale,
lightTheme: lightThemeData,
darkTheme: darkThemeData,
@@ -195,7 +197,7 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
_isProcessRunning = true;
_logger.info("Initializing... inBG =$isBackground via: $via");
final SharedPreferences preferences = await SharedPreferences.getInstance();
const secureStorage = FlutterSecureStorage();
await _logFGHeartBeatInfo();
_logger.info("_logFGHeartBeatInfo done");
unawaited(_scheduleHeartBeat(preferences, isBackground));
@@ -209,6 +211,9 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
Computer.shared().turnOn(workersCount: 4).ignore();
CryptoUtil.init();
_logger.info("Lockscreen init");
LockscreenSetting.instance.init(secureStorage);
_logger.info("Configuration init");
await Configuration.instance.init();
_logger.info("Configuration done");

View File

@@ -3,8 +3,8 @@ import "dart:async";
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:photos/core/configuration.dart';
import "package:photos/ui/settings/TEMP/lock_screen_option_password.dart";
import "package:photos/ui/settings/TEMP/lock_screen_option_pin.dart";
import "package:photos/ui/settings/lockscreen/lock_screen_option_password.dart";
import "package:photos/ui/settings/lockscreen/lock_screen_option_pin.dart";
import 'package:photos/ui/tools/app_lock.dart';
import 'package:photos/utils/auth_util.dart';
import 'package:photos/utils/dialog_util.dart';
@@ -23,7 +23,7 @@ class LocalAuthenticationService {
AppLock.of(context)!.setEnabled(false);
final result = await requestAuthentication(context, infoMessage);
AppLock.of(context)!.setEnabled(
Configuration.instance.shouldShowLockScreen(),
await Configuration.instance.shouldShowLockScreen(),
);
if (!result) {
showToast(context, infoMessage);
@@ -88,13 +88,13 @@ class LocalAuthenticationService {
);
if (result) {
AppLock.of(context)!.setEnabled(shouldEnableLockScreen);
await Configuration.instance
.setShouldShowLockScreen(shouldEnableLockScreen);
await Configuration.instance
.setSystemLockScreen(shouldEnableLockScreen);
return true;
} else {
AppLock.of(context)!
.setEnabled(Configuration.instance.shouldShowLockScreen());
.setEnabled(await Configuration.instance.shouldShowLockScreen());
}
} else {
unawaited(

View File

@@ -7,9 +7,10 @@ import "package:photos/ui/components/menu_item_widget/menu_item_widget.dart";
import "package:photos/ui/components/title_bar_title_widget.dart";
import "package:photos/ui/components/title_bar_widget.dart";
import "package:photos/ui/components/toggle_switch_widget.dart";
import "package:photos/ui/settings/TEMP/lock_screen_option_password.dart";
import "package:photos/ui/settings/TEMP/lock_screen_option_pin.dart";
import "package:photos/ui/settings/lockscreen/lock_screen_option_password.dart";
import "package:photos/ui/settings/lockscreen/lock_screen_option_pin.dart";
import "package:photos/ui/tools/app_lock.dart";
import "package:photos/utils/lockscreen_setting.dart";
class LockScreenOption extends StatefulWidget {
const LockScreenOption({super.key});
@@ -20,6 +21,7 @@ class LockScreenOption extends StatefulWidget {
class _LockScreenOptionState extends State<LockScreenOption> {
final Configuration _configuration = Configuration.instance;
final LockscreenSetting _lockscreenSetting = LockscreenSetting.instance;
late bool appLock;
bool isPinEnabled = false;
bool isPasswordEnabled = false;
@@ -30,12 +32,12 @@ class _LockScreenOptionState extends State<LockScreenOption> {
_initializeSettings();
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowLockScreen();
_configuration.shouldShowSystemLockScreen();
}
Future<void> _initializeSettings() async {
final bool passwordEnabled = await _configuration.isPasswordSet();
final bool pinEnabled = await _configuration.isPinSet();
final bool passwordEnabled = await _lockscreenSetting.isPasswordSet();
final bool pinEnabled = await _lockscreenSetting.isPinSet();
setState(() {
isPasswordEnabled = passwordEnabled;
isPinEnabled = pinEnabled;
@@ -43,7 +45,7 @@ class _LockScreenOptionState extends State<LockScreenOption> {
}
Future<void> _deviceLock() async {
await _configuration.removePinAndPassword();
await _lockscreenSetting.removePinAndPassword();
await _initializeSettings();
}
@@ -57,12 +59,10 @@ class _LockScreenOptionState extends State<LockScreenOption> {
);
setState(() {
_initializeSettings();
if (result == false) {
appLock = appLock;
} else {
if (result) {
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowLockScreen();
_configuration.shouldShowSystemLockScreen();
}
});
}
@@ -77,20 +77,18 @@ class _LockScreenOptionState extends State<LockScreenOption> {
);
setState(() {
_initializeSettings();
if (result == false) {
appLock = appLock;
} else {
if (result) {
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowLockScreen();
_configuration.shouldShowSystemLockScreen();
}
});
}
Future<void> _onToggleSwitch() async {
AppLock.of(context)!.setEnabled(!appLock);
await Configuration.instance.setShouldShowLockScreen(!appLock);
await _configuration.removePinAndPassword();
await _configuration.setSystemLockScreen(!appLock);
await _lockscreenSetting.removePinAndPassword();
setState(() {
_initializeSettings();
appLock = !appLock;

View File

@@ -1,11 +1,11 @@
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:photos/core/configuration.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/common/dynamic_fab.dart";
import "package:photos/ui/components/buttons/icon_button_widget.dart";
import "package:photos/ui/components/text_input_widget.dart";
import "package:photos/utils/lockscreen_setting.dart";
class LockScreenOptionConfirmPassword extends StatefulWidget {
const LockScreenOptionConfirmPassword({
@@ -23,7 +23,8 @@ class _LockScreenOptionConfirmPasswordState
extends State<LockScreenOptionConfirmPassword> {
/// _confirmPasswordController is disposed by the [TextInputWidget]
final _confirmPasswordController = TextEditingController(text: null);
final Configuration _configuration = Configuration.instance;
final LockscreenSetting _lockscreenSetting = LockscreenSetting.instance;
final _focusNode = FocusNode();
final _isFormValid = ValueNotifier<bool>(false);
final _submitNotifier = ValueNotifier(false);
@@ -45,7 +46,7 @@ class _LockScreenOptionConfirmPasswordState
Future<void> _confirmPasswordMatch() async {
if (widget.password == _confirmPasswordController.text) {
await _configuration.setPassword(_confirmPasswordController.text);
await _lockscreenSetting.setPassword(_confirmPasswordController.text);
Navigator.of(context).pop(true);
Navigator.of(context).pop(true);

View File

@@ -1,10 +1,10 @@
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:photos/core/configuration.dart";
import "package:photos/theme/colors.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/theme/text_style.dart";
import "package:photos/ui/components/buttons/icon_button_widget.dart";
import "package:photos/utils/lockscreen_setting.dart";
import "package:pinput/pinput.dart";
class LockScreenOptionConfirmPin extends StatefulWidget {
@@ -18,7 +18,8 @@ class LockScreenOptionConfirmPin extends StatefulWidget {
class _LockScreenOptionConfirmPinState
extends State<LockScreenOptionConfirmPin> {
final _confirmPinController = TextEditingController(text: null);
final Configuration _configuration = Configuration.instance;
final LockscreenSetting _lockscreenSetting = LockscreenSetting.instance;
final _pinPutDecoration = PinTheme(
height: 48,
width: 48,
@@ -49,7 +50,7 @@ class _LockScreenOptionConfirmPinState
Future<void> _confirmPinMatch() async {
if (widget.pin == _confirmPinController.text) {
await _configuration.setPin(_confirmPinController.text);
await _lockscreenSetting.setPin(_confirmPinController.text);
Navigator.of(context).pop(true);
Navigator.of(context).pop(true);

View File

@@ -3,14 +3,14 @@ import "dart:convert";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:flutter_sodium/flutter_sodium.dart";
import "package:photos/core/configuration.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/common/dynamic_fab.dart";
import "package:photos/ui/components/buttons/icon_button_widget.dart";
import "package:photos/ui/components/text_input_widget.dart";
import "package:photos/ui/settings/TEMP/lock_screen_option_confirm_password.dart";
import "package:photos/ui/settings/lockscreen/lock_screen_option_confirm_password.dart";
import "package:photos/utils/crypto_util.dart";
import "package:photos/utils/lockscreen_setting.dart";
class LockScreenOptionPassword extends StatefulWidget {
const LockScreenOptionPassword({
@@ -31,7 +31,8 @@ class _LockScreenOptionPasswordState extends State<LockScreenOptionPassword> {
final _focusNode = FocusNode();
final _isFormValid = ValueNotifier<bool>(false);
final _submitNotifier = ValueNotifier(false);
Configuration configuration = Configuration.instance;
final LockscreenSetting _lockscreenSetting = LockscreenSetting.instance;
late String hashedPassword;
@override
void initState() {
@@ -50,7 +51,7 @@ class _LockScreenOptionPasswordState extends State<LockScreenOptionPassword> {
}
Future<bool> confirmPasswordAuth(String code) async {
final Uint8List? salt = await configuration.getSalt();
final Uint8List? salt = await _lockscreenSetting.getSalt();
final hash = cryptoPwHash({
"password": utf8.encode(code),
"salt": salt,

View File

@@ -3,13 +3,13 @@ import "dart:convert";
import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:flutter_sodium/flutter_sodium.dart";
import "package:photos/core/configuration.dart";
import "package:photos/theme/colors.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/theme/text_style.dart";
import "package:photos/ui/components/buttons/icon_button_widget.dart";
import "package:photos/ui/settings/TEMP/lock_screen_option_confirm_pin.dart";
import "package:photos/ui/settings/lockscreen/lock_screen_option_confirm_pin.dart";
import "package:photos/utils/crypto_util.dart";
import "package:photos/utils/lockscreen_setting.dart";
import 'package:pinput/pinput.dart';
class LockScreenOptionPin extends StatefulWidget {
@@ -27,7 +27,8 @@ class LockScreenOptionPin extends StatefulWidget {
class _LockScreenOptionPinState extends State<LockScreenOptionPin> {
final _pinController = TextEditingController(text: null);
Configuration configuration = Configuration.instance;
final LockscreenSetting _lockscreenSetting = LockscreenSetting.instance;
late String hashedPin;
@override
void dispose() {
@@ -49,7 +50,7 @@ class _LockScreenOptionPinState extends State<LockScreenOptionPin> {
}
Future<bool> confirmPinAuth(String code) async {
final Uint8List? salt = await configuration.getSalt();
final Uint8List? salt = await _lockscreenSetting.getSalt();
final hash = cryptoPwHash({
"password": utf8.encode(code),
"salt": salt,

View File

@@ -20,8 +20,8 @@ import 'package:photos/ui/components/captioned_text_widget.dart';
import 'package:photos/ui/components/expandable_menu_item_widget.dart';
import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
import 'package:photos/ui/components/toggle_switch_widget.dart';
import "package:photos/ui/settings/TEMP/lock_screen_option.dart";
import 'package:photos/ui/settings/common_settings.dart';
import "package:photos/ui/settings/lockscreen/lock_screen_option.dart";
import "package:photos/utils/auth_util.dart";
import "package:photos/utils/crypto_util.dart";
import "package:photos/utils/dialog_util.dart";

View File

@@ -3,16 +3,17 @@ import 'package:local_auth/local_auth.dart';
import 'package:local_auth_android/local_auth_android.dart';
import 'package:local_auth_ios/local_auth_ios.dart';
import 'package:logging/logging.dart';
import "package:photos/core/configuration.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/services/local_authentication_service.dart";
import "package:photos/utils/lockscreen_setting.dart";
Future<bool> requestAuthentication(BuildContext context, String reason) async {
Logger("AuthUtil").info("Requesting authentication");
await LocalAuthentication().stopAuthentication();
final Configuration configuration = Configuration.instance;
final String? savedPin = await configuration.getPin();
final String? savedPassword = await configuration.getPassword();
final LockscreenSetting lockscreenSetting = LockscreenSetting.instance;
final String? savedPin = await lockscreenSetting.getPin();
final String? savedPassword = await lockscreenSetting.getPassword();
if (savedPassword != null || savedPin != null) {
return await LocalAuthenticationService.instance
.requestEnteAuthForLockScreen(context, savedPin, savedPassword);

View File

@@ -0,0 +1,96 @@
import "dart:convert";
import "package:flutter/foundation.dart";
import "package:flutter_secure_storage/flutter_secure_storage.dart";
import "package:flutter_sodium/flutter_sodium.dart";
import "package:photos/utils/crypto_util.dart";
class LockscreenSetting {
LockscreenSetting._privateConstructor();
static final LockscreenSetting instance =
LockscreenSetting._privateConstructor();
static const password = "user_pass";
static const pin = "user_pin";
static const saltKey = "user_salt";
late FlutterSecureStorage _secureStorage;
void init(FlutterSecureStorage secureStorage) {
_secureStorage = secureStorage;
}
static Uint8List generateSalt() {
return Sodium.randombytesBuf(Sodium.cryptoPwhashSaltbytes);
}
Future<void> setPin(String userPin) async {
await _secureStorage.delete(key: saltKey);
final salt = generateSalt();
final hash = cryptoPwHash({
"password": utf8.encode(userPin),
"salt": salt,
"opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
"memLimit": Sodium.cryptoPwhashMemlimitInteractive,
});
final String saltPin = base64Encode(salt);
final String hashedPin = base64Encode(hash);
await _secureStorage.write(key: saltKey, value: saltPin);
await _secureStorage.write(key: pin, value: hashedPin);
await _secureStorage.delete(key: password);
return;
}
Future<Uint8List?> getSalt() async {
final String? salt = await _secureStorage.read(key: saltKey);
if (salt == null) return null;
return base64Decode(salt);
}
Future<String?> getPin() async {
return _secureStorage.read(key: pin);
}
Future<void> setPassword(String pass) async {
await _secureStorage.delete(key: saltKey);
final salt = generateSalt();
final hash = cryptoPwHash({
"password": utf8.encode(pass),
"salt": salt,
"opsLimit": Sodium.cryptoPwhashOpslimitInteractive,
"memLimit": Sodium.cryptoPwhashMemlimitInteractive,
});
final String saltPassword = base64Encode(salt);
final String hashPassword = base64Encode(hash);
await _secureStorage.write(key: saltKey, value: saltPassword);
await _secureStorage.write(key: password, value: hashPassword);
await _secureStorage.delete(key: pin);
return;
}
Future<String?> getPassword() async {
return _secureStorage.read(key: password);
}
Future<void> removePinAndPassword() async {
await _secureStorage.delete(key: saltKey);
await _secureStorage.delete(key: pin);
await _secureStorage.delete(key: password);
}
Future<bool> isPinSet() async {
return await _secureStorage.containsKey(key: pin);
}
Future<bool> isPasswordSet() async {
return await _secureStorage.containsKey(key: password);
}
}