99 lines
2.8 KiB
Dart
99 lines
2.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
class LoginResult {
|
|
LoginResult({required this.success, required this.message});
|
|
|
|
final bool success;
|
|
final String message;
|
|
}
|
|
|
|
/// Matches native `ServiceGenerator.createService` + login POST (Basic auth + JSON body).
|
|
class OntimeAuth {
|
|
OntimeAuth._();
|
|
|
|
static const String baseUrl = 'https://apitest.semestaterpadu.my.id/api/';
|
|
|
|
static Future<LoginResult> login({
|
|
required String path,
|
|
required String password,
|
|
String email = '',
|
|
required String phoneDigits,
|
|
required String dialCodeWithoutPlus,
|
|
required String fcmToken,
|
|
}) async {
|
|
final cleanedDial = dialCodeWithoutPlus.replaceAll('+', '').trim();
|
|
final digitsOnly = phoneDigits.replaceAll(RegExp(r'\D'), '');
|
|
final local = digitsOnly.replaceFirst(RegExp(r'^0+'), '');
|
|
final fullPhone = digitsOnly.startsWith(cleanedDial)
|
|
? digitsOnly
|
|
: '$cleanedDial$local';
|
|
final useEmail = email.trim().isNotEmpty;
|
|
final basicUser = useEmail ? email.trim() : fullPhone;
|
|
|
|
final body = <String, dynamic>{
|
|
'password': password,
|
|
// Send all common aliases expected by backend FCM v1 helper.
|
|
'firebase_token': fcmToken,
|
|
'fcm_token': fcmToken,
|
|
'reg_id': fcmToken,
|
|
'token': fcmToken,
|
|
if (useEmail) ...{
|
|
'email': email.trim(),
|
|
'no_telepon': '',
|
|
} else ...{
|
|
'email': null,
|
|
'no_telepon': fullPhone,
|
|
},
|
|
};
|
|
|
|
final uri = Uri.parse('$baseUrl$path');
|
|
final auth = base64Encode(utf8.encode('$basicUser:$password'));
|
|
|
|
final resp = await http
|
|
.post(
|
|
uri,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Basic $auth',
|
|
},
|
|
body: jsonEncode(body),
|
|
)
|
|
.timeout(const Duration(seconds: 60));
|
|
|
|
Map<String, dynamic>? json;
|
|
try {
|
|
if (resp.body.isNotEmpty) {
|
|
final decoded = jsonDecode(resp.body);
|
|
if (decoded is Map<String, dynamic>) json = decoded;
|
|
}
|
|
} catch (_) {}
|
|
|
|
final msg = json?['message']?.toString() ?? '';
|
|
final data = json?['data'];
|
|
final hasData = data is List && data.isNotEmpty;
|
|
final ok = resp.statusCode >= 200 &&
|
|
resp.statusCode < 300 &&
|
|
msg.toLowerCase() == 'found' &&
|
|
hasData;
|
|
|
|
if (ok) return LoginResult(success: true, message: msg);
|
|
|
|
if (msg.isNotEmpty) {
|
|
return LoginResult(success: false, message: msg);
|
|
}
|
|
if (resp.statusCode == 401) {
|
|
return LoginResult(success: false, message: 'no hp atau password salah!');
|
|
}
|
|
if (resp.body.isNotEmpty && resp.body.length < 400) {
|
|
return LoginResult(success: false, message: resp.body);
|
|
}
|
|
return LoginResult(
|
|
success: false,
|
|
message: 'Login gagal (HTTP ${resp.statusCode})',
|
|
);
|
|
}
|
|
}
|