Skip to content

Commit

Permalink
Fix iat claim verification (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
labrom authored Oct 1, 2024
1 parent 7988c7d commit f4d6ca4
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
12 changes: 10 additions & 2 deletions lib/src/jwt.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ class JWT {
/// - RSAPublicKey with RSA algorithm
/// - ECPublicKey with ECDSA algorithm
/// - EdDSAPublicKey with EdDSA algorithm
///
/// [issueAt] allows to verify that the token wasn't issued too long ago. The
/// value is a timestamp (number of seconds since epoch) that is compared to
/// the value of the 'iat' claim. Verification fails if the 'iat' claim is
/// before [issueAt].
static JWT verify(
String token,
JWTKey key, {
Expand Down Expand Up @@ -88,8 +93,11 @@ class JWT {
final iat = DateTime.fromMillisecondsSinceEpoch(
(payload['iat'] * 1000).toInt(),
);
if (!iat.isAtSameMomentAs(clock.now())) {
throw JWTInvalidException('invalid issue at');
final issueAtTime =
DateTime.fromMillisecondsSinceEpoch(issueAt.inMilliseconds);
// Verify that the token isn't expired
if (iat.isBefore(issueAtTime)) {
throw JWTInvalidException('expired issue at');
}
}

Expand Down
56 changes: 56 additions & 0 deletions test/verify_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,62 @@ final edKey = EdDSAPublicKey(

void main() {
group('Verify a JWT', () {
group('Claims', () {
group('iat', () {
final oneMinuteAgo = DateTime.now().subtract(Duration(minutes: 1));
test('exact issueAt passes validation', () {
final jwt = JWT(
{
'foo': 'bar',
'iat': oneMinuteAgo.millisecondsSinceEpoch ~/ 1000,
},
);
final verified = JWT.tryVerify(
jwt.sign(hsKey, noIssueAt: true),
hsKey,
issueAt:
Duration(seconds: oneMinuteAgo.millisecondsSinceEpoch ~/ 1000),
);
expect(verified, isNotNull);
});
test('expired issueAt fails validation', () {
final jwt = JWT(
{
'foo': 'bar',
'iat': oneMinuteAgo
.subtract(Duration(seconds: 1))
.millisecondsSinceEpoch ~/
1000,
},
);
final verified = JWT.tryVerify(
jwt.sign(hsKey, noIssueAt: true),
hsKey,
issueAt:
Duration(seconds: oneMinuteAgo.millisecondsSinceEpoch ~/ 1000),
);
expect(verified, isNull);
});
test('fresher issueAt passes validation', () {
final jwt = JWT(
{
'foo': 'bar',
'iat': oneMinuteAgo
.add(Duration(seconds: 1))
.millisecondsSinceEpoch ~/
1000,
},
);
final verified = JWT.tryVerify(
jwt.sign(hsKey, noIssueAt: true),
hsKey,
issueAt:
Duration(seconds: oneMinuteAgo.millisecondsSinceEpoch ~/ 1000),
);
expect(verified, isNotNull);
});
});
});
//------//
// HMAC //
//------//
Expand Down

0 comments on commit f4d6ca4

Please sign in to comment.