Skip to content

Commit

Permalink
Merge branch 'main' into main_android
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkbee1 committed Oct 2, 2023
2 parents be29adf + e3d1670 commit a8948c1
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 53 deletions.
14 changes: 11 additions & 3 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ Future<OIDC4VCType?> getOIDC4VCTypeForIssuance({

issuer = credentialOfferJson['credential_issuer'].toString();
} else {
throw Exception();
return null;
}

final openidConfigurationResponse = await getOpenIdConfig(
Expand Down Expand Up @@ -628,14 +628,22 @@ Future<String> getHost({

/// check if request uri is provided or not
if (requestUri != null) {
final requestUri = uri.queryParameters['request_uri'].toString();
final dynamic response = await client.get(requestUri);
final Map<String, dynamic> decodedResponse = decodePayload(
jwtDecode: JWTDecode(),
token: response as String,
);

return Uri.parse(decodedResponse['redirect_uri'].toString()).host;
final redirectUri = decodedResponse['redirect_uri'];
final responseUri = decodedResponse['response_uri'];

if (redirectUri != null) {
return Uri.parse(redirectUri.toString()).host;
} else if (responseUri != null) {
return Uri.parse(responseUri.toString()).host;
}

return '';
} else {
final String? redirectUri = getRedirectUri(uri);
if (redirectUri == null) return '';
Expand Down
14 changes: 10 additions & 4 deletions lib/app/shared/launch_url/launch_url.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import 'package:url_launcher/url_launcher.dart';

class LaunchUrl {
static Future<void> launch(String url) async {
static Future<void> launch(
String url, {
LaunchMode launchMode = LaunchMode.externalApplication,
}) async {
await canLaunchUrl(Uri.parse(url))
? await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication)
? await launchUrl(Uri.parse(url), mode: launchMode)
: throw Exception('Could not launch $url');
}

static Future<void> launchUri(Uri uri) async {
static Future<void> launchUri(
Uri uri, {
LaunchMode launchMode = LaunchMode.externalApplication,
}) async {
await canLaunchUrl(uri)
? await launchUrl(uri, mode: LaunchMode.externalApplication)
? await launchUrl(uri, mode: launchMode)
: throw Exception('Could not launch $uri');
}
}
16 changes: 7 additions & 9 deletions lib/app/shared/widget/dialog/error_details_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import 'package:altme/app/app.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

class ErrorDetailsDialog extends StatelessWidget {
const ErrorDetailsDialog({
super.key,
this.erroDescription,
this.erroUrl,
this.icon = IconStrings.alert,
this.dialogColor,
this.bgColor,
this.textColor,
Expand All @@ -19,7 +19,6 @@ class ErrorDetailsDialog extends StatelessWidget {
final Color? dialogColor;
final Color? bgColor;
final Color? textColor;
final String icon;

@override
Widget build(BuildContext context) {
Expand All @@ -39,11 +38,6 @@ class ErrorDetailsDialog extends StatelessWidget {
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
icon,
width: 50,
height: 50,
),
const SizedBox(height: 25),
if (erroDescription != null) ...[
Text(
Expand All @@ -59,7 +53,10 @@ class ErrorDetailsDialog extends StatelessWidget {
const SizedBox(height: Sizes.spaceXSmall),
TransparentInkWell(
onTap: () async {
await LaunchUrl.launch(erroUrl!);
await LaunchUrl.launch(
erroUrl!,
launchMode: LaunchMode.inAppWebView,
);
},
child: Text(
l10n.moreDetails,
Expand All @@ -83,7 +80,8 @@ class ErrorDetailsDialog extends StatelessWidget {
onPressed: () {
Navigator.of(context).pop(true);
},
)
),
const SizedBox(height: 15),
],
),
);
Expand Down
17 changes: 8 additions & 9 deletions lib/app/shared/widget/dialog/error_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ class ErrorDialog extends StatelessWidget {
required this.title,
this.erroDescription,
this.erroUrl,
this.icon = IconStrings.alert,
this.dialogColor,
this.bgColor,
this.textColor,
Expand All @@ -21,7 +20,6 @@ class ErrorDialog extends StatelessWidget {
final Color? dialogColor;
final Color? bgColor;
final Color? textColor;
final String icon;

@override
Widget build(BuildContext context) {
Expand All @@ -41,12 +39,12 @@ class ErrorDialog extends StatelessWidget {
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
icon,
width: 50,
height: 50,
),
const SizedBox(height: 15),
// Image.asset(
// icon,
// width: 50,
// height: 50,
// ),
const SizedBox(height: 25),
Text(
title,
style: Theme.of(context)
Expand Down Expand Up @@ -90,7 +88,8 @@ class ErrorDialog extends StatelessWidget {
onPressed: () {
Navigator.of(context).pop(true);
},
)
),
const SizedBox(height: 10),
],
),
);
Expand Down
58 changes: 38 additions & 20 deletions lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import 'package:bloc/bloc.dart';
import 'package:credential_manifest/credential_manifest.dart';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
import 'package:did_kit/did_kit.dart';
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
Expand Down Expand Up @@ -497,6 +496,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {

responseType = response['response_type'];
final redirectUri = response['redirect_uri'];
final responseUri = response['response_uri'];
final responseMode = response['response_mode'];
final nonce = response['nonce'];
final clientId = response['client_id'];
Expand All @@ -516,6 +516,10 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
queryJson['redirect_uri'] = redirectUri;
}

if (responseUri != null) {
queryJson['response_uri'] = responseUri;
}

if (responseMode != null) {
queryJson['response_mode'] = responseMode;
}
Expand Down Expand Up @@ -573,23 +577,23 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
}

final String? responseMode = state.uri!.queryParameters['response_mode'];

final bool correctResponeMode = responseMode != null &&
(responseMode == 'post' || responseMode == 'direct_post');

/// check response mode value
if (!correctResponeMode) {
return emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_responseTypeNotSupported),
ResponseString.RESPONSE_STRING_responseTypeNotSupported,
),
);
}

final registration = state.uri!.queryParameters['registration'];
final bool isSecurityLow = profileCubit.state.model.isSecurityLow;
final bool isSecurityHigh = !profileCubit.state.model.isSecurityLow;

if (registration == null) {
if (isSecurityLow) {
if (isSecurityHigh) {
return emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_subjectSyntaxTypeNotSupported,
Expand All @@ -601,7 +605,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
final data =
registrationMap['subject_syntax_types_supported'] as List<dynamic>;
if (!data.contains('did:key')) {
if (isSecurityLow) {
if (isSecurityHigh) {
return emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_subjectSyntaxTypeNotSupported,
Expand All @@ -614,13 +618,37 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
log.i('responseType - $responseType');
if (responseType == 'id_token') {
/// verifier side (siopv2)
await completeSiopV2Flow();
final String? redirectUri = getRedirectUri(state.uri!);

if (redirectUri == null) {
emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_invalidRequest,
),
);
return;
}
await completeSiopV2Flow(redirectUri: redirectUri);
} else if (responseType == 'vp_token' ||
responseType == 'id_token vp_token') {
/// responseType == 'vp_token' => verifier side (oidc4vp)
///
/// responseType == 'id_token vp_token' => verifier side (oidc4vp)
/// or (oidc4vp and siopv2)
if (responseMode == 'direct_post') {
final redirectUri = state.uri!.queryParameters['redirect_uri'];
final responseUri = state.uri!.queryParameters['response_uri'];
final bothPresent = redirectUri != null && responseUri != null;
final bothAbsent = redirectUri == null && responseUri == null;

if (bothPresent || bothAbsent) {
return emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_invalidRequest,
),
);
}
}
await launchOIDC4VPAndSIOPV2Flow(keys);
} else {
return emitError(
Expand Down Expand Up @@ -847,34 +875,24 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
} else {
emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_theRequestIsRejected,
ResponseString.RESPONSE_STRING_invalidRequest,
),
);
}
} catch (e) {
emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_theRequestIsRejected,
ResponseString.RESPONSE_STRING_invalidRequest,
),
);
}
}
}

/// complete SIOPV2 Flow
Future<void> completeSiopV2Flow() async {
Future<void> completeSiopV2Flow({required String redirectUri}) async {
try {
final clientId = state.uri!.queryParameters['client_id'] ?? '';
final String? redirectUri = getRedirectUri(state.uri!);

if (redirectUri == null) {
emitError(
ResponseMessage(
ResponseString.RESPONSE_STRING_invalidRequest,
),
);
return;
}

final nonce = state.uri?.queryParameters['nonce'];
final stateValue = state.uri?.queryParameters['state'];
Expand Down
18 changes: 14 additions & 4 deletions lib/scan/cubit/scan_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -501,9 +501,6 @@ class ScanCubit extends Cubit<ScanState> {
await Future<void>.delayed(const Duration(milliseconds: 500));

try {
final String? redirectUri = getRedirectUri(uri);
if (redirectUri == null) throw Exception();

final String vpToken = await createVpToken(
credentialsToBePresented: credentialsToBePresented!,
did: did,
Expand All @@ -528,10 +525,23 @@ class ScanCubit extends Cubit<ScanState> {
responseData['state'] = stateValue;
}

final redirectUri = uri.queryParameters['redirect_uri'];
final responseUri = uri.queryParameters['response_uri'];

late String url;

if (responseUri != null) {
url = responseUri;
} else if (redirectUri != null) {
url = redirectUri;
} else {
throw Exception();
}

final formData = FormData.fromMap(responseData);

final result = await client.post(
redirectUri,
url,
data: formData,
headers: <String, dynamic>{
'Content-Type': 'application/x-www-form-urlencoded',
Expand Down
4 changes: 1 addition & 3 deletions lib/splash/widgets/subtitle_text.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:altme/app/app.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';
Expand All @@ -11,9 +10,8 @@ class SubTitle extends StatelessWidget {
final l10n = context.l10n;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: MyText(
child: Text(
l10n.splashSubtitle,
maxLines: 2,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.starterSubTitleStyle,
),
Expand Down
1 change: 1 addition & 0 deletions packages/oidc4vc/lib/src/oidc4vc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ class OIDC4VC {
tokenData = <String, dynamic>{
'pre-authorized_code': preAuthorizedCode,
'grant_type': 'urn:ietf:params:oauth:grant-type:pre-authorized_code',
'client_id': did,
};
} else if (code != null && codeVerifier != null && did != null) {
tokenData = <String, dynamic>{
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: altme
description: AltMe Flutter App
version: 1.20.29+278
version: 1.20.30+279
publish_to: none

environment:
Expand Down

0 comments on commit a8948c1

Please sign in to comment.