[mob][auth] Option to add pin/passcode without having a system lock (#2738)

This commit is contained in:
Ashil
2024-08-20 19:36:10 +05:30
committed by GitHub
6 changed files with 111 additions and 54 deletions

View File

@@ -6,6 +6,7 @@ import 'package:ente_auth/ui/settings/lock_screen/lock_screen_pin.dart';
import 'package:ente_auth/ui/tools/app_lock.dart';
import 'package:ente_auth/utils/auth_util.dart';
import 'package:ente_auth/utils/dialog_util.dart';
import 'package:ente_auth/utils/lock_screen_settings.dart';
import 'package:ente_auth/utils/toast_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -23,7 +24,8 @@ class LocalAuthenticationService {
BuildContext context,
String infoMessage,
) async {
if (await isLocalAuthSupportedOnDevice()) {
if (await isLocalAuthSupportedOnDevice() ||
LockScreenSettings.instance.getIsAppLockSet()) {
AppLock.of(context)!.setEnabled(false);
final result = await requestAuthentication(
context,
@@ -122,7 +124,7 @@ class LocalAuthenticationService {
Future<bool> isLocalAuthSupportedOnDevice() async {
try {
return Platform.isMacOS || Platform.isLinux
return Platform.isLinux
? await FlutterLocalAuthentication().canAuthenticate()
: await LocalAuthentication().isDeviceSupported();
} on MissingPluginException {

View File

@@ -3,6 +3,7 @@ import "dart:io";
import "package:ente_auth/core/configuration.dart";
import "package:ente_auth/l10n/l10n.dart";
import "package:ente_auth/services/local_authentication_service.dart";
import "package:ente_auth/theme/ente_theme.dart";
import "package:ente_auth/ui/components/captioned_text_widget.dart";
import "package:ente_auth/ui/components/divider_widget.dart";
@@ -14,6 +15,7 @@ import "package:ente_auth/ui/settings/lock_screen/lock_screen_auto_lock.dart";
import "package:ente_auth/ui/settings/lock_screen/lock_screen_password.dart";
import "package:ente_auth/ui/settings/lock_screen/lock_screen_pin.dart";
import "package:ente_auth/ui/tools/app_lock.dart";
import "package:ente_auth/utils/dialog_util.dart";
import "package:ente_auth/utils/lock_screen_settings.dart";
import "package:ente_auth/utils/navigation_util.dart";
import "package:ente_auth/utils/platform_util.dart";
@@ -29,11 +31,12 @@ class LockScreenOptions extends StatefulWidget {
class _LockScreenOptionsState extends State<LockScreenOptions> {
final Configuration _configuration = Configuration.instance;
final LockScreenSettings _lockscreenSetting = LockScreenSettings.instance;
late bool appLock;
late bool appLock = false;
bool isPinEnabled = false;
bool isPasswordEnabled = false;
late int autoLockTimeInMilliseconds;
late bool hideAppContent;
late bool isSystemLockEnabled = false;
@override
void initState() {
@@ -41,9 +44,7 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
hideAppContent = _lockscreenSetting.getShouldHideAppContent();
autoLockTimeInMilliseconds = _lockscreenSetting.getAutoLockTime();
_initializeSettings();
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowSystemLockScreen();
appLock = _lockscreenSetting.getIsAppLockSet();
}
Future<void> _initializeSettings() async {
@@ -51,15 +52,27 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
final bool pinEnabled = await _lockscreenSetting.isPinSet();
final bool shouldHideAppContent =
_lockscreenSetting.getShouldHideAppContent();
final bool systemLockEnabled = _configuration.shouldShowSystemLockScreen();
setState(() {
isPasswordEnabled = passwordEnabled;
isPinEnabled = pinEnabled;
hideAppContent = shouldHideAppContent;
isSystemLockEnabled = systemLockEnabled;
});
}
Future<void> _deviceLock() async {
await _lockscreenSetting.removePinAndPassword();
if (await LocalAuthenticationService.instance
.isLocalAuthSupportedOnDevice()) {
await _lockscreenSetting.removePinAndPassword();
await _configuration.setSystemLockScreen(!isSystemLockEnabled);
} else {
await showErrorDialog(
context,
context.l10n.noSystemLockFound,
context.l10n.toEnableAppLockPleaseSetupDevicePasscodeOrScreen,
);
}
await _initializeSettings();
}
@@ -71,14 +84,15 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
},
),
);
setState(() {
_initializeSettings();
if (result) {
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowSystemLockScreen();
}
});
if (result) {
await _configuration.setSystemLockScreen(false);
await _lockscreenSetting.setAppLockEnabled(true);
setState(() {
appLock = _lockscreenSetting.getIsAppLockSet();
});
}
await _initializeSettings();
}
Future<void> _passwordLock() async {
@@ -89,27 +103,35 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
},
),
);
setState(() {
_initializeSettings();
if (result) {
appLock = isPinEnabled ||
isPasswordEnabled ||
_configuration.shouldShowSystemLockScreen();
}
});
if (result) {
await _configuration.setSystemLockScreen(false);
setState(() {
appLock = _lockscreenSetting.getIsAppLockSet();
});
}
await _initializeSettings();
}
Future<void> _onToggleSwitch() async {
AppLock.of(context)!.setEnabled(!appLock);
await _configuration.setSystemLockScreen(!appLock);
if (await LocalAuthenticationService.instance
.isLocalAuthSupportedOnDevice()) {
await _configuration.setSystemLockScreen(!appLock);
await _lockscreenSetting.setAppLockEnabled(!appLock);
} else {
await _configuration.setSystemLockScreen(false);
await _lockscreenSetting.setAppLockEnabled(false);
}
await _lockscreenSetting.removePinAndPassword();
if (PlatformUtil.isMobile()) {
await _lockscreenSetting.setHideAppContent(!appLock);
setState(() {
hideAppContent = _lockscreenSetting.getShouldHideAppContent();
});
}
await _initializeSettings();
setState(() {
_initializeSettings();
appLock = !appLock;
hideAppContent = _lockscreenSetting.getShouldHideAppContent();
});
}
@@ -224,10 +246,9 @@ class _LockScreenOptionsState extends State<LockScreenOptions> {
isTopBorderRadiusRemoved: false,
isBottomBorderRadiusRemoved: true,
menuItemColor: colorTheme.fillFaint,
trailingIcon:
!(isPasswordEnabled || isPinEnabled)
? Icons.check
: null,
trailingIcon: isSystemLockEnabled
? Icons.check
: null,
trailingIconColor: colorTheme.textBase,
onTap: () => _deviceLock(),
),

View File

@@ -144,11 +144,10 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
trailingIcon: Icons.chevron_right_outlined,
trailingIconIsMuted: true,
onTap: () async {
if (await LocalAuthenticationService.instance
.isLocalAuthSupportedOnDevice()) {
if (await Configuration.instance.shouldShowLockScreen()) {
final bool result = await requestAuthentication(
context,
context.l10n.authToChangeLockscreenSetting,
context.l10n.about,
);
if (result) {
await Navigator.of(context).push(
@@ -160,10 +159,12 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
);
}
} else {
await showErrorDialog(
context,
context.l10n.noSystemLockFound,
context.l10n.toEnableAppLockPleaseSetupDevicePasscodeOrScreen,
await Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return const LockScreenOptions();
},
),
);
}
},

View File

@@ -1,6 +1,7 @@
import "dart:convert";
import "dart:typed_data";
import "package:ente_auth/core/configuration.dart";
import "package:ente_auth/utils/platform_util.dart";
import "package:ente_crypto_dart/ente_crypto_dart.dart";
import "package:flutter_secure_storage/flutter_secure_storage.dart";
@@ -19,6 +20,9 @@ class LockScreenSettings {
static const lastInvalidAttemptTime = "ls_last_invalid_attempt_time";
static const autoLockTime = "ls_auto_lock_time";
static const keyHideAppContent = "ls_hide_app_content";
static const keyAppLockSet = "ls_is_app_lock_set";
static const keyHasMigratedLockScreenChanges =
"ls_has_migrated_lock_screen_changes";
final List<Duration> autoLockDurations = const [
Duration(seconds: 0),
Duration(seconds: 5),
@@ -37,6 +41,27 @@ class LockScreenSettings {
///Workaround for privacyScreen not working when app is killed and opened.
await setHideAppContent(getShouldHideAppContent());
/// Function to Check if the migration for lock screen changes has
/// already been done by checking a stored boolean value.
await runLockScreenChangesMigration();
}
Future<void> runLockScreenChangesMigration() async {
if (_preferences.getBool(keyHasMigratedLockScreenChanges) != null) {
return;
}
final bool passwordEnabled = await isPasswordSet();
final bool pinEnabled = await isPinSet();
final bool systemLockEnabled =
Configuration.instance.shouldShowSystemLockScreen();
if (passwordEnabled || pinEnabled || systemLockEnabled) {
await setAppLockEnabled(true);
}
await _preferences.setBool(keyHasMigratedLockScreenChanges, true);
}
Future<void> setHideAppContent(bool hideContent) async {
@@ -83,6 +108,14 @@ class LockScreenSettings {
await _preferences.setInt(keyInvalidAttempts, count);
}
Future<void> setAppLockEnabled(bool value) async {
await _preferences.setBool(keyAppLockSet, value);
}
bool getIsAppLockSet() {
return _preferences.getBool(keyAppLockSet) ?? false;
}
static Uint8List _generateSalt() {
return sodium.randombytes.buf(sodium.crypto.pwhash.saltBytes);
}

View File

@@ -869,18 +869,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.4"
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
@@ -901,10 +901,10 @@ packages:
dependency: "direct main"
description:
name: local_auth
sha256: "280421b416b32de31405b0a25c3bd42dfcef2538dfbb20c03019e02a5ed55ed0"
sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.3.0"
local_auth_android:
dependency: "direct main"
description:
@@ -917,10 +917,10 @@ packages:
dependency: "direct main"
description:
name: local_auth_darwin
sha256: e424ebf90d5233452be146d4a7da4bcd7a70278b67791592f3fde1bda8eef9e2
sha256: "7ba5738c874ca2b910d72385d00d2bebad9d4e807612936cf5e32bc01a048c71"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.4.0"
local_auth_platform_interface:
dependency: transitive
description:
@@ -957,10 +957,10 @@ packages:
dependency: transitive
description:
name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.8.0"
version: "0.11.1"
menu_base:
dependency: transitive
description:
@@ -973,10 +973,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.15.0"
mime:
dependency: transitive
description:
@@ -1539,10 +1539,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
version: "0.7.2"
timezone:
dependency: transitive
description:
@@ -1707,10 +1707,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
url: "https://pub.dev"
source: hosted
version: "14.2.1"
version: "14.2.4"
watcher:
dependency: transitive
description:

View File

@@ -67,7 +67,7 @@ dependencies:
http: ^1.1.0
intl: ^0.19.0
json_annotation: ^4.5.0
local_auth: ^2.2.0
local_auth: ^2.3.0
local_auth_android: ^1.0.37
local_auth_darwin: ^1.2.2
logging: ^1.0.1