Passkey changes

This commit is contained in:
Neeraj Gupta 2024-03-06 14:26:00 +05:30
parent 942da28b53
commit c175973ff0
7 changed files with 41 additions and 57 deletions

View file

@ -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,
);
}
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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(

View file

@ -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) {

View file

@ -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);
}

View file

@ -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(