fix&feat:fixing auth and secure token also initian for userpin preparation
This commit is contained in:
parent
4af31d867e
commit
de39c9d7fd
|
@ -1,23 +1,71 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||||
|
|
||||||
class ApiService {
|
class ApiService {
|
||||||
final String baseUrl = dotenv.get('BASE_URL');
|
final String baseUrl = dotenv.get('BASE_URL');
|
||||||
final String apiKey = dotenv.get('API_KEY');
|
final String apiKey = dotenv.get('API_KEY');
|
||||||
|
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
|
||||||
|
|
||||||
static const Map<String, String> _headers = {
|
static const Map<String, String> _headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Future<String?> _getAuthToken() async {
|
||||||
|
return await _secureStorage.read(key: 'token');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, String>> _getHeaders() async {
|
||||||
|
final token = await _getAuthToken();
|
||||||
|
return {
|
||||||
|
..._headers,
|
||||||
|
'x-api-key': apiKey,
|
||||||
|
if (token != null) 'Authorization': 'Bearer $token',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> _processResponse(http.Response response) {
|
||||||
|
if (response.body.isEmpty) {
|
||||||
|
throw Exception('Empty response body');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final responseJson = jsonDecode(response.body);
|
||||||
|
|
||||||
|
switch (response.statusCode) {
|
||||||
|
case 200:
|
||||||
|
return responseJson;
|
||||||
|
case 400:
|
||||||
|
throw BadRequestException(
|
||||||
|
'Bad request. The server could not process your request.',
|
||||||
|
);
|
||||||
|
case 401:
|
||||||
|
throw UnauthorizedException(
|
||||||
|
'Unauthorized. Please check your credentials.',
|
||||||
|
);
|
||||||
|
case 404:
|
||||||
|
throw NotFoundException(
|
||||||
|
'Not found. The requested resource could not be found.',
|
||||||
|
);
|
||||||
|
case 500:
|
||||||
|
throw ServerException(
|
||||||
|
'Internal server error. Please try again later.',
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw Exception('Failed with status code: ${response.statusCode}');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw Exception('Error parsing response: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> get(String endpoint) async {
|
Future<Map<String, dynamic>> get(String endpoint) async {
|
||||||
try {
|
try {
|
||||||
|
final headers = await _getHeaders();
|
||||||
final url = Uri.parse('$baseUrl$endpoint');
|
final url = Uri.parse('$baseUrl$endpoint');
|
||||||
final response = await http.get(
|
final response = await http.get(url, headers: headers);
|
||||||
url,
|
|
||||||
headers: {..._headers, 'API_KEY': apiKey},
|
|
||||||
);
|
|
||||||
|
|
||||||
return _processResponse(response);
|
return _processResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -27,26 +75,24 @@ class ApiService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> post(String endpoint, Map<String, dynamic> body) async {
|
Future<Map<String, dynamic>> post(
|
||||||
|
String endpoint,
|
||||||
|
Map<String, dynamic> body,
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
|
final headers = await _getHeaders();
|
||||||
final url = Uri.parse('$baseUrl$endpoint');
|
final url = Uri.parse('$baseUrl$endpoint');
|
||||||
|
|
||||||
// Debugging URL dan Body Request
|
|
||||||
debugPrint('Request URL: $url');
|
debugPrint('Request URL: $url');
|
||||||
debugPrint('Request Body: ${jsonEncode(body)}');
|
debugPrint('Request Body: ${jsonEncode(body)}');
|
||||||
debugPrint('API_KEY: $apiKey');
|
|
||||||
|
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
url,
|
url,
|
||||||
headers: {
|
headers: headers,
|
||||||
..._headers, // Menggunakan _headers untuk Content-Type
|
|
||||||
'x-api-key': apiKey, // Pastikan API_KEY dimasukkan dengan benar di sini
|
|
||||||
},
|
|
||||||
body: jsonEncode(body),
|
body: jsonEncode(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
debugPrint('Response: ${response.body}'); // Debugging Response
|
debugPrint('Response: ${response.body}');
|
||||||
|
|
||||||
return _processResponse(response);
|
return _processResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error during API request: $e');
|
debugPrint('Error during API request: $e');
|
||||||
|
@ -61,15 +107,22 @@ class ApiService {
|
||||||
Map<String, dynamic> body,
|
Map<String, dynamic> body,
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
|
final headers = await _getHeaders();
|
||||||
final url = Uri.parse('$baseUrl$endpoint');
|
final url = Uri.parse('$baseUrl$endpoint');
|
||||||
|
|
||||||
|
debugPrint('Request URL: $url');
|
||||||
|
debugPrint('Request Body: ${jsonEncode(body)}');
|
||||||
|
|
||||||
final response = await http.put(
|
final response = await http.put(
|
||||||
url,
|
url,
|
||||||
headers: {..._headers, 'API_KEY': apiKey},
|
headers: headers,
|
||||||
body: jsonEncode(body),
|
body: jsonEncode(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
debugPrint('Response: ${response.body}');
|
||||||
return _processResponse(response);
|
return _processResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
debugPrint('Error during API request: $e');
|
||||||
throw NetworkException(
|
throw NetworkException(
|
||||||
'Failed to connect to the server. Please check your internet connection.',
|
'Failed to connect to the server. Please check your internet connection.',
|
||||||
);
|
);
|
||||||
|
@ -81,15 +134,22 @@ class ApiService {
|
||||||
Map<String, dynamic> body,
|
Map<String, dynamic> body,
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
|
final headers = await _getHeaders();
|
||||||
final url = Uri.parse('$baseUrl$endpoint');
|
final url = Uri.parse('$baseUrl$endpoint');
|
||||||
|
|
||||||
|
debugPrint('Request URL: $url');
|
||||||
|
debugPrint('Request Body: ${jsonEncode(body)}');
|
||||||
|
|
||||||
final response = await http.patch(
|
final response = await http.patch(
|
||||||
url,
|
url,
|
||||||
headers: {..._headers, 'API_KEY': apiKey},
|
headers: headers,
|
||||||
body: jsonEncode(body),
|
body: jsonEncode(body),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
debugPrint('Response: ${response.body}');
|
||||||
return _processResponse(response);
|
return _processResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
debugPrint('Error during API request: $e');
|
||||||
throw NetworkException(
|
throw NetworkException(
|
||||||
'Failed to connect to the server. Please check your internet connection.',
|
'Failed to connect to the server. Please check your internet connection.',
|
||||||
);
|
);
|
||||||
|
@ -98,11 +158,9 @@ class ApiService {
|
||||||
|
|
||||||
Future<Map<String, dynamic>> delete(String endpoint) async {
|
Future<Map<String, dynamic>> delete(String endpoint) async {
|
||||||
try {
|
try {
|
||||||
|
final headers = await _getHeaders();
|
||||||
final url = Uri.parse('$baseUrl$endpoint');
|
final url = Uri.parse('$baseUrl$endpoint');
|
||||||
final response = await http.delete(
|
final response = await http.delete(url, headers: headers);
|
||||||
url,
|
|
||||||
headers: {..._headers, 'API_KEY': apiKey},
|
|
||||||
);
|
|
||||||
|
|
||||||
return _processResponse(response);
|
return _processResponse(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -111,29 +169,6 @@ class ApiService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _processResponse(http.Response response) {
|
|
||||||
switch (response.statusCode) {
|
|
||||||
case 200:
|
|
||||||
return jsonDecode(response.body);
|
|
||||||
case 400:
|
|
||||||
throw BadRequestException(
|
|
||||||
'Bad request. The server could not process your request.',
|
|
||||||
);
|
|
||||||
case 401:
|
|
||||||
throw UnauthorizedException(
|
|
||||||
'Unauthorized. Please check your credentials.',
|
|
||||||
);
|
|
||||||
case 404:
|
|
||||||
throw NotFoundException(
|
|
||||||
'Not found. The requested resource could not be found.',
|
|
||||||
);
|
|
||||||
case 500:
|
|
||||||
throw ServerException('Internal server error. Please try again later.');
|
|
||||||
default:
|
|
||||||
throw Exception('Failed with status code: ${response.statusCode}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetworkException implements Exception {
|
class NetworkException implements Exception {
|
||||||
|
|
|
@ -18,13 +18,6 @@ final router = GoRouter(
|
||||||
builder: (context, state) => OnboardingPageScreen(),
|
builder: (context, state) => OnboardingPageScreen(),
|
||||||
),
|
),
|
||||||
GoRoute(path: '/login', builder: (context, state) => LoginScreen()),
|
GoRoute(path: '/login', builder: (context, state) => LoginScreen()),
|
||||||
GoRoute(
|
|
||||||
path: '/navigasi',
|
|
||||||
builder: (context, state) {
|
|
||||||
dynamic data = state.extra;
|
|
||||||
return NavigationPage(data: data);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/verif-otp',
|
path: '/verif-otp',
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
@ -32,6 +25,17 @@ final router = GoRouter(
|
||||||
return VerifotpScreen(phone: phone!);
|
return VerifotpScreen(phone: phone!);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/inputpin',
|
||||||
|
builder: (context, state) => OnboardingPageScreen(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/navigasi',
|
||||||
|
builder: (context, state) {
|
||||||
|
dynamic data = state.extra;
|
||||||
|
return NavigationPage(data: data);
|
||||||
|
},
|
||||||
|
),
|
||||||
GoRoute(path: '/home', builder: (context, state) => HomeScreen()),
|
GoRoute(path: '/home', builder: (context, state) => HomeScreen()),
|
||||||
GoRoute(path: '/activity', builder: (context, state) => ActivityScreen()),
|
GoRoute(path: '/activity', builder: (context, state) => ActivityScreen()),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
|
|
|
@ -1,40 +1,27 @@
|
||||||
import 'package:rijig_mobile/core/api_services.dart';
|
import 'package:rijig_mobile/core/api_services.dart';
|
||||||
|
import 'package:rijig_mobile/model/response_model.dart';
|
||||||
|
|
||||||
class AuthModel {
|
class AuthModel {
|
||||||
final int status;
|
|
||||||
final String message;
|
|
||||||
|
|
||||||
AuthModel({required this.status, required this.message});
|
|
||||||
|
|
||||||
factory AuthModel.fromJson(Map<String, dynamic> json) {
|
|
||||||
return AuthModel(
|
|
||||||
status: json['meta']?['status'] ?? 0,
|
|
||||||
message: json['meta']?['message'] ?? '',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AuthService {
|
|
||||||
final ApiService _apiService = ApiService();
|
final ApiService _apiService = ApiService();
|
||||||
|
|
||||||
Future<AuthModel?> login(String phone) async {
|
Future<ResponseModel?> login(String phone) async {
|
||||||
try {
|
try {
|
||||||
var response = await _apiService.post('/authmasyarakat/auth', {
|
var response = await _apiService.post('/authmasyarakat/auth', {
|
||||||
'phone': phone,
|
'phone': phone,
|
||||||
});
|
});
|
||||||
return AuthModel.fromJson(response);
|
return ResponseModel.fromJson(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> verifyOtp(String phone, String otp) async {
|
Future<ResponseModel?> verifyOtp(String phone, String otp) async {
|
||||||
try {
|
try {
|
||||||
var response = await _apiService.post('/authmasyarakat/verify-otp', {
|
var response = await _apiService.post('/authmasyarakat/verify-otp', {
|
||||||
'phone': phone,
|
'phone': phone,
|
||||||
'otp': otp,
|
'otp': otp,
|
||||||
});
|
});
|
||||||
return response;
|
return ResponseModel.fromJson(response);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
class ResponseModel {
|
||||||
|
final int status;
|
||||||
|
final String message;
|
||||||
|
final Map<String, dynamic>? data;
|
||||||
|
|
||||||
|
ResponseModel({required this.status, required this.message, this.data});
|
||||||
|
|
||||||
|
factory ResponseModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ResponseModel(
|
||||||
|
status: json['meta']?['status'] ?? 0,
|
||||||
|
message: json['meta']?['message'] ?? '',
|
||||||
|
data: json['data'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import 'package:rijig_mobile/core/api_services.dart';
|
||||||
|
import 'package:rijig_mobile/model/response_model.dart';
|
||||||
|
|
||||||
|
class AuthService {
|
||||||
|
final ApiService _apiService = ApiService();
|
||||||
|
|
||||||
|
Future<ResponseModel?> cekPinStatus(String userid) async {
|
||||||
|
try {
|
||||||
|
var response = await _apiService.get('/cek-pin-status');
|
||||||
|
return ResponseModel.fromJson(response);
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> verifyOtp(String phone, String otp) async {
|
||||||
|
try {
|
||||||
|
var response = await _apiService.post('/authmasyarakat/verify-otp', {
|
||||||
|
'phone': phone,
|
||||||
|
'otp': otp,
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,42 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:rijig_mobile/core/guide.dart';
|
|
||||||
import 'package:rijig_mobile/core/router.dart';
|
import 'package:rijig_mobile/core/router.dart';
|
||||||
import 'package:rijig_mobile/viewmodel/auth_vmod.dart';
|
import 'package:rijig_mobile/viewmodel/auth_vmod.dart';
|
||||||
import 'package:rijig_mobile/widget/buttoncard.dart';
|
import 'package:rijig_mobile/widget/buttoncard.dart';
|
||||||
import 'package:rijig_mobile/widget/formfiled.dart';
|
import 'package:rijig_mobile/widget/formfiled.dart';
|
||||||
|
|
||||||
class LoginScreen extends StatelessWidget {
|
class LoginScreen extends StatefulWidget {
|
||||||
|
const LoginScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
LoginScreenState createState() => LoginScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoginScreenState extends State<LoginScreen> {
|
||||||
final _phoneController = TextEditingController();
|
final _phoneController = TextEditingController();
|
||||||
|
|
||||||
LoginScreen({super.key});
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_phoneController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: PaddingCustom().paddingHorizontalVertical(15, 30),
|
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 30),
|
||||||
child: Consumer<AuthViewModel>(
|
child: Consumer<AuthViewModel>(
|
||||||
builder: (context, userVM, child) {
|
builder: (context, userVM, child) {
|
||||||
if (userVM.authModel?.status == 200) {
|
debugPrint('AuthModel Status: ${userVM.authModel?.status}');
|
||||||
Future.delayed(Duration.zero, () {
|
|
||||||
|
if (userVM.authModel?.status == 200 && !userVM.isLoading) {
|
||||||
|
debugPrint(
|
||||||
|
'OTP Sent Successfully. Navigating to Verif-OTP Screen.',
|
||||||
|
);
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
router.go('/verif-otp', extra: _phoneController.text);
|
router.go('/verif-otp', extra: _phoneController.text);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -36,10 +52,20 @@ class LoginScreen extends StatelessWidget {
|
||||||
keyboardType: TextInputType.phone,
|
keyboardType: TextInputType.phone,
|
||||||
errorText: userVM.errorMessage,
|
errorText: userVM.errorMessage,
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
userVM.isLoading
|
userVM.isLoading
|
||||||
? CircularProgressIndicator()
|
? CardButtonOne(
|
||||||
|
textButton: 'Sending OTP...',
|
||||||
|
fontSized: 16,
|
||||||
|
colorText: Colors.white,
|
||||||
|
borderRadius: 12,
|
||||||
|
horizontal: double.infinity,
|
||||||
|
vertical: 50,
|
||||||
|
onTap: () {},
|
||||||
|
loadingTrue: true,
|
||||||
|
usingRow: false,
|
||||||
|
)
|
||||||
: CardButtonOne(
|
: CardButtonOne(
|
||||||
textButton: 'Send OTP',
|
textButton: 'Send OTP',
|
||||||
fontSized: 16,
|
fontSized: 16,
|
||||||
|
@ -49,21 +75,27 @@ class LoginScreen extends StatelessWidget {
|
||||||
vertical: 50,
|
vertical: 50,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (_phoneController.text.isNotEmpty) {
|
if (_phoneController.text.isNotEmpty) {
|
||||||
|
debugPrint(
|
||||||
|
'Sending OTP to: ${_phoneController.text}',
|
||||||
|
);
|
||||||
userVM.login(_phoneController.text);
|
userVM.login(_phoneController.text);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadingTrue: userVM.isLoading,
|
loadingTrue: false,
|
||||||
usingRow: false,
|
usingRow: false,
|
||||||
),
|
),
|
||||||
|
|
||||||
if (userVM.authModel != null)
|
if (userVM.authModel != null)
|
||||||
Text(
|
Padding(
|
||||||
userVM.authModel!.message,
|
padding: const EdgeInsets.only(top: 20),
|
||||||
style: TextStyle(
|
child: Text(
|
||||||
color:
|
userVM.authModel!.message,
|
||||||
userVM.authModel!.status == 200
|
style: TextStyle(
|
||||||
? Colors.green
|
color:
|
||||||
: Colors.red,
|
userVM.authModel!.status == 200
|
||||||
|
? Colors.green
|
||||||
|
: Colors.red,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rijig_mobile/model/response_model.dart';
|
||||||
import 'package:rijig_mobile/model/auth_model.dart';
|
import 'package:rijig_mobile/model/auth_model.dart';
|
||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class AuthViewModel extends ChangeNotifier {
|
class AuthViewModel extends ChangeNotifier {
|
||||||
final AuthService _authService = AuthService();
|
final AuthModel _authModel = AuthModel();
|
||||||
|
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
String? errorMessage;
|
String? errorMessage;
|
||||||
AuthModel? authModel;
|
ResponseModel? authModel;
|
||||||
|
|
||||||
Future<void> login(String phone) async {
|
Future<void> login(String phone) async {
|
||||||
try {
|
try {
|
||||||
|
@ -14,10 +17,15 @@ class AuthViewModel extends ChangeNotifier {
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
authModel = await _authService.login(phone);
|
final response = await _authModel.login(phone);
|
||||||
|
|
||||||
if (authModel?.status != 200) {
|
if (response != null && response.status == 200) {
|
||||||
errorMessage = authModel?.message ?? 'Failed to send OTP';
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.setBool('isLoggedIn', false);
|
||||||
|
|
||||||
|
authModel = response;
|
||||||
|
} else {
|
||||||
|
errorMessage = response?.message ?? 'Failed to send OTP';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorMessage = 'Error: $e';
|
errorMessage = 'Error: $e';
|
||||||
|
@ -33,18 +41,28 @@ class AuthViewModel extends ChangeNotifier {
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
var response = await _authService.verifyOtp(phone, otp);
|
var response = await _authModel.verifyOtp(phone, otp);
|
||||||
|
|
||||||
|
if (response != null && response.status == 200) {
|
||||||
|
await _secureStorage.write(
|
||||||
|
key: 'token',
|
||||||
|
value: response.data?['token'],
|
||||||
|
);
|
||||||
|
await _secureStorage.write(
|
||||||
|
key: 'user_id',
|
||||||
|
value: response.data?['user_id'],
|
||||||
|
);
|
||||||
|
await _secureStorage.write(
|
||||||
|
key: 'user_role',
|
||||||
|
value: response.data?['user_role'],
|
||||||
|
);
|
||||||
|
|
||||||
if (response['meta'] != null && response['meta']['status'] == 200) {
|
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
await prefs.setString('token', response['data']['token']);
|
|
||||||
await prefs.setString('user_id', response['data']['user_id']);
|
|
||||||
await prefs.setString('user_role', response['data']['user_role']);
|
|
||||||
await prefs.setBool('isLoggedIn', true);
|
await prefs.setBool('isLoggedIn', true);
|
||||||
|
|
||||||
authModel = AuthModel.fromJson(response['data']);
|
authModel = response;
|
||||||
} else {
|
} else {
|
||||||
errorMessage = response['meta']?['message'] ?? 'Failed to verify OTP';
|
errorMessage = response?.message ?? 'Failed to verify OTP';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorMessage = 'Error: $e';
|
errorMessage = 'Error: $e';
|
||||||
|
@ -53,4 +71,31 @@ class AuthViewModel extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String?> getAuthToken() async {
|
||||||
|
return await _secureStorage.read(key: 'token');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> getUserId() async {
|
||||||
|
return await _secureStorage.read(key: 'user_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> getUserRole() async {
|
||||||
|
return await _secureStorage.read(key: 'user_role');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> logout() async {
|
||||||
|
await _secureStorage.delete(key: 'token');
|
||||||
|
await _secureStorage.delete(key: 'user_id');
|
||||||
|
await _secureStorage.delete(key: 'user_role');
|
||||||
|
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
await prefs.remove('isLoggedIn');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isUserLoggedIn() async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
return prefs.getBool('isLoggedIn') ?? false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
||||||
|
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
flutter_secure_storage_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import flutter_secure_storage_macos
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
}
|
}
|
||||||
|
|
64
pubspec.lock
64
pubspec.lock
|
@ -126,6 +126,54 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.9.3"
|
version: "5.9.3"
|
||||||
|
flutter_secure_storage:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage
|
||||||
|
sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.2.4"
|
||||||
|
flutter_secure_storage_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_linux
|
||||||
|
sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.3"
|
||||||
|
flutter_secure_storage_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_macos
|
||||||
|
sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.3"
|
||||||
|
flutter_secure_storage_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_platform_interface
|
||||||
|
sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_secure_storage_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_web
|
||||||
|
sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
flutter_secure_storage_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_secure_storage_windows
|
||||||
|
sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
flutter_svg:
|
flutter_svg:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -200,6 +248,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.20.2"
|
version: "0.20.2"
|
||||||
|
js:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: js
|
||||||
|
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.7"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -541,6 +597,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
win32:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32
|
||||||
|
sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.12.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_dotenv: ^5.2.1
|
flutter_dotenv: ^5.2.1
|
||||||
flutter_screenutil: ^5.9.3
|
flutter_screenutil: ^5.9.3
|
||||||
|
flutter_secure_storage: ^9.2.4
|
||||||
flutter_svg: ^2.1.0
|
flutter_svg: ^2.1.0
|
||||||
gap: ^3.0.1
|
gap: ^3.0.1
|
||||||
go_router: ^15.1.1
|
go_router: ^15.1.1
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
flutter_secure_storage_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
Loading…
Reference in New Issue