added frontend
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import 'dart:convert' show base64, utf8;
|
||||
import 'dart:convert' show jsonDecode, jsonEncode;
|
||||
|
||||
import 'package:fotodocumentation/controller/base_controller.dart';
|
||||
import 'package:fotodocumentation/dto/jwt_token_pair_dto.dart';
|
||||
import 'package:fotodocumentation/main.dart' show logger;
|
||||
import 'package:fotodocumentation/utils/di_container.dart';
|
||||
import 'package:fotodocumentation/utils/jwt_token_storage.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
typedef AuthenticateReply = ({JwtTokenPairDto? jwtTokenPairDto});
|
||||
|
||||
abstract interface class LoginController {
|
||||
Future<AuthenticateReply> authenticate(String username, String password);
|
||||
Future<bool> refreshAccessToken();
|
||||
Future<bool> isUsingJwtAuth();
|
||||
}
|
||||
|
||||
class LoginControllerImpl extends BaseController implements LoginController {
|
||||
final String path = "login";
|
||||
|
||||
JwtTokenStorage get _jwtTokenStorage => DiContainer.get();
|
||||
|
||||
@override
|
||||
Future<AuthenticateReply> authenticate(String username, String password) async {
|
||||
http.Client client = httpClientUtils.client;
|
||||
try {
|
||||
Header cred = _getLoginHeader(username, password);
|
||||
String uriStr = '${uriUtils.getBaseUrl()}$path';
|
||||
Uri uri = Uri.parse(uriStr);
|
||||
|
||||
var response = await client.get(uri, headers: {cred.name: cred.value});
|
||||
if (response.statusCode == 200) {
|
||||
final Map<String, dynamic> data = Map.castFrom(jsonDecode(response.body));
|
||||
|
||||
final tokenPair = JwtTokenPairDto.fromJson(data);
|
||||
|
||||
// Store tokens securely
|
||||
await _jwtTokenStorage.saveTokens(tokenPair.accessToken, tokenPair.refreshToken);
|
||||
|
||||
// Load user data using the new token
|
||||
return (jwtTokenPairDto: tokenPair);
|
||||
} else {
|
||||
logger.e('Authentication failed: ${response.statusCode} ${response.body}');
|
||||
return (jwtTokenPairDto: null);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e("Authentication error: $e");
|
||||
return (jwtTokenPairDto: null);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> refreshAccessToken() async {
|
||||
try {
|
||||
final refreshToken = await _jwtTokenStorage.getRefreshToken();
|
||||
if (refreshToken == null) {
|
||||
logger.i('No refresh token available');
|
||||
return false;
|
||||
}
|
||||
String uriStr = '${uriUtils.getBaseUrl()}$path/login/refresh';
|
||||
Uri uri = Uri.parse(uriStr);
|
||||
|
||||
final response = await http.post(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
'refreshToken': refreshToken,
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
final newAccessToken = data['accessToken'] as String;
|
||||
|
||||
// Update only the access token (keep same refresh token)
|
||||
await _jwtTokenStorage.updateAccessToken(newAccessToken);
|
||||
|
||||
logger.d('Access token refreshed successfully');
|
||||
return true;
|
||||
} else {
|
||||
logger.d('Token refresh failed: ${response.statusCode} ${response.body}');
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e('Token refresh error: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isUsingJwtAuth() async {
|
||||
return await _jwtTokenStorage.hasTokens();
|
||||
}
|
||||
|
||||
Header _getLoginHeader(String username, String password) {
|
||||
String combined = "$username:$password";
|
||||
final bytes = utf8.encode(combined);
|
||||
String asBase64 = base64.encode(bytes);
|
||||
return Header("Authorization", "Basic $asBase64");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user