Skip to content

Commit f8bd32e

Browse files
MaikuBrfuerst87
andauthoredNov 17, 2021
[flutter_appauth][flutter_appauth_platform_interface] added support for end session requests (MaikuB#216)
* progress on end session on iOS * various fixes * further updates to platform interface to handle end session requests * bump AppAuth iOS dependency to 1.4.0 * update AuthorizationServiceConfiguration to have nullable props * complete wiring up end session request on Android and iOS * update plugin for prerelease * add missing changelog entry on SDK dependencies being bumped * update Dart SDK constraints * update readmes and add mention to changelog * fix null endSessionEndpoint crash on iOS * bump platform interface * fix merge issue * bump plugin * Skip https issuer check if allowInsecureConnections is true. (MaikuB#228) * bump to 2.0.0-dev.3 * bump AppAuth Android dependency * create external user agent per request, which also issue where cancelling an end session request once won't allow for subsequent sessions to work * fix example app so that refreshing access token works again * bump for release * fix imports in example app * fix spacing in changelog * bump platform interface to 4.0.0 stable release * bump plugin to 2.0.0 stable Co-authored-by: Roman Fürst <r.fuerst@gmx.ch>

23 files changed

+518
-146
lines changed
 

‎README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# flutter_appauth
22
A Flutter plugin that provides a wrapper for native AppAuth SDKs (https://appauth.io) used authenticating and authorizing users. The repository consists of the following folders
33

4-
- flutter_appauth: code for the plugin
5-
- flutter_appauth_platform_interface: the code for common platform interface
4+
- [flutter_appauth](https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth): code for the plugin
5+
- [flutter_appauth_platform_interface](https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth_platform_interface): the code for common platform interface

‎flutter_appauth/CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 2.0.0
2+
3+
* **Breaking change** `AuthorizationServiceConfiguration` constructor has changed to take named parameters
4+
* Added `endSession()` method, `EndSessionRequest` and `EndSessionResponse` classes to support end session requests
5+
* [Android] skips https issuer check if `allowInsecureConnections` is true. Thanks to the PR from [Roman Fürst](https://github.com/rfuerst87)
6+
* Bumped AppAuth Android and iOS SDK dependencies
7+
* Added FAQs section to readme to describe a common iOS issue with Azure B2C and Azure AD
8+
19
## 1.1.1
210

311
* [Android] Migrate maven repository from jcenter to mavenCentral.

‎flutter_appauth/README.md

+22-3
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode
5454
);
5555
```
5656

57-
If you already know the authorization and token endpoints, which may be because discovery isn't supported, then these could be explicitly specified
57+
In the event that discovery isn't supported or that you already know the endpoints for your server, they could be explicitly specified in the event that the dis
5858

5959
```dart
6060
final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
6161
AuthorizationTokenRequest(
6262
'<client_id>',
6363
'<redirect_url>',
64-
serviceConfiguration: AuthorizationServiceConfiguration('<authorization_endpoint>', '<token_endpoint>'),
65-
scopes: ['openid','profile', 'email', 'offline_access', 'api']
64+
serviceConfiguration: AuthorizationServiceConfiguration(authorizationEndpoint: '<authorization_endpoint>', tokenEndpooint: '<token_endpoint>', endSessionEndpoint: '<end_session_endpoint>'),
65+
scopes: [...]
6666
),
6767
);
6868
```
@@ -90,6 +90,19 @@ final TokenResponse result = await appAuth.token(TokenRequest('<client_id>', '<r
9090
scopes: ['openid','profile', 'email', 'offline_access', 'api']));
9191
```
9292

93+
### End session
94+
95+
If your server has an [end session endpoint](https://openid.net/specs/openid-connect-rpinitiated-1_0.html), you can trigger an end session request that is typically used for logging out of the built-in browser with code similar to what's shown below
96+
97+
```dart
98+
await appAuth.endSession(EndSessionRequest(
99+
idTokenHint: '<idToken>',
100+
postLogoutRedirectUrl: '<postLogoutRedirectUrl>',
101+
serviceConfiguration: AuthorizationServiceConfiguration(authorizationEndpoint: '<authorization_endpoint>', tokenEndpooint: '<token_endpoint>', endSessionEndpoint: '<end_session_endpoint>'));
102+
```
103+
104+
The above code passes an `AuthorizationServiceConfiguration` with all the endpoints defined but alternatives are to specify an `issuer` or `discoveryUrl` like you would with the other APIs in the plugin (e.g. `authorizeAndExchangeCode()`).
105+
93106
## Android setup
94107

95108
Go to the `build.gradle` file for your Android app to specify the custom scheme so that there should be a section in it that look similar to the following but replace `<your_custom_scheme>` with the desired value
@@ -145,3 +158,9 @@ Go to the `Info.plist` for your iOS app to specify the custom scheme so that the
145158
</dict>
146159
</array>
147160
```
161+
162+
## FAQs
163+
164+
**When connecting to Azure B2C or Azure AD, the login request redirects properly on Android but not on iOS. What's going on?**
165+
166+
The AppAuth iOS SDK has some logic to validate the redirect URL to see if it should be responsible for processing the redirect. This appears to be failing under certain circumstances. Adding a trailing slash to the redirect URL specified in your code has been reported to fix the issue.

‎flutter_appauth/android/src/main/java/io/crossingthestreams/flutterappauth/FlutterAppauthPlugin.java

+144-40
Large diffs are not rendered by default.

‎flutter_appauth/example/lib/main.dart

+49-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'dart:io' show Platform;
22
import 'package:flutter/material.dart';
3-
import 'package:http/http.dart' as http;
43
import 'package:flutter_appauth/flutter_appauth.dart';
4+
import 'package:http/http.dart' as http;
55

66
void main() => runApp(MyApp());
77

@@ -17,6 +17,8 @@ class _MyAppState extends State<MyApp> {
1717
String? _authorizationCode;
1818
String? _refreshToken;
1919
String? _accessToken;
20+
String? _idToken;
21+
2022
final TextEditingController _authorizationCodeTextController =
2123
TextEditingController();
2224
final TextEditingController _accessTokenTextController =
@@ -27,14 +29,15 @@ class _MyAppState extends State<MyApp> {
2729
final TextEditingController _idTokenTextController = TextEditingController();
2830
final TextEditingController _refreshTokenTextController =
2931
TextEditingController();
30-
String _userInfo = '';
32+
String? _userInfo;
3133

3234
// For a list of client IDs, go to https://demo.identityserver.io
3335
final String _clientId = 'interactive.public';
3436
final String _redirectUrl = 'io.identityserver.demo:/oauthredirect';
3537
final String _issuer = 'https://demo.identityserver.io';
3638
final String _discoveryUrl =
3739
'https://demo.identityserver.io/.well-known/openid-configuration';
40+
final String _postLogoutRedirectUrl = 'io.identityserver.demo:/';
3841
final List<String> _scopes = <String>[
3942
'openid',
4043
'profile',
@@ -45,13 +48,10 @@ class _MyAppState extends State<MyApp> {
4548

4649
final AuthorizationServiceConfiguration _serviceConfiguration =
4750
const AuthorizationServiceConfiguration(
48-
'https://demo.identityserver.io/connect/authorize',
49-
'https://demo.identityserver.io/connect/token');
50-
51-
@override
52-
void initState() {
53-
super.initState();
54-
}
51+
authorizationEndpoint: 'https://demo.identityserver.io/connect/authorize',
52+
tokenEndpoint: 'https://demo.identityserver.io/connect/token',
53+
endSessionEndpoint: 'https://demo.identityserver.io/connect/endsession',
54+
);
5555

5656
@override
5757
Widget build(BuildContext context) {
@@ -95,6 +95,14 @@ class _MyAppState extends State<MyApp> {
9595
child: const Text('Refresh token'),
9696
onPressed: _refreshToken != null ? _refresh : null,
9797
),
98+
ElevatedButton(
99+
child: const Text('End session'),
100+
onPressed: _idToken != null
101+
? () async {
102+
await _endSession();
103+
}
104+
: null,
105+
),
98106
const Text('authorization code'),
99107
TextField(
100108
controller: _authorizationCodeTextController,
@@ -116,22 +124,48 @@ class _MyAppState extends State<MyApp> {
116124
controller: _refreshTokenTextController,
117125
),
118126
const Text('test api results'),
119-
Text(_userInfo),
127+
Text(_userInfo ?? ''),
120128
],
121129
),
122130
),
123131
),
124132
);
125133
}
126134

135+
Future<void> _endSession() async {
136+
try {
137+
_setBusyState();
138+
await _appAuth.endSession(EndSessionRequest(
139+
idTokenHint: _idToken,
140+
postLogoutRedirectUrl: _postLogoutRedirectUrl,
141+
serviceConfiguration: _serviceConfiguration));
142+
_clearSessionInfo();
143+
} catch (_) {}
144+
_clearBusyState();
145+
}
146+
147+
void _clearSessionInfo() {
148+
setState(() {
149+
_codeVerifier = null;
150+
_authorizationCode = null;
151+
_authorizationCodeTextController.clear();
152+
_accessToken = null;
153+
_accessTokenTextController.clear();
154+
_idToken = null;
155+
_idTokenTextController.clear();
156+
_refreshToken = null;
157+
_refreshTokenTextController.clear();
158+
_accessTokenExpirationTextController.clear();
159+
_userInfo = null;
160+
});
161+
}
162+
127163
Future<void> _refresh() async {
128164
try {
129165
_setBusyState();
130166
final TokenResponse? result = await _appAuth.token(TokenRequest(
131167
_clientId, _redirectUrl,
132-
refreshToken: _refreshToken,
133-
discoveryUrl: _discoveryUrl,
134-
scopes: _scopes));
168+
refreshToken: _refreshToken, issuer: _issuer, scopes: _scopes));
135169
_processTokenResponse(result);
136170
await _testApi(result);
137171
} catch (_) {
@@ -230,7 +264,7 @@ class _MyAppState extends State<MyApp> {
230264
void _processAuthTokenResponse(AuthorizationTokenResponse response) {
231265
setState(() {
232266
_accessToken = _accessTokenTextController.text = response.accessToken!;
233-
_idTokenTextController.text = response.idToken!;
267+
_idToken = _idTokenTextController.text = response.idToken!;
234268
_refreshToken = _refreshTokenTextController.text = response.refreshToken!;
235269
_accessTokenExpirationTextController.text =
236270
response.accessTokenExpirationDateTime!.toIso8601String();
@@ -250,7 +284,7 @@ class _MyAppState extends State<MyApp> {
250284
void _processTokenResponse(TokenResponse? response) {
251285
setState(() {
252286
_accessToken = _accessTokenTextController.text = response!.accessToken!;
253-
_idTokenTextController.text = response.idToken!;
287+
_idToken = _idTokenTextController.text = response.idToken!;
254288
_refreshToken = _refreshTokenTextController.text = response.refreshToken!;
255289
_accessTokenExpirationTextController.text =
256290
response.accessTokenExpirationDateTime!.toIso8601String();

‎flutter_appauth/ios/Classes/FlutterAppauthPlugin.m

+137-53
Large diffs are not rendered by default.

‎flutter_appauth/lib/flutter_appauth.dart

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ export 'package:flutter_appauth_platform_interface/flutter_appauth_platform_inte
55
AuthorizationServiceConfiguration,
66
AuthorizationTokenRequest,
77
AuthorizationTokenResponse,
8+
EndSessionRequest,
9+
EndSessionResponse,
810
GrantType,
911
TokenRequest,
1012
TokenResponse;

‎flutter_appauth/lib/src/flutter_appauth.dart

+4
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ class FlutterAppAuth {
1616
Future<TokenResponse?> token(TokenRequest request) {
1717
return FlutterAppAuthPlatform.instance.token(request);
1818
}
19+
20+
Future<EndSessionResponse?> endSession(EndSessionRequest request) {
21+
return FlutterAppAuthPlatform.instance.endSession(request);
22+
}
1923
}

‎flutter_appauth/pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: flutter_appauth
22
description: This plugin provides an abstraction around the Android and iOS AppAuth SDKs so it can be used to communicate with OAuth 2.0 and OpenID Connect providers
3-
version: 1.1.1
3+
version: 2.0.0
44
homepage: https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth
55

66
environment:
@@ -10,7 +10,7 @@ environment:
1010
dependencies:
1111
flutter:
1212
sdk: flutter
13-
flutter_appauth_platform_interface: ^3.0.0
13+
flutter_appauth_platform_interface: ^4.0.0
1414

1515
flutter:
1616
plugin:

‎flutter_appauth_platform_interface/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## [4.0.0]
2+
3+
* **Breaking change** `AuthorizationServiceConfiguration` constructor has changed to take named parameters
4+
* Added `endSession()` method, `EndSessionRequest` and `EndSessionResponse` classes to support end session requests
5+
16
## [3.1.0]
27

38
* Added the ability to specify the response mode for authorization requests. This can be done using the `responseMode` parameter when constructing either an `AuthorizationRequest` or `AuthorizationTokenRequest`. This was done as the AppAuth Android SDK throws an exception when this was done via `additionalParameters`

‎flutter_appauth_platform_interface/lib/flutter_appauth_platform_interface.dart

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ export 'src/authorization_response.dart';
33
export 'src/authorization_service_configuration.dart';
44
export 'src/authorization_token_request.dart';
55
export 'src/authorization_token_response.dart';
6+
export 'src/end_session_request.dart';
7+
export 'src/end_session_response.dart';
68
export 'src/grant_types.dart';
79
export 'src/token_request.dart';
810
export 'src/token_response.dart';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'authorization_service_configuration.dart';
2+
3+
mixin AcceptedAuthorizationServiceConfigurationDetails {
4+
/// The issuer.
5+
String? issuer;
6+
7+
/// The URL of where the discovery document can be found.
8+
String? discoveryUrl;
9+
10+
/// The details of the OAuth 2.0 endpoints that can be explicitly provided when discovery isn't used or not possible.
11+
AuthorizationServiceConfiguration? serviceConfiguration;
12+
13+
void assertConfigurationInfo() {
14+
assert(
15+
issuer != null || discoveryUrl != null || serviceConfiguration != null,
16+
'Either the issuer, discovery URL or service configuration must be provided');
17+
}
18+
}

‎flutter_appauth_platform_interface/lib/src/authorization_request.dart

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ class AuthorizationRequest extends CommonRequestDetails
88
AuthorizationRequest(
99
String clientId,
1010
String redirectUrl, {
11+
String? issuer,
12+
String? discoveryUrl,
13+
AuthorizationServiceConfiguration? serviceConfiguration,
1114
String? loginHint,
1215
List<String>? scopes,
13-
AuthorizationServiceConfiguration? serviceConfiguration,
1416
Map<String, String>? additionalParameters,
15-
String? issuer,
16-
String? discoveryUrl,
1717
List<String>? promptValues,
1818
bool allowInsecureConnections = false,
1919
bool preferEphemeralSession = false,
@@ -31,5 +31,6 @@ class AuthorizationRequest extends CommonRequestDetails
3131
this.allowInsecureConnections = allowInsecureConnections;
3232
this.preferEphemeralSession = preferEphemeralSession;
3333
this.responseMode = responseMode;
34+
assertConfigurationInfo();
3435
}
3536
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
class AuthorizationServiceConfiguration {
2-
const AuthorizationServiceConfiguration(
3-
this.authorizationEndpoint,
4-
this.tokenEndpoint,
5-
);
2+
const AuthorizationServiceConfiguration({
3+
required this.authorizationEndpoint,
4+
required this.tokenEndpoint,
5+
this.endSessionEndpoint,
6+
});
67

78
final String authorizationEndpoint;
89

910
final String tokenEndpoint;
11+
12+
final String? endSessionEndpoint;
1013
}

‎flutter_appauth_platform_interface/lib/src/common_request_details.dart

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
1-
import 'authorization_service_configuration.dart';
1+
import 'accepted_authorization_service_configuration_details.dart';
22

3-
class CommonRequestDetails {
3+
class CommonRequestDetails
4+
with AcceptedAuthorizationServiceConfigurationDetails {
45
/// The client id.
56
late String clientId;
67

7-
/// The issuer.
8-
String? issuer;
9-
10-
/// The URL of where the discovery document can be found.
11-
String? discoveryUrl;
12-
138
/// The redirect URL.
149
late String redirectUrl;
1510

1611
/// The request scopes.
1712
List<String>? scopes;
1813

19-
/// The details of the OAuth 2.0 endpoints that can be explicitly when discovery isn't used or not possible.
20-
AuthorizationServiceConfiguration? serviceConfiguration;
21-
2214
/// Additional parameters to include in the request.
2315
Map<String, String>? additionalParameters;
2416

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'package:flutter_appauth_platform_interface/flutter_appauth_platform_interface.dart';
2+
import 'package:flutter_appauth_platform_interface/src/accepted_authorization_service_configuration_details.dart';
3+
4+
class EndSessionRequest with AcceptedAuthorizationServiceConfigurationDetails {
5+
EndSessionRequest({
6+
this.idTokenHint,
7+
this.postLogoutRedirectUrl,
8+
this.state,
9+
this.allowInsecureConnections = false,
10+
this.additionalParameters,
11+
String? issuer,
12+
String? discoveryUrl,
13+
AuthorizationServiceConfiguration? serviceConfiguration,
14+
}) {
15+
assert((idTokenHint == null && postLogoutRedirectUrl == null) ||
16+
(idTokenHint != null && postLogoutRedirectUrl != null));
17+
this.serviceConfiguration = serviceConfiguration;
18+
this.issuer = issuer;
19+
this.discoveryUrl = discoveryUrl;
20+
}
21+
22+
/// Represents the ID token previously issued to the user.
23+
///
24+
/// Used to indicate the identity of the user requesting to be logged out.
25+
final String? idTokenHint;
26+
27+
/// Represents the URL to redirect to after the logout operation has been completed.
28+
///
29+
/// When specified, the [idTokenHint] must also be provided.
30+
final String? postLogoutRedirectUrl;
31+
32+
final String? state;
33+
34+
/// Whether to allow non-HTTPS endpoints.
35+
///
36+
/// This property is only applicable to Android.
37+
bool allowInsecureConnections;
38+
39+
final Map<String, String>? additionalParameters;
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class EndSessionResponse {
2+
final String? state;
3+
4+
EndSessionResponse(this.state);
5+
}

‎flutter_appauth_platform_interface/lib/src/flutter_appauth_platform.dart

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import 'package:flutter_appauth_platform_interface/src/method_channel_flutter_appauth.dart';
21
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
32

43
import 'authorization_request.dart';
54
import 'authorization_response.dart';
65
import 'authorization_token_request.dart';
76
import 'authorization_token_response.dart';
7+
import 'end_session_request.dart';
8+
import 'end_session_response.dart';
9+
import 'method_channel_flutter_appauth.dart';
810
import 'token_request.dart';
911
import 'token_response.dart';
1012

@@ -44,4 +46,8 @@ abstract class FlutterAppAuthPlatform extends PlatformInterface {
4446
Future<TokenResponse?> token(TokenRequest request) {
4547
throw UnimplementedError('token() has not been implemented');
4648
}
49+
50+
Future<EndSessionResponse?> endSession(EndSessionRequest request) {
51+
throw UnimplementedError('endSession() has not been implemented');
52+
}
4753
}

‎flutter_appauth_platform_interface/lib/src/method_channel_flutter_appauth.dart

+12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import 'package:flutter/services.dart';
2+
import 'package:flutter_appauth_platform_interface/src/end_session_request.dart';
3+
import 'package:flutter_appauth_platform_interface/src/end_session_response.dart';
24

35
import 'authorization_request.dart';
46
import 'authorization_response.dart';
@@ -65,4 +67,14 @@ class MethodChannelFlutterAppAuth extends FlutterAppAuthPlatform {
6567
result['tokenType'],
6668
result['tokenAdditionalParameters']?.cast<String, dynamic>());
6769
}
70+
71+
@override
72+
Future<EndSessionResponse?> endSession(EndSessionRequest request) async {
73+
final Map<dynamic, dynamic>? result =
74+
await _channel.invokeMethod('endSession', request.toMap());
75+
if (result == null) {
76+
return null;
77+
}
78+
return EndSessionResponse(result['state']);
79+
}
6880
}

‎flutter_appauth_platform_interface/lib/src/method_channel_mappers.dart

+19-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'authorization_request.dart';
33
import 'authorization_service_configuration.dart';
44
import 'authorization_token_request.dart';
55
import 'common_request_details.dart';
6+
import 'end_session_request.dart';
67
import 'grant_types.dart';
78
import 'token_request.dart';
89

@@ -20,6 +21,21 @@ Map<String, Object?> _convertCommonRequestDetailsToMap(
2021
};
2122
}
2223

24+
extension EndSessionRequestMapper on EndSessionRequest {
25+
Map<String, Object?> toMap() {
26+
return <String, Object?>{
27+
'idTokenHint': idTokenHint,
28+
'postLogoutRedirectUrl': postLogoutRedirectUrl,
29+
'state': state,
30+
'allowInsecureConnections': allowInsecureConnections,
31+
'additionalParameters': additionalParameters,
32+
'issuer': issuer,
33+
'discoveryUrl': discoveryUrl,
34+
'serviceConfiguration': serviceConfiguration?.toMap(),
35+
};
36+
}
37+
}
38+
2339
extension AuthorizationRequestParameters on AuthorizationRequest {
2440
Map<String, Object?> toMap() {
2541
return _convertAuthorizationParametersToMap(this)
@@ -29,10 +45,11 @@ extension AuthorizationRequestParameters on AuthorizationRequest {
2945

3046
extension AuthorizationServiceConfigurationMapper
3147
on AuthorizationServiceConfiguration {
32-
Map<String, Object> toMap() {
33-
return <String, Object>{
48+
Map<String, Object?> toMap() {
49+
return <String, Object?>{
3450
'tokenEndpoint': tokenEndpoint,
3551
'authorizationEndpoint': authorizationEndpoint,
52+
'endSessionEndpoint': endSessionEndpoint,
3653
};
3754
}
3855
}

‎flutter_appauth_platform_interface/lib/src/token_request.dart

+5-9
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,22 @@ import 'authorization_service_configuration.dart';
22
import 'common_request_details.dart';
33

44
/// Details for a token exchange request.
5-
class TokenRequest with CommonRequestDetails {
5+
class TokenRequest extends CommonRequestDetails {
66
TokenRequest(
77
String clientId,
88
String redirectUrl, {
99
this.clientSecret,
1010
List<String>? scopes,
11+
String? issuer,
12+
String? discoveryUrl,
1113
AuthorizationServiceConfiguration? serviceConfiguration,
1214
Map<String, String>? additionalParameters,
1315
this.refreshToken,
1416
this.grantType,
15-
String? issuer,
16-
String? discoveryUrl,
1717
this.authorizationCode,
1818
this.codeVerifier,
1919
bool allowInsecureConnections = false,
20-
}) : assert(
21-
issuer != null ||
22-
discoveryUrl != null ||
23-
(serviceConfiguration?.authorizationEndpoint != null &&
24-
serviceConfiguration?.tokenEndpoint != null),
25-
'Either the issuer, discovery URL or service configuration must be provided') {
20+
}) {
2621
this.clientId = clientId;
2722
this.redirectUrl = redirectUrl;
2823
this.scopes = scopes;
@@ -31,6 +26,7 @@ class TokenRequest with CommonRequestDetails {
3126
this.issuer = issuer;
3227
this.discoveryUrl = discoveryUrl;
3328
this.allowInsecureConnections = allowInsecureConnections;
29+
assertConfigurationInfo();
3430
}
3531

3632
/// The client secret.

‎flutter_appauth_platform_interface/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: flutter_appauth_platform_interface
22
description: A common platform interface for the flutter_appauth plugin.
3-
version: 3.1.0
3+
version: 4.0.0
44
homepage: https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth_platform_interface
55

66
environment:

‎flutter_appauth_platform_interface/test/method_channel_flutter_appauth_test.dart

+20
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,26 @@ void main() {
159159
);
160160
});
161161
});
162+
163+
test('endSession', () async {
164+
await flutterAppAuth.endSession(EndSessionRequest(
165+
idTokenHint: 'someIdToken',
166+
postLogoutRedirectUrl: 'somePostLogoutRedirectUrl',
167+
state: 'someState',
168+
discoveryUrl: 'someDiscoveryUrl'));
169+
expect(log, <Matcher>[
170+
isMethodCall('endSession', arguments: <String, Object?>{
171+
'idTokenHint': 'someIdToken',
172+
'postLogoutRedirectUrl': 'somePostLogoutRedirectUrl',
173+
'state': 'someState',
174+
'allowInsecureConnections': false,
175+
'additionalParameters': null,
176+
'issuer': null,
177+
'discoveryUrl': 'someDiscoveryUrl',
178+
'serviceConfiguration': null,
179+
})
180+
]);
181+
});
162182
}
163183

164184
class FlutterAppAuthPlatformMock extends Mock

0 commit comments

Comments
 (0)
Please sign in to comment.