Skip to content

Commit b0d390f

Browse files
authored
[flutter_appauth_platform_interface][flutter_appauth] migrate to null safety (MaikuB#187)
* migrate platform interface to null safety * update cirrus script * migrate plugin to null safety * address warnings in example app * updated constraints for plugin_platform_interface dependency * make clientId and redirectUrl non-nullable * updated plugin_platform_interface version requirement * update flutter_appauth_platform_interface for stable release * switch cirrus script to build on stable * make ios build task upgrade from stable * bump version for stable release
1 parent 8d266d8 commit b0d390f

21 files changed

+130
-121
lines changed

Diff for: .cirrus.yml

+2
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ task:
2424
pub_cache:
2525
folder: ~/.pub-cache
2626
build_script:
27+
- flutter channel stable
28+
- flutter upgrade
2729
- cd flutter_appauth/example
2830
- flutter build ios --no-codesign

Diff for: flutter_appauth/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.0.0
2+
3+
* Migrated to null safety
4+
15
## 0.9.2+6
26

37
* [Android] community has reported that there seem to be instances where the plugin encounters a null intent on some devices upon processing a authorisation request. This resulted in a crash before but will now throw a `PlatformException`. Thanks to the PR from [Leon Havenga](https://github.com/li0nza)

Diff for: flutter_appauth/example/lib/main.dart

+26-26
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ class MyApp extends StatefulWidget {
1313
class _MyAppState extends State<MyApp> {
1414
bool _isBusy = false;
1515
final FlutterAppAuth _appAuth = FlutterAppAuth();
16-
String _codeVerifier;
17-
String _authorizationCode;
18-
String _refreshToken;
19-
String _accessToken;
16+
String? _codeVerifier;
17+
String? _authorizationCode;
18+
String? _refreshToken;
19+
String? _accessToken;
2020
final TextEditingController _authorizationCodeTextController =
2121
TextEditingController();
2222
final TextEditingController _accessTokenTextController =
@@ -44,7 +44,7 @@ class _MyAppState extends State<MyApp> {
4444
];
4545

4646
final AuthorizationServiceConfiguration _serviceConfiguration =
47-
AuthorizationServiceConfiguration(
47+
const AuthorizationServiceConfiguration(
4848
'https://demo.identityserver.io/connect/authorize',
4949
'https://demo.identityserver.io/connect/token');
5050

@@ -67,22 +67,22 @@ class _MyAppState extends State<MyApp> {
6767
visible: _isBusy,
6868
child: const LinearProgressIndicator(),
6969
),
70-
RaisedButton(
70+
ElevatedButton(
7171
child: const Text('Sign in with no code exchange'),
7272
onPressed: _signInWithNoCodeExchange,
7373
),
74-
RaisedButton(
74+
ElevatedButton(
7575
child: const Text('Exchange code'),
7676
onPressed: _authorizationCode != null ? _exchangeCode : null,
7777
),
78-
RaisedButton(
78+
ElevatedButton(
7979
child: const Text('Sign in with auto code exchange'),
8080
onPressed: () => _signInWithAutoCodeExchange(),
8181
),
8282
if (Platform.isIOS)
8383
Padding(
8484
padding: const EdgeInsets.all(8.0),
85-
child: RaisedButton(
85+
child: ElevatedButton(
8686
child: const Text(
8787
'Sign in with auto code exchange using ephemeral session (iOS only)',
8888
textAlign: TextAlign.center,
@@ -91,7 +91,7 @@ class _MyAppState extends State<MyApp> {
9191
preferEphemeralSession: true),
9292
),
9393
),
94-
RaisedButton(
94+
ElevatedButton(
9595
child: const Text('Refresh token'),
9696
onPressed: _refreshToken != null ? _refresh : null,
9797
),
@@ -127,7 +127,7 @@ class _MyAppState extends State<MyApp> {
127127
Future<void> _refresh() async {
128128
try {
129129
_setBusyState();
130-
final TokenResponse result = await _appAuth.token(TokenRequest(
130+
final TokenResponse? result = await _appAuth.token(TokenRequest(
131131
_clientId, _redirectUrl,
132132
refreshToken: _refreshToken,
133133
discoveryUrl: _discoveryUrl,
@@ -142,7 +142,7 @@ class _MyAppState extends State<MyApp> {
142142
Future<void> _exchangeCode() async {
143143
try {
144144
_setBusyState();
145-
final TokenResponse result = await _appAuth.token(TokenRequest(
145+
final TokenResponse? result = await _appAuth.token(TokenRequest(
146146
_clientId, _redirectUrl,
147147
authorizationCode: _authorizationCode,
148148
discoveryUrl: _discoveryUrl,
@@ -159,7 +159,7 @@ class _MyAppState extends State<MyApp> {
159159
try {
160160
_setBusyState();
161161
// use the discovery endpoint to find the configuration
162-
final AuthorizationResponse result = await _appAuth.authorize(
162+
final AuthorizationResponse? result = await _appAuth.authorize(
163163
AuthorizationRequest(_clientId, _redirectUrl,
164164
discoveryUrl: _discoveryUrl, scopes: _scopes, loginHint: 'bob'),
165165
);
@@ -187,7 +187,7 @@ class _MyAppState extends State<MyApp> {
187187
_setBusyState();
188188

189189
// show that we can also explicitly specify the endpoints rather than getting from the details from the discovery document
190-
final AuthorizationTokenResponse result =
190+
final AuthorizationTokenResponse? result =
191191
await _appAuth.authorizeAndExchangeCode(
192192
AuthorizationTokenRequest(
193193
_clientId,
@@ -229,11 +229,11 @@ class _MyAppState extends State<MyApp> {
229229

230230
void _processAuthTokenResponse(AuthorizationTokenResponse response) {
231231
setState(() {
232-
_accessToken = _accessTokenTextController.text = response.accessToken;
233-
_idTokenTextController.text = response.idToken;
234-
_refreshToken = _refreshTokenTextController.text = response.refreshToken;
232+
_accessToken = _accessTokenTextController.text = response.accessToken!;
233+
_idTokenTextController.text = response.idToken!;
234+
_refreshToken = _refreshTokenTextController.text = response.refreshToken!;
235235
_accessTokenExpirationTextController.text =
236-
response.accessTokenExpirationDateTime?.toIso8601String();
236+
response.accessTokenExpirationDateTime!.toIso8601String();
237237
});
238238
}
239239

@@ -242,24 +242,24 @@ class _MyAppState extends State<MyApp> {
242242
// save the code verifier as it must be used when exchanging the token
243243
_codeVerifier = response.codeVerifier;
244244
_authorizationCode =
245-
_authorizationCodeTextController.text = response.authorizationCode;
245+
_authorizationCodeTextController.text = response.authorizationCode!;
246246
_isBusy = false;
247247
});
248248
}
249249

250-
void _processTokenResponse(TokenResponse response) {
250+
void _processTokenResponse(TokenResponse? response) {
251251
setState(() {
252-
_accessToken = _accessTokenTextController.text = response.accessToken;
253-
_idTokenTextController.text = response.idToken;
254-
_refreshToken = _refreshTokenTextController.text = response.refreshToken;
252+
_accessToken = _accessTokenTextController.text = response!.accessToken!;
253+
_idTokenTextController.text = response.idToken!;
254+
_refreshToken = _refreshTokenTextController.text = response.refreshToken!;
255255
_accessTokenExpirationTextController.text =
256-
response.accessTokenExpirationDateTime?.toIso8601String();
256+
response.accessTokenExpirationDateTime!.toIso8601String();
257257
});
258258
}
259259

260-
Future<void> _testApi(TokenResponse response) async {
260+
Future<void> _testApi(TokenResponse? response) async {
261261
final http.Response httpResponse = await http.get(
262-
'https://demo.identityserver.io/api/test',
262+
Uri.parse('https://demo.identityserver.io/api/test'),
263263
headers: <String, String>{'Authorization': 'Bearer $_accessToken'});
264264
setState(() {
265265
_userInfo = httpResponse.statusCode == 200 ? httpResponse.body : '';

Diff for: flutter_appauth/example/pubspec.yaml

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ version: 1.0.0+1
44
publish_to: 'none'
55

66
environment:
7-
sdk: ">=2.6.0 <3.0.0"
7+
sdk: '>=2.12.0-0 <3.0.0'
88

99
dependencies:
10+
cupertino_icons: ^1.0.2
1011
flutter:
1112
sdk: flutter
12-
13-
cupertino_icons: ^0.1.2
14-
http: ^0.12.0+1
1513
flutter_appauth:
1614
path: ../
15+
http: ^0.13.0
1716

1817
dev_dependencies:
1918
flutter_test:

Diff for: flutter_appauth/lib/src/flutter_appauth.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ import 'package:flutter_appauth_platform_interface/flutter_appauth_platform_inte
22

33
class FlutterAppAuth {
44
/// Convenience method for authorizing and then exchanges code
5-
Future<AuthorizationTokenResponse> authorizeAndExchangeCode(
5+
Future<AuthorizationTokenResponse?> authorizeAndExchangeCode(
66
AuthorizationTokenRequest request) {
77
return FlutterAppAuthPlatform.instance.authorizeAndExchangeCode(request);
88
}
99

1010
/// Sends an authorization request
11-
Future<AuthorizationResponse> authorize(AuthorizationRequest request) {
11+
Future<AuthorizationResponse?> authorize(AuthorizationRequest request) {
1212
return FlutterAppAuthPlatform.instance.authorize(request);
1313
}
1414

1515
/// For exchanging tokens
16-
Future<TokenResponse> token(TokenRequest request) {
16+
Future<TokenResponse?> token(TokenRequest request) {
1717
return FlutterAppAuthPlatform.instance.token(request);
1818
}
1919
}

Diff for: flutter_appauth/pubspec.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
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: 0.9.2+6
3+
version: 1.0.0
44
homepage: https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth
55

66
environment:
7-
sdk: '>=2.6.0 <3.0.0'
7+
sdk: '>=2.12.0-0 <3.0.0'
88
flutter: '>=1.12.13+hotfix.5'
99

1010
dependencies:
1111
flutter:
1212
sdk: flutter
13-
flutter_appauth_platform_interface: ^2.0.0
13+
flutter_appauth_platform_interface: ^3.0.0
1414

1515
flutter:
1616
plugin:

Diff for: flutter_appauth_platform_interface/CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
## [3.0.0]
2+
3+
* Migrated to null safety
4+
* `AuthorizationServiceConfiguration` and `AuthorizationResponse` now have `const` constructors
5+
16
## [2.0.0]
27

3-
* **BREAKING CHANGE** Removed the `toMap` methods so that it's not part of the public API surface. This was done as these methods were for internal use. Currently `flutter_appauth` (version 0.8.3) is constrained to depend on versions >= 1.0.2 and < 2.0.0. As it's possible that plugin consumers were calling the methods via the plugin, where the platform interface is a transitive dependency, the platform interface has been bumped to version 2.0.0 instead of 1.1.0 to be safe.
8+
* **Breaking change** Removed the `toMap` methods so that it's not part of the public API surface. This was done as these methods were for internal use. Currently `flutter_appauth` (version 0.8.3) is constrained to depend on versions >= 1.0.2 and < 2.0.0. As it's possible that plugin consumers were calling the methods via the plugin, where the platform interface is a transitive dependency, the platform interface has been bumped to version 2.0.0 instead of 1.1.0 to be safe.
49
* Added `preferEphemeralSession` to `AuthorizationRequest` and `AuthorizationTokenRequest` classes. Thanks to the PR from [Matthew Smith](https://github.com/matthewtsmith).
510

611
## [1.0.2]
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
mixin AuthorizationParameters {
22
/// Hint to the Authorization Server about the login identifier the End-User might use to log in.
3-
String loginHint;
3+
String? loginHint;
44

55
/// List of ASCII string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent.
6-
List<String> promptValues;
6+
List<String>? promptValues;
77

88
/// Whether to use an ephemeral session that prevents cookies and other browser data being shared with the user's normal browser session.
99
///
1010
/// This property is only applicable to iOS versions 13 and above.
11-
bool preferEphemeralSession;
11+
bool? preferEphemeralSession;
1212
}

Diff for: flutter_appauth_platform_interface/lib/src/authorization_request.dart

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ class AuthorizationRequest extends CommonRequestDetails
88
AuthorizationRequest(
99
String clientId,
1010
String redirectUrl, {
11-
String loginHint,
12-
List<String> scopes,
13-
AuthorizationServiceConfiguration serviceConfiguration,
14-
Map<String, String> additionalParameters,
15-
String issuer,
16-
String discoveryUrl,
17-
List<String> promptValues,
11+
String? loginHint,
12+
List<String>? scopes,
13+
AuthorizationServiceConfiguration? serviceConfiguration,
14+
Map<String, String>? additionalParameters,
15+
String? issuer,
16+
String? discoveryUrl,
17+
List<String>? promptValues,
1818
bool allowInsecureConnections = false,
1919
bool preferEphemeralSession = false,
2020
}) {
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/// Contains the response from making an authorization request.
22
class AuthorizationResponse {
3-
AuthorizationResponse(
3+
const AuthorizationResponse(
44
this.authorizationCode,
55
this.codeVerifier,
66
this.authorizationAdditionalParameters,
77
);
88

99
/// The authorization code.
10-
final String authorizationCode;
10+
final String? authorizationCode;
1111

1212
/// The code verifier generated by AppAuth when issue the authorization request. Use this when exchanging the [authorizationCode] for a token.
13-
final String codeVerifier;
13+
final String? codeVerifier;
1414

1515
/// Additional parameters included in the response.
16-
final Map<String, dynamic> authorizationAdditionalParameters;
16+
final Map<String, dynamic>? authorizationAdditionalParameters;
1717
}

Diff for: flutter_appauth_platform_interface/lib/src/authorization_service_configuration.dart

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
class AuthorizationServiceConfiguration {
2-
AuthorizationServiceConfiguration(
2+
const AuthorizationServiceConfiguration(
33
this.authorizationEndpoint,
44
this.tokenEndpoint,
5-
) : assert(tokenEndpoint != null && authorizationEndpoint != null,
6-
'Must specify both the authorization and token endpoints');
5+
);
76

87
final String authorizationEndpoint;
98

Diff for: flutter_appauth_platform_interface/lib/src/authorization_token_request.dart

+8-8
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ class AuthorizationTokenRequest extends TokenRequest
99
AuthorizationTokenRequest(
1010
String clientId,
1111
String redirectUrl, {
12-
String loginHint,
13-
String clientSecret,
14-
List<String> scopes,
15-
AuthorizationServiceConfiguration serviceConfiguration,
16-
Map<String, String> additionalParameters,
17-
String issuer,
18-
String discoveryUrl,
19-
List<String> promptValues,
12+
String? loginHint,
13+
String? clientSecret,
14+
List<String>? scopes,
15+
AuthorizationServiceConfiguration? serviceConfiguration,
16+
Map<String, String>? additionalParameters,
17+
String? issuer,
18+
String? discoveryUrl,
19+
List<String>? promptValues,
2020
bool allowInsecureConnections = false,
2121
bool preferEphemeralSession = false,
2222
}) : super(

Diff for: flutter_appauth_platform_interface/lib/src/authorization_token_response.dart

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import 'token_response.dart';
33
/// The details from making a successful combined authorization and token exchange request.
44
class AuthorizationTokenResponse extends TokenResponse {
55
AuthorizationTokenResponse(
6-
String accessToken,
7-
String refreshToken,
8-
DateTime accessTokenExpirationDateTime,
9-
String idToken,
10-
String tokenType,
6+
String? accessToken,
7+
String? refreshToken,
8+
DateTime? accessTokenExpirationDateTime,
9+
String? idToken,
10+
String? tokenType,
1111
this.authorizationAdditionalParameters,
12-
Map<String, dynamic> tokenAdditionalParameters,
12+
Map<String, dynamic>? tokenAdditionalParameters,
1313
) : super(accessToken, refreshToken, accessTokenExpirationDateTime, idToken,
1414
tokenType, tokenAdditionalParameters);
1515

1616
/// Contains additional parameters returned by the authorization server from making the authorization request.
17-
final Map<String, dynamic> authorizationAdditionalParameters;
17+
final Map<String, dynamic>? authorizationAdditionalParameters;
1818
}

Diff for: flutter_appauth_platform_interface/lib/src/common_request_details.dart

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@ import 'authorization_service_configuration.dart';
22

33
class CommonRequestDetails {
44
/// The client id.
5-
String clientId;
5+
late String clientId;
66

77
/// The issuer.
8-
String issuer;
8+
String? issuer;
99

1010
/// The URL of where the discovery document can be found.
11-
String discoveryUrl;
11+
String? discoveryUrl;
1212

1313
/// The redirect URL.
14-
String redirectUrl;
14+
late String redirectUrl;
1515

1616
/// The request scopes.
17-
List<String> scopes;
17+
List<String>? scopes;
1818

1919
/// The details of the OAuth 2.0 endpoints that can be explicitly when discovery isn't used or not possible.
20-
AuthorizationServiceConfiguration serviceConfiguration;
20+
AuthorizationServiceConfiguration? serviceConfiguration;
2121

2222
/// Additional parameters to include in the request.
23-
Map<String, String> additionalParameters;
23+
Map<String, String>? additionalParameters;
2424

2525
/// Whether to allow non-HTTPS endpoints.
2626
///
2727
/// This property is only applicable to Android.
28-
bool allowInsecureConnections;
28+
bool? allowInsecureConnections;
2929
}

0 commit comments

Comments
 (0)