Skip to content

Commit

Permalink
Merge pull request #37 from bamlab/feat/add-invalid-refresh-token-exc…
Browse files Browse the repository at this point in the history
…eption

Feat/add invalid refresh token exception
  • Loading branch information
Cteq3132 committed Mar 12, 2024
2 parents 475f90b + ffb5c9a commit cb5de2d
Show file tree
Hide file tree
Showing 33 changed files with 291 additions and 51 deletions.
4 changes: 4 additions & 0 deletions flutter_reach_five/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.4.1

- **FEAT**: Add a custom exception thrown when the refresh token is not valid anymore

# 0.4.0

- **BREAKING**: Update Android SDK version to 9.1.0 and iOS SDK version to 6.1.0
Expand Down
2 changes: 1 addition & 1 deletion flutter_reach_five/example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
compileSdkVersion 34

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
2 changes: 1 addition & 1 deletion flutter_reach_five/example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
3 changes: 3 additions & 0 deletions flutter_reach_five/lib/helpers/adapt_errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ Never adaptErrors({
if (error is SocialAccountEmailAlreadyInUseExceptionInterface) {
throw SocialAccountEmailAlreadyInUseException();
}
if (error is UnauthorizedRefreshTokenExceptionInterface) {
throw UnauthorizedRefreshTokenException();
}
Error.throwWithStackTrace(error, stackTrace);
}
7 changes: 7 additions & 0 deletions flutter_reach_five/lib/models/errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,10 @@ class UserCancelledOrClosedTheWebFlowCodeException implements Exception {}
/// But its email is already in use by another mean of connection
/// {@endtemplate}
class SocialAccountEmailAlreadyInUseException implements Exception {}

/// {@template flutter_reach_five.errors.unauthorized_refresh_token}
/// Error thrown when a user tries to refresh its token but it's not authorized
/// anymore (either because it's expired or because it's been revoked
/// for example)
/// {@endtemplate}
class UnauthorizedRefreshTokenException implements Exception {}
21 changes: 16 additions & 5 deletions flutter_reach_five/lib/reach_five.dart
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,23 @@ class ReachFive {
/// For more on refresh tokens, check out the [Refresh Tokens](https://developer.reachfive.com/docs/refresh-tokens.html) page.
/// {@endtemplate}
Future<AuthToken> refreshAccessToken(AuthToken authToken) async {
final authTokenInterface = await _platform.refreshAccessToken(
reachFiveKey: ReachFiveKeyConverter.toInterface(reachFiveKey),
authToken: AuthTokenConverter.toInterface(authToken),
);
try {
final authTokenInterface = await _platform.refreshAccessToken(
reachFiveKey: ReachFiveKeyConverter.toInterface(reachFiveKey),
authToken: AuthTokenConverter.toInterface(authToken),
);

return AuthTokenConverter.fromInterface(authTokenInterface);
return AuthTokenConverter.fromInterface(authTokenInterface);
} catch (error, stackTrace) {
try {
_platform.parseError(error, stackTrace);
} catch (interfaceError, interfaceStackTrace) {
adaptErrors(
error: interfaceError,
stackTrace: interfaceStackTrace,
);
}
}
}

/// {@template flutter_reach_five.reachFive.revokeToken}
Expand Down
10 changes: 5 additions & 5 deletions flutter_reach_five/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_reach_five
description: This package allows you to use the methods from the reachFive android and ios native sdks in Flutter
version: 0.4.0
version: 0.4.1
homepage: https://github.com/bamlab/Flutter-ReachFive
repository: https://github.com/bamlab/Flutter-ReachFive

Expand All @@ -22,12 +22,12 @@ dependencies:
equatable: ^2.0.5
flutter:
sdk: flutter
flutter_reach_five_android: ^0.4.0
flutter_reach_five_ios: ^0.4.0
flutter_reach_five_platform_interface: ^0.4.0
flutter_reach_five_android: ^0.4.1
flutter_reach_five_ios: ^0.4.1
flutter_reach_five_platform_interface: ^0.4.1
freezed: ^2.1.0+1
freezed_annotation: ^2.1.0
reach_five_identity_repo: ^0.4.0
reach_five_identity_repo: ^0.4.1

dev_dependencies:
build_runner: ^2.4.8
Expand Down
15 changes: 15 additions & 0 deletions flutter_reach_five/test/helpers/adapt_errors_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,20 @@ void main() {

expect(error, isA<SocialAccountEmailAlreadyInUseException>());
});

test('$UnauthorizedRefreshTokenException', () async {
Object? error;

try {
adaptErrors(
error: UnauthorizedRefreshTokenExceptionInterface(),
stackTrace: StackTrace.fromString('test'),
);
} catch (e) {
error = e;
}

expect(error, isA<UnauthorizedRefreshTokenException>());
});
});
}
31 changes: 31 additions & 0 deletions flutter_reach_five/test/reach_five_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,37 @@ void main() {
refreshAccessTokenAuthToken,
);
});

test('parse throw error', () async {
const firstAuthToken = AuthToken(
accessToken: 'firstAccessToken',
);

registerFallbackValue(
ReachFiveKeyConverter.toInterface(reachFive.reachFiveKey),
);
registerFallbackValue(AuthTokenConverter.toInterface(firstAuthToken));
when(
() => flutterReachFivePlatform.refreshAccessToken(
reachFiveKey: any(named: 'reachFiveKey'),
authToken: any(named: 'authToken'),
),
).thenThrow(Exception());

registerFallbackValue(
StackTrace.fromString('test'),
);
when(
() => flutterReachFivePlatform.parseError(any(), any()),
).thenThrow(Exception());

try {
await reachFive.refreshAccessToken(firstAuthToken);
} catch (_) {}

verify(() => flutterReachFivePlatform.parseError(any(), any()))
.called(1);
});
});

group('revokeToken', () {
Expand Down
4 changes: 4 additions & 0 deletions flutter_reach_five_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.4.1

- **FEAT**: Add a custom exception thrown when the refresh token is not valid anymore

# 0.4.0

- **BREAKING**: Update Android SDK version to 9.1.0 and iOS SDK version to 6.1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Autogenerated from Pigeon (v17.1.1), do not edit directly.
// Autogenerated from Pigeon (v17.1.2), do not edit directly.
// See also: https://pub.dev/packages/pigeon

package tech.bam.flutter_reach_five.android;
Expand Down Expand Up @@ -182,6 +182,19 @@ public void setSocialAccountEmailAlreadyInUse(@NonNull String setterArg) {
this.socialAccountEmailAlreadyInUse = setterArg;
}

private @NonNull String unauthorizedRefreshToken;

public @NonNull String getUnauthorizedRefreshToken() {
return unauthorizedRefreshToken;
}

public void setUnauthorizedRefreshToken(@NonNull String setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"unauthorizedRefreshToken\" is null.");
}
this.unauthorizedRefreshToken = setterArg;
}

/** Constructor is non-public to enforce null safety; use Builder. */
ErrorCodesInterface() {}

Expand Down Expand Up @@ -243,6 +256,14 @@ public static final class Builder {
return this;
}

private @Nullable String unauthorizedRefreshToken;

@CanIgnoreReturnValue
public @NonNull Builder setUnauthorizedRefreshToken(@NonNull String setterArg) {
this.unauthorizedRefreshToken = setterArg;
return this;
}

public @NonNull ErrorCodesInterface build() {
ErrorCodesInterface pigeonReturn = new ErrorCodesInterface();
pigeonReturn.setEmailAlreadyInUseCode(emailAlreadyInUseCode);
Expand All @@ -252,20 +273,22 @@ public static final class Builder {
pigeonReturn.setInvalidGrant(invalidGrant);
pigeonReturn.setUserCancelledOrClosedTheWebFlow(userCancelledOrClosedTheWebFlow);
pigeonReturn.setSocialAccountEmailAlreadyInUse(socialAccountEmailAlreadyInUse);
pigeonReturn.setUnauthorizedRefreshToken(unauthorizedRefreshToken);
return pigeonReturn;
}
}

@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(7);
ArrayList<Object> toListResult = new ArrayList<Object>(8);
toListResult.add(emailAlreadyInUseCode);
toListResult.add(invalidEmailOrPasswordCode);
toListResult.add(invalidVerificationCode);
toListResult.add(updateSamePassword);
toListResult.add(invalidGrant);
toListResult.add(userCancelledOrClosedTheWebFlow);
toListResult.add(socialAccountEmailAlreadyInUse);
toListResult.add(unauthorizedRefreshToken);
return toListResult;
}

Expand All @@ -285,6 +308,8 @@ ArrayList<Object> toList() {
pigeonResult.setUserCancelledOrClosedTheWebFlow((String) userCancelledOrClosedTheWebFlow);
Object socialAccountEmailAlreadyInUse = list.get(6);
pigeonResult.setSocialAccountEmailAlreadyInUse((String) socialAccountEmailAlreadyInUse);
Object unauthorizedRefreshToken = list.get(7);
pigeonResult.setUnauthorizedRefreshToken((String) unauthorizedRefreshToken);
return pigeonResult;
}
}
Expand Down Expand Up @@ -2726,6 +2751,19 @@ public void setAuthToken(@NonNull AuthTokenInterface setterArg) {
this.authToken = setterArg;
}

private @NonNull ErrorCodesInterface errorCodes;

public @NonNull ErrorCodesInterface getErrorCodes() {
return errorCodes;
}

public void setErrorCodes(@NonNull ErrorCodesInterface setterArg) {
if (setterArg == null) {
throw new IllegalStateException("Nonnull field \"errorCodes\" is null.");
}
this.errorCodes = setterArg;
}

/** Constructor is non-public to enforce null safety; use Builder. */
RefreshAccessTokenRequestInterface() {}

Expand All @@ -2747,19 +2785,29 @@ public static final class Builder {
return this;
}

private @Nullable ErrorCodesInterface errorCodes;

@CanIgnoreReturnValue
public @NonNull Builder setErrorCodes(@NonNull ErrorCodesInterface setterArg) {
this.errorCodes = setterArg;
return this;
}

public @NonNull RefreshAccessTokenRequestInterface build() {
RefreshAccessTokenRequestInterface pigeonReturn = new RefreshAccessTokenRequestInterface();
pigeonReturn.setReachFiveKey(reachFiveKey);
pigeonReturn.setAuthToken(authToken);
pigeonReturn.setErrorCodes(errorCodes);
return pigeonReturn;
}
}

@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(2);
ArrayList<Object> toListResult = new ArrayList<Object>(3);
toListResult.add((reachFiveKey == null) ? null : reachFiveKey.toList());
toListResult.add((authToken == null) ? null : authToken.toList());
toListResult.add((errorCodes == null) ? null : errorCodes.toList());
return toListResult;
}

Expand All @@ -2769,6 +2817,8 @@ ArrayList<Object> toList() {
pigeonResult.setReachFiveKey((reachFiveKey == null) ? null : ReachFiveKeyInterface.fromList((ArrayList<Object>) reachFiveKey));
Object authToken = list.get(1);
pigeonResult.setAuthToken((authToken == null) ? null : AuthTokenInterface.fromList((ArrayList<Object>) authToken));
Object errorCodes = list.get(2);
pigeonResult.setErrorCodes((errorCodes == null) ? null : ErrorCodesInterface.fromList((ArrayList<Object>) errorCodes));
return pigeonResult;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ class Converters {
details = null
)
}
if (reachFiveError.data?.errorMessageKey == "error.refreshToken.revoked"
|| reachFiveError.data?.errorMessageKey == "error.refreshToken.expired") {
val errorCode = errorCodesInterface.unauthorizedRefreshToken
val errorUsrMessage = reachFiveError.data?.errorDescription ?: ""
return FlutterError(
code= errorCode,
message= "$errorCode - $errorUsrMessage",
details = null
)
}
if (reachFiveError.data?.error == "invalid_grant") {
val errorCode = errorCodesInterface.invalidGrant
val errorUsrMessage = reachFiveError.data?.errorDescription ?: ""
Expand Down

0 comments on commit cb5de2d

Please sign in to comment.