feat(base): the changes of SimpleLogin accounts' keys, each with the password and a fresh sign-in (ADR 0020, D20)
Every change takes the password's proof by its own proof key (the recovery phrase's for a lost password) and a SimpleLogin sign-in of the last ten minutes on the device (`KeysOwnerProof`, its attempt), as ADR 0017's take the password and a code. The sign-in is checked before the proof and taken with the change, so a wrong proof leaves it standing and each sign-in serves one change. - `keys.set(attempt, setup, handle?)`: the first keys of an account that SimpleLogin was added to (anonymous before, or signing in with GitHub or a code), with the handle where it has none; the sign-in alone, as there is no password to prove yet. - `keys.changePassword`, `keys.beginPhrase` and `keys.resetPassword` (a lost password, with the phrase): every other session ends, in every service, as ADR 0017's change has it. - `keys.setRecoveryKeys`: a new phrase. - `account.delete(keysProof)`: an account without SRP's verifier deletes itself with the proof and the sign-in; `requireOwnerToDelete` no longer asks such an account for SRP. - `newKeysPasswordDigest` on both sides, held to each other by a test; a challenge purpose of its own for the phrase's proof while signed in. - Members ask the register for all of it; `RemoteRegister` and the instance API carry the five new operations and the deletion's proof. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
090d901e92
commit
7c58d23424
7 changed files with 3163 additions and 78 deletions
|
|
@ -22,6 +22,10 @@ import 'package:halkyon_base_client/src/protocol/keys/device_keys.dart'
|
|||
as _invv3u3l;
|
||||
import 'package:halkyon_base_client/src/protocol/keys/keys_challenge.dart'
|
||||
as _ivkzjgkp;
|
||||
import 'package:halkyon_base_client/src/protocol/keys/keys_owner_proof.dart'
|
||||
as _i1sdq72h;
|
||||
import 'package:halkyon_base_client/src/protocol/keys/keys_password.dart'
|
||||
as _i7elvg0l;
|
||||
import 'package:halkyon_base_client/src/protocol/keys/keys_proof.dart'
|
||||
as _iznbn55x;
|
||||
import 'package:halkyon_base_client/src/protocol/keys/keys_setup.dart'
|
||||
|
|
@ -78,14 +82,22 @@ class EndpointAccount extends _isc.EndpointRef {
|
|||
/// register deletes it and tells every member, this one deleting its own
|
||||
/// data at once; an anonymous person is this service's alone. An account
|
||||
/// with a password deletes itself only with [proof] (the password's proof
|
||||
/// and a code, `requireOwnerToDelete`), which the register checks, its
|
||||
/// base URL the one the device addressed here.
|
||||
_ida.Future<void> delete({_ifxctuoq.DeletionProof? proof}) =>
|
||||
caller.callServerEndpoint<void>(
|
||||
'halkyon_base.account',
|
||||
'delete',
|
||||
{'proof': proof},
|
||||
);
|
||||
/// and a code, `requireOwnerToDelete`), one that signs in with SimpleLogin
|
||||
/// only with [keysProof] (the password's proof for a challenge of
|
||||
/// `keys.begin` and a SimpleLogin sign-in of the last ten minutes on the
|
||||
/// device, Halkyon Learn's ADR 0020, D20), which the register checks,
|
||||
/// their base URL the one the device addressed here.
|
||||
_ida.Future<void> delete({
|
||||
_ifxctuoq.DeletionProof? proof,
|
||||
_i1sdq72h.KeysOwnerProof? keysProof,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.account',
|
||||
'delete',
|
||||
{
|
||||
'proof': proof,
|
||||
'keysProof': keysProof,
|
||||
},
|
||||
);
|
||||
|
||||
/// How the caller signs in besides their sessions: with GitHub, with an
|
||||
/// email address, both, or neither (anonymous).
|
||||
|
|
@ -231,9 +243,11 @@ class EndpointInstance extends _isc.EndpointRef {
|
|||
}
|
||||
|
||||
/// The keys of an account that signs in with SimpleLogin (Halkyon Learn's
|
||||
/// ADR 0020, 7 and D19), for its signed-in devices: the password proven
|
||||
/// with its own proof key, which the instance's register checks (ADR 0016).
|
||||
/// Refusals are `PasswordRefusedException`s.
|
||||
/// ADR 0020, 6, 7, D19 and D20), for its signed-in devices: the password
|
||||
/// proven with its own proof key, which the instance's register checks (ADR
|
||||
/// 0016), and every change with that proof and a SimpleLogin sign-in of the
|
||||
/// last ten minutes on the device (`KeysOwnerProof`). Refusals are
|
||||
/// `PasswordRefusedException`s; the sign-in's, `OidcRefusedException`s.
|
||||
/// {@category Endpoint}
|
||||
class EndpointKeys extends _isc.EndpointRef {
|
||||
EndpointKeys(_isc.EndpointCaller caller) : super(caller);
|
||||
|
|
@ -265,6 +279,93 @@ class EndpointKeys extends _isc.EndpointRef {
|
|||
'unlock',
|
||||
{'proof': proof},
|
||||
);
|
||||
|
||||
/// Your first keys, for an account SimpleLogin was added to that has none
|
||||
/// (`simpleLogin.complete` says `hasKeys`), all made on your device and
|
||||
/// described by [setup]; [handle] where the account has none (it said no
|
||||
/// `handle`), null otherwise. Takes your SimpleLogin sign-in of the last
|
||||
/// ten minutes on this device, under [attempt]. Refused for an account
|
||||
/// with keys (`PasswordRefusal.passwordExists`), a setup out of range
|
||||
/// (`PasswordRefusal.invalidSetup`), a handle refused or missing
|
||||
/// (`ProfileRefusedException`), and without that sign-in
|
||||
/// (`OidcRefusal.unknownAttempt`).
|
||||
_ida.Future<void> set({
|
||||
required _isc.UuidValue attempt,
|
||||
required _iec2fqr0.KeysSetup setup,
|
||||
String? handle,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.keys',
|
||||
'set',
|
||||
{
|
||||
'attempt': attempt,
|
||||
'setup': setup,
|
||||
'handle': handle,
|
||||
},
|
||||
);
|
||||
|
||||
/// The first step of proving your recovery phrase, for a password you
|
||||
/// lost: your keys wrapped under the phrase's key and your public keys,
|
||||
/// which your device opens with the phrase, and a nonce to sign with its
|
||||
/// proof key, within two minutes, once. Refused for an account without
|
||||
/// such keys (`PasswordRefusal.noPassword`).
|
||||
_ida.Future<_ir3ecgdn.KeyProofChallenge> beginPhrase() =>
|
||||
caller.callServerEndpoint<_ir3ecgdn.KeyProofChallenge>(
|
||||
'halkyon_base.keys',
|
||||
'beginPhrase',
|
||||
{},
|
||||
);
|
||||
|
||||
/// Changes your password to [password] (the same keys, wrapped under the
|
||||
/// new password's key on your device), with [proof]: the old password's
|
||||
/// for a challenge of [begin], binding the new password, and your
|
||||
/// SimpleLogin sign-in of the last ten minutes on this device. Every
|
||||
/// other session of yours ends, in every service of the instance; this
|
||||
/// one stays. The proof counts against this session, as [unlock]'s.
|
||||
_ida.Future<void> changePassword({
|
||||
required _i1sdq72h.KeysOwnerProof proof,
|
||||
required _i7elvg0l.KeysPassword password,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.keys',
|
||||
'changePassword',
|
||||
{
|
||||
'proof': proof,
|
||||
'password': password,
|
||||
},
|
||||
);
|
||||
|
||||
/// Sets a new [password] for the one you lost, with [proof]: your
|
||||
/// recovery phrase's for a challenge of [beginPhrase], binding the new
|
||||
/// password, and your SimpleLogin sign-in of the last ten minutes on this
|
||||
/// device. Every other session of yours ends, as [changePassword] has it.
|
||||
_ida.Future<void> resetPassword({
|
||||
required _i1sdq72h.KeysOwnerProof proof,
|
||||
required _i7elvg0l.KeysPassword password,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.keys',
|
||||
'resetPassword',
|
||||
{
|
||||
'proof': proof,
|
||||
'password': password,
|
||||
},
|
||||
);
|
||||
|
||||
/// A new recovery phrase: [recoveryKeys], your keys wrapped under it on
|
||||
/// your device, replace the old wrapping, and [recoveryProofKey], the
|
||||
/// public half of its proof key, the old one, with [proof] as
|
||||
/// [changePassword] takes it, binding the new phrase.
|
||||
_ida.Future<void> setRecoveryKeys({
|
||||
required _i1sdq72h.KeysOwnerProof proof,
|
||||
required _i3so7e0p.WrappedKeys recoveryKeys,
|
||||
required _idt.ByteData recoveryProofKey,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.keys',
|
||||
'setRecoveryKeys',
|
||||
{
|
||||
'proof': proof,
|
||||
'recoveryKeys': recoveryKeys,
|
||||
'recoveryProofKey': recoveryProofKey,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Getting back into an account (ADR 0017): a lost authenticator, a lost
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:typed_data' as _idt;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// What a change of an account that signs in with SimpleLogin takes
|
||||
/// (Halkyon Learn's ADR 0020, D20), as ADR 0017's `OwnerProof` takes the
|
||||
/// password and a code: a key proof for a challenge of `keys.begin` (the
|
||||
/// password's proof key), or of `keys.beginPhrase` for a lost password
|
||||
/// (the recovery phrase's), and a SimpleLogin sign-in of the last ten
|
||||
/// minutes on this device, the attempt it ended (`simpleLogin.complete`),
|
||||
/// taken by the change.
|
||||
abstract class KeysOwnerProof
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
KeysOwnerProof._({
|
||||
required this.challenge,
|
||||
required this.signature,
|
||||
required this.instanceUrl,
|
||||
required this.attempt,
|
||||
});
|
||||
|
||||
factory KeysOwnerProof({
|
||||
required _isc.UuidValue challenge,
|
||||
required _idt.ByteData signature,
|
||||
required String instanceUrl,
|
||||
required _isc.UuidValue attempt,
|
||||
}) = _KeysOwnerProofImpl;
|
||||
|
||||
factory KeysOwnerProof.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return KeysOwnerProof(
|
||||
challenge: _isc.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['challenge'],
|
||||
),
|
||||
signature: _isc.ByteDataJsonExtension.fromJson(
|
||||
jsonSerialization['signature'],
|
||||
),
|
||||
instanceUrl: jsonSerialization['instanceUrl'] as String,
|
||||
attempt: _isc.UuidValueJsonExtension.fromJson(
|
||||
jsonSerialization['attempt'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_isc.UuidValue challenge;
|
||||
|
||||
/// Ed25519's signature over `keyProofMessage`, 64 bytes.
|
||||
_idt.ByteData signature;
|
||||
|
||||
/// The instance's base URL the device addressed (scheme, host, port,
|
||||
/// path): the server it reached checks it is its own before the
|
||||
/// register binds the proof to it.
|
||||
String instanceUrl;
|
||||
|
||||
/// The SimpleLogin sign-in's attempt.
|
||||
_isc.UuidValue attempt;
|
||||
|
||||
/// Returns a shallow copy of this [KeysOwnerProof]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
KeysOwnerProof copyWith({
|
||||
_isc.UuidValue? challenge,
|
||||
_idt.ByteData? signature,
|
||||
String? instanceUrl,
|
||||
_isc.UuidValue? attempt,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.KeysOwnerProof',
|
||||
'challenge': challenge.toJson(),
|
||||
'signature': signature.toJson(),
|
||||
'instanceUrl': instanceUrl,
|
||||
'attempt': attempt.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.KeysOwnerProof',
|
||||
'challenge': challenge.toJson(),
|
||||
'signature': signature.toJson(),
|
||||
'instanceUrl': instanceUrl,
|
||||
'attempt': attempt.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _KeysOwnerProofImpl extends KeysOwnerProof {
|
||||
_KeysOwnerProofImpl({
|
||||
required _isc.UuidValue challenge,
|
||||
required _idt.ByteData signature,
|
||||
required String instanceUrl,
|
||||
required _isc.UuidValue attempt,
|
||||
}) : super._(
|
||||
challenge: challenge,
|
||||
signature: signature,
|
||||
instanceUrl: instanceUrl,
|
||||
attempt: attempt,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [KeysOwnerProof]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
KeysOwnerProof copyWith({
|
||||
_isc.UuidValue? challenge,
|
||||
_idt.ByteData? signature,
|
||||
String? instanceUrl,
|
||||
_isc.UuidValue? attempt,
|
||||
}) {
|
||||
return KeysOwnerProof(
|
||||
challenge: challenge ?? this.challenge,
|
||||
signature: signature ?? this.signature.clone(),
|
||||
instanceUrl: instanceUrl ?? this.instanceUrl,
|
||||
attempt: attempt ?? this.attempt,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
|
||||
/* To generate run: "serverpod generate" */
|
||||
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: library_private_types_in_public_api
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
// ignore_for_file: public_member_api_docs
|
||||
// ignore_for_file: type_literal_in_constant_pattern
|
||||
// ignore_for_file: use_super_parameters
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:typed_data' as _idt;
|
||||
import 'package:halkyon_base_client/src/protocol/protocol.dart' as _iwgbpyo5;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import '../password/password_costs.dart' as _ioe6tior;
|
||||
import '../password/wrapped_keys.dart' as _i2rxumte;
|
||||
|
||||
/// A new password for the keys of an account that signs in with SimpleLogin
|
||||
/// (Halkyon Learn's ADR 0020, 7 and D19), all made on the device, which
|
||||
/// holds the keys: the salt and costs it derived the password's keys with,
|
||||
/// the public half of the password's proof key, and the account's private
|
||||
/// keys wrapped under the password's key. As ADR 0017's `NewPassword`,
|
||||
/// without SRP's verifier.
|
||||
abstract class KeysPassword
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
KeysPassword._({
|
||||
required this.salt,
|
||||
required this.costs,
|
||||
required this.passwordProofKey,
|
||||
required this.passwordKeys,
|
||||
});
|
||||
|
||||
factory KeysPassword({
|
||||
required _idt.ByteData salt,
|
||||
required _ioe6tior.PasswordCosts costs,
|
||||
required _idt.ByteData passwordProofKey,
|
||||
required _i2rxumte.WrappedKeys passwordKeys,
|
||||
}) = _KeysPasswordImpl;
|
||||
|
||||
factory KeysPassword.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return KeysPassword(
|
||||
salt: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['salt']),
|
||||
costs: _iwgbpyo5.Protocol().deserialize<_ioe6tior.PasswordCosts>(
|
||||
jsonSerialization['costs'],
|
||||
),
|
||||
passwordProofKey: _isc.ByteDataJsonExtension.fromJson(
|
||||
jsonSerialization['passwordProofKey'],
|
||||
),
|
||||
passwordKeys: _iwgbpyo5.Protocol().deserialize<_i2rxumte.WrappedKeys>(
|
||||
jsonSerialization['passwordKeys'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_idt.ByteData salt;
|
||||
|
||||
_ioe6tior.PasswordCosts costs;
|
||||
|
||||
/// The public half of the new password's proof key (Ed25519).
|
||||
_idt.ByteData passwordProofKey;
|
||||
|
||||
_i2rxumte.WrappedKeys passwordKeys;
|
||||
|
||||
/// Returns a shallow copy of this [KeysPassword]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
KeysPassword copyWith({
|
||||
_idt.ByteData? salt,
|
||||
_ioe6tior.PasswordCosts? costs,
|
||||
_idt.ByteData? passwordProofKey,
|
||||
_i2rxumte.WrappedKeys? passwordKeys,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.KeysPassword',
|
||||
'salt': salt.toJson(),
|
||||
'costs': costs.toJson(),
|
||||
'passwordProofKey': passwordProofKey.toJson(),
|
||||
'passwordKeys': passwordKeys.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'halkyon_base.KeysPassword',
|
||||
'salt': salt.toJson(),
|
||||
'costs': costs.toJsonForProtocol(),
|
||||
'passwordProofKey': passwordProofKey.toJson(),
|
||||
'passwordKeys': passwordKeys.toJsonForProtocol(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _KeysPasswordImpl extends KeysPassword {
|
||||
_KeysPasswordImpl({
|
||||
required _idt.ByteData salt,
|
||||
required _ioe6tior.PasswordCosts costs,
|
||||
required _idt.ByteData passwordProofKey,
|
||||
required _i2rxumte.WrappedKeys passwordKeys,
|
||||
}) : super._(
|
||||
salt: salt,
|
||||
costs: costs,
|
||||
passwordProofKey: passwordProofKey,
|
||||
passwordKeys: passwordKeys,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [KeysPassword]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
KeysPassword copyWith({
|
||||
_idt.ByteData? salt,
|
||||
_ioe6tior.PasswordCosts? costs,
|
||||
_idt.ByteData? passwordProofKey,
|
||||
_i2rxumte.WrappedKeys? passwordKeys,
|
||||
}) {
|
||||
return KeysPassword(
|
||||
salt: salt ?? this.salt.clone(),
|
||||
costs: costs ?? this.costs.copyWith(),
|
||||
passwordProofKey: passwordProofKey ?? this.passwordProofKey.clone(),
|
||||
passwordKeys: passwordKeys ?? this.passwordKeys.copyWith(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,12 @@ enum SignInChallengePurpose implements _isc.SerializableModel {
|
|||
/// by signing a nonce with the password's proof key (Halkyon Learn's ADR
|
||||
/// 0020, D19): to get the keys on a device, or for a change. Counted per
|
||||
/// session (`asOwnerProofTry`).
|
||||
passwordProof;
|
||||
passwordProof,
|
||||
|
||||
/// Proving the recovery phrase of an account without SRP's verifier,
|
||||
/// signed in, by signing a nonce with the phrase's proof key, for a lost
|
||||
/// password (Halkyon Learn's ADR 0020, D20). Counted per session.
|
||||
phraseProof;
|
||||
|
||||
static SignInChallengePurpose fromJson(String name) {
|
||||
switch (name) {
|
||||
|
|
@ -41,6 +46,8 @@ enum SignInChallengePurpose implements _isc.SerializableModel {
|
|||
return SignInChallengePurpose.change;
|
||||
case 'passwordProof':
|
||||
return SignInChallengePurpose.passwordProof;
|
||||
case 'phraseProof':
|
||||
return SignInChallengePurpose.phraseProof;
|
||||
default:
|
||||
throw ArgumentError(
|
||||
'Value "$name" cannot be converted to "SignInChallengePurpose"',
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import 'auth/sign_in_ways.dart' as _ie6tbh85;
|
|||
import 'instance/instance_basics.dart' as _i8jixqx6;
|
||||
import 'keys/device_keys.dart' as _iz50cwqw;
|
||||
import 'keys/keys_challenge.dart' as _itebbsfc;
|
||||
import 'keys/keys_owner_proof.dart' as _iis161ma;
|
||||
import 'keys/keys_password.dart' as _i70xpmnz;
|
||||
import 'keys/keys_proof.dart' as _iviximyh;
|
||||
import 'keys/keys_setup.dart' as _iqdhlx3t;
|
||||
import 'password/account_reset_kind.dart' as _i91ka1it;
|
||||
|
|
@ -63,6 +65,8 @@ export 'auth/sign_in_ways.dart';
|
|||
export 'instance/instance_basics.dart';
|
||||
export 'keys/device_keys.dart';
|
||||
export 'keys/keys_challenge.dart';
|
||||
export 'keys/keys_owner_proof.dart';
|
||||
export 'keys/keys_password.dart';
|
||||
export 'keys/keys_proof.dart';
|
||||
export 'keys/keys_setup.dart';
|
||||
export 'password/account_reset_kind.dart';
|
||||
|
|
@ -163,6 +167,12 @@ class Protocol extends _isc.SerializationManager {
|
|||
if (t == _itebbsfc.KeysChallenge) {
|
||||
return _itebbsfc.KeysChallenge.fromJson(data) as T;
|
||||
}
|
||||
if (t == _iis161ma.KeysOwnerProof) {
|
||||
return _iis161ma.KeysOwnerProof.fromJson(data) as T;
|
||||
}
|
||||
if (t == _i70xpmnz.KeysPassword) {
|
||||
return _i70xpmnz.KeysPassword.fromJson(data) as T;
|
||||
}
|
||||
if (t == _iviximyh.KeysProof) {
|
||||
return _iviximyh.KeysProof.fromJson(data) as T;
|
||||
}
|
||||
|
|
@ -281,6 +291,13 @@ class Protocol extends _isc.SerializationManager {
|
|||
return (data != null ? _itebbsfc.KeysChallenge.fromJson(data) : null)
|
||||
as T;
|
||||
}
|
||||
if (t == _isc.getType<_iis161ma.KeysOwnerProof?>()) {
|
||||
return (data != null ? _iis161ma.KeysOwnerProof.fromJson(data) : null)
|
||||
as T;
|
||||
}
|
||||
if (t == _isc.getType<_i70xpmnz.KeysPassword?>()) {
|
||||
return (data != null ? _i70xpmnz.KeysPassword.fromJson(data) : null) as T;
|
||||
}
|
||||
if (t == _isc.getType<_iviximyh.KeysProof?>()) {
|
||||
return (data != null ? _iviximyh.KeysProof.fromJson(data) : null) as T;
|
||||
}
|
||||
|
|
@ -436,6 +453,8 @@ class Protocol extends _isc.SerializationManager {
|
|||
_i8jixqx6.InstanceBasics => 'InstanceBasics',
|
||||
_iz50cwqw.DeviceKeys => 'DeviceKeys',
|
||||
_itebbsfc.KeysChallenge => 'KeysChallenge',
|
||||
_iis161ma.KeysOwnerProof => 'KeysOwnerProof',
|
||||
_i70xpmnz.KeysPassword => 'KeysPassword',
|
||||
_iviximyh.KeysProof => 'KeysProof',
|
||||
_iqdhlx3t.KeysSetup => 'KeysSetup',
|
||||
_i91ka1it.AccountResetKind => 'AccountResetKind',
|
||||
|
|
@ -497,6 +516,10 @@ class Protocol extends _isc.SerializationManager {
|
|||
return 'DeviceKeys';
|
||||
case _itebbsfc.KeysChallenge():
|
||||
return 'KeysChallenge';
|
||||
case _iis161ma.KeysOwnerProof():
|
||||
return 'KeysOwnerProof';
|
||||
case _i70xpmnz.KeysPassword():
|
||||
return 'KeysPassword';
|
||||
case _iviximyh.KeysProof():
|
||||
return 'KeysProof';
|
||||
case _iqdhlx3t.KeysSetup():
|
||||
|
|
@ -586,6 +609,12 @@ class Protocol extends _isc.SerializationManager {
|
|||
if (dataClassName == 'KeysChallenge') {
|
||||
return deserialize<_itebbsfc.KeysChallenge>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'KeysOwnerProof') {
|
||||
return deserialize<_iis161ma.KeysOwnerProof>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'KeysPassword') {
|
||||
return deserialize<_i70xpmnz.KeysPassword>(data['data']);
|
||||
}
|
||||
if (dataClassName == 'KeysProof') {
|
||||
return deserialize<_iviximyh.KeysProof>(data['data']);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ abstract class SimpleLoginCompleted
|
|||
|
||||
/// Whether the account signed in to, or SimpleLogin was added to, has its
|
||||
/// keys (`keys.unlock` opens them); one without (an account of before,
|
||||
/// adding SimpleLogin) makes them next.
|
||||
/// adding SimpleLogin) makes them next (`keys.set`).
|
||||
bool hasKeys;
|
||||
|
||||
/// The account's handle; null for one without (it chooses one with its
|
||||
|
|
|
|||
|
|
@ -158,6 +158,28 @@ Uint8List newPasswordDigest({
|
|||
keysCipherText,
|
||||
]);
|
||||
|
||||
/// The SHA-256 of a new password for the keys of an account that signs in
|
||||
/// with SimpleLogin as the device sends it, framed: what a proof for it
|
||||
/// binds (the old password's, or the phrase's).
|
||||
Uint8List newKeysPasswordDigest({
|
||||
required List<int> salt,
|
||||
required String algorithm,
|
||||
required int opsLimit,
|
||||
required int memLimit,
|
||||
required List<int> proofKey,
|
||||
required List<int> keysNonce,
|
||||
required List<int> keysCipherText,
|
||||
}) => _sha256([
|
||||
utf8.encode('halkyon new keys password v1'),
|
||||
salt,
|
||||
utf8.encode(algorithm),
|
||||
utf8.encode('$opsLimit'),
|
||||
utf8.encode('$memLimit'),
|
||||
proofKey,
|
||||
keysNonce,
|
||||
keysCipherText,
|
||||
]);
|
||||
|
||||
/// The SHA-256 of a new recovery phrase as the device sends it (the keys
|
||||
/// wrapped under it and its proof key's public half), framed: what the
|
||||
/// owner's proof for it binds.
|
||||
|
|
|
|||
Loading…
Reference in a new issue