feat(flutter/auth): login screen + AuthApi.login posting to /api/auth/login
Login uses a non-authenticated dio (token resolver returns null) since we don't have one yet. On success, setSession persists token + user into secure storage and the AuthController state flips, which the router watches to navigate.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../../models/user.dart';
|
||||
|
||||
class AuthApi {
|
||||
AuthApi(this._dio);
|
||||
final Dio _dio;
|
||||
|
||||
/// Returns (token, user, rawUserJson) on success. Server emits
|
||||
/// LoginResponse{token, user{id, username, is_admin}}.
|
||||
Future<({String token, User user, String rawUserJson})> login({
|
||||
required String username,
|
||||
required String password,
|
||||
}) async {
|
||||
final r = await _dio.post<Map<String, dynamic>>(
|
||||
'/api/auth/login',
|
||||
data: {'username': username, 'password': password},
|
||||
);
|
||||
final body = r.data!;
|
||||
final userMap = (body['user'] as Map).cast<String, dynamic>();
|
||||
return (
|
||||
token: body['token'] as String,
|
||||
user: User.fromJson(userMap),
|
||||
rawUserJson: jsonEncode(userMap),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
await _dio.post<void>('/api/auth/logout');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user