Skip to content

Instantly share code, notes, and snippets.

@luo3house
Created April 26, 2023 13:01
Show Gist options
  • Save luo3house/dc636e1315aeb8ac6c1d11ee23275b21 to your computer and use it in GitHub Desktop.
Save luo3house/dc636e1315aeb8ac6c1d11ee23275b21 to your computer and use it in GitHub Desktop.
Easy to manage access tokens and refresh tokens
class VariableTokenStore<Token> {
/// validate token is valid
/// - true = ok
/// - false = not ok
/// - neverthrow
final Future<bool> Function(Token token) checkToken;
/// fetch a new token
/// - null = require authenticate
/// - not null = ok
/// - neverthrow
final Future<Token?> Function(Token? oldToken) fetchToken;
VariableTokenStore(this.checkToken, this.fetchToken);
Token? token;
Token? getToken() {
return this.token;
}
void setToken(Token token) {
this.token = token;
}
void clearToken() {
this.token = null;
}
/// get or refresh this store
/// - not null = ok
/// - null = require authenticate
/// - neverthrow
Future<Token?> check() {
return Future.sync(() async {
final token = this.token;
if (token == null) {
this.token = await fetchToken(token);
} else if (!await checkToken(token)) {
this.token = await fetchToken(token);
}
return this.token;
});
}
}
void main() {
test("basic", () async {
var version = 1;
final tokenStore = VariableTokenStore<Map<String, dynamic>>(
(token) => Future.value(token["version"] == version),
(old) => Future.value(version <= 2 ? {"version": version} : null),
);
expect(tokenStore.getToken(), null);
await tokenStore.check(); // refresh success
expect(tokenStore.getToken()?["version"], version);
expect((await tokenStore.check())?["version"], version); // check success
version++;
expect((await tokenStore.check())?["version"], version); // refresh success
version++;
expect((await tokenStore.check()), null); // should login
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment