Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: add built-in token expiration support #112

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/fresh/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
An token refresh library for dart. This package exposes the core components that are common to various refresh token implementations (REST, GraphQL, etc...).

| Package | Pub |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [fresh_dio](https://github.com/felangel/fresh/tree/master/packages/fresh_dio) | [![pub package](https://img.shields.io/pub/v/fresh_dio.svg)](https://pub.dev/packages/fresh_dio) |
| [fresh_graphql](https://github.com/felangel/fresh/tree/master/packages/fresh_graphql) | [![pub package](https://img.shields.io/pub/v/fresh_graphql.svg)](https://pub.dev/packages/fresh_graphql) |
36 changes: 0 additions & 36 deletions packages/fresh/example/main.dart

This file was deleted.

45 changes: 43 additions & 2 deletions packages/fresh/lib/src/fresh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ enum AuthenticationStatus {
}

/// An interface which must be implemented to
/// read, write, and delete the `Token`.
/// manage the underlying `Token`.
abstract class TokenStorage<T> {
/// Returns the stored token asynchronously.
Future<T?> read();
Expand All @@ -58,6 +58,9 @@ abstract class TokenStorage<T> {

/// Deletes the stored token asynchronously.
Future<void> delete();

/// Whether the stored token is expired.
Future<bool> isExpired() async => false;
}

/// Function responsible for building the token header(s) give a [token].
Expand All @@ -66,12 +69,43 @@ typedef TokenHeaderBuilder<T> = Map<String, String> Function(
);

/// A [TokenStorage] implementation that keeps the token in memory.
class InMemoryTokenStorage<T> implements TokenStorage<T> {
class InMemoryTokenStorage<T> extends TokenStorage<T> {
T? _token;

@override
Future<void> delete() async {
_token = null;
}

@override
Future<T?> read() async {
return _token;
}

@override
Future<void> write(T token) async {
_token = token;
}
}

/// A [TokenStorage] implementation that keeps the [OAuth2Token] in memory.
class InMemoryOAuth2TokenStorage<T extends OAuth2Token>
extends TokenStorage<T> {
T? _token;
DateTime? _expiresAt;

@override
Future<bool> isExpired() async {
if (_expiresAt == null) return false;
return DateTime.now()
.toUtc()
.isAfter(_expiresAt!.subtract(const Duration(seconds: 10)));
}

@override
Future<void> delete() async {
_token = null;
_expiresAt = null;
}

@override
Expand All @@ -82,6 +116,10 @@ class InMemoryTokenStorage<T> implements TokenStorage<T> {
@override
Future<void> write(T token) async {
_token = token;
if (token.expiresIn != null) {
_expiresAt =
DateTime.now().toUtc().add(Duration(seconds: token.expiresIn!));
}
}
}

Expand All @@ -104,6 +142,9 @@ mixin FreshMixin<T> {
_tokenStorage = tokenStorage..read().then(_updateStatus);
}

/// Returns whether the current token is expired.
Future<bool> isTokenExpired() => _tokenStorage.isExpired();

/// Returns the current token.
Future<T?> get token async {
if (_authenticationStatus != AuthenticationStatus.initial) return _token;
Expand Down
4 changes: 2 additions & 2 deletions packages/fresh/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ issue_tracker: https://github.com/felangel/fresh/issues
homepage: https://github.com/felangel/fresh
funding: [https://github.com/sponsors/felangel]

version: 0.4.3
version: 0.5.0

environment:
sdk: ">=2.12.0 <4.0.0"
sdk: ">=3.0.0 <4.0.0"

dev_dependencies:
mocktail: ^1.0.0
Expand Down
24 changes: 22 additions & 2 deletions packages/fresh_dio/example/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,27 @@
# This file should be version controlled and should not be manually edited.

version:
revision: d3ed9ec945f8869f0e136c357d0c2a6be2b60c98
channel: beta
revision: "dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
- platform: web
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
13 changes: 0 additions & 13 deletions packages/fresh_dio/example/android/.gitignore

This file was deleted.

68 changes: 0 additions & 68 deletions packages/fresh_dio/example/android/app/build.gradle

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading