Frontend first draft
This commit is contained in:
85
frontend/pshared/lib/service/authorization/token.dart
Normal file
85
frontend/pshared/lib/service/authorization/token.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import 'package:pshared/api/errors/unauthorized.dart';
|
||||
import 'package:pshared/api/requests/tokens/access_refresh.dart';
|
||||
import 'package:pshared/api/requests/tokens/refresh_rotate.dart';
|
||||
import 'package:pshared/api/responses/account.dart';
|
||||
import 'package:pshared/api/responses/login.dart';
|
||||
import 'package:pshared/api/responses/token.dart';
|
||||
import 'package:pshared/config/constants.dart';
|
||||
import 'package:pshared/service/authorization/storage.dart';
|
||||
import 'package:pshared/service/device_id.dart';
|
||||
import 'package:pshared/service/services.dart';
|
||||
import 'package:pshared/utils/http/requests.dart';
|
||||
|
||||
|
||||
class TokenService {
|
||||
static final _logger = Logger('service.authorization.token');
|
||||
static const String _objectType = Services.account;
|
||||
|
||||
static bool _isTokenExpiringSoon(TokenData token, Duration duration) {
|
||||
return token.expiration.isBefore(DateTime.now().add(duration));
|
||||
}
|
||||
|
||||
static Future<String> getAccessToken() async {
|
||||
TokenData token = await AuthorizationStorage.getAccessToken();
|
||||
if (_isTokenExpiringSoon(token, const Duration(hours: 4))) {
|
||||
token = (await _refreshAccessToken()).accessToken;
|
||||
}
|
||||
return token.token;
|
||||
}
|
||||
|
||||
static Future<void> _updateTokens(LoginResponse response) async {
|
||||
await AuthorizationStorage.updateToken(response.accessToken);
|
||||
await AuthorizationStorage.updateRefreshToken(response.refreshToken);
|
||||
}
|
||||
|
||||
static Future<AccountResponse> _refreshAccessToken() async {
|
||||
_logger.fine('Refreshing access token...');
|
||||
final deviceId = await DeviceIdManager.getDeviceId();
|
||||
final refresh = await AuthorizationStorage.getRefreshToken();
|
||||
|
||||
if (_isTokenExpiringSoon(refresh, const Duration(days: 7))) {
|
||||
return await rotateRefreshToken();
|
||||
}
|
||||
|
||||
final response = await getPOSTResponse(
|
||||
_objectType,
|
||||
'/refresh',
|
||||
AccessTokenRefreshRequest(
|
||||
deviceId: deviceId,
|
||||
clientId: Constants.clientId,
|
||||
token: refresh.token,
|
||||
).toJson(),
|
||||
);
|
||||
|
||||
final accountResp = AccountResponse.fromJson(response);
|
||||
await AuthorizationStorage.updateToken(accountResp.accessToken);
|
||||
return accountResp;
|
||||
}
|
||||
|
||||
static Future<LoginResponse> rotateRefreshToken() async {
|
||||
_logger.fine('Rotating refresh token...');
|
||||
final refresh = await AuthorizationStorage.getRefreshToken();
|
||||
|
||||
if (refresh.expiration.isBefore(DateTime.now())) throw ErrorUnauthorized();
|
||||
|
||||
final deviceId = await DeviceIdManager.getDeviceId();
|
||||
final response = await getPOSTResponse(
|
||||
_objectType,
|
||||
'/rotate',
|
||||
RotateRefreshTokenRequest(
|
||||
token: refresh.token,
|
||||
clientId: Constants.clientId,
|
||||
deviceId: deviceId,
|
||||
).toJson(),
|
||||
);
|
||||
|
||||
final loginResponse = LoginResponse.fromJson(response);
|
||||
await _updateTokens(loginResponse);
|
||||
return loginResponse;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user