[auth] Add endpoint to check passkey status

This commit is contained in:
Neeraj Gupta
2024-06-13 13:54:31 +05:30
parent 7930e95f4a
commit c193377640
3 changed files with 55 additions and 0 deletions

View File

@@ -42,3 +42,7 @@ class InvalidStateError extends AssertionError {
class SrpSetupNotCompleteError extends Error {}
class AuthenticatorKeyNotFound extends Error {}
class PassKeySessionNotVerifiedError extends Error {}
class PassKeySessionExpiredError extends Error {}

View File

@@ -266,6 +266,31 @@ class UserService {
}
}
Future<dynamic> getTokenForPasskeySession(String sessionID) async {
try {
final response = await _dio.get(
"${_config.getHttpEndpoint()}/users/two-factor/passkeys/get-token",
queryParameters: {
"sessionID": sessionID,
},
);
return response.data;
} on DioException catch (e) {
if (e.response != null) {
if (e.response!.statusCode == 404 || e.response!.statusCode == 410) {
throw PassKeySessionExpiredError();
}
if (e.response!.statusCode == 400) {
throw PassKeySessionNotVerifiedError();
}
}
rethrow;
} catch (e, s) {
_logger.severe("unexpected error", e, s);
rethrow;
}
}
Future<void> onPassKeyVerified(BuildContext context, Map response) async {
final ProgressDialog dialog =
createProgressDialog(context, context.l10n.pleaseWait);

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:app_links/app_links.dart';
import 'package:ente_auth/core/configuration.dart';
import 'package:ente_auth/core/errors.dart';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/models/account/two_factor.dart';
import 'package:ente_auth/services/user_service.dart';
@@ -51,6 +52,24 @@ class _PasskeyPageState extends State<PasskeyPage> {
);
}
Future<void> checkStatus() async {
late dynamic response;
try {
response = await UserService.instance
.getTokenForPasskeySession(widget.sessionID);
} on PassKeySessionNotVerifiedError catch (e) {
showToast(context, "Verification is still pending.");
} on PassKeySessionExpiredError catch (e) {
showToast(context, "Passkey session expired. Please try again.");
return;
} catch (e, s) {
_logger.severe("failed to check status", e, s);
showGenericErrorDialog(context: context).ignore();
return;
}
await UserService.instance.onPassKeyVerified(context, response);
}
Future<void> _handleDeeplink(String? link) async {
if (!context.mounted ||
Configuration.instance.hasConfiguredAccount() ||
@@ -129,6 +148,13 @@ class _PasskeyPageState extends State<PasskeyPage> {
labelText: context.l10n.tryAgain,
onTap: () => launchPasskey(),
),
const SizedBox(height: 16),
ButtonWidget(
buttonType: ButtonType.neutral,
labelText: context.l10n.checkForUpdates,
onTap: checkStatus,
shouldSurfaceExecutionStates: true,
),
const Padding(padding: EdgeInsets.all(30)),
GestureDetector(
behavior: HitTestBehavior.opaque,