diff --git a/CHANGELOG.md b/CHANGELOG.md index a3255ba..f95446e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.8.0 + +- **BREAKING CHANGE**: Renaming all JWT...Error to JWT...Exception (https://github.com/jonasroussel/dart_jsonwebtoken/pull/42) +- Fixing assert message (https://github.com/jonasroussel/dart_jsonwebtoken/pull/42) + ## 2.7.1 - Migrating from `pedantic` to `lints` diff --git a/README.md b/README.md index 506cac2..1a2c2a3 100644 --- a/README.md +++ b/README.md @@ -52,15 +52,10 @@ try { final jwt = JWT.verify(token, SecretKey('secret passphrase')); print('Payload: ${jwt.payload}'); - -} on JWTExpiredError { - +} on JWTExpiredException { print('jwt expired'); - -} on JWTError catch (ex) { - +} on JWTException catch (ex) { print(ex.message); // ex: invalid signature - } ``` diff --git a/example/example.dart b/example/example.dart index 3dfa23c..bfad9a1 100644 --- a/example/example.dart +++ b/example/example.dart @@ -45,9 +45,9 @@ void hs256() { final jwt = JWT.verify(token, SecretKey('secret passphrase')); print('Payload: ${jwt.payload}'); - } on JWTExpiredError { + } on JWTExpiredException { print('jwt expired'); - } on JWTError catch (ex) { + } on JWTException catch (ex) { print(ex.message); // ex: invalid signature } } @@ -88,9 +88,9 @@ void rs256() { final jwt = JWT.verify(token, key); print('Payload: ${jwt.payload}'); - } on JWTExpiredError { + } on JWTExpiredException { print('jwt expired'); - } on JWTError catch (ex) { + } on JWTException catch (ex) { print(ex.message); // ex: invalid signature } } @@ -131,9 +131,9 @@ void es256() { final jwt = JWT.verify(token, key); print('Payload: ${jwt.payload}'); - } on JWTExpiredError { + } on JWTExpiredException { print('jwt expired'); - } on JWTError catch (ex) { + } on JWTException catch (ex) { print(ex.message); // ex: invalid signature } } diff --git a/lib/dart_jsonwebtoken.dart b/lib/dart_jsonwebtoken.dart index 56a5f3f..7b1ac63 100644 --- a/lib/dart_jsonwebtoken.dart +++ b/lib/dart_jsonwebtoken.dart @@ -1,6 +1,6 @@ library jsonwebtoken; export 'src/jwt.dart'; -export 'src/errors.dart'; +export 'src/exceptions.dart'; export 'src/algorithms.dart'; export 'src/keys.dart'; diff --git a/lib/src/algorithms.dart b/lib/src/algorithms.dart index 144093d..90d365f 100644 --- a/lib/src/algorithms.dart +++ b/lib/src/algorithms.dart @@ -5,7 +5,7 @@ import 'package:crypto/crypto.dart'; import 'package:pointycastle/pointycastle.dart' as pc; import 'package:ed25519_edwards/ed25519_edwards.dart' as ed; -import 'errors.dart'; +import 'exceptions.dart'; import 'keys.dart'; import 'utils.dart'; @@ -64,7 +64,7 @@ abstract class JWTAlgorithm { case 'EdDSA': return JWTAlgorithm.EdDSA; default: - throw JWTInvalidError('unknown algorithm'); + throw JWTInvalidException('unknown algorithm'); } } diff --git a/lib/src/errors.dart b/lib/src/errors.dart deleted file mode 100644 index 83189c0..0000000 --- a/lib/src/errors.dart +++ /dev/null @@ -1,55 +0,0 @@ -/// JWTError objects thrown in the case of a jwt sign or verify failure. -class JWTError extends Error { - JWTError(this.message); - - /// Describes the error thrown - final String message; - - @override - String toString() => 'JWTError: $message'; -} - -/// An error thrown when jwt is invalid -class JWTInvalidError extends JWTError { - JWTInvalidError(String message) : super(message); - - @override - String toString() => 'JWTInvalidError: $message'; -} - -/// An error thrown when jwt is expired -class JWTExpiredError extends JWTError { - JWTExpiredError() : super('jwt expired'); - - @override - String toString() => 'JWTExpiredError: $message'; -} - -/// An error thrown when jwt is not active -class JWTNotActiveError extends JWTError { - JWTNotActiveError() : super('jwt not active'); - - @override - String toString() => 'JWTNotActiveError: $message'; -} - -/// An error thrown when parsing failed -class JWTParseError extends JWTError { - JWTParseError(String message) : super(message); - - @override - String toString() => 'JWTParseError: $message'; -} - -/// An error thrown by default -class JWTUndefinedError extends JWTError { - JWTUndefinedError(this.error) : super(error.toString()); - - final Error error; - - @override - String toString() => 'JWTUndefinedError: $message'; - - @override - StackTrace? get stackTrace => error.stackTrace; -} diff --git a/lib/src/exceptions.dart b/lib/src/exceptions.dart new file mode 100644 index 0000000..caa81f4 --- /dev/null +++ b/lib/src/exceptions.dart @@ -0,0 +1,51 @@ +/// JWTException objects thrown in the case of a jwt sign or verify failure. +class JWTException implements Exception { + JWTException(this.message); + + final String message; + + @override + String toString() => 'JWTException: $message'; +} + +/// An exception thrown when jwt is invalid +class JWTInvalidException extends JWTException { + JWTInvalidException(String message) : super(message); + + @override + String toString() => 'JWTInvalidException: $message'; +} + +/// An exception thrown when jwt is expired +class JWTExpiredException extends JWTException { + JWTExpiredException() : super('jwt expired'); + + @override + String toString() => 'JWTExpiredException: $message'; +} + +/// An exception thrown when jwt is not active +class JWTNotActiveException extends JWTException { + JWTNotActiveException() : super('jwt not active'); + + @override + String toString() => 'JWTNotActiveException: $message'; +} + +/// An exception thrown when parsing failed +class JWTParseException extends JWTException { + JWTParseException(String message) : super(message); + + @override + String toString() => 'JWTParseException: $message'; +} + +/// An exception thrown by default +class JWTUndefinedException extends JWTException { + JWTUndefinedException(Exception ex, this.stackTrace) : super(ex.toString()); + + final StackTrace stackTrace; + + @override + String toString() => 'JWTUndefinedException: $message'; +} diff --git a/lib/src/jwt.dart b/lib/src/jwt.dart index 635990c..ba29422 100644 --- a/lib/src/jwt.dart +++ b/lib/src/jwt.dart @@ -5,7 +5,7 @@ import 'dart:typed_data'; import 'package:collection/collection.dart'; import 'algorithms.dart'; -import 'errors.dart'; +import 'exceptions.dart'; import 'keys.dart'; import 'utils.dart'; @@ -34,11 +34,11 @@ class JWT { final header = jsonBase64.decode(base64Padded(parts[0])); if (header == null || header is! Map) { - throw JWTInvalidError('invalid header'); + throw JWTInvalidException('invalid header'); } if (checkHeaderType && header['typ'] != 'JWT') { - throw JWTInvalidError('not a jwt'); + throw JWTInvalidException('not a jwt'); } final algorithm = JWTAlgorithm.fromName(header['alg']); @@ -47,7 +47,7 @@ class JWT { final signature = base64Url.decode(base64Padded(parts[2])); if (!algorithm.verify(key, Uint8List.fromList(body), signature)) { - throw JWTInvalidError('invalid signature'); + throw JWTInvalidException('invalid signature'); } dynamic payload; @@ -65,7 +65,7 @@ class JWT { payload['exp'] * 1000, ); if (exp.isBefore(DateTime.now())) { - throw JWTExpiredError(); + throw JWTExpiredException(); } } @@ -75,20 +75,20 @@ class JWT { payload['nbf'] * 1000, ); if (nbf.isAfter(DateTime.now())) { - throw JWTNotActiveError(); + throw JWTNotActiveException(); } } // iat if (issueAt != null) { if (!payload.containsKey('iat')) { - throw JWTInvalidError('invalid issue at'); + throw JWTInvalidException('invalid issue at'); } final iat = DateTime.fromMillisecondsSinceEpoch( payload['iat'] * 1000, ); if (!iat.isAtSameMomentAs(DateTime.now())) { - throw JWTInvalidError('invalid issue at'); + throw JWTInvalidException('invalid issue at'); } } @@ -96,34 +96,34 @@ class JWT { if (audience != null) { if (payload.containsKey('aud')) { if (payload['aud'] is String && payload['aud'] != audience.first) { - throw JWTInvalidError('invalid audience'); + throw JWTInvalidException('invalid audience'); } else if (payload['aud'] is List && !ListEquality().equals(payload['aud'], audience)) { - throw JWTInvalidError('invalid audience'); + throw JWTInvalidException('invalid audience'); } } else { - throw JWTInvalidError('invalid audience'); + throw JWTInvalidException('invalid audience'); } } // sub if (subject != null) { if (!payload.containsKey('sub') || payload['sub'] != subject) { - throw JWTInvalidError('invalid subject'); + throw JWTInvalidException('invalid subject'); } } // iss if (issuer != null) { if (!payload.containsKey('iss') || payload['iss'] != issuer) { - throw JWTInvalidError('invalid issuer'); + throw JWTInvalidException('invalid issuer'); } } // jti if (jwtId != null) { if (!payload.containsKey('jti') || payload['jti'] != jwtId) { - throw JWTInvalidError('invalid jwt id'); + throw JWTInvalidException('invalid jwt id'); } } @@ -138,16 +138,16 @@ class JWT { } else { return JWT(payload); } - } catch (ex) { - if (ex is Error && ex is! JWTError) { - throw JWTUndefinedError(ex); + } catch (ex, stackTrace) { + if (ex is Exception && ex is! JWTException) { + throw JWTUndefinedException(ex, stackTrace); } else { rethrow; } } } - /// Exactly like `verify`, just return null instead of throwing errors. + /// Exactly like `verify`, just return null instead of throwing exceptions. static JWT? tryVerify( String token, JWTKey key, { @@ -200,16 +200,16 @@ class JWT { header: header, ); } - } catch (ex) { - if (ex is Error && ex is! JWTError) { - throw JWTUndefinedError(ex); + } catch (ex, stackTrace) { + if (ex is Exception && ex is! JWTException) { + throw JWTUndefinedException(ex, stackTrace); } else { rethrow; } } } - /// Exactly like `decode`, just return `null` instead of throwing errors. + /// Exactly like `decode`, just return `null` instead of throwing exceptions. static JWT? tryDecode(String token) { try { return decode(token); @@ -297,7 +297,7 @@ class JWT { : jsonBase64.encode(payload), ); } catch (ex) { - throw JWTError( + throw JWTException( 'invalid payload json format (Map keys must be String type)', ); } @@ -313,16 +313,16 @@ class JWT { ); return body + '.' + signature; - } catch (ex) { - if (ex is Error && ex is! JWTError) { - throw JWTUndefinedError(ex); + } catch (ex, stackTrace) { + if (ex is Exception && ex is! JWTException) { + throw JWTUndefinedException(ex, stackTrace); } else { rethrow; } } } - /// Exactly like `sign`, just return `null` instead of throwing errors. + /// Exactly like `sign`, just return `null` instead of throwing exceptions. String? trySign( JWTKey key, { JWTAlgorithm algorithm = JWTAlgorithm.HS256, diff --git a/lib/src/keys.dart b/lib/src/keys.dart index 2889c51..bed7c29 100644 --- a/lib/src/keys.dart +++ b/lib/src/keys.dart @@ -1,7 +1,7 @@ import 'package:pointycastle/pointycastle.dart' as pc; import 'package:ed25519_edwards/ed25519_edwards.dart' as ed; -import 'errors.dart'; +import 'exceptions.dart'; import 'crypto_utils.dart'; abstract class JWTKey {} @@ -55,7 +55,7 @@ class ECPrivateKey extends JWTKey { final _params = _key.parameters; if (_params == null) { - throw JWTParseError('ECPrivateKey parameters are invalid'); + throw JWTParseException('ECPrivateKey parameters are invalid'); } key = _key; @@ -66,7 +66,7 @@ class ECPrivateKey extends JWTKey { final _params = _key.parameters; if (_params == null) { - throw JWTParseError('ECPrivateKey parameters are invalid'); + throw JWTParseException('ECPrivateKey parameters are invalid'); } key = _key; diff --git a/pubspec.yaml b/pubspec.yaml index 2e52fb6..3d4ee4c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,11 +1,11 @@ name: dart_jsonwebtoken description: A dart implementation of the famous javascript library 'jsonwebtoken' (JWT). -version: 2.7.1 +version: 2.8.0 repository: https://github.com/jonasroussel/dart_jsonwebtoken homepage: https://github.com/jonasroussel/dart_jsonwebtoken#readme environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.12.0 <4.0.0" false_secrets: - /example/ec_private.pem