mirror of https://github.com/mitchell/selfpass.git
Add automatic background lock to home screen; refactor repo names
This commit is contained in:
parent
27215e6596
commit
474f0c056b
|
@ -4,12 +4,12 @@ PODS:
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Flutter (from `.symlinks/flutter/ios-release`)
|
- Flutter (from `.symlinks/flutter/ios`)
|
||||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: ".symlinks/flutter/ios-release"
|
:path: ".symlinks/flutter/ios"
|
||||||
flutter_secure_storage:
|
flutter_secure_storage:
|
||||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||||
"${PODS_ROOT}/../.symlinks/flutter/ios-release/Flutter.framework",
|
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
|
||||||
);
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'repositories/credentials_client.dart';
|
import 'repositories/grpc_credentials_client.dart';
|
||||||
import 'repositories/config.dart' as repo;
|
import 'repositories/secure_storage_config.dart';
|
||||||
|
|
||||||
import 'screens/authentication.dart';
|
import 'screens/authentication.dart';
|
||||||
import 'screens/credential.dart';
|
import 'screens/credential.dart';
|
||||||
|
@ -19,7 +19,7 @@ class Selfpass extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Provider<ConfigRepo>(
|
return Provider<ConfigRepo>(
|
||||||
builder: (BuildContext context) => repo.Config(),
|
builder: (BuildContext context) => SecureStorageConfig(),
|
||||||
child: CupertinoApp(
|
child: CupertinoApp(
|
||||||
title: 'Selfpass',
|
title: 'Selfpass',
|
||||||
onGenerateRoute: (RouteSettings settings) {
|
onGenerateRoute: (RouteSettings settings) {
|
||||||
|
@ -36,7 +36,7 @@ class Selfpass extends StatelessWidget {
|
||||||
title = 'Hosts';
|
title = 'Hosts';
|
||||||
builder = (BuildContext context) => Provider<CredentialsRepo>(
|
builder = (BuildContext context) => Provider<CredentialsRepo>(
|
||||||
builder: (BuildContext context) =>
|
builder: (BuildContext context) =>
|
||||||
CredentialsClient.cached(config: settings.arguments),
|
GRPCCredentialsClient.cached(config: settings.arguments),
|
||||||
child: Home(),
|
child: Home(),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -45,7 +45,7 @@ class Selfpass extends StatelessWidget {
|
||||||
title = 'Credentials';
|
title = 'Credentials';
|
||||||
builder = (BuildContext context) => Provider<CredentialsRepo>(
|
builder = (BuildContext context) => Provider<CredentialsRepo>(
|
||||||
builder: (BuildContext context) =>
|
builder: (BuildContext context) =>
|
||||||
CredentialsClient.cached(),
|
GRPCCredentialsClient.cached(),
|
||||||
child: Credentials(settings.arguments),
|
child: Credentials(settings.arguments),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -54,7 +54,7 @@ class Selfpass extends StatelessWidget {
|
||||||
title = 'Credential';
|
title = 'Credential';
|
||||||
builder = (BuildContext context) => Provider<CredentialsRepo>(
|
builder = (BuildContext context) => Provider<CredentialsRepo>(
|
||||||
builder: (BuildContext context) =>
|
builder: (BuildContext context) =>
|
||||||
CredentialsClient.cached(),
|
GRPCCredentialsClient.cached(),
|
||||||
child: Credential(settings.arguments),
|
child: Credential(settings.arguments),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -63,6 +63,7 @@ class Selfpass extends StatelessWidget {
|
||||||
final ConfigScreenArguments arguments = settings.arguments == null
|
final ConfigScreenArguments arguments = settings.arguments == null
|
||||||
? ConfigScreenArguments()
|
? ConfigScreenArguments()
|
||||||
: settings.arguments;
|
: settings.arguments;
|
||||||
|
|
||||||
title = 'Configuration';
|
title = 'Configuration';
|
||||||
builder = (BuildContext context) =>
|
builder = (BuildContext context) =>
|
||||||
Config(arguments.connectionConfig, arguments.privateKey);
|
Config(arguments.connectionConfig, arguments.privateKey);
|
||||||
|
|
|
@ -11,11 +11,11 @@ import '../types/abstracts.dart';
|
||||||
import '../types/connection_config.dart';
|
import '../types/connection_config.dart';
|
||||||
import '../types/credential.dart';
|
import '../types/credential.dart';
|
||||||
|
|
||||||
class CredentialsClient implements CredentialsRepo {
|
class GRPCCredentialsClient implements CredentialsRepo {
|
||||||
static CredentialsClient _cached;
|
static GRPCCredentialsClient _cached;
|
||||||
grpc.CredentialServiceClient _client;
|
grpc.CredentialServiceClient _client;
|
||||||
|
|
||||||
CredentialsClient(ConnectionConfig config) {
|
GRPCCredentialsClient(ConnectionConfig config) {
|
||||||
final caCert = utf8.encode(config.caCertificate);
|
final caCert = utf8.encode(config.caCertificate);
|
||||||
final cert = utf8.encode(config.certificate);
|
final cert = utf8.encode(config.certificate);
|
||||||
final privateCert = utf8.encode(config.privateCertificate);
|
final privateCert = utf8.encode(config.privateCertificate);
|
||||||
|
@ -33,8 +33,8 @@ class CredentialsClient implements CredentialsRepo {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
factory CredentialsClient.cached({ConnectionConfig config}) =>
|
factory GRPCCredentialsClient.cached({ConnectionConfig config}) =>
|
||||||
_cached == null ? _cached = CredentialsClient(config) : _cached;
|
config == null ? _cached : _cached = GRPCCredentialsClient(config);
|
||||||
|
|
||||||
Stream<Metadata> getAllMetadata(String sourceHost) {
|
Stream<Metadata> getAllMetadata(String sourceHost) {
|
||||||
final request = grpc.GetAllMetadataRequest();
|
final request = grpc.GetAllMetadataRequest();
|
|
@ -7,11 +7,13 @@ import '../types/connection_config.dart';
|
||||||
|
|
||||||
import '../utils/crypto.dart' as crypto;
|
import '../utils/crypto.dart' as crypto;
|
||||||
|
|
||||||
class Config implements ConfigRepo {
|
class SecureStorageConfig implements ConfigRepo {
|
||||||
static const _keyPrivateKey = "private_key";
|
static const _keyPrivateKey = "private_key";
|
||||||
static const _keyConnectionConfig = "connection_config";
|
static const _keyConnectionConfig = "connection_config";
|
||||||
static const _keyPassword = "password";
|
static const _keyPassword = "password";
|
||||||
final FlutterSecureStorage _storage = FlutterSecureStorage();
|
|
||||||
|
final _storage = FlutterSecureStorage();
|
||||||
|
|
||||||
bool _passwordMatched = false;
|
bool _passwordMatched = false;
|
||||||
String _password;
|
String _password;
|
||||||
|
|
||||||
|
@ -32,13 +34,15 @@ class Config implements ConfigRepo {
|
||||||
|
|
||||||
Future<void> setPassword(String password) {
|
Future<void> setPassword(String password) {
|
||||||
_checkIfPasswordMatched();
|
_checkIfPasswordMatched();
|
||||||
|
|
||||||
_password = password;
|
_password = password;
|
||||||
|
|
||||||
return _storage.write(
|
return _storage.write(
|
||||||
key: _keyPassword, value: crypto.hashPassword(password));
|
key: _keyPassword, value: crypto.hashPassword(password));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> get passwordSet async {
|
Future<bool> get passwordIsSet async {
|
||||||
var passHash = await _storage.read(key: _keyPassword);
|
final passHash = await _storage.read(key: _keyPassword);
|
||||||
|
|
||||||
if (passHash != null) {
|
if (passHash != null) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -53,9 +57,7 @@ class Config implements ConfigRepo {
|
||||||
_passwordMatched = crypto.matchHashedPassword(
|
_passwordMatched = crypto.matchHashedPassword(
|
||||||
await _storage.read(key: _keyPassword), password);
|
await _storage.read(key: _keyPassword), password);
|
||||||
|
|
||||||
if (_passwordMatched) {
|
if (_passwordMatched) _password = password;
|
||||||
_password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _passwordMatched;
|
return _passwordMatched;
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ class _AuthenticationState extends State<Authentication> {
|
||||||
didChangeDependencies() {
|
didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
_config = Provider.of<ConfigRepo>(context);
|
_config = Provider.of<ConfigRepo>(context);
|
||||||
_passwordIsSet = _config.passwordSet;
|
_passwordIsSet = _config.passwordIsSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -8,32 +10,56 @@ import '../types/screen_arguments.dart';
|
||||||
import '../widgets/tappable_text_list.dart';
|
import '../widgets/tappable_text_list.dart';
|
||||||
|
|
||||||
class Home extends StatefulWidget {
|
class Home extends StatefulWidget {
|
||||||
|
const Home({Key key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State createState() => _HomeState();
|
State createState() => _HomeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomeState extends State<Home> {
|
class _HomeState extends State<Home> with WidgetsBindingObserver {
|
||||||
CredentialsRepo _client;
|
CredentialsRepo _client;
|
||||||
ConfigRepo _config;
|
ConfigRepo _config;
|
||||||
Future<List<Metadata>> _metadatas;
|
Future<List<Metadata>> _metadatas;
|
||||||
|
bool _stateIsPaused = false;
|
||||||
|
Timer _pausedStateTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
didChangeDependencies() {
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
|
|
||||||
_config = Provider.of<ConfigRepo>(context);
|
_config = Provider.of<ConfigRepo>(context);
|
||||||
|
|
||||||
_client = Provider.of<CredentialsRepo>(context);
|
_client = Provider.of<CredentialsRepo>(context);
|
||||||
|
|
||||||
_metadatas = _client.getAllMetadata('').toList();
|
_metadatas = _client.getAllMetadata('').toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
|
_stateIsPaused = state == AppLifecycleState.paused;
|
||||||
|
|
||||||
|
if (_stateIsPaused) {
|
||||||
|
_pausedStateTimer = _newPausedStateTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pausedStateTimer != null) _pausedStateTimer.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return CupertinoPageScaffold(
|
return CupertinoPageScaffold(
|
||||||
child: FutureBuilder<List<Metadata>>(
|
child: FutureBuilder<List<Metadata>>(
|
||||||
future: _metadatas,
|
future: _metadatas,
|
||||||
builder: (BuildContext context,
|
builder: (
|
||||||
AsyncSnapshot<List<Metadata>> snapshot) =>
|
BuildContext context,
|
||||||
|
AsyncSnapshot<List<Metadata>> snapshot,
|
||||||
|
) =>
|
||||||
(snapshot.connectionState == ConnectionState.done)
|
(snapshot.connectionState == ConnectionState.done)
|
||||||
? TappableTextList(
|
? TappableTextList(
|
||||||
tappableText: _buildTappableText(context, snapshot.data))
|
tappableText: _buildTappableText(context, snapshot.data))
|
||||||
|
@ -55,6 +81,22 @@ class _HomeState extends State<Home> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
if (_pausedStateTimer != null) _pausedStateTimer.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer _newPausedStateTimer() {
|
||||||
|
const checkPeriod = 30;
|
||||||
|
|
||||||
|
return Timer(Duration(seconds: checkPeriod), () {
|
||||||
|
Navigator.of(context)
|
||||||
|
.pushNamedAndRemoveUntil('/', ModalRoute.withName('/home'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, GestureTapCallback> _buildTappableText(
|
Map<String, GestureTapCallback> _buildTappableText(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
List<Metadata> metadatas,
|
List<Metadata> metadatas,
|
||||||
|
|
|
@ -17,7 +17,7 @@ abstract class ConfigRepo {
|
||||||
|
|
||||||
String get password;
|
String get password;
|
||||||
Future<void> setPassword(String password);
|
Future<void> setPassword(String password);
|
||||||
Future<bool> get passwordSet;
|
Future<bool> get passwordIsSet;
|
||||||
Future<bool> matchesPasswordHash(String password);
|
Future<bool> matchesPasswordHash(String password);
|
||||||
|
|
||||||
Future<void> setConnectionConfig(ConnectionConfig config);
|
Future<void> setConnectionConfig(ConnectionConfig config);
|
||||||
|
|
14
pubspec.lock
14
pubspec.lock
|
@ -1,13 +1,6 @@
|
||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
_discoveryapis_commons:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: _discoveryapis_commons
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.8+1"
|
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -116,13 +109,6 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
googleapis:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: googleapis
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.53.0"
|
|
||||||
googleapis_auth:
|
googleapis_auth:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -11,7 +11,7 @@ description: The cross-platform Selfpass client.
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.0.0+1
|
version: 0.1.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.1.0 <3.0.0"
|
sdk: ">=2.1.0 <3.0.0"
|
||||||
|
@ -24,7 +24,6 @@ dependencies:
|
||||||
|
|
||||||
grpc: ^1.0.3
|
grpc: ^1.0.3
|
||||||
protobuf: ^0.13.12
|
protobuf: ^0.13.12
|
||||||
googleapis: ^0.53.0
|
|
||||||
|
|
||||||
provider: ^3.0.0
|
provider: ^3.0.0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue