Skip to content

Commit

Permalink
Merge pull request #69 from fga-eps-mds/dev
Browse files Browse the repository at this point in the history
release 10/01
  • Loading branch information
gabrielm2q authored Jan 11, 2025
2 parents c898afd + e63bf90 commit 1fd4e1d
Show file tree
Hide file tree
Showing 72 changed files with 3,771 additions and 1,087 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/code-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ jobs:
restore-keys: ${{ runner.os }}-sonar
- name: Build
run: flutter build
- name: Execute tests
run: flutter test --coverage
- name: Download sonar-scanner
run: |
curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.2.1.4610-linux-x64.zip
unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
- name: Execute tests
run: |
flutter test --coverage
ls coverage/
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# APP em Flutter para o Projeto Arandu

A new Flutter project.
## APK

- [APK](https://drive.google.com/file/d/1Onw1dsXU3rjpezBIfxpIiuR0Qq4BxE3D/view?usp=drive_link)

## Getting Started

Expand Down
4 changes: 4 additions & 0 deletions android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-ignorewarnings
-keep class * {
public private *;
}
6 changes: 6 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission android:name="android.permission.INTERNET"/>


<application
android:label="aranduapp"
android:name="${applicationName}"
Expand Down Expand Up @@ -31,6 +36,7 @@
android:name="flutterEmbedding"
android:value="2" />
</application>

<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.example.aranduapp

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity: FlutterActivity()
class MainActivity: FlutterFragmentActivity()
Binary file modified assets/images/Component1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/Component2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/Component3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 0 additions & 27 deletions lib/core/network/AppInterceptors.dart

This file was deleted.

42 changes: 0 additions & 42 deletions lib/core/network/BaseApi.dart

This file was deleted.

53 changes: 53 additions & 0 deletions lib/core/network/app_interceptors.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'package:aranduapp/core/data/local/StorageValue.dart';
import 'package:aranduapp/core/log/Log.dart';
import 'package:aranduapp/core/network/token_manager/auth_service.dart';
import 'package:aranduapp/core/network/token_manager/model/refresh_token_response.dart';
import 'package:dio/dio.dart';

class AppInterceptors extends Interceptor {
@override
Future<void> onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
String? token = await StorageValue.getInstance().getAuthToken();

Log.w(token);

if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
} else {
Log.w('Token não encontrado');
}

super.onRequest(options, handler);
}

@override
Future onError(DioException err, ErrorInterceptorHandler handler) async {
if (err.response?.statusCode == 401) {
try {
Log.i('Token expirado. Tentando atualizar o token...');

RefreshTokenResponse tokens =
await AuthService().refreshToken();

final requestOptions = err.requestOptions;

requestOptions.headers['Authorization'] = 'Bearer ${tokens.authToken}';

final response = await Dio().request(
requestOptions.path,
options: Options(
method: requestOptions.method,
headers: requestOptions.headers,
),
data: requestOptions.data,
);

Log.i('Token expirado atualizado.');
return handler.resolve(response);
} catch (e) {
super.onError(err, handler);
}
}
}
}
77 changes: 77 additions & 0 deletions lib/core/network/base_api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'package:aranduapp/core/log/Log.dart';
import 'package:aranduapp/core/network/app_interceptors.dart';

import 'package:dio/dio.dart';

class BaseApi {
final Dio _dio;

static BaseApi? _authInstance, _nonAuthInstance;

final String url = 'https://arandu-user-service.onrender.com';

BaseApi._internal(bool auth) : _dio = Dio() {
_dio.options.baseUrl = url;
_dio.options.connectTimeout = const Duration(seconds: 5);
_dio.options.receiveTimeout = const Duration(seconds: 5);

if (auth) _dio.interceptors.add(AppInterceptors());

_dio.interceptors.add(LogInterceptor(
requestBody: true,
responseBody: true,
requestHeader: true,
error: true,
responseHeader: true,
request: true));
}

static BaseApi getInstance({required bool auth}) {
if (auth) {
return _authInstance ??= BaseApi._internal(auth);
} else {
return _nonAuthInstance ??= BaseApi._internal(auth);
}
}

Future<Response> get(
{required String path, Map<String, dynamic>? queryParameters}) async {
try {
return await _dio.get(path, queryParameters: queryParameters);
} catch (e) {
Log.e(e);
rethrow;
}
}

Future<Response> post({required String path, Object? data}) async {
try {
return await _dio.post(path, data: data);
} catch (e) {
Log.e(e);
rethrow;
}
}


Future<Response> patch({required String path, Object? data}) async {
try {
return await _dio.patch(path, data: data);
} catch (e) {
Log.e(e);
rethrow;
}
}



Future<Response> put({required String path, Object? data}) async {
try {
return await _dio.put(path, data: data);
} catch (e) {
Log.e(e);
rethrow;
}
}

}
31 changes: 31 additions & 0 deletions lib/core/network/token_manager/auth_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:aranduapp/core/data/local/StorageValue.dart';
import 'package:aranduapp/core/log/Log.dart';
import 'package:aranduapp/core/network/base_api.dart';
import 'package:aranduapp/core/network/token_manager/model/refresh_token_response.dart';
import 'package:dio/dio.dart';

class AuthService {
Future<RefreshTokenResponse> refreshToken() async {
String? refresh = await StorageValue.getInstance().getRefreshToken();

assert(refresh != null);

Response response = await BaseApi.getInstance(auth: false).post(
path: '/auth/refresh',
data: <String, dynamic>{'refreshToken': refresh});

RefreshTokenResponse tokens =
RefreshTokenResponse.fromJsonString(response.toString());

await StorageValue.getInstance().setAuthToken(tokens.authToken!);
await StorageValue.getInstance().setRefreshToken(tokens.refreshToken!);

Log.i("Tokens atualizados com sucesso.");

return tokens;
}

Future<void> validateToken() async {
await BaseApi.getInstance(auth: true).get(path: '/auth/validate-token');
}
}
18 changes: 18 additions & 0 deletions lib/core/network/token_manager/model/refresh_token_response.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'dart:convert';

class RefreshTokenResponse {

String? authToken;
String? refreshToken;

RefreshTokenResponse(this.authToken, this.refreshToken);

factory RefreshTokenResponse.fromJsonString(String jsonString) {
Map<String, dynamic> json = jsonDecode(jsonString);
return RefreshTokenResponse(
json['accessToken'] as String?,
json['refreshToken'] as String?
);
}

}
47 changes: 47 additions & 0 deletions lib/core/state/command.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:async/async.dart';
import 'package:flutter/material.dart';

abstract class Command<T> extends ChangeNotifier {
Result<T>? _result;

bool _running = false;

Command();

bool get isError => result?.asError != null;

bool get isOk => result?.asValue != null;

Result<T>? get result => _result;

bool get running => _running;

Future<void> _execute(action) async {
if (running) return;

_result = null;
_running = true;
notifyListeners();

try {
_result = await action();
} catch (e) {
_result = Result.error(e);
} finally {
_running = false;
notifyListeners();
}
}
}

class Command0<T> extends Command<T> {
final Future<Result<T>> Function() action;

Command0(this.action);

Future<Result<T>> execute() async {
await _execute(action);

return _result!;
}
}
28 changes: 28 additions & 0 deletions lib/ui/edit_password/model/edit_password_request.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'dart:convert';

class EditPasswordRequest {
final String oldPassword;
final String newPassword;

EditPasswordRequest({
required this.oldPassword,
required this.newPassword,
});

Map<String, dynamic> toJson() {
return <String, dynamic>{
'oldPassword': oldPassword,
'newPassword': newPassword,
};
}

factory EditPasswordRequest.fromJsonString(String jsonString) {
final json = jsonDecode(jsonString);

return EditPasswordRequest(
oldPassword: json['oldPpassword']! as String,
newPassword: json['newPassword']! as String,
);
}
}

Loading

0 comments on commit 1fd4e1d

Please sign in to comment.