-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,795 additions
and
3 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
.idea/runConfigurations/melos_flutter_test_encrypted_storage.xml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# Change Log | ||
|
||
All notable changes to this project will be documented in this file. | ||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. | ||
|
||
## 2023-08-30 | ||
|
||
### Changes | ||
|
||
--- | ||
|
||
Packages with breaking changes: | ||
|
||
- There are no breaking changes in this release. | ||
|
||
Packages with other changes: | ||
|
||
- [`encrypted_storage` - `v0.1.2`](#encrypted_storage---v012) | ||
|
||
--- | ||
|
||
#### `encrypted_storage` - `v0.1.2` | ||
|
||
- **FIX**: flutter test concurrency (#6). | ||
- **FEAT**: use flutter templates repository (#9). | ||
- **DOCS**: add package description (#3). | ||
|
||
## 0.1.2 | ||
|
||
- **FIX**: flutter test concurrency (#6). | ||
- **FEAT**: use flutter templates repository (#9). | ||
- **DOCS**: add package description (#3). | ||
|
||
|
||
## 2023-08-22 | ||
|
||
### Changes | ||
|
||
--- | ||
|
||
Packages with breaking changes: | ||
|
||
- There are no breaking changes in this release. | ||
|
||
Packages with other changes: | ||
|
||
- [`encrypted_storage` - `v0.1.1`](#encrypted_storage---v011) | ||
|
||
--- | ||
|
||
#### `encrypted_storage` - `v0.1.1` | ||
|
||
- **FIX**: flutter test concurrency (#6). | ||
- **FEAT**: use flutter templates repository (#9). | ||
- **DOCS**: add package description (#3). | ||
|
||
## 0.1.1 | ||
|
||
- **FIX**: flutter test concurrency (#6). | ||
- **FEAT**: use flutter templates repository (#9). | ||
- **DOCS**: add package description (#3). | ||
|
||
|
||
## 2023-07-06 | ||
|
||
### Changes | ||
|
||
--- | ||
|
||
Packages with breaking changes: | ||
|
||
- There are no breaking changes in this release. | ||
|
||
Packages with other changes: | ||
|
||
- [`encrypted_storage` - `v0.1.0+2`](#encrypted_storage---v0102) | ||
|
||
Packages graduated to a stable release (see pre-releases prior to the stable version for changelog entries): | ||
|
||
- `encrypted_storage` - `v0.1.0+2` | ||
|
||
--- | ||
|
||
#### `encrypted_storage` - `v0.1.0+2` | ||
|
||
## 0.1.0+2 | ||
|
||
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries. | ||
|
||
|
||
## 2023-06-15 | ||
|
||
### Changes | ||
|
||
--- | ||
|
||
Packages with breaking changes: | ||
|
||
- There are no breaking changes in this release. | ||
|
||
Packages with other changes: | ||
|
||
- [`encrypted_storage` - `v0.1.0-dev.0+2`](#encrypted_storage---v010-dev02) | ||
|
||
--- | ||
|
||
#### `encrypted_storage` - `v0.1.0-dev.0+2` | ||
|
||
- **DOCS**: add package description (#3). | ||
|
||
## 0.1.0-dev.0+2 | ||
|
||
- **DOCS**: add package description (#3). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# Encrypted Storage | ||
|
||
[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] | ||
[![License: AGPLv3][license_badge]][license_link] | ||
|
||
This package provides a fast and simple way to store and retrieve encrypted data usind [sqflite][sqflite_link]. It uses AES encryption via [encrypt][encrypt_link] to encrypt the data and [flutter_secure_storage][flutter_secure_storage_link] to store key and initialization vector. | ||
Check warning on line 6 in packages/encrypted_storage/README.md GitHub Actions / spell-check / build
|
||
|
||
## Installation 💻 | ||
|
||
**❗ In order to start using Encrypted Storage you must have the [Flutter SDK][flutter_install_link] installed on your machine.** | ||
|
||
Add [encrypted_storage][pubdev_link] to your `pubspec.yaml`: | ||
|
||
```yaml | ||
dependencies: | ||
encrypted_storage: | ||
``` | ||
## Melos magic 🪄 | ||
Using [melos](https://melos.invertase.dev/) makes it very easy to work with the project, so enjoy. | ||
You can run any job interactively run running `melos run` and selecting needed case or directly (e.g. `melos run test`). | ||
|
||
### Bootstrap 🏁 | ||
|
||
Melos takes care about dependencies of all packages, including managing of local-generated library version. So, just run: | ||
|
||
``` | ||
melos bs | ||
``` | ||
|
||
### Codegen 🦾 | ||
|
||
This thing will run all code generators for all packages: | ||
|
||
``` | ||
$ melos run codegen | ||
``` | ||
|
||
### Clean up 🧹 | ||
|
||
Just run commands below to clean all, including build directories and flutter projects. | ||
|
||
``` | ||
melos clean | ||
``` | ||
### Tests ✔️ | ||
You can run all tests at one by running this command. | ||
``` | ||
melos run test | ||
``` | ||
### Code 📊 | ||
You can run code analysis: | ||
``` | ||
melos run analyze | ||
``` | ||
### Code format 🗃️ | ||
`melos run check-format` will check, `melos run format` will fix dart code formatting. | ||
``` | ||
melos run check-format | ||
melos run format | ||
``` | ||
### Prepare to commit 🤝🏻 | ||
`melos run check-all` will ckeck, analyze and run all tests. | ||
``` | ||
melos run check-all | ||
``` | ||
## Conventional Commits ❤️ | ||
[This magic](https://melos.invertase.dev/guides/automated-releases#versioning) will update version and build our library automatically using commit messages and tags. [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) is a lightweight convention on top of commit messages. | ||
## Version 🏷️ | ||
Package version control is done by melos. It runs by gh action 'Create version PR' ```melos version -a --yes```. | ||
## Github Secrets 🔑 | ||
`BOT_ACCESS_TOKEN`: Personal access token (PAT) used to fetch the repository. We should use PAT and not default GITHUB_TOKEN because ["When you use the repository's GITHUB_TOKEN to perform tasks, events triggered by the GITHUB_TOKEN, with the exception of workflow_dispatch and repository_dispatch, will not create a new workflow run"](https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow). We want to trigger a workflow from the workflow (to run tests), so we need to use PAT. This thing is used in `version` workflow. | ||
[flutter_install_link]: https://docs.flutter.dev/get-started/install | ||
[license_badge]: https://img.shields.io/badge/license-AGPLv3-blue.svg | ||
[license_link]: https://opensource.org/license/agpl-v3/ | ||
[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg | ||
[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis | ||
[flutter_secure_storage_link]: https://pub.dev/packages/flutter_secure_storage | ||
[sqflite_link]: https://pub.dev/packages/sqflite | ||
[encrypt_link]: https://pub.dev/packages/encrypt | ||
[pubdev_link]: https://pub.dev/packages/encrypted_storage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include: ../../analysis_options.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/// Encrypted storage | ||
library encrypted_storage; | ||
|
||
export 'src/abstract_storage.dart'; | ||
export 'src/encrypted_storage.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import 'dart:async'; | ||
|
||
/// Default domain name | ||
const String defaultDomain = 'default'; | ||
|
||
/// {@template storage} | ||
/// AbstractStorage: storage interface | ||
/// {@endtemplate} | ||
abstract class AbstractStorage { | ||
/// Clear storage: all records | ||
Future<void> clearAll(); | ||
|
||
/// Clear storage: all records in one domain | ||
Future<void> clearDomain([String? domain = defaultDomain]); | ||
|
||
/// Write the key-value pair. [value] will be written for the [key] in | ||
/// [domain]. | ||
/// If the pair was already existed it will be overwritten if [overwrite] | ||
/// is true (by default) | ||
Future<void> set( | ||
String key, | ||
String value, { | ||
String domain = defaultDomain, | ||
bool overwrite = true, | ||
}); | ||
|
||
/// Write the key-value pair map. [pairs] will be written in [domain]. | ||
/// If the pair was already existed it will be overwritten if [overwrite] | ||
/// is true (by default). Unspecified in [pairs] in db will not be altered | ||
/// or deleted. | ||
Future<void> setDomain( | ||
Map<String, String> pairs, { | ||
String domain = defaultDomain, | ||
bool overwrite = true, | ||
}); | ||
|
||
/// Delete by [key] from [domain]. | ||
Future<void> delete( | ||
String key, { | ||
String domain = defaultDomain, | ||
}); | ||
|
||
/// Delete by [keys] from [domain]. | ||
Future<void> deleteDomain( | ||
List<String> keys, { | ||
String domain = defaultDomain, | ||
}); | ||
|
||
/// Get value by [key] and [domain]. If not found will return [defaultValue] | ||
Future<String?> get( | ||
String key, { | ||
String? defaultValue, | ||
String domain = defaultDomain, | ||
}); | ||
|
||
/// Get key-value pair map from [domain]. | ||
Future<Map<String, String>> getDomain({ | ||
String domain = defaultDomain, | ||
}); | ||
|
||
/// Get keys from [domain] | ||
Future<List<String>> getDomainKeys({ | ||
String domain = defaultDomain, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import 'package:encrypt/encrypt.dart'; | ||
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; | ||
|
||
const _keyLength = 32; | ||
const _ivLength = 16; | ||
|
||
/// {@template ciper_storage} | ||
/// Ciper storage | ||
/// {@endtemplate} | ||
class CipherStorage { | ||
/// {@macro ciper_storage} | ||
CipherStorage(); | ||
|
||
static const String _keyKey = 'cipher_storage_key'; | ||
static const String _ivKey = 'cipher_storage_iv'; | ||
late FlutterSecureStorage _storage; | ||
late final Key _key; | ||
late final IV _iv; | ||
|
||
/// Init ciper storage | ||
Future<void> init() async { | ||
_storage = FlutterSecureStorage(aOptions: _getAndroidOptions()); | ||
|
||
final rows = await _storage.readAll(); | ||
final key = rows[_keyKey]; | ||
final iv = rows[_ivKey]; | ||
|
||
if (key != null && iv != null) { | ||
_key = keyFromBase64(key); | ||
_iv = ivFromBase64(iv); | ||
|
||
return; | ||
} | ||
|
||
if ((key == null && iv != null) || (key != null && iv == null)) { | ||
throw StateError( | ||
'key and iv reading error: one of them is null while another is not', | ||
); | ||
} | ||
|
||
_key = keyFromSecureRandom(); | ||
_iv = ivFromSecureRandom(); | ||
|
||
await _storage.write(key: _keyKey, value: _key.base64); | ||
await _storage.write(key: _ivKey, value: _iv.base64); | ||
} | ||
|
||
/// Get key | ||
Key get key => _key; | ||
|
||
/// Get initialization vector | ||
IV get iv => _iv; | ||
|
||
AndroidOptions _getAndroidOptions() => const AndroidOptions( | ||
encryptedSharedPreferences: true, | ||
); | ||
|
||
/// Generate key from base64 | ||
static Key keyFromBase64(String key) => Key.fromBase64(key); | ||
|
||
/// Generate initialization vector from base64 | ||
static IV ivFromBase64(String iv) => IV.fromBase64(iv); | ||
|
||
/// Generate a new key | ||
static Key keyFromSecureRandom() => Key.fromSecureRandom(_keyLength); | ||
|
||
/// Generate a new initialization vector | ||
static IV ivFromSecureRandom() => IV.fromSecureRandom(_ivLength); | ||
} |
Oops, something went wrong.