mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-10-01 06:55:46 -04:00
password work
This commit is contained in:
parent
9d1eaeed4c
commit
960b8375b5
@ -101,7 +101,13 @@
|
||||
},
|
||||
"enter_pin_dialog": {
|
||||
"enter_pin": "Enter PIN",
|
||||
"reenter_pin": "Re-Enter PIN To Confirm"
|
||||
"reenter_pin": "Re-Enter PIN To Confirm",
|
||||
"pin_does_not_match": "PIN does not match"
|
||||
},
|
||||
"enter_password_dialog": {
|
||||
"enter_password": "Enter Password",
|
||||
"reenter_password": "Re-Enter Password To Confirm",
|
||||
"password_does_not_match": "Password does not match"
|
||||
},
|
||||
"contact_list": {
|
||||
"title": "Contact List",
|
||||
|
@ -10,12 +10,12 @@ import '../tools/tools.dart';
|
||||
|
||||
class EnterPinDialog extends ConsumerStatefulWidget {
|
||||
const EnterPinDialog({
|
||||
this.matchPin,
|
||||
this.description,
|
||||
required this.reenter,
|
||||
required this.description,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String? matchPin;
|
||||
final bool reenter;
|
||||
final String? description;
|
||||
|
||||
@override
|
||||
@ -25,8 +25,8 @@ class EnterPinDialog extends ConsumerStatefulWidget {
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties
|
||||
..add(StringProperty('matchPin', matchPin))
|
||||
..add(StringProperty('description', description));
|
||||
..add(StringProperty('description', description))
|
||||
..add(DiagnosticsProperty<bool>('reenter', reenter));
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class EnterPinDialogState extends ConsumerState<EnterPinDialog> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
widget.matchPin == null
|
||||
!widget.reenter
|
||||
? translate('enter_pin_dialog.enter_pin')
|
||||
: translate('enter_pin_dialog.reenter_pin'),
|
||||
style: theme.textTheme.titleLarge,
|
||||
@ -94,23 +94,10 @@ class EnterPinDialogState extends ConsumerState<EnterPinDialog> {
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly
|
||||
],
|
||||
// validator: (widget.matchPin != null)
|
||||
// ? (value) => value == widget.matchPin
|
||||
// ? null
|
||||
// : translate('enter_pin_dialog.pin_does_not_match')
|
||||
// : null,
|
||||
// onClipboardFound: (value) {
|
||||
// debugPrint('onClipboardFound: $value');
|
||||
// pinController.setText(value);
|
||||
// },
|
||||
hapticFeedbackType: HapticFeedbackType.lightImpact,
|
||||
onCompleted: (pin) {
|
||||
debugPrint('onCompleted: $pin');
|
||||
Navigator.pop(context, pin);
|
||||
},
|
||||
onChanged: (value) {
|
||||
debugPrint('onChanged: $value');
|
||||
},
|
||||
cursor: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -129,13 +116,6 @@ class EnterPinDialogState extends ConsumerState<EnterPinDialog> {
|
||||
border: Border.all(color: borderColor),
|
||||
),
|
||||
),
|
||||
errorText: '',
|
||||
errorPinTheme: defaultPinTheme.copyWith(
|
||||
decoration: BoxDecoration(
|
||||
color: scale.errorScale.border,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
).paddingAll(16),
|
||||
),
|
||||
if (widget.description != null)
|
||||
|
@ -11,6 +11,7 @@ import '../providers/contact.dart';
|
||||
import '../providers/contact_invite.dart';
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'enter_password.dart';
|
||||
import 'enter_pin.dart';
|
||||
import 'profile_widget.dart';
|
||||
|
||||
@ -184,22 +185,22 @@ class PasteInviteDialogState extends ConsumerState<PasteInviteDialog> {
|
||||
}
|
||||
final pin = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
EnterPinDialog(description: description));
|
||||
builder: (context) => EnterPinDialog(
|
||||
reenter: false, description: description));
|
||||
if (pin == null) {
|
||||
return null;
|
||||
}
|
||||
encryptionKey = pin;
|
||||
case EncryptionKeyType.password:
|
||||
final description =
|
||||
translate('contact_invite.protected_with_pin');
|
||||
translate('contact_invite.protected_with_password');
|
||||
if (!context.mounted) {
|
||||
return null;
|
||||
}
|
||||
final password = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
EnterPinDialog(description: description));
|
||||
EnterPasswordDialog(description: description));
|
||||
if (password == null) {
|
||||
return null;
|
||||
}
|
||||
@ -215,6 +216,7 @@ class PasteInviteDialogState extends ConsumerState<PasteInviteDialog> {
|
||||
// Check if validation was cancelled
|
||||
if (validatedContactInvitation == null) {
|
||||
setState(() {
|
||||
_pasteTextController.text = '';
|
||||
_validatingPaste = false;
|
||||
_validInvitation = null;
|
||||
});
|
||||
@ -233,20 +235,22 @@ class PasteInviteDialogState extends ConsumerState<PasteInviteDialog> {
|
||||
switch (e.type) {
|
||||
case EncryptionKeyType.none:
|
||||
errorText = translate('contact_invite.invalid_invitation');
|
||||
case EncryptionKeyType.password:
|
||||
errorText = translate('contact_invite.invalid_pin');
|
||||
case EncryptionKeyType.pin:
|
||||
errorText = translate('contact_invite.invalid_pin');
|
||||
case EncryptionKeyType.password:
|
||||
errorText = translate('contact_invite.invalid_password');
|
||||
}
|
||||
if (context.mounted) {
|
||||
showErrorToast(context, errorText);
|
||||
}
|
||||
setState(() {
|
||||
_pasteTextController.text = '';
|
||||
_validatingPaste = false;
|
||||
_validInvitation = null;
|
||||
});
|
||||
} on Exception catch (_) {
|
||||
setState(() {
|
||||
_pasteTextController.text = '';
|
||||
_validatingPaste = false;
|
||||
_validInvitation = null;
|
||||
});
|
||||
|
@ -14,6 +14,7 @@ import '../providers/contact_invite.dart';
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'contact_invitation_display.dart';
|
||||
import 'enter_password.dart';
|
||||
import 'enter_pin.dart';
|
||||
|
||||
class SendInviteDialog extends ConsumerStatefulWidget {
|
||||
@ -55,7 +56,8 @@ class SendInviteDialogState extends ConsumerState<SendInviteDialog> {
|
||||
final description = translate('send_invite_dialog.pin_description');
|
||||
final pin = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => EnterPinDialog(description: description));
|
||||
builder: (context) =>
|
||||
EnterPinDialog(reenter: false, description: description));
|
||||
if (pin == null) {
|
||||
return;
|
||||
}
|
||||
@ -66,7 +68,7 @@ class SendInviteDialogState extends ConsumerState<SendInviteDialog> {
|
||||
final matchpin = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => EnterPinDialog(
|
||||
matchPin: pin,
|
||||
reenter: true,
|
||||
description: description,
|
||||
));
|
||||
if (matchpin == null) {
|
||||
@ -91,11 +93,42 @@ class SendInviteDialogState extends ConsumerState<SendInviteDialog> {
|
||||
}
|
||||
|
||||
Future<void> _onPasswordEncryptionSelected(bool selected) async {
|
||||
setState(() {
|
||||
if (selected) {
|
||||
final description = translate('send_invite_dialog.password_description');
|
||||
final password = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => EnterPasswordDialog(description: description));
|
||||
if (password == null) {
|
||||
return;
|
||||
}
|
||||
// ignore: use_build_context_synchronously
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
final matchpass = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => EnterPasswordDialog(
|
||||
matchPass: password,
|
||||
description: description,
|
||||
));
|
||||
if (matchpass == null) {
|
||||
return;
|
||||
} else if (password == matchpass) {
|
||||
setState(() {
|
||||
_encryptionKeyType = EncryptionKeyType.password;
|
||||
_encryptionKey = password;
|
||||
});
|
||||
} else {
|
||||
// ignore: use_build_context_synchronously
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
showErrorToast(
|
||||
context, translate('send_invite_dialog.password_does_not_match'));
|
||||
setState(() {
|
||||
_encryptionKeyType = EncryptionKeyType.none;
|
||||
_encryptionKey = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onGenerateButtonPressed() async {
|
||||
|
@ -1,2 +0,0 @@
|
||||
export 'loggy.dart';
|
||||
export 'state_logger.dart';
|
@ -1,104 +0,0 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:ansicolor/ansicolor.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:loggy/loggy.dart';
|
||||
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
|
||||
String wrapWithLogColor(LogLevel? level, String text) {
|
||||
// XXX: https://github.com/flutter/flutter/issues/64491
|
||||
if (!kIsWeb && Platform.isIOS) {
|
||||
return text;
|
||||
}
|
||||
|
||||
if (level == null) {
|
||||
return text;
|
||||
}
|
||||
final pen = AnsiPen();
|
||||
ansiColorDisabled = false;
|
||||
switch (level) {
|
||||
case LogLevel.error:
|
||||
pen
|
||||
..reset()
|
||||
..red(bold: true);
|
||||
return pen(text);
|
||||
case LogLevel.warning:
|
||||
pen
|
||||
..reset()
|
||||
..yellow(bold: true);
|
||||
return pen(text);
|
||||
case LogLevel.info:
|
||||
pen
|
||||
..reset()
|
||||
..white(bold: true);
|
||||
return pen(text);
|
||||
case LogLevel.debug:
|
||||
pen
|
||||
..reset()
|
||||
..green(bold: true);
|
||||
return pen(text);
|
||||
case traceLevel:
|
||||
pen
|
||||
..reset()
|
||||
..blue(bold: true);
|
||||
return pen(text);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
extension PrettyPrintLogRecord on LogRecord {
|
||||
String pretty() {
|
||||
final lstr =
|
||||
wrapWithLogColor(level, '[${level.toString().substring(0, 1)}]');
|
||||
return '$lstr $message';
|
||||
}
|
||||
}
|
||||
|
||||
class CallbackPrinter extends LoggyPrinter {
|
||||
CallbackPrinter() : super();
|
||||
|
||||
void Function(LogRecord)? callback;
|
||||
|
||||
@override
|
||||
void onLog(LogRecord record) {
|
||||
debugPrint(record.pretty());
|
||||
callback?.call(record);
|
||||
}
|
||||
|
||||
void setCallback(void Function(LogRecord)? cb) {
|
||||
callback = cb;
|
||||
}
|
||||
}
|
||||
|
||||
CallbackPrinter globalTerminalPrinter = CallbackPrinter();
|
||||
|
||||
LogOptions getLogOptions(LogLevel? level) => LogOptions(
|
||||
level ?? LogLevel.all,
|
||||
stackTraceLevel: LogLevel.error,
|
||||
);
|
||||
|
||||
class RootLoggy implements LoggyType {
|
||||
@override
|
||||
Loggy<RootLoggy> get loggy => Loggy<RootLoggy>('');
|
||||
}
|
||||
|
||||
Loggy get log => Loggy<RootLoggy>('veilidchat');
|
||||
|
||||
void initLoggy() {
|
||||
Loggy.initLoggy(
|
||||
logPrinter: globalTerminalPrinter,
|
||||
logOptions: getLogOptions(null),
|
||||
);
|
||||
|
||||
// ignore: do_not_use_environment
|
||||
const isTrace = String.fromEnvironment('LOG_TRACE') != '';
|
||||
LogLevel logLevel;
|
||||
if (isTrace) {
|
||||
logLevel = traceLevel;
|
||||
} else {
|
||||
logLevel = kDebugMode ? LogLevel.debug : LogLevel.info;
|
||||
}
|
||||
|
||||
Loggy('').level = getLogOptions(logLevel);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'loggy.dart';
|
||||
|
||||
class StateLogger extends ProviderObserver {
|
||||
const StateLogger();
|
||||
@override
|
||||
void didUpdateProvider(
|
||||
ProviderBase<Object?> provider,
|
||||
Object? previousValue,
|
||||
Object? newValue,
|
||||
ProviderContainer container,
|
||||
) {
|
||||
log.debug('''
|
||||
{
|
||||
provider: ${provider.name ?? provider.runtimeType},
|
||||
oldValue: $previousValue,
|
||||
newValue: $newValue
|
||||
}
|
||||
''');
|
||||
super.didUpdateProvider(provider, previousValue, newValue, container);
|
||||
}
|
||||
}
|
@ -7,9 +7,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_translate/flutter_translate.dart';
|
||||
|
||||
import 'app.dart';
|
||||
import 'log/log.dart';
|
||||
import 'providers/window_control.dart';
|
||||
import 'tools/theme_service.dart';
|
||||
import 'tools/tools.dart';
|
||||
import 'veilid_init.dart';
|
||||
|
||||
void main() async {
|
||||
|
@ -2,8 +2,8 @@ import 'dart:async';
|
||||
|
||||
import 'package:veilid/veilid.dart';
|
||||
|
||||
import 'log/log.dart';
|
||||
import 'providers/connection_state.dart';
|
||||
import 'tools/tools.dart';
|
||||
import 'veilid_support/src/config.dart';
|
||||
import 'veilid_support/src/veilid_log.dart';
|
||||
|
||||
|
@ -15,7 +15,6 @@ import '../proto/proto.dart'
|
||||
ContactResponse,
|
||||
SignedContactInvitation,
|
||||
SignedContactResponse;
|
||||
import '../log/log.dart';
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'account.dart';
|
||||
@ -345,7 +344,7 @@ Future<ValidContactInvitation?> validateContactInvitation(
|
||||
final contactRequestInboxKey =
|
||||
proto.TypedKeyProto.fromProto(contactInvitation.contactRequestInboxKey);
|
||||
|
||||
late final ValidContactInvitation out;
|
||||
ValidContactInvitation? out;
|
||||
|
||||
final pool = await DHTRecordPool.instance();
|
||||
final cs = await pool.veilid.getCryptoSystem(contactRequestInboxKey.kind);
|
||||
@ -365,14 +364,20 @@ Future<ValidContactInvitation?> validateContactInvitation(
|
||||
// Decrypt contact request private
|
||||
final encryptionKeyType =
|
||||
EncryptionKeyType.fromProto(contactRequest!.encryptionKeyType);
|
||||
final writerSecret = await getEncryptionKeyCallback(cs, encryptionKeyType,
|
||||
Uint8List.fromList(contactInvitation.writerSecret));
|
||||
late final SharedSecret? writerSecret;
|
||||
try {
|
||||
writerSecret = await getEncryptionKeyCallback(cs, encryptionKeyType,
|
||||
Uint8List.fromList(contactInvitation.writerSecret));
|
||||
} on Exception catch (_) {
|
||||
throw ContactInviteInvalidKeyException(encryptionKeyType);
|
||||
}
|
||||
if (writerSecret == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final contactRequestPrivateBytes = await cs.decryptAeadWithNonce(
|
||||
Uint8List.fromList(contactRequest.private), writerSecret);
|
||||
|
||||
final contactRequestPrivate =
|
||||
proto.ContactRequestPrivate.fromBuffer(contactRequestPrivateBytes);
|
||||
final contactIdentityMasterRecordKey = proto.TypedKeyProto.fromProto(
|
||||
@ -385,12 +390,8 @@ Future<ValidContactInvitation?> validateContactInvitation(
|
||||
// Verify
|
||||
final signature = proto.SignatureProto.fromProto(
|
||||
signedContactInvitation.identitySignature);
|
||||
try {
|
||||
await cs.verify(contactIdentityMaster.identityPublicKey,
|
||||
contactInvitationBytes, signature);
|
||||
} on Exception catch (_) {
|
||||
throw ContactInviteInvalidKeyException(encryptionKeyType);
|
||||
}
|
||||
await cs.verify(contactIdentityMaster.identityPublicKey,
|
||||
contactInvitationBytes, signature);
|
||||
|
||||
final writer = KeyPair(
|
||||
key: proto.CryptoKeyProto.fromProto(contactRequestPrivate.writerKey),
|
||||
|
@ -6,7 +6,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import '../proto/proto.dart' as proto;
|
||||
import '../proto/proto.dart' show Conversation, Message;
|
||||
|
||||
import '../log/loggy.dart';
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_init.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
import 'account.dart';
|
||||
|
@ -5,7 +5,6 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../entities/entities.dart';
|
||||
import '../proto/proto.dart' as proto;
|
||||
import '../log/loggy.dart';
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_init.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
|
@ -4,7 +4,6 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../entities/entities.dart';
|
||||
import '../log/loggy.dart';
|
||||
import '../tools/tools.dart';
|
||||
import '../veilid_init.dart';
|
||||
import '../veilid_support/veilid_support.dart';
|
||||
|
@ -1,8 +1,10 @@
|
||||
export 'animations.dart';
|
||||
export 'external_stream_state.dart';
|
||||
export 'loggy.dart';
|
||||
export 'phono_byte.dart';
|
||||
export 'radix_generator.dart';
|
||||
export 'responsive.dart';
|
||||
export 'secret_crypto.dart';
|
||||
export 'state_logger.dart';
|
||||
export 'theme_service.dart';
|
||||
export 'widget_helpers.dart';
|
||||
|
Loading…
Reference in New Issue
Block a user