Skip to content

Commit

Permalink
Merge branch 'dev-securestorage' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ErnestoMoraes committed May 23, 2023
2 parents 9f74574 + 72b2a6c commit 18cc18e
Show file tree
Hide file tree
Showing 16 changed files with 359 additions and 40 deletions.
4 changes: 2 additions & 2 deletions lib/academico_mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:academico_mobile/app/pages/recover_password/recover_password_pag
import 'package:academico_mobile/app/pages/request_documents/request_documents_page.dart';
import 'package:academico_mobile/app/pages/schedule/schedule_router.dart';
import 'package:academico_mobile/app/pages/school_records/school_records_page.dart';
import 'package:academico_mobile/app/pages/splash/splash_page.dart';
import 'package:academico_mobile/app/pages/splash/splash_route.dart';
import 'package:flutter/material.dart';

class AcademicoMobile extends StatelessWidget {
Expand All @@ -22,7 +22,7 @@ class AcademicoMobile extends StatelessWidget {
theme: ThemeConfig.theme,
debugShowCheckedModeBanner: false,
routes: {
'/': (context) => const SplashPage(),
'/': (context) => SplashRoute.page,
'/login': (context) => LoginRouter.page,
'/schedule': (context) => ScheduleRouter.page,
'/daily': (context) => DailyRouter.page,
Expand Down
32 changes: 32 additions & 0 deletions lib/app/core/secure_storage/secure_storage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class SecureStorage {
// Create storage
final storage = const FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
));

final String _keyUserName = 'username';
final String _keyPassWord = 'password';

Future setUserName(String username) async {
await storage.write(key: _keyUserName, value: username);
}

Future<String?> getUserName() async {
return await storage.read(key: _keyUserName);
}

Future setPassWord(String password) async {
await storage.write(key: _keyPassWord, value: password);
}

Future<String?> getPassWord() async {
return await storage.read(key: _keyPassWord);
}

Future deleteAll() async {
await storage.deleteAll();
}
}
6 changes: 4 additions & 2 deletions lib/app/pages/about/about_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,20 @@ class AboutPage extends StatelessWidget {
children: [
Image.asset(
'assets/images/logos/logo_academico.png',
height: context.percentHeight(.2),
width: context.percentWidth(.6),
),
Text(
'Acadêmico Mobile',
style: context.textStyles.texLabelH1.copyWith(
color: context.colorsApp.cardwhite,
fontSize: context.percentHeight(.03),
fontSize: context.percentHeight(.025),
),
),
SizedBox(height: context.percentHeight(.01)),
Text('Versão 1.0.0',
style: context.textStyles.texLabelH4.copyWith(
color: context.colorsApp.cardwhite,
fontSize: context.percentHeight(.015),
)),
],
),
Expand Down
2 changes: 1 addition & 1 deletion lib/app/pages/home/home_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class HomeController extends Cubit<HomeState> {
emit(state.copyWith(status: HomeStateStatus.loading));
try {
await Future.delayed(const Duration(seconds: 2));
emit(state.copyWith(status: HomeStateStatus.loaded));
emit(state.copyWith(status: HomeStateStatus.deslogado, isOn: false));
} catch (e, s) {
log('Error ao realizar logout', error: e, stackTrace: s);
emit(state.copyWith(
Expand Down
14 changes: 11 additions & 3 deletions lib/app/pages/home/home_page.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:academico_mobile/app/core/secure_storage/secure_storage.dart';
import 'package:academico_mobile/app/core/ui/base_state/base_state.dart';
import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart';
import 'package:academico_mobile/app/core/ui/styles/colors_app.dart';
Expand All @@ -7,6 +8,7 @@ import 'package:academico_mobile/app/pages/home/home_state.dart';
import 'package:academico_mobile/app/pages/home/widgets/card_home.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';

class HomePage extends StatefulWidget {
const HomePage({super.key});
Expand All @@ -17,6 +19,8 @@ class HomePage extends StatefulWidget {

class _HomePageState extends BaseState<HomePage, HomeController> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final SecureStorage _secureStorage = SecureStorage();
final prefs = SharedPreferences.getInstance();

@override
void onReady() {
Expand Down Expand Up @@ -44,9 +48,8 @@ class _HomePageState extends BaseState<HomePage, HomeController> {

Widget finishDrawer(BuildContext context) => InkWell(
onTap: () async {
await controller.logout().then((value) {
Navigator.of(context).pop();
});
prefs.then((value) => value.clear());
await controller.logout();
},
child: Container(
padding: EdgeInsets.only(
Expand Down Expand Up @@ -174,6 +177,11 @@ class _HomePageState extends BaseState<HomePage, HomeController> {
hideLoader();
showError(state.errorMessage ?? 'Error ao carregar Home Page');
},
deslogado: () {
hideLoader();
_secureStorage.deleteAll();
Navigator.of(context).pushReplacementNamed('/login');
},
);
},
buildWhen: (previous, current) => current.status.matchAny(
Expand Down
1 change: 1 addition & 0 deletions lib/app/pages/home/home_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum HomeStateStatus {
initial,
loading,
loaded,
deslogado,
error,
}

Expand Down
10 changes: 10 additions & 0 deletions lib/app/pages/home/home_state.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions lib/app/pages/login/login_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ class LoginController extends Cubit<LoginState> {
try {
emit(state.copyWith(status: LoginStatus.login));
final authModel = await _authRepository.login(matricula, password);

final prefs = await SharedPreferences.getInstance();
await prefs.setString('access_token', authModel.accessToken);

emit(state.copyWith(status: LoginStatus.sucess));
} on UnauthorizedException catch (e, s) {
log('Permissão Negada Controller 1', error: e, stackTrace: s);
Expand Down
36 changes: 30 additions & 6 deletions lib/app/pages/login/login_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// ignore_for_file: unnecessary_string_interpolations, avoid_print
import 'package:academico_mobile/app/core/secure_storage/secure_storage.dart';
import 'package:academico_mobile/app/core/ui/base_state/base_state.dart';
import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart';
import 'package:academico_mobile/app/core/ui/styles/colors_app.dart';
Expand All @@ -24,6 +25,19 @@ class _LoginPageState extends BaseState<LoginPage, LoginController> {
TextEditingController passwordEC = TextEditingController();
bool _obscuredText = true;
bool check = false;
final SecureStorage _secureStorage = SecureStorage();

@override
void initState() {
super.initState();
fetchSecureStorageData();
}

Future<void> fetchSecureStorageData() async {
matriculaEC.text = await _secureStorage.getUserName() ?? '';
passwordEC.text = await _secureStorage.getPassWord() ?? '';
print('username: ${matriculaEC.text}, password: ${passwordEC.text}');
}

@override
void dispose() {
Expand All @@ -32,14 +46,14 @@ class _LoginPageState extends BaseState<LoginPage, LoginController> {
super.dispose();
}

void toogleCheck() {
setState(() {
check = !check;
});
}

@override
Widget build(BuildContext context) {
void toogleCheck() {
setState(() {
check = !check;
});
}

return BlocListener<LoginController, LoginState>(
listener: (context, state) {
state.status.matchAny(
Expand Down Expand Up @@ -151,6 +165,16 @@ class _LoginPageState extends BaseState<LoginPage, LoginController> {
formKey.currentState?.validate() ??
false;
if (formValid) {
if (check == true) {
await _secureStorage
.setUserName(matriculaEC.text);
await _secureStorage
.setPassWord(passwordEC.text);
} else {
await _secureStorage.setUserName('');
await _secureStorage.setPassWord('');
}

await controller.login(
matriculaEC.text,
passwordEC.text,
Expand Down
30 changes: 30 additions & 0 deletions lib/app/pages/splash/splash_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'dart:developer';
import 'package:academico_mobile/app/pages/splash/splash_state.dart';
import 'package:academico_mobile/app/repositories/auth/auth_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SplashController extends Cubit<SplashState> {
final AuthRepository _authRepository;
SplashController(this._authRepository) : super(const SplashState.initial());

Future<void> splashLogin(String matricula, String password) async {
emit(state.copyWith(status: SplashStatus.loading));
try {
await Future.delayed(const Duration(seconds: 2));
final authModel = await _authRepository.login(matricula, password);

final prefs = await SharedPreferences.getInstance();
await prefs.setString('access_token', authModel.accessToken);

emit(state.copyWith(status: SplashStatus.loaded));
} catch (e, s) {
log('Erro ao realizar Login Controller 1', error: e, stackTrace: s);
emit(
state.copyWith(
status: SplashStatus.error,
errorMessage: 'Erro ao realizar Login Controller 2'),
);
}
}
}
96 changes: 70 additions & 26 deletions lib/app/pages/splash/splash_page.dart
Original file line number Diff line number Diff line change
@@ -1,38 +1,82 @@
import 'package:academico_mobile/app/core/secure_storage/secure_storage.dart';
import 'package:academico_mobile/app/core/ui/base_state/base_state.dart';
import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart';
import 'package:academico_mobile/app/core/ui/widgets/my_input_button.dart';
import 'package:academico_mobile/app/pages/splash/splash_controller.dart';
import 'package:academico_mobile/app/pages/splash/splash_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class SplashPage extends StatelessWidget {
class SplashPage extends StatefulWidget {
const SplashPage({super.key});

@override
State<SplashPage> createState() => _SplashPageState();
}

class _SplashPageState extends BaseState<SplashPage, SplashController> {
final SecureStorage _secureStorage = SecureStorage();
late String username;
late String password;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
username = await _secureStorage.getUserName() ?? '';
password = await _secureStorage.getPassWord() ?? '';
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/logos/logo_ifce.png',
height: context.percentWidth(.5),
fit: BoxFit.cover,
),
SizedBox(
height: context.percentHeight(.1),
),
MyInputButton(
width: context.percentWidth(.6),
height: context.percentHeight(.07),
label: 'Acessar',
onPressed: () =>
Navigator.of(context).popAndPushNamed('/login'),
),
],
return BlocListener<SplashController, SplashState>(
listener: (context, state) {
state.status.matchAny(
any: () => hideLoader(),
loading: () => showLoader(),
loaded: () {
hideLoader();
Navigator.of(context).pushReplacementNamed('/home');
},
error: () {
hideLoader();
showError('Error ao realizar login');
},
);
},
child: Scaffold(
body: Stack(
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/logos/logo_ifce.png',
height: context.percentWidth(.5),
fit: BoxFit.cover,
),
SizedBox(
height: context.percentHeight(.1),
),
MyInputButton(
width: context.percentWidth(.6),
height: context.percentHeight(.07),
label: 'Acessar',
onPressed: () async {
if (username.toString().isNotEmpty &&
password.toString().isNotEmpty) {
controller.splashLogin(username, password);
} else {
Navigator.of(context).pushNamed('/login');
}
},
),
],
),
),
),
],
],
),
),
);
}
Expand Down
Loading

0 comments on commit 18cc18e

Please sign in to comment.