Skip to content

Commit 3b06677

Browse files
author
LamNguyen176
committed
add github action
1 parent 968f8b2 commit 3b06677

File tree

10 files changed

+229
-47
lines changed

10 files changed

+229
-47
lines changed

.github/workflows/flutter.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Flutter CI
2+
3+
on:
4+
push:
5+
branches:
6+
- aes-algorithm # Adjust this to your default branch if necessary
7+
pull_request:
8+
branches:
9+
- aes-algorithm
10+
11+
jobs:
12+
build_android:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Check out the repository
17+
uses: actions/checkout@v2
18+
19+
- name: Set up Flutter
20+
uses: subosito/flutter-action@v2
21+
with:
22+
flutter-version: '3.19.6' # Specify the Flutter version, e.g., '2.10.0'
23+
24+
- name: Install dependencies
25+
run: flutter pub get
26+
27+
- name: Run tests
28+
run: flutter test
29+
30+
- name: Upload coverage to Codecov
31+
uses: codecov/codecov-action@v2
32+
with:
33+
files: ./coverage/lcov.info
34+
flags: flutter
35+
name: code-coverage-report
36+
token: 2f59bcbb-7263-4e0c-9a37-e710e39705bb # Add this to your GitHub secrets
37+
fail_ci_if_error: true
38+
39+
- name: Build APK
40+
run: flutter build apk --release # Build APK for Android
41+
42+
# Optionally, you can add a step to upload the APK as an artifact
43+
- name: Upload APK artifact
44+
uses: actions/upload-artifact@v2
45+
with:
46+
name: my_app_apk
47+
path: build/app/outputs/flutter-apk/app-release.apk
48+
49+
build_ios:
50+
runs-on: macos-latest
51+
52+
steps:
53+
- name: Check out the repository
54+
uses: actions/checkout@v2
55+
56+
- name: Set up Flutter
57+
uses: subosito/flutter-action@v2
58+
with:
59+
flutter-version: '3.19.6'
60+
61+
- name: Install dependencies
62+
run: flutter pub get
63+
64+
- name: Build iOS
65+
run: flutter build ios --release --no-codesign # Build iOS without code signing
66+
67+
# Optionally, you can add a step to upload the iOS build as an artifact
68+
- name: Upload iOS artifact
69+
uses: actions/upload-artifact@v2
70+
with:
71+
name: my_app_ios
72+
path: build/ios/iphoneos/*.app # Adjust the path according to your iOS build output

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
[![](https://img.shields.io/badge/author-Forest_Nguyen-f59642)](https://github.com/LamNguyen17)
66

77
A Flutter package for secure encryption algorithms, providing efficient tools for data protection and encryption operations
8+
9+
## Installation
10+
Run this command:
11+
With Flutter:
12+
```sh
13+
flutter pub add encryption_algorithm
14+
```
15+
16+
817
## Getting Started
918

1019
This project is a starting point for a Flutter

android/src/main/kotlin/com/example/flutter_crypto_algorithm/AesAlgorithm.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ class AesAlgorithm {
2525
val decryptedBytes = cipher.doFinal(decodedBytes)
2626
String(decryptedBytes, Charsets.UTF_8)
2727
} catch (e: BadPaddingException) {
28-
CryptoHelper.CONSTANTS.DECRYPTION_ERR_VALID_KEY
28+
CryptoHelper.CONSTANTS.ERR_VALID_KEY
2929
} catch (e: IllegalBlockSizeException) {
30-
CryptoHelper.CONSTANTS.DECRYPTION_ERR_INCORRECT_BLOCK_SIZE
30+
CryptoHelper.CONSTANTS.ERR_INCORRECT_BLOCK_SIZE
3131
} catch (e: Exception) {
32-
CryptoHelper.CONSTANTS.DECRYPTION_ERR_UNEXPECTED_ERROR
32+
CryptoHelper.CONSTANTS.ERR_UNEXPECTED_ERROR
3333
}
3434
}
3535
}

android/src/main/kotlin/com/example/flutter_crypto_algorithm/CryptoHelper.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ import javax.crypto.SecretKey
66
import javax.crypto.spec.*
77

88
class CryptoHelper {
9-
enum class CryptoType {
10-
ENCRYPT,
11-
DECRYPT,
12-
}
13-
149
object CONSTANTS {
1510
const val ERR_VALID_KEY = "Invalid key or corrupted data"
1611
const val ERR_INCORRECT_BLOCK_SIZE = "Incorrect block size"
@@ -32,7 +27,7 @@ class CryptoHelper {
3227
return hexLength;
3328
}
3429

35-
fun genSecretKey(algorithmType: String, secretKey: String?): SecretKey? {
30+
fun genSecretKey(algorithmType: String, secretKey: String?): SecretKey {
3631
return when (algorithmType) {
3732
AES.ALGORITHM -> {
3833
if (secretKey != null) {

android/src/main/kotlin/com/example/flutter_crypto_algorithm/FlutterCryptoAlgorithmPlugin.kt

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import io.flutter.plugin.common.MethodChannel
88
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
99
import io.flutter.plugin.common.MethodChannel.Result
1010
import kotlinx.coroutines.*
11+
import kotlinx.coroutines.flow.*
12+
import kotlinx.coroutines.launch
1113

1214
class FlutterCryptoAlgorithmPlugin : FlutterPlugin, MethodCallHandler {
1315
private lateinit var channel: MethodChannel
@@ -34,14 +36,15 @@ class FlutterCryptoAlgorithmPlugin : FlutterPlugin, MethodCallHandler {
3436
ENCRYPT_METHOD -> {
3537
val value = call.argument<String>("value")
3638
val privateKey = call.argument<String>("privateKey")
37-
val ivKey = call.argument<String>("ivKey")
38-
if (value != null && privateKey != null && ivKey != null) {
39+
val ivKey = call.argument<String>("ivKey") ?: ""
40+
if (value != null && privateKey != null) {
3941
activityScope.launch {
4042
flow {
41-
cryptoHelper.encrypt(value, privateKey, ivKey)
43+
val encryptedData = aesAlgorithm.encrypt(value, privateKey, ivKey)
44+
emit(encryptedData)
4245
}.flowOn(Dispatchers.IO).catch {
4346
result.error(
44-
CryptoHelper.Constants.ERR_VALID_KEY,
47+
CryptoHelper.CONSTANTS.ERR_VALID_KEY,
4548
"Data to encrypt is null",
4649
null
4750
)
@@ -51,7 +54,7 @@ class FlutterCryptoAlgorithmPlugin : FlutterPlugin, MethodCallHandler {
5154
}
5255
} else {
5356
result.error(
54-
CryptoHelper.Constants.ERR_VALID_KEY,
57+
CryptoHelper.CONSTANTS.ERR_VALID_KEY,
5558
"Data to encrypt is null",
5659
null
5760
)
@@ -61,14 +64,15 @@ class FlutterCryptoAlgorithmPlugin : FlutterPlugin, MethodCallHandler {
6164
DECRYPT_METHOD -> {
6265
val value = call.argument<String>("value")
6366
val privateKey = call.argument<String>("privateKey")
64-
val ivKey = call.argument<String>("ivKey")
65-
if (value != null && privateKey != null && ivKey != null) {
67+
val ivKey = call.argument<String>("ivKey") ?: ""
68+
if (value != null && privateKey != null) {
6669
activityScope.launch {
6770
flow {
68-
cryptoHelper.decrypt(value, privateKey, ivKey)
71+
val decryptData = aesAlgorithm.decrypt(value, privateKey, ivKey)
72+
emit(decryptData)
6973
}.flowOn(Dispatchers.IO).catch {
7074
result.error(
71-
CryptoHelper.Constants.ERR_VALID_KEY,
75+
CryptoHelper.CONSTANTS.ERR_VALID_KEY,
7276
"Data to decrypt is null",
7377
null
7478
)
@@ -78,14 +82,12 @@ class FlutterCryptoAlgorithmPlugin : FlutterPlugin, MethodCallHandler {
7882
}
7983
} else {
8084
result.error(
81-
CryptoHelper.Constants.ERR_VALID_KEY,
85+
CryptoHelper.CONSTANTS.ERR_VALID_KEY,
8286
"Data to decrypt is null",
8387
null
8488
)
8589
}
8690
}
87-
88-
"getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}")
8991
else -> result.notImplemented()
9092
}
9193
}

coverage/lcov.info

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
SF:lib/flutter_crypto_algorithm.dart
2+
DA:5,1
3+
DA:6,2
4+
LF:2
5+
LH:2
6+
end_of_record
7+
SF:lib/flutter_crypto_algorithm_platform_interface.dart
8+
DA:7,6
9+
DA:9,6
10+
DA:11,3
11+
DA:16,2
12+
DA:21,1
13+
DA:22,2
14+
DA:26,0
15+
DA:27,0
16+
LF:8
17+
LH:6
18+
end_of_record
19+
SF:lib/flutter_crypto_algorithm_method_channel.dart
20+
DA:12,1
21+
DA:14,2
22+
LF:2
23+
LH:2
24+
end_of_record

example/lib/main.dart

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import 'package:flutter/material.dart';
21
import 'dart:async';
3-
2+
import 'package:flutter/material.dart';
43
import 'package:flutter/services.dart';
4+
55
import 'package:flutter_crypto_algorithm/flutter_crypto_algorithm.dart';
66

77
void main() {
@@ -16,34 +16,36 @@ class MyApp extends StatefulWidget {
1616
}
1717

1818
class _MyAppState extends State<MyApp> {
19-
String _platformVersion = 'Unknown';
19+
String _encrypt = 'Unknown';
20+
String _decrypt = 'Unknown';
2021
final _flutterCryptoAlgorithmPlugin = FlutterCryptoAlgorithm();
2122

2223
@override
2324
void initState() {
2425
super.initState();
25-
initPlatformState();
26+
crypto();
2627
}
2728

2829
// Platform messages are asynchronous, so we initialize in an async method.
29-
Future<void> initPlatformState() async {
30-
String platformVersion;
31-
// Platform messages may fail, so we use a try/catch PlatformException.
32-
// We also handle the message potentially returning null.
30+
Future<void> crypto() async {
31+
String encrypt;
32+
String decrypt;
3333
try {
34-
platformVersion =
35-
await _flutterCryptoAlgorithmPlugin.getPlatformVersion() ?? 'Unknown platform version';
34+
encrypt =
35+
await _flutterCryptoAlgorithmPlugin.encrypt('Hello123', 'Hello') ??
36+
'Unknown encrypt';
37+
decrypt = await _flutterCryptoAlgorithmPlugin.decrypt(encrypt, 'Hello') ??
38+
'Unknown decrypt';
3639
} on PlatformException {
37-
platformVersion = 'Failed to get platform version.';
40+
encrypt = 'Failed encrypt.';
41+
decrypt = 'Failed decrypt.';
3842
}
3943

40-
// If the widget was removed from the tree while the asynchronous platform
41-
// message was in flight, we want to discard the reply rather than calling
42-
// setState to update our non-existent appearance.
4344
if (!mounted) return;
4445

4546
setState(() {
46-
_platformVersion = platformVersion;
47+
_encrypt = encrypt;
48+
_decrypt = decrypt;
4749
});
4850
}
4951

@@ -52,12 +54,61 @@ class _MyAppState extends State<MyApp> {
5254
return MaterialApp(
5355
home: Scaffold(
5456
appBar: AppBar(
55-
title: const Text('Plugin example app'),
57+
title: const Text('Flutter Crypto Algorithm'),
5658
),
57-
body: Center(
58-
child: Text('Running on: $_platformVersion\n'),
59+
body: SingleChildScrollView(
60+
child: Column(
61+
children: [
62+
Section(title: 'AES', children: [
63+
_buildText('Encrypt: ', _encrypt),
64+
_buildText('Decrypt: ', _decrypt),
65+
]),
66+
],
67+
),
5968
),
6069
),
6170
);
6271
}
72+
73+
Widget _buildText(String label, String value) {
74+
return Text.rich(
75+
overflow: TextOverflow.ellipsis,
76+
maxLines: 2,
77+
TextSpan(
78+
text: label,
79+
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.red),
80+
children: [
81+
TextSpan(
82+
text: value,
83+
style: const TextStyle(
84+
fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black),
85+
),
86+
],
87+
),
88+
);
89+
}
90+
}
91+
92+
class Section extends StatelessWidget {
93+
final String title;
94+
final List<Widget> children;
95+
96+
const Section({super.key, required this.title, required this.children});
97+
98+
@override
99+
Widget build(BuildContext context) {
100+
return Padding(
101+
padding: const EdgeInsets.all(16.0),
102+
child: Column(
103+
crossAxisAlignment: CrossAxisAlignment.start,
104+
children: [
105+
Text(
106+
title,
107+
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
108+
),
109+
...children,
110+
],
111+
),
112+
);
113+
}
63114
}

lib/flutter_crypto_algorithm.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
21
import 'flutter_crypto_algorithm_platform_interface.dart';
32

43
class FlutterCryptoAlgorithm {
5-
Future<String?> getPlatformVersion() {
6-
return FlutterCryptoAlgorithmPlatform.instance.getPlatformVersion();
4+
Future<String?> encrypt(String value, String privateKey, {String? ivKey}) {
5+
return FlutterCryptoAlgorithmPlatform.instance
6+
.encrypt(value, privateKey, ivKey);
7+
}
8+
9+
Future<String?> decrypt(String value, String privateKey, {String? ivKey}) {
10+
return FlutterCryptoAlgorithmPlatform.instance
11+
.decrypt(value, privateKey, ivKey);
712
}
813
}

lib/flutter_crypto_algorithm_method_channel.dart

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,28 @@ class MethodChannelFlutterCryptoAlgorithm extends FlutterCryptoAlgorithmPlatform
1010
final methodChannel = const MethodChannel('flutter_crypto_algorithm');
1111

1212
@override
13-
Future<String?> getPlatformVersion() async {
14-
final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
15-
return version;
13+
Future<String?> encrypt(String value, String privateKey, String? ivKey) async {
14+
try {
15+
return await methodChannel.invokeMethod('encrypt', {
16+
'value': value,
17+
'privateKey': privateKey,
18+
'ivKey': ivKey,
19+
});
20+
} catch (e) {
21+
return null;
22+
}
23+
}
24+
25+
@override
26+
Future<String?> decrypt(String value, String privateKey, String? ivKey) async {
27+
try {
28+
return await methodChannel.invokeMethod('decrypt', {
29+
'value': value,
30+
'privateKey': privateKey,
31+
'ivKey': ivKey,
32+
});
33+
} catch (e) {
34+
return null;
35+
}
1636
}
1737
}

0 commit comments

Comments
 (0)