home,signin,login view and ol logik

This commit is contained in:
2026-09-30 20:31:01 +02:00
parent 63d03baac9
commit df71b15ff9
27 changed files with 1654 additions and 127 deletions
+16
View File
@@ -0,0 +1,16 @@
import 'package:intl/intl.dart';
/// Retrieves the current date in the format "yyyy-MM-dd".
///
/// @return [String] A formatted date.
String getCurrentDate(DateTime date) {
return DateFormat("yyyy-MM-dd").format(date);
}
var kListDropDownYear = <int>[
for (var year = DateTime.now().year; year >= 2020; year--) year
];
var kCurrentUserIdentId = '';
+10
View File
@@ -0,0 +1,10 @@
import 'dart:io';
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
+120
View File
@@ -0,0 +1,120 @@
import 'dart:convert';
import 'dart:math';
import 'package:cryptography/cryptography.dart';
class PasswordHelper {
static const int _saltLength = 16;
static const int _hashLength = 32;
// 19 MiB, laut aktueller cryptography-Doku ein sinnvoller Startwert.
static const int _memory = 19 * 1024;
static const int _iterations = 2;
static const int _parallelism = 1;
static final Argon2id _algorithm = Argon2id(
memory: _memory,
iterations: _iterations,
parallelism: _parallelism,
hashLength: _hashLength,
);
/// Erstellt einen neuen Passwort-Hash inklusive zufälligem Salt.
///
/// Rückgabeformat:
/// argon2id$memory$iterations$parallelism$saltBase64$hashBase64
static Future<String> hashPassword(String password) async {
final salt = _generateSalt(_saltLength);
final secretKey = await _algorithm.deriveKeyFromPassword(
password: password,
nonce: salt,
);
final hashBytes = await secretKey.extractBytes();
final saltBase64 = base64UrlEncode(salt);
final hashBase64 = base64UrlEncode(hashBytes);
return 'argon2id'
'\$$_memory'
'\$$_iterations'
'\$$_parallelism'
'\$$saltBase64'
'\$$hashBase64';
}
/// Prüft ein Klartext-Passwort gegen den gespeicherten Hash.
static Future<bool> verifyPassword(
String password,
String storedHash,
) async {
try {
final parts = storedHash.split('\$');
if (parts.length != 6) {
return false;
}
if (parts[0] != 'argon2id') {
return false;
}
final memory = int.parse(parts[1]);
final iterations = int.parse(parts[2]);
final parallelism = int.parse(parts[3]);
final salt = base64Url.decode(parts[4]);
final expectedHash = base64Url.decode(parts[5]);
final algorithm = Argon2id(
memory: memory,
iterations: iterations,
parallelism: parallelism,
hashLength: expectedHash.length,
);
final secretKey = await algorithm.deriveKeyFromPassword(
password: password,
nonce: salt,
);
final calculatedHash = await secretKey.extractBytes();
return _constantTimeEquals(
calculatedHash,
expectedHash,
);
} catch (_) {
return false;
}
}
/// Erzeugt kryptographisch zufälligen Salt.
static List<int> _generateSalt(int length) {
final random = Random.secure();
return List<int>.generate(
length,
(_) => random.nextInt(256),
);
}
/// Vergleich ohne vorzeitigen Abbruch.
static bool _constantTimeEquals(
List<int> a,
List<int> b,
) {
if (a.length != b.length) {
return false;
}
var difference = 0;
for (var i = 0; i < a.length; i++) {
difference |= a[i] ^ b[i];
}
return difference == 0;
}
}
+21
View File
@@ -0,0 +1,21 @@
import 'package:get/get.dart';
import '../controller/home_controller.dart';
import '../controller/login_controller.dart';
import '../controller/signin_controller.dart';
class SampleBindings extends Bindings {
@override
void dependencies() {
// Define your dependencies here no permanent Binding
Get.lazyPut<LoginController>(() => LoginController());
Get.lazyPut<SigninController>(() => SigninController());
Get.lazyPut<HomeController>(() => HomeController());
}
}
+26
View File
@@ -0,0 +1,26 @@
import 'package:get/get.dart';
import '../pages/home_view.dart';
import '../pages/login_view.dart';
import '../pages/signin_view.dart';
import 'sample_bindings.dart';
class SampleRouts {
static final sampleBindings = SampleBindings();
static List<GetPage<dynamic>> samplePages = [
GetPage(
name: LoginPage.namedRoute,
page: () => const LoginPage(),
binding: sampleBindings,
),
GetPage(
name: SigninPage.namedRoute,
page: () => const SigninPage(),
binding: sampleBindings,
),
GetPage(
name: HomePage.namedRoute,
page: () => const HomePage(),
binding: sampleBindings,
),
];
}