Passkey changes
This commit is contained in:
parent
942da28b53
commit
c175973ff0
7 changed files with 41 additions and 57 deletions
|
@ -1,4 +1,7 @@
|
|||
import 'package:ente_auth/core/network.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class PasskeyService {
|
||||
|
@ -7,27 +10,24 @@ class PasskeyService {
|
|||
|
||||
final _enteDio = Network.instance.enteDio;
|
||||
|
||||
Future<String?> getJwtToken() async {
|
||||
Future<String> getJwtToken() async {
|
||||
final response = await _enteDio.get(
|
||||
"/users/accounts-token",
|
||||
);
|
||||
return response.data!["accountsToken"] as String;
|
||||
}
|
||||
|
||||
Future<void> openPasskeyPage(BuildContext context) async {
|
||||
try {
|
||||
final response = await _enteDio.get(
|
||||
"/users/accounts-token",
|
||||
final jwtToken = await getJwtToken();
|
||||
final url = "https://accounts.ente.io/account-handoff?token=$jwtToken";
|
||||
await launchUrlString(
|
||||
url,
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
if (response.data?["accountsToken"] == null) return null;
|
||||
return response.data["accountsToken"] as String?;
|
||||
} catch (e) {
|
||||
return null;
|
||||
Logger('PasskeyService').severe("failed to open passkey page", e);
|
||||
showGenericErrorDialog(context: context).ignore();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> openPasskeyPage() async {
|
||||
final jwtToken = await getJwtToken();
|
||||
|
||||
final url = jwtToken != null
|
||||
? "https://accounts.ente.io/account-handoff?token=$jwtToken"
|
||||
: "https://accounts.ente.io/";
|
||||
await launchUrlString(
|
||||
url,
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,11 +265,7 @@ class UserService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> acceptPasskey(
|
||||
BuildContext context,
|
||||
Map response,
|
||||
Uint8List keyEncryptionKey,
|
||||
) async {
|
||||
Future<void> onPassKeyVerified(BuildContext context, Map response) async {
|
||||
final userPassword = Configuration.instance.getVolatilePassword();
|
||||
if (userPassword == null) throw Exception("volatile password is null");
|
||||
|
||||
|
@ -280,7 +276,6 @@ class UserService {
|
|||
await Configuration.instance.decryptSecretsAndGetKeyEncKey(
|
||||
userPassword,
|
||||
Configuration.instance.getKeyAttributes()!,
|
||||
keyEncryptionKey: keyEncryptionKey,
|
||||
);
|
||||
page = const HomePage();
|
||||
} else {
|
||||
|
@ -622,10 +617,7 @@ class UserService {
|
|||
if (twoFASessionID.isNotEmpty) {
|
||||
page = TwoFactorAuthenticationPage(twoFASessionID);
|
||||
} else if (passkeySessionID.isNotEmpty) {
|
||||
page = PasskeyPage(
|
||||
passkeySessionID,
|
||||
keyEncryptionKey: keyEncryptionKey,
|
||||
);
|
||||
page = PasskeyPage(passkeySessionID);
|
||||
} else {
|
||||
await _saveConfiguration(response);
|
||||
if (Configuration.instance.getEncryptedToken() != null) {
|
||||
|
|
|
@ -5,19 +5,16 @@ import 'package:ente_auth/ente_theme_data.dart';
|
|||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:uni_links/uni_links.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class PasskeyPage extends StatefulWidget {
|
||||
final String sessionID;
|
||||
final Uint8List keyEncryptionKey;
|
||||
|
||||
const PasskeyPage(
|
||||
this.sessionID, {
|
||||
Key? key,
|
||||
required this.keyEncryptionKey,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -56,16 +53,10 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
|||
}
|
||||
if (mounted && link.toLowerCase().startsWith("enteauth://passkey")) {
|
||||
final uri = Uri.parse(link).queryParameters['response'];
|
||||
|
||||
// response to json
|
||||
final res = utf8.decode(base64.decode(uri!));
|
||||
final json = jsonDecode(res) as Map<String, dynamic>;
|
||||
|
||||
await UserService.instance.acceptPasskey(
|
||||
context,
|
||||
json,
|
||||
widget.keyEncryptionKey,
|
||||
);
|
||||
await UserService.instance.onPassKeyVerified(context, json);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
trailingIcon: Icons.chevron_right_outlined,
|
||||
trailingIconIsMuted: true,
|
||||
onTap: () => PasskeyService.instance.openPasskeyPage(),
|
||||
onTap: () => PasskeyService.instance.openPasskeyPage(context),
|
||||
),
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
|
|
|
@ -315,11 +315,7 @@ class UserService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> acceptPasskey(
|
||||
BuildContext context,
|
||||
Map response,
|
||||
Uint8List keyEncryptionKey,
|
||||
) async {
|
||||
Future<void> onPassKeyVerified(BuildContext context, Map response) async {
|
||||
final userPassword = Configuration.instance.getVolatilePassword();
|
||||
if (userPassword == null) throw Exception("volatile password is null");
|
||||
|
||||
|
@ -329,7 +325,6 @@ class UserService {
|
|||
await Configuration.instance.decryptSecretsAndGetKeyEncKey(
|
||||
userPassword,
|
||||
Configuration.instance.getKeyAttributes()!,
|
||||
keyEncryptionKey: keyEncryptionKey,
|
||||
);
|
||||
} else {
|
||||
throw Exception("unexpected response during passkey verification");
|
||||
|
@ -680,10 +675,7 @@ class UserService {
|
|||
await setTwoFactor(value: true);
|
||||
page = TwoFactorAuthenticationPage(twoFASessionID);
|
||||
} else if (passkeySessionID.isNotEmpty) {
|
||||
page = PasskeyPage(
|
||||
passkeySessionID,
|
||||
keyEncryptionKey: keyEncryptionKey,
|
||||
);
|
||||
page = PasskeyPage(passkeySessionID);
|
||||
} else {
|
||||
await _saveConfiguration(response);
|
||||
if (Configuration.instance.getEncryptedToken() != null) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
|
@ -12,12 +11,10 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||
|
||||
class PasskeyPage extends StatefulWidget {
|
||||
final String sessionID;
|
||||
final Uint8List keyEncryptionKey;
|
||||
|
||||
const PasskeyPage(
|
||||
this.sessionID, {
|
||||
Key? key,
|
||||
required this.keyEncryptionKey,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -62,11 +59,7 @@ class _PasskeyPageState extends State<PasskeyPage> {
|
|||
final json = jsonDecode(res) as Map<String, dynamic>;
|
||||
|
||||
try {
|
||||
await UserService.instance.acceptPasskey(
|
||||
context,
|
||||
json,
|
||||
widget.keyEncryptionKey,
|
||||
);
|
||||
await UserService.instance.onPassKeyVerified(context, json);
|
||||
} catch (e) {
|
||||
_logger.severe(e);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,11 @@ import 'package:photos/core/event_bus.dart';
|
|||
import 'package:photos/ente_theme_data.dart';
|
||||
import 'package:photos/events/two_factor_status_change_event.dart';
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/l10n/l10n.dart";
|
||||
import "package:photos/models/user_details.dart";
|
||||
import "package:photos/services/feature_flag_service.dart";
|
||||
import 'package:photos/services/local_authentication_service.dart';
|
||||
import "package:photos/services/passkey_service.dart";
|
||||
import 'package:photos/services/user_service.dart';
|
||||
import 'package:photos/theme/ente_theme.dart';
|
||||
import "package:photos/ui/account/request_pwd_verification_page.dart";
|
||||
|
@ -65,6 +68,8 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||
final Completer completer = Completer();
|
||||
final List<Widget> children = [];
|
||||
if (_config.hasConfiguredAccount()) {
|
||||
final bool isInternalUser =
|
||||
FeatureFlagService.instance.isInternalUserOrDebugBuild();
|
||||
children.addAll(
|
||||
[
|
||||
sectionOptionSpacing,
|
||||
|
@ -96,6 +101,17 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
|||
},
|
||||
),
|
||||
),
|
||||
if (isInternalUser) sectionOptionSpacing,
|
||||
if (isInternalUser)
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: context.l10n.passkey,
|
||||
),
|
||||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
trailingIcon: Icons.chevron_right_outlined,
|
||||
trailingIconIsMuted: true,
|
||||
onTap: () => PasskeyService.instance.openPasskeyPage(context),
|
||||
),
|
||||
sectionOptionSpacing,
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
|
|
Loading…
Add table
Reference in a new issue