@@ -53,9 +53,14 @@ class FilcAPI {
|
||||
.map((json) => School.fromJson(json))
|
||||
.toList();
|
||||
schools.add(School(
|
||||
city: "Tiszabura",
|
||||
instituteCode: "supporttest-reni-tiszabura-teszt01",
|
||||
name: "FILC Éles Reni tiszabura-teszt",
|
||||
city: "Stockholm",
|
||||
instituteCode: "refilc-test-sweden",
|
||||
name: "reFilc Test SE - Leo Ekström High School",
|
||||
));
|
||||
schools.add(School(
|
||||
city: "Madrid",
|
||||
instituteCode: "refilc-test-spain",
|
||||
name: "reFilc Test ES - Emilio Obrero University",
|
||||
));
|
||||
return schools;
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ignore_for_file: avoid_print, use_build_context_synchronously
|
||||
|
||||
import 'package:filcnaplo/utils/jwt.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/school.dart';
|
||||
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
|
||||
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
|
||||
import 'package:filcnaplo_kreta_api/providers/exam_provider.dart';
|
||||
@@ -20,6 +21,7 @@ import 'package:filcnaplo_kreta_api/models/week.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:filcnaplo/api/nonce.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
enum LoginState {
|
||||
missingFields,
|
||||
@@ -47,87 +49,141 @@ Future loginAPI({
|
||||
void Function(User)? onLogin,
|
||||
void Function()? onSuccess,
|
||||
}) async {
|
||||
Provider.of<KretaClient>(context, listen: false).userAgent =
|
||||
Provider.of<SettingsProvider>(context, listen: false).config.userAgent;
|
||||
Future testLogin(School school) async {
|
||||
var user = User(
|
||||
username: username,
|
||||
password: password,
|
||||
instituteCode: instituteCode,
|
||||
name: 'Teszt Lajos',
|
||||
student: Student(
|
||||
birth: DateTime.now(),
|
||||
id: const Uuid().v4(),
|
||||
name: 'Teszt Lajos',
|
||||
school: school,
|
||||
yearId: '1',
|
||||
parents: ['Teszt András', 'Teszt Linda'],
|
||||
json: {"a": "b"},
|
||||
address: '1117 Budapest, Gábor Dénes utca 4.',
|
||||
),
|
||||
role: Role.parent,
|
||||
);
|
||||
|
||||
Map<String, String> headers = {
|
||||
"content-type": "application/x-www-form-urlencoded",
|
||||
};
|
||||
if (onLogin != null) onLogin(user);
|
||||
|
||||
String nonceStr = await Provider.of<KretaClient>(context, listen: false)
|
||||
.getAPI(KretaAPI.nonce, json: false);
|
||||
// store test user in db
|
||||
await Provider.of<DatabaseProvider>(context, listen: false)
|
||||
.store
|
||||
.storeUser(user);
|
||||
Provider.of<UserProvider>(context, listen: false).addUser(user);
|
||||
Provider.of<UserProvider>(context, listen: false).setUser(user.id);
|
||||
|
||||
Nonce nonce = getNonce(nonceStr, username, instituteCode);
|
||||
headers.addAll(nonce.header());
|
||||
if (onSuccess != null) onSuccess();
|
||||
|
||||
Map? res = await Provider.of<KretaClient>(context, listen: false)
|
||||
.postAPI(KretaAPI.login,
|
||||
headers: headers,
|
||||
body: User.loginBody(
|
||||
username: username,
|
||||
password: password,
|
||||
instituteCode: instituteCode,
|
||||
));
|
||||
if (res != null) {
|
||||
if (res.containsKey("error")) {
|
||||
if (res["error"] == "invalid_grant") {
|
||||
return LoginState.invalidGrant;
|
||||
}
|
||||
} else {
|
||||
if (res.containsKey("access_token")) {
|
||||
try {
|
||||
Provider.of<KretaClient>(context, listen: false).accessToken =
|
||||
res["access_token"];
|
||||
Map? studentJson =
|
||||
await Provider.of<KretaClient>(context, listen: false)
|
||||
.getAPI(KretaAPI.student(instituteCode));
|
||||
Student student = Student.fromJson(studentJson!);
|
||||
var user = User(
|
||||
username: username,
|
||||
password: password,
|
||||
instituteCode: instituteCode,
|
||||
name: student.name,
|
||||
student: student,
|
||||
role: JwtUtils.getRoleFromJWT(res["access_token"])!,
|
||||
);
|
||||
return LoginState.success;
|
||||
}
|
||||
|
||||
if (onLogin != null) onLogin(user);
|
||||
// if institute matches one of test things do test login
|
||||
if (instituteCode == 'refilc-test-sweden') {
|
||||
School school = School(
|
||||
city: "Stockholm",
|
||||
instituteCode: "refilc-test-sweden",
|
||||
name: "reFilc Test SE - Leo Ekström High School",
|
||||
);
|
||||
|
||||
// Store User in the database
|
||||
await Provider.of<DatabaseProvider>(context, listen: false)
|
||||
.store
|
||||
.storeUser(user);
|
||||
Provider.of<UserProvider>(context, listen: false).addUser(user);
|
||||
Provider.of<UserProvider>(context, listen: false).setUser(user.id);
|
||||
await testLogin(school);
|
||||
} else if (instituteCode == 'refilc-test-spain') {
|
||||
School school = School(
|
||||
city: "Madrid",
|
||||
instituteCode: "refilc-test-spain",
|
||||
name: "reFilc Test ES - Emilio Obrero University",
|
||||
);
|
||||
|
||||
// Get user data
|
||||
await testLogin(school);
|
||||
} else {
|
||||
// normal login from here
|
||||
Provider.of<KretaClient>(context, listen: false).userAgent =
|
||||
Provider.of<SettingsProvider>(context, listen: false).config.userAgent;
|
||||
|
||||
Map<String, String> headers = {
|
||||
"content-type": "application/x-www-form-urlencoded",
|
||||
};
|
||||
|
||||
String nonceStr = await Provider.of<KretaClient>(context, listen: false)
|
||||
.getAPI(KretaAPI.nonce, json: false);
|
||||
|
||||
Nonce nonce = getNonce(nonceStr, username, instituteCode);
|
||||
headers.addAll(nonce.header());
|
||||
|
||||
Map? res = await Provider.of<KretaClient>(context, listen: false)
|
||||
.postAPI(KretaAPI.login,
|
||||
headers: headers,
|
||||
body: User.loginBody(
|
||||
username: username,
|
||||
password: password,
|
||||
instituteCode: instituteCode,
|
||||
));
|
||||
if (res != null) {
|
||||
if (res.containsKey("error")) {
|
||||
if (res["error"] == "invalid_grant") {
|
||||
return LoginState.invalidGrant;
|
||||
}
|
||||
} else {
|
||||
if (res.containsKey("access_token")) {
|
||||
try {
|
||||
await Future.wait([
|
||||
Provider.of<GradeProvider>(context, listen: false).fetch(),
|
||||
Provider.of<TimetableProvider>(context, listen: false)
|
||||
.fetch(week: Week.current()),
|
||||
Provider.of<ExamProvider>(context, listen: false).fetch(),
|
||||
Provider.of<HomeworkProvider>(context, listen: false).fetch(),
|
||||
Provider.of<MessageProvider>(context, listen: false).fetchAll(),
|
||||
Provider.of<NoteProvider>(context, listen: false).fetch(),
|
||||
Provider.of<EventProvider>(context, listen: false).fetch(),
|
||||
Provider.of<AbsenceProvider>(context, listen: false).fetch(),
|
||||
]);
|
||||
Provider.of<KretaClient>(context, listen: false).accessToken =
|
||||
res["access_token"];
|
||||
Map? studentJson =
|
||||
await Provider.of<KretaClient>(context, listen: false)
|
||||
.getAPI(KretaAPI.student(instituteCode));
|
||||
Student student = Student.fromJson(studentJson!);
|
||||
var user = User(
|
||||
username: username,
|
||||
password: password,
|
||||
instituteCode: instituteCode,
|
||||
name: student.name,
|
||||
student: student,
|
||||
role: JwtUtils.getRoleFromJWT(res["access_token"])!,
|
||||
);
|
||||
|
||||
if (onLogin != null) onLogin(user);
|
||||
|
||||
// Store User in the database
|
||||
await Provider.of<DatabaseProvider>(context, listen: false)
|
||||
.store
|
||||
.storeUser(user);
|
||||
Provider.of<UserProvider>(context, listen: false).addUser(user);
|
||||
Provider.of<UserProvider>(context, listen: false).setUser(user.id);
|
||||
|
||||
// Get user data
|
||||
try {
|
||||
await Future.wait([
|
||||
Provider.of<GradeProvider>(context, listen: false).fetch(),
|
||||
Provider.of<TimetableProvider>(context, listen: false)
|
||||
.fetch(week: Week.current()),
|
||||
Provider.of<ExamProvider>(context, listen: false).fetch(),
|
||||
Provider.of<HomeworkProvider>(context, listen: false).fetch(),
|
||||
Provider.of<MessageProvider>(context, listen: false).fetchAll(),
|
||||
Provider.of<NoteProvider>(context, listen: false).fetch(),
|
||||
Provider.of<EventProvider>(context, listen: false).fetch(),
|
||||
Provider.of<AbsenceProvider>(context, listen: false).fetch(),
|
||||
]);
|
||||
} catch (error) {
|
||||
print("WARNING: failed to fetch user data: $error");
|
||||
}
|
||||
|
||||
if (onSuccess != null) onSuccess();
|
||||
|
||||
return LoginState.success;
|
||||
} catch (error) {
|
||||
print("WARNING: failed to fetch user data: $error");
|
||||
print("ERROR: loginAPI: $error");
|
||||
// maybe check debug mode
|
||||
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("ERROR: $error")));
|
||||
return LoginState.failed;
|
||||
}
|
||||
|
||||
if (onSuccess != null) onSuccess();
|
||||
|
||||
return LoginState.success;
|
||||
} catch (error) {
|
||||
print("ERROR: loginAPI: $error");
|
||||
// maybe check debug mode
|
||||
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("ERROR: $error")));
|
||||
return LoginState.failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LoginState.failed;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
@@ -12,6 +14,7 @@ class StatusProvider extends ChangeNotifier {
|
||||
|
||||
StatusProvider() {
|
||||
_handleNetworkChanges();
|
||||
_handleDNSFailure();
|
||||
Connectivity().checkConnectivity().then((value) => _networkType = value);
|
||||
}
|
||||
|
||||
@@ -24,6 +27,7 @@ class StatusProvider extends ChangeNotifier {
|
||||
_networkType = event;
|
||||
if (event == ConnectivityResult.none) {
|
||||
if (!_stack.contains(Status.network)) {
|
||||
_stack.remove(Status.apiError);
|
||||
_stack.insert(0, Status.network);
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -36,6 +40,31 @@ class StatusProvider extends ChangeNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
void _handleDNSFailure() {
|
||||
try {
|
||||
InternetAddress.lookup('api.refilc.hu').then((status) {
|
||||
if (status.isEmpty) {
|
||||
if (!_stack.contains(Status.network)) {
|
||||
_stack.remove(Status.apiError);
|
||||
_stack.insert(0, Status.network);
|
||||
notifyListeners();
|
||||
}
|
||||
} else {
|
||||
if (_stack.contains(Status.network)) {
|
||||
_stack.remove(Status.network);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
});
|
||||
} on SocketException catch (_) {
|
||||
if (!_stack.contains(Status.network)) {
|
||||
_stack.remove(Status.apiError);
|
||||
_stack.insert(0, Status.network);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void triggerRequest(http.Response res) {
|
||||
if (res.headers.containsKey("x-maintenance-mode") ||
|
||||
res.statusCode == 503) {
|
||||
@@ -50,6 +79,7 @@ class StatusProvider extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
if (_stack.contains(Status.network)) return;
|
||||
if (res.body == "invalid_grant" ||
|
||||
res.body.replaceAll(' ', '') == '' ||
|
||||
res.statusCode == 400) {
|
||||
|
||||
@@ -33,6 +33,7 @@ const settingsDB = DatabaseStruct("settings", {
|
||||
"renamed_subjects_italics": int, "renamed_teachers_enabled": int,
|
||||
"renamed_teachers_italics": int,
|
||||
"live_activity_color": String,
|
||||
"welcome_message": String,
|
||||
});
|
||||
// DON'T FORGET TO UPDATE DEFAULT VALUES IN `initDB` MIGRATION OR ELSE PARENTS WILL COMPLAIN ABOUT THEIR CHILDREN MISSING
|
||||
// YOU'VE BEEN WARNED!!!
|
||||
|
||||
@@ -20,7 +20,6 @@ class Ad {
|
||||
});
|
||||
|
||||
factory Ad.fromJson(Map json) {
|
||||
print(json);
|
||||
return Ad(
|
||||
title: json['title'] ?? 'Ad',
|
||||
description: json['description'] ?? '',
|
||||
|
||||
@@ -76,6 +76,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
bool _renamedTeachersEnabled;
|
||||
bool _renamedTeachersItalics;
|
||||
Color _liveActivityColor;
|
||||
String _welcomeMessage;
|
||||
|
||||
SettingsProvider({
|
||||
DatabaseProvider? database,
|
||||
@@ -120,6 +121,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
required bool renameTeachersEnabled,
|
||||
required bool renameTeachersItalics,
|
||||
required Color liveActivityColor,
|
||||
required String welcomeMessage,
|
||||
}) : _database = database,
|
||||
_language = language,
|
||||
_startPage = startPage,
|
||||
@@ -161,7 +163,8 @@ class SettingsProvider extends ChangeNotifier {
|
||||
_renamedSubjectsItalics = renameSubjectsItalics,
|
||||
_renamedTeachersEnabled = renameTeachersEnabled,
|
||||
_renamedTeachersItalics = renameTeachersItalics,
|
||||
_liveActivityColor = liveActivityColor;
|
||||
_liveActivityColor = liveActivityColor,
|
||||
_welcomeMessage = welcomeMessage;
|
||||
|
||||
factory SettingsProvider.fromMap(Map map,
|
||||
{required DatabaseProvider database}) {
|
||||
@@ -223,6 +226,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
renameTeachersEnabled: map["renamed_teachers_enabled"] == 1,
|
||||
renameTeachersItalics: map["renamed_teachers_italics"] == 1,
|
||||
liveActivityColor: Color(map["live_activity_color"]),
|
||||
welcomeMessage: map["welcome_message"],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -272,6 +276,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
"renamed_teachers_enabled": _renamedTeachersEnabled ? 1 : 0,
|
||||
"renamed_teachers_italics": _renamedTeachersItalics ? 1 : 0,
|
||||
"live_activity_color": _liveActivityColor.value,
|
||||
"welcome_message": _welcomeMessage,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -325,6 +330,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
renameTeachersEnabled: false,
|
||||
renameTeachersItalics: false,
|
||||
liveActivityColor: const Color(0xFF676767),
|
||||
welcomeMessage: '',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -373,6 +379,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
bool get renamedTeachersEnabled => _renamedTeachersEnabled;
|
||||
bool get renamedTeachersItalics => _renamedTeachersItalics;
|
||||
Color get liveActivityColor => _liveActivityColor;
|
||||
String get welcomeMessage => _welcomeMessage;
|
||||
|
||||
Future<void> update({
|
||||
bool store = true,
|
||||
@@ -417,6 +424,7 @@ class SettingsProvider extends ChangeNotifier {
|
||||
bool? renamedTeachersEnabled,
|
||||
bool? renamedTeachersItalics,
|
||||
Color? liveActivityColor,
|
||||
String? welcomeMessage,
|
||||
}) async {
|
||||
if (language != null && language != _language) _language = language;
|
||||
if (startPage != null && startPage != _startPage) _startPage = startPage;
|
||||
@@ -535,6 +543,9 @@ class SettingsProvider extends ChangeNotifier {
|
||||
if (liveActivityColor != null && liveActivityColor != _liveActivityColor) {
|
||||
_liveActivityColor = liveActivityColor;
|
||||
}
|
||||
if (welcomeMessage != null && welcomeMessage != _welcomeMessage) {
|
||||
_welcomeMessage = welcomeMessage;
|
||||
}
|
||||
if (store) await _database?.store.storeSettings(this);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -93,4 +93,13 @@ class User {
|
||||
"refresh_user_data": "false",
|
||||
};
|
||||
}
|
||||
|
||||
static Map<String, Object?> logoutBody({
|
||||
required String refreshToken,
|
||||
}) {
|
||||
return {
|
||||
"refresh_token": refreshToken,
|
||||
"client_id": KretaAPI.clientId,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ description: "Nem hivatalos e-napló alkalmazás az e-Kréta rendszerhez"
|
||||
homepage: https://refilc.hu
|
||||
publish_to: "none"
|
||||
|
||||
version: 4.2.3+223
|
||||
version: 4.2.4+224
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <3.0.0"
|
||||
|
||||
Reference in New Issue
Block a user