- import 'dart:convert';
-
- import 'package:flutter/material.dart';
- import 'package:http/http.dart' as http;
-
- import '/components/flash_message.dart';
- import '/database/models/my_profile.dart';
- import '/utils/storage/session_cookie.dart';
-
- class LoginResponse {
- final String userId;
- final String username;
- final String publicKey;
- final String privateKey;
- final String symmetricKey;
- final String? imageLink;
-
- const LoginResponse({
- required this.publicKey,
- required this.privateKey,
- required this.symmetricKey,
- required this.userId,
- required this.username,
- this.imageLink,
- });
-
- factory LoginResponse.fromJson(Map<String, dynamic> json) {
- return LoginResponse(
- userId: json['user_id'],
- username: json['username'],
- publicKey: json['asymmetric_public_key'],
- privateKey: json['asymmetric_private_key'],
- symmetricKey: json['symmetric_key'],
- imageLink: json['image_link'],
- );
- }
- }
-
- class Login extends StatelessWidget {
- const Login({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: null,
- automaticallyImplyLeading: true,
- leading: IconButton(icon: const Icon(Icons.arrow_back),
- onPressed:() => {
- Navigator.pop(context)
- }
- ),
- backgroundColor: Colors.transparent,
- shadowColor: Colors.transparent,
- ),
- body: const SafeArea(
- child: LoginWidget(),
- ),
- );
- }
- }
-
- class LoginWidget extends StatefulWidget {
- const LoginWidget({Key? key}) : super(key: key);
-
- @override
- State<LoginWidget> createState() => _LoginWidgetState();
- }
-
- class _LoginWidgetState extends State<LoginWidget> {
- final _formKey = GlobalKey<FormState>();
-
- final TextEditingController _usernameController = TextEditingController();
- final TextEditingController _passwordController = TextEditingController();
- final TextEditingController _urlController = TextEditingController();
-
- bool _changedUrl = false;
- String _initialServerUrl = '';
-
- @override
- void initState() {
- MyProfile.getBaseServerUrl().then((String url) {
- _urlController.text = url;
- _initialServerUrl = url;
- });
-
- super.initState();
- }
-
-
- @override
- Widget build(BuildContext context) {
- const TextStyle inputTextStyle = TextStyle(
- fontSize: 18,
- );
-
- final OutlineInputBorder inputBorderStyle = OutlineInputBorder(
- borderRadius: BorderRadius.circular(5),
- borderSide: const BorderSide(
- color: Colors.transparent,
- )
- );
-
- final ButtonStyle buttonStyle = ElevatedButton.styleFrom(
- backgroundColor: Theme.of(context).colorScheme.tertiary,
- minimumSize: const Size.fromHeight(50),
- padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
- textStyle: TextStyle(
- fontSize: 20,
- fontWeight: FontWeight.bold,
- color: Theme.of(context).colorScheme.error,
- ),
- );
-
- return Center(
- child: Form(
- key: _formKey,
- child: Center(
- child: Padding(
- padding: const EdgeInsets.only(
- left: 20,
- right: 20,
- top: 0,
- bottom: 80,
- ),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Text(
- 'Login',
- style: TextStyle(
- fontSize: 35,
- color: Theme.of(context).colorScheme.onBackground,
- ),
- ),
- const SizedBox(height: 30),
- TextFormField(
- controller: _usernameController,
- decoration: InputDecoration(
- hintText: 'Username',
- enabledBorder: inputBorderStyle,
- focusedBorder: inputBorderStyle,
- ),
- style: inputTextStyle,
- // The validator receives the text that the user has entered.
- validator: (value) {
- if (value == null || value.isEmpty) {
- return 'Enter a username';
- }
- return null;
- },
- ),
- const SizedBox(height: 10),
- TextFormField(
- controller: _passwordController,
- obscureText: true,
- enableSuggestions: false,
- autocorrect: false,
- decoration: InputDecoration(
- hintText: 'Password',
- enabledBorder: inputBorderStyle,
- focusedBorder: inputBorderStyle,
- ),
- style: inputTextStyle,
- // The validator receives the text that the user has entered.
- validator: (value) {
- if (value == null || value.isEmpty) {
- return 'Enter a password';
- }
- return null;
- },
- ),
- const SizedBox(height: 15),
- changeUrl(),
- const SizedBox(height: 20),
- ElevatedButton(
- style: buttonStyle,
- onPressed: () {
- if (_formKey.currentState!.validate()) {
- login()
- .then((val) {
- Navigator.
- pushNamedAndRemoveUntil(
- context,
- '/home',
- ModalRoute.withName('/home'),
- );
- }).catchError((error) {
- showMessage(
- 'Could not login to Envelope, please try again later.',
- context,
- );
- });
- }
- },
- child: const Text('Submit'),
- ),
- ],
- )
- )
- )
- )
- );
- }
-
- Widget changeUrl() {
- if (_changedUrl) {
- return TextFormField(
- controller: _urlController,
- decoration: InputDecoration(
- hintText: 'URL',
- enabledBorder: OutlineInputBorder(
- borderRadius: BorderRadius.circular(5),
- borderSide: const BorderSide(
- color: Colors.transparent,
- )
- ),
- focusedBorder: OutlineInputBorder(
- borderRadius: BorderRadius.circular(5),
- borderSide: const BorderSide(
- color: Colors.transparent,
- )
- ),
- ),
- style: const TextStyle(
- fontSize: 18,
- ),
- // The validator receives the text that the user has entered.
- validator: (value) {
- if (value == null || value.isEmpty) {
- return 'Enter a URL';
- }
- return null;
- },
- );
- }
-
- return GestureDetector(
- onTap: () {
- setState(() {
- _changedUrl = true;
- });
- },
- child: Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- Text(
- 'Change URL',
- style: TextStyle(
- color: Theme.of(context).disabledColor,
- ),
- ),
- const SizedBox(width: 10),
- Icon(
- Icons.edit,
- color: Theme.of(context).disabledColor,
- size: 14,
- ),
- const SizedBox(width: 10),
- ],
- )
- );
- }
-
- Future<dynamic> login() async {
- if (_urlController.text != _initialServerUrl) {
- await MyProfile.setServerUrl(_urlController.text);
- }
-
- final resp = await http.post(
- await MyProfile.getServerUrl('api/v1/login'),
- headers: <String, String>{
- 'Content-Type': 'application/json; charset=UTF-8',
- },
- body: jsonEncode(<String, String>{
- 'username': _usernameController.text,
- 'password': _passwordController.text,
- }),
- );
-
- if (resp.statusCode != 200) {
- throw Exception(resp.body);
- }
-
- String? rawCookie = resp.headers['set-cookie'];
- if (rawCookie != null) {
- int index = rawCookie.indexOf(';');
- setSessionCookie((index == -1) ? rawCookie : rawCookie.substring(0, index));
- }
-
- return await MyProfile.login(
- json.decode(resp.body),
- _passwordController.text,
- );
- }
- }
|