feat(auth): a password with TOTP on the register, and resets

The register's side of signing in with an address, a password that never
leaves the device (SRP-6a) and a code from an authenticator (ADR 0017),
with members forwarding every step through AccountRegister:

- password.set: salt, Argon2id's costs, SRP's verifier, the public keys
  and the private keys wrapped twice, all made on the device; with the
  address a mailed code proves, an anonymous person becomes identified
  under their ID. It signs in once an authenticator is confirmed.
- passwordSignIn.begin and complete: SRP's two steps with a TOTP or
  recovery code. An address nobody has is answered from a decoy key as
  an account would be; every wrong credential is refused alike.
- authenticator: secrets sealed under totpKey (XChaCha20-Poly1305, bound
  to their row), each code accepted once, ten recovery codes with the
  first, the last one kept.
- accountRecovery: a lost authenticator reset 72 hours after the
  password and a mailed code or the recovery phrase ask, a lost password
  set anew with the phrase's signature, or the account reset with new
  keys 72 hours after a mailed code asks; a mail at each start, a
  sign-in calling it off.
- An account with a password no longer signs in by a mailed code or
  GitHub; no new GitHub account is linked where passwords are offered,
  and from GITHUB_SIGN_IN_ENDS GitHub signs nobody in and its IDs go.

Five tables, added by the module's migration; deletePerson deletes
their rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-20 13:32:12 +02:00
commit a3a8ed3890
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
117 changed files with 22557 additions and 60 deletions

View file

@ -40,7 +40,11 @@ enum EmailSignInRefusal implements _isc.SerializableModel {
otherAddressLinked,
/// The mail couldn't be sent; nothing was kept of the request.
mailFailed;
mailFailed,
/// The account signs in with its password and an authenticator (ADR
/// 0017): a code by mail no longer signs into it.
usePassword;
static EmailSignInRefusal fromJson(String name) {
switch (name) {
@ -60,6 +64,8 @@ enum EmailSignInRefusal implements _isc.SerializableModel {
return EmailSignInRefusal.otherAddressLinked;
case 'mailFailed':
return EmailSignInRefusal.mailFailed;
case 'usePassword':
return EmailSignInRefusal.usePassword;
default:
throw ArgumentError(
'Value "$name" cannot be converted to "EmailSignInRefusal"',

View file

@ -25,7 +25,19 @@ enum GitHubSignInRefusal implements _isc.SerializableModel {
otherGitHubAccountLinked,
/// No person has this GitHub account; only linking one creates it.
unknownAccount;
unknownAccount,
/// The account signs in with its password: GitHub is deprecated (ADR 0017),
/// and can't unlock the account's keys.
usePassword,
/// GitHub accounts are no longer linked (ADR 0017): an address and a
/// password are the way in.
deprecated,
/// GitHub signs nobody in any more here: its time ended
/// (`GITHUB_SIGN_IN_ENDS`).
ended;
static GitHubSignInRefusal fromJson(String name) {
switch (name) {
@ -37,6 +49,12 @@ enum GitHubSignInRefusal implements _isc.SerializableModel {
return GitHubSignInRefusal.otherGitHubAccountLinked;
case 'unknownAccount':
return GitHubSignInRefusal.unknownAccount;
case 'usePassword':
return GitHubSignInRefusal.usePassword;
case 'deprecated':
return GitHubSignInRefusal.deprecated;
case 'ended':
return GitHubSignInRefusal.ended;
default:
throw ArgumentError(
'Value "$name" cannot be converted to "GitHubSignInRefusal"',

View file

@ -18,17 +18,28 @@ abstract class SignInWays
SignInWays._({
required this.gitHub,
required this.email,
});
bool? password,
bool? authenticator,
}) : password = password ?? false,
authenticator = authenticator ?? false;
factory SignInWays({
required bool gitHub,
required bool email,
bool? password,
bool? authenticator,
}) = _SignInWaysImpl;
factory SignInWays.fromJson(Map<String, dynamic> jsonSerialization) {
return SignInWays(
gitHub: _isc.BoolJsonExtension.fromJson(jsonSerialization['gitHub']),
email: _isc.BoolJsonExtension.fromJson(jsonSerialization['email']),
password: jsonSerialization['password'] == null
? null
: _isc.BoolJsonExtension.fromJson(jsonSerialization['password']),
authenticator: jsonSerialization['authenticator'] == null
? null
: _isc.BoolJsonExtension.fromJson(jsonSerialization['authenticator']),
);
}
@ -36,12 +47,20 @@ abstract class SignInWays
bool email;
/// A password (ADR 0017), which an address needs for resets.
bool password;
/// A confirmed authenticator: the password signs in only with one.
bool authenticator;
/// Returns a shallow copy of this [SignInWays]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
SignInWays copyWith({
bool? gitHub,
bool? email,
bool? password,
bool? authenticator,
});
@override
Map<String, dynamic> toJson() {
@ -49,6 +68,8 @@ abstract class SignInWays
'__className__': 'halkyon_base.SignInWays',
'gitHub': gitHub,
'email': email,
'password': password,
'authenticator': authenticator,
};
}
@ -58,6 +79,8 @@ abstract class SignInWays
'__className__': 'halkyon_base.SignInWays',
'gitHub': gitHub,
'email': email,
'password': password,
'authenticator': authenticator,
};
}
@ -71,9 +94,13 @@ class _SignInWaysImpl extends SignInWays {
_SignInWaysImpl({
required bool gitHub,
required bool email,
bool? password,
bool? authenticator,
}) : super._(
gitHub: gitHub,
email: email,
password: password,
authenticator: authenticator,
);
/// Returns a shallow copy of this [SignInWays]
@ -83,10 +110,14 @@ class _SignInWaysImpl extends SignInWays {
SignInWays copyWith({
bool? gitHub,
bool? email,
bool? password,
bool? authenticator,
}) {
return SignInWays(
gitHub: gitHub ?? this.gitHub,
email: email ?? this.email,
password: password ?? this.password,
authenticator: authenticator ?? this.authenticator,
);
}
}

View file

@ -18,6 +18,22 @@ import 'package:halkyon_base_client/src/protocol/auth/sign_in_ways.dart'
as _ifld8s4r;
import 'package:halkyon_base_client/src/protocol/instance/instance_basics.dart'
as _isnyur2i;
import 'package:halkyon_base_client/src/protocol/password/authenticator.dart'
as _ivfmflch;
import 'package:halkyon_base_client/src/protocol/password/authenticator_enrolment.dart'
as _it1lo7kq;
import 'package:halkyon_base_client/src/protocol/password/key_proof_challenge.dart'
as _ir3ecgdn;
import 'package:halkyon_base_client/src/protocol/password/new_password.dart'
as _i95l60wq;
import 'package:halkyon_base_client/src/protocol/password/password_challenge.dart'
as _iykren7a;
import 'package:halkyon_base_client/src/protocol/password/password_setup.dart'
as _ipn3lqh9;
import 'package:halkyon_base_client/src/protocol/password/password_signed_in.dart'
as _ix90myvx;
import 'package:halkyon_base_client/src/protocol/password/reset_pending.dart'
as _ippuf33k;
import 'package:halkyon_base_client/src/protocol/profile/profile.dart'
as _i8qdmv6n;
import 'package:halkyon_base_client/src/protocol/profile/profile_refusal.dart'
@ -153,9 +169,8 @@ class EndpointGitHubSignIn extends _isc.EndpointRef {
@override
String get name => 'halkyon_base.gitHubSignIn';
/// A session for the person with the GitHub account that [code] proves,
/// whom the instance's register knows by it; an account it doesn't know
/// is refused ([GitHubSignInRefusal.unknownAccount]).
/// A session for the person with the GitHub account that [code] proves;
/// refusals as [gitHubAccountToSignIn]'s.
_ida.Future<_iacc.AuthSuccess> signIn({
required String code,
required String codeVerifier,
@ -209,8 +224,10 @@ class EndpointInstance extends _isc.EndpointRef {
String get name => 'halkyon_base.instance';
/// This instance's basics: the app it serves, GitHub sign-in only with the
/// operator's OAuth app, email sign-in only where the register can mail
/// codes (this server, or on a member the register, ADR 0016), where its
/// operator's OAuth app and until it ends (ADR 0017), email sign-in only
/// where the register can mail codes (this server, or on a member the
/// register, ADR 0016), password sign-in where the register holds its
/// keys, where its
/// source is, the oldest app build it works with, and where it keeps
/// people's data and its backups.
_ida.Future<_isnyur2i.InstanceBasics> basics() =>
@ -221,6 +238,285 @@ class EndpointInstance extends _isc.EndpointRef {
);
}
/// Getting back into an account (ADR 0017): a lost authenticator, a lost
/// password with the recovery phrase, a lost password without it. Called
/// without a session, as the person can't sign in. The instance's register
/// checks every proof (ADR 0016); a session is this server's.
/// {@category Endpoint}
class EndpointAccountRecovery extends _isc.EndpointRef {
EndpointAccountRecovery(_isc.EndpointCaller caller) : super(caller);
@override
String get name => 'halkyon_base.accountRecovery';
/// Mails a code to [address], worded in [language] (`en`, `de`), as email
/// sign-in mails it, and returns the request it answers: the proof of the
/// address that resets take. Refusals as `sendSignInCode`'s.
_ida.Future<_isc.UuidValue> sendCode({
required String address,
required String language,
}) => caller.callServerEndpoint<_isc.UuidValue>(
'halkyon_base.accountRecovery',
'sendCode',
{
'address': address,
'language': language,
},
);
/// Asks for the reset of the authenticators of the account at [address]:
/// the password's proof for [challenge] (`passwordSignIn.begin`), and a
/// [code] mailed for [request] or the recovery phrase's [signature] for
/// [keyChallenge] ([beginKeyProof]). It takes effect 72 hours later
/// unless the owner signs in with a code meanwhile; a mail in [language]
/// says so. Refusals as `resetAuthenticator`'s.
_ida.Future<_ippuf33k.ResetPending> resetAuthenticator({
required _isc.UuidValue challenge,
required _idt.ByteData clientValue,
required _idt.ByteData clientProof,
required String address,
required String language,
_isc.UuidValue? request,
String? code,
_isc.UuidValue? keyChallenge,
_idt.ByteData? signature,
}) => caller.callServerEndpoint<_ippuf33k.ResetPending>(
'halkyon_base.accountRecovery',
'resetAuthenticator',
{
'challenge': challenge,
'clientValue': clientValue,
'clientProof': clientProof,
'address': address,
'language': language,
'request': request,
'code': code,
'keyChallenge': keyChallenge,
'signature': signature,
},
);
/// The first step of proving the recovery phrase for [address]: the
/// account's keys wrapped under the phrase and a nonce to sign; alike for
/// an address nobody has. Refusals as `beginKeyProof`'s.
_ida.Future<_ir3ecgdn.KeyProofChallenge> beginKeyProof({
required String address,
}) => caller.callServerEndpoint<_ir3ecgdn.KeyProofChallenge>(
'halkyon_base.accountRecovery',
'beginKeyProof',
{'address': address},
);
/// Sets a new [password] with the recovery phrase's [signature] for
/// [challenge] and a [totpCode] or [recoveryCode]; the keys stay. Signs
/// in. Refusals as `resetPasswordWithPhrase`'s.
_ida.Future<_iacc.AuthSuccess> resetPassword({
required _isc.UuidValue challenge,
required _idt.ByteData signature,
required _i95l60wq.NewPassword password,
String? totpCode,
String? recoveryCode,
}) => caller.callServerEndpoint<_iacc.AuthSuccess>(
'halkyon_base.accountRecovery',
'resetPassword',
{
'challenge': challenge,
'signature': signature,
'password': password,
'totpCode': totpCode,
'recoveryCode': recoveryCode,
},
);
/// Asks for the reset of the whole account at [address], as a [code]
/// mailed for [request] proves: new keys, 72 hours later unless the owner
/// signs in with the password meanwhile; a mail in [language] says so.
/// Refusals as `startAccountReset`'s.
_ida.Future<_ippuf33k.ResetPending> startAccountReset({
required String address,
required String language,
required _isc.UuidValue request,
required String code,
}) => caller.callServerEndpoint<_ippuf33k.ResetPending>(
'halkyon_base.accountRecovery',
'startAccountReset',
{
'address': address,
'language': language,
'request': request,
'code': code,
},
);
/// Carries out the reset of the whole account at [address] once due, as
/// a new [code] mailed for [request] proves: [setup] replaces its
/// password and keys, and an authenticator must be set up again. Signs
/// in. Refusals as `completeAccountReset`'s.
_ida.Future<_iacc.AuthSuccess> completeAccountReset({
required String address,
required _isc.UuidValue request,
required String code,
required _ipn3lqh9.PasswordSetup setup,
}) => caller.callServerEndpoint<_iacc.AuthSuccess>(
'halkyon_base.accountRecovery',
'completeAccountReset',
{
'address': address,
'request': request,
'code': code,
'setup': setup,
},
);
}
/// The signed-in person's authenticators and recovery codes (ADR 0017),
/// which the instance's register keeps (ADR 0016).
/// {@category Endpoint}
class EndpointAuthenticator extends _isc.EndpointRef {
EndpointAuthenticator(_isc.EndpointCaller caller) : super(caller);
@override
String get name => 'halkyon_base.authenticator';
/// A new authenticator called [name], for the app to read from the
/// returned URI (shown once), which names the account [label] (the
/// address the device signs in with). Refusals as `enrolAuthenticator`'s.
_ida.Future<_it1lo7kq.AuthenticatorEnrolment> enrol({
required String name,
required String label,
}) => caller.callServerEndpoint<_it1lo7kq.AuthenticatorEnrolment>(
'halkyon_base.authenticator',
'enrol',
{
'name': name,
'label': label,
},
);
/// Confirms [authenticator] with a [code] from it; the account's first
/// returns its recovery codes, shown once. Refusals as
/// `confirmAuthenticator`'s.
_ida.Future<List<String>> confirm({
required _isc.UuidValue authenticator,
required String code,
}) => caller.callServerEndpoint<List<String>>(
'halkyon_base.authenticator',
'confirm',
{
'authenticator': authenticator,
'code': code,
},
);
/// The caller's authenticators, the oldest first.
_ida.Future<List<_ivfmflch.Authenticator>> list() =>
caller.callServerEndpoint<List<_ivfmflch.Authenticator>>(
'halkyon_base.authenticator',
'list',
{},
);
/// Removes [authenticator]: a confirmed one with a [code] from one of the
/// caller's, while another stays. Refusals as `removeAuthenticator`'s.
_ida.Future<void> remove({
required _isc.UuidValue authenticator,
String? code,
}) => caller.callServerEndpoint<void>(
'halkyon_base.authenticator',
'remove',
{
'authenticator': authenticator,
'code': code,
},
);
/// New recovery codes in place of the old, with a [code] from one of the
/// caller's authenticators: shown once. Refusals as `newRecoveryCodes`'.
_ida.Future<List<String>> newRecoveryCodes({required String code}) =>
caller.callServerEndpoint<List<String>>(
'halkyon_base.authenticator',
'newRecoveryCodes',
{'code': code},
);
}
/// Giving the signed-in person a password (ADR 0017): the way an anonymous
/// person becomes identified, keeping everything they have, and the way
/// someone who signs in with a code by mail or GitHub moves to a password.
/// The instance's register keeps it (ADR 0016).
/// {@category Endpoint}
class EndpointPassword extends _isc.EndpointRef {
EndpointPassword(_isc.EndpointCaller caller) : super(caller);
@override
String get name => 'halkyon_base.password';
/// Gives the caller the password [setup] describes (all of it made on the
/// device), with the address [code] proves for [request] (mailed with
/// `emailCode.sendCode`) unless the caller has one; refusals as
/// `setPassword`'s. It signs in once an authenticator is confirmed
/// (`authenticator.confirm`).
_ida.Future<void> set({
required _ipn3lqh9.PasswordSetup setup,
_isc.UuidValue? request,
String? code,
}) => caller.callServerEndpoint<void>(
'halkyon_base.password',
'set',
{
'setup': setup,
'request': request,
'code': code,
},
);
}
/// Signing in with an address, a password and a code from an authenticator
/// (ADR 0017), in SRP-6a's two steps. Called without a session: Serverpod
/// issues no session for another person inside a signed-in call. The
/// instance's register checks both steps (ADR 0016); the session is this
/// server's.
/// {@category Endpoint}
class EndpointPasswordSignIn extends _isc.EndpointRef {
EndpointPasswordSignIn(_isc.EndpointCaller caller) : super(caller);
@override
String get name => 'halkyon_base.passwordSignIn';
/// The first step for [address]: its salt and costs, which the device
/// derives the password's keys with, and SRP's B; alike for an address
/// nobody has. Refusals as `beginPasswordSignIn`'s.
_ida.Future<_iykren7a.PasswordChallenge> begin({required String address}) =>
caller.callServerEndpoint<_iykren7a.PasswordChallenge>(
'halkyon_base.passwordSignIn',
'begin',
{'address': address},
);
/// The second step: the device's A ([clientValue]) and proof M1
/// ([clientProof]) for [challenge], and a [totpCode] or a [recoveryCode].
/// Signed in, SRP's M2 (which the device checks before trusting anything
/// else), the account's keys as the register keeps them, and the session.
/// Refusals as `completePasswordSignIn`'s.
_ida.Future<_ix90myvx.PasswordSignedIn> complete({
required _isc.UuidValue challenge,
required _idt.ByteData clientValue,
required _idt.ByteData clientProof,
String? totpCode,
String? recoveryCode,
}) => caller.callServerEndpoint<_ix90myvx.PasswordSignedIn>(
'halkyon_base.passwordSignIn',
'complete',
{
'challenge': challenge,
'clientValue': clientValue,
'clientProof': clientProof,
'totpCode': totpCode,
'recoveryCode': recoveryCode,
},
);
}
/// Your public profile (Halkyon Learn's ADR 0005, rule 2; ADR 0016): the
/// handle others find you by, your display name, bio and links, the same in
/// every service of the instance. Only for people with an identity: a profile
@ -347,6 +643,10 @@ class Caller extends _isc.ModuleEndpointCaller {
gitHubSignIn = EndpointGitHubSignIn(this);
gitHubUpgrade = EndpointGitHubUpgrade(this);
instance = EndpointInstance(this);
accountRecovery = EndpointAccountRecovery(this);
authenticator = EndpointAuthenticator(this);
password = EndpointPassword(this);
passwordSignIn = EndpointPasswordSignIn(this);
profile = EndpointProfile(this);
profiles = EndpointProfiles(this);
}
@ -365,6 +665,14 @@ class Caller extends _isc.ModuleEndpointCaller {
late final EndpointInstance instance;
late final EndpointAccountRecovery accountRecovery;
late final EndpointAuthenticator authenticator;
late final EndpointPassword password;
late final EndpointPasswordSignIn passwordSignIn;
late final EndpointProfile profile;
late final EndpointProfiles profiles;
@ -378,6 +686,10 @@ class Caller extends _isc.ModuleEndpointCaller {
'halkyon_base.gitHubSignIn': gitHubSignIn,
'halkyon_base.gitHubUpgrade': gitHubUpgrade,
'halkyon_base.instance': instance,
'halkyon_base.accountRecovery': accountRecovery,
'halkyon_base.authenticator': authenticator,
'halkyon_base.password': password,
'halkyon_base.passwordSignIn': passwordSignIn,
'halkyon_base.profile': profile,
'halkyon_base.profiles': profiles,
};

View file

@ -26,7 +26,8 @@ abstract class InstanceBasics
required this.minimumAppBuild,
this.dataLocation,
this.backupLocation,
});
bool? passwordSignIn,
}) : passwordSignIn = passwordSignIn ?? false;
factory InstanceBasics({
required String app,
@ -36,6 +37,7 @@ abstract class InstanceBasics
required int minimumAppBuild,
String? dataLocation,
String? backupLocation,
bool? passwordSignIn,
}) = _InstanceBasicsImpl;
factory InstanceBasics.fromJson(Map<String, dynamic> jsonSerialization) {
@ -49,6 +51,11 @@ abstract class InstanceBasics
minimumAppBuild: jsonSerialization['minimumAppBuild'] as int,
dataLocation: jsonSerialization['dataLocation'] as String?,
backupLocation: jsonSerialization['backupLocation'] as String?,
passwordSignIn: jsonSerialization['passwordSignIn'] == null
? null
: _isc.BoolJsonExtension.fromJson(
jsonSerialization['passwordSignIn'],
),
);
}
@ -82,6 +89,10 @@ abstract class InstanceBasics
/// `none` where it keeps none. Null where the operator says nothing.
String? backupLocation;
/// Whether people sign in with a password and TOTP here (ADR 0017): the
/// operator set the keys it needs.
bool passwordSignIn;
/// Returns a shallow copy of this [InstanceBasics]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@ -93,6 +104,7 @@ abstract class InstanceBasics
int? minimumAppBuild,
String? dataLocation,
String? backupLocation,
bool? passwordSignIn,
});
@override
Map<String, dynamic> toJson() {
@ -105,6 +117,7 @@ abstract class InstanceBasics
'minimumAppBuild': minimumAppBuild,
if (dataLocation != null) 'dataLocation': dataLocation,
if (backupLocation != null) 'backupLocation': backupLocation,
'passwordSignIn': passwordSignIn,
};
}
@ -119,6 +132,7 @@ abstract class InstanceBasics
'minimumAppBuild': minimumAppBuild,
if (dataLocation != null) 'dataLocation': dataLocation,
if (backupLocation != null) 'backupLocation': backupLocation,
'passwordSignIn': passwordSignIn,
};
}
@ -139,6 +153,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
required int minimumAppBuild,
String? dataLocation,
String? backupLocation,
bool? passwordSignIn,
}) : super._(
app: app,
gitHubClientId: gitHubClientId,
@ -147,6 +162,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
minimumAppBuild: minimumAppBuild,
dataLocation: dataLocation,
backupLocation: backupLocation,
passwordSignIn: passwordSignIn,
);
/// Returns a shallow copy of this [InstanceBasics]
@ -161,6 +177,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
int? minimumAppBuild,
Object? dataLocation = _Undefined,
Object? backupLocation = _Undefined,
bool? passwordSignIn,
}) {
return InstanceBasics(
app: app ?? this.app,
@ -174,6 +191,7 @@ class _InstanceBasicsImpl extends InstanceBasics {
backupLocation: backupLocation is String?
? backupLocation
: this.backupLocation,
passwordSignIn: passwordSignIn ?? this.passwordSignIn,
);
}
}

View file

@ -0,0 +1,42 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// Which reset an account waits for.
enum AccountResetKind implements _isc.SerializableModel {
/// Its authenticators and recovery codes go: a lost second factor.
authenticator,
/// Its password and keys are made anew: a lost password without the
/// recovery phrase, which loses what was encrypted under the old keys.
account;
static AccountResetKind fromJson(String name) {
switch (name) {
case 'authenticator':
return AccountResetKind.authenticator;
case 'account':
return AccountResetKind.account;
default:
throw ArgumentError(
'Value "$name" cannot be converted to "AccountResetKind"',
);
}
}
@override
String toJson() => name;
@override
String toString() => name;
}

View file

@ -0,0 +1,122 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// One of the account's authenticators, as its owner sees them: never its
/// secret.
abstract class Authenticator
implements _isc.SerializableModel, _isc.ProtocolSerialization {
Authenticator._({
required this.id,
required this.name,
required this.confirmed,
required this.createdAt,
});
factory Authenticator({
required _isc.UuidValue id,
required String name,
required bool confirmed,
required DateTime createdAt,
}) = _AuthenticatorImpl;
factory Authenticator.fromJson(Map<String, dynamic> jsonSerialization) {
return Authenticator(
id: _isc.UuidValueJsonExtension.fromJson(jsonSerialization['id']),
name: jsonSerialization['name'] as String,
confirmed: _isc.BoolJsonExtension.fromJson(
jsonSerialization['confirmed'],
),
createdAt: _isc.DateTimeJsonExtension.fromJson(
jsonSerialization['createdAt'],
),
);
}
_isc.UuidValue id;
String name;
/// Whether a code from it was accepted; one that wasn't counts for nothing.
bool confirmed;
DateTime createdAt;
/// Returns a shallow copy of this [Authenticator]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
Authenticator copyWith({
_isc.UuidValue? id,
String? name,
bool? confirmed,
DateTime? createdAt,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.Authenticator',
'id': id.toJson(),
'name': name,
'confirmed': confirmed,
'createdAt': createdAt.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.Authenticator',
'id': id.toJson(),
'name': name,
'confirmed': confirmed,
'createdAt': createdAt.toJson(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _AuthenticatorImpl extends Authenticator {
_AuthenticatorImpl({
required _isc.UuidValue id,
required String name,
required bool confirmed,
required DateTime createdAt,
}) : super._(
id: id,
name: name,
confirmed: confirmed,
createdAt: createdAt,
);
/// Returns a shallow copy of this [Authenticator]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
Authenticator copyWith({
_isc.UuidValue? id,
String? name,
bool? confirmed,
DateTime? createdAt,
}) {
return Authenticator(
id: id ?? this.id,
name: name ?? this.name,
confirmed: confirmed ?? this.confirmed,
createdAt: createdAt ?? this.createdAt,
);
}
}

View file

@ -0,0 +1,97 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// A new authenticator (ADR 0017): the `otpauth://` URI its app reads from a
/// QR code, shown this once, and the ID a code from it confirms.
abstract class AuthenticatorEnrolment
implements _isc.SerializableModel, _isc.ProtocolSerialization {
AuthenticatorEnrolment._({
required this.authenticator,
required this.uri,
});
factory AuthenticatorEnrolment({
required _isc.UuidValue authenticator,
required String uri,
}) = _AuthenticatorEnrolmentImpl;
factory AuthenticatorEnrolment.fromJson(
Map<String, dynamic> jsonSerialization,
) {
return AuthenticatorEnrolment(
authenticator: _isc.UuidValueJsonExtension.fromJson(
jsonSerialization['authenticator'],
),
uri: jsonSerialization['uri'] as String,
);
}
_isc.UuidValue authenticator;
String uri;
/// Returns a shallow copy of this [AuthenticatorEnrolment]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
AuthenticatorEnrolment copyWith({
_isc.UuidValue? authenticator,
String? uri,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.AuthenticatorEnrolment',
'authenticator': authenticator.toJson(),
'uri': uri,
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.AuthenticatorEnrolment',
'authenticator': authenticator.toJson(),
'uri': uri,
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _AuthenticatorEnrolmentImpl extends AuthenticatorEnrolment {
_AuthenticatorEnrolmentImpl({
required _isc.UuidValue authenticator,
required String uri,
}) : super._(
authenticator: authenticator,
uri: uri,
);
/// Returns a shallow copy of this [AuthenticatorEnrolment]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
AuthenticatorEnrolment copyWith({
_isc.UuidValue? authenticator,
String? uri,
}) {
return AuthenticatorEnrolment(
authenticator: authenticator ?? this.authenticator,
uri: uri ?? this.uri,
);
}
}

View file

@ -0,0 +1,144 @@
/* 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/wrapped_keys.dart' as _i2rxumte;
/// What a device needs to prove the recovery phrase (ADR 0017): the
/// account's private keys wrapped under the phrase's key and its public
/// keys, which the device opens with the phrase, and a nonce it signs with
/// the signing key so opened, within two minutes, once. Alike for an address
/// nobody has.
abstract class KeyProofChallenge
implements _isc.SerializableModel, _isc.ProtocolSerialization {
KeyProofChallenge._({
required this.challenge,
required this.nonce,
required this.encryptionPublicKey,
required this.signingPublicKey,
required this.recoveryKeys,
});
factory KeyProofChallenge({
required _isc.UuidValue challenge,
required _idt.ByteData nonce,
required _idt.ByteData encryptionPublicKey,
required _idt.ByteData signingPublicKey,
required _i2rxumte.WrappedKeys recoveryKeys,
}) = _KeyProofChallengeImpl;
factory KeyProofChallenge.fromJson(Map<String, dynamic> jsonSerialization) {
return KeyProofChallenge(
challenge: _isc.UuidValueJsonExtension.fromJson(
jsonSerialization['challenge'],
),
nonce: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['nonce']),
encryptionPublicKey: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['encryptionPublicKey'],
),
signingPublicKey: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['signingPublicKey'],
),
recoveryKeys: _iwgbpyo5.Protocol().deserialize<_i2rxumte.WrappedKeys>(
jsonSerialization['recoveryKeys'],
),
);
}
_isc.UuidValue challenge;
_idt.ByteData nonce;
_idt.ByteData encryptionPublicKey;
_idt.ByteData signingPublicKey;
_i2rxumte.WrappedKeys recoveryKeys;
/// Returns a shallow copy of this [KeyProofChallenge]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
KeyProofChallenge copyWith({
_isc.UuidValue? challenge,
_idt.ByteData? nonce,
_idt.ByteData? encryptionPublicKey,
_idt.ByteData? signingPublicKey,
_i2rxumte.WrappedKeys? recoveryKeys,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.KeyProofChallenge',
'challenge': challenge.toJson(),
'nonce': nonce.toJson(),
'encryptionPublicKey': encryptionPublicKey.toJson(),
'signingPublicKey': signingPublicKey.toJson(),
'recoveryKeys': recoveryKeys.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.KeyProofChallenge',
'challenge': challenge.toJson(),
'nonce': nonce.toJson(),
'encryptionPublicKey': encryptionPublicKey.toJson(),
'signingPublicKey': signingPublicKey.toJson(),
'recoveryKeys': recoveryKeys.toJsonForProtocol(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _KeyProofChallengeImpl extends KeyProofChallenge {
_KeyProofChallengeImpl({
required _isc.UuidValue challenge,
required _idt.ByteData nonce,
required _idt.ByteData encryptionPublicKey,
required _idt.ByteData signingPublicKey,
required _i2rxumte.WrappedKeys recoveryKeys,
}) : super._(
challenge: challenge,
nonce: nonce,
encryptionPublicKey: encryptionPublicKey,
signingPublicKey: signingPublicKey,
recoveryKeys: recoveryKeys,
);
/// Returns a shallow copy of this [KeyProofChallenge]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
KeyProofChallenge copyWith({
_isc.UuidValue? challenge,
_idt.ByteData? nonce,
_idt.ByteData? encryptionPublicKey,
_idt.ByteData? signingPublicKey,
_i2rxumte.WrappedKeys? recoveryKeys,
}) {
return KeyProofChallenge(
challenge: challenge ?? this.challenge,
nonce: nonce ?? this.nonce.clone(),
encryptionPublicKey:
encryptionPublicKey ?? this.encryptionPublicKey.clone(),
signingPublicKey: signingPublicKey ?? this.signingPublicKey.clone(),
recoveryKeys: recoveryKeys ?? this.recoveryKeys.copyWith(),
);
}
}

View file

@ -0,0 +1,128 @@
/* 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 an account whose keys stay (ADR 0017: a lost password,
/// proven with the recovery phrase): a new salt, costs, verifier, and the
/// same private keys wrapped under the new password's key.
abstract class NewPassword
implements _isc.SerializableModel, _isc.ProtocolSerialization {
NewPassword._({
required this.salt,
required this.costs,
required this.verifier,
required this.passwordKeys,
});
factory NewPassword({
required _idt.ByteData salt,
required _ioe6tior.PasswordCosts costs,
required _idt.ByteData verifier,
required _i2rxumte.WrappedKeys passwordKeys,
}) = _NewPasswordImpl;
factory NewPassword.fromJson(Map<String, dynamic> jsonSerialization) {
return NewPassword(
salt: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['salt']),
costs: _iwgbpyo5.Protocol().deserialize<_ioe6tior.PasswordCosts>(
jsonSerialization['costs'],
),
verifier: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['verifier'],
),
passwordKeys: _iwgbpyo5.Protocol().deserialize<_i2rxumte.WrappedKeys>(
jsonSerialization['passwordKeys'],
),
);
}
_idt.ByteData salt;
_ioe6tior.PasswordCosts costs;
_idt.ByteData verifier;
_i2rxumte.WrappedKeys passwordKeys;
/// Returns a shallow copy of this [NewPassword]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
NewPassword copyWith({
_idt.ByteData? salt,
_ioe6tior.PasswordCosts? costs,
_idt.ByteData? verifier,
_i2rxumte.WrappedKeys? passwordKeys,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.NewPassword',
'salt': salt.toJson(),
'costs': costs.toJson(),
'verifier': verifier.toJson(),
'passwordKeys': passwordKeys.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.NewPassword',
'salt': salt.toJson(),
'costs': costs.toJsonForProtocol(),
'verifier': verifier.toJson(),
'passwordKeys': passwordKeys.toJsonForProtocol(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _NewPasswordImpl extends NewPassword {
_NewPasswordImpl({
required _idt.ByteData salt,
required _ioe6tior.PasswordCosts costs,
required _idt.ByteData verifier,
required _i2rxumte.WrappedKeys passwordKeys,
}) : super._(
salt: salt,
costs: costs,
verifier: verifier,
passwordKeys: passwordKeys,
);
/// Returns a shallow copy of this [NewPassword]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
NewPassword copyWith({
_idt.ByteData? salt,
_ioe6tior.PasswordCosts? costs,
_idt.ByteData? verifier,
_i2rxumte.WrappedKeys? passwordKeys,
}) {
return NewPassword(
salt: salt ?? this.salt.clone(),
costs: costs ?? this.costs.copyWith(),
verifier: verifier ?? this.verifier.clone(),
passwordKeys: passwordKeys ?? this.passwordKeys.copyWith(),
);
}
}

View file

@ -0,0 +1,129 @@
/* 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;
/// The register's answer to the first step of signing in with a password
/// (ADR 0017, SRP-6a): what the device needs to derive the password's keys
/// and its proof. Alike for an address nobody has.
abstract class PasswordChallenge
implements _isc.SerializableModel, _isc.ProtocolSerialization {
PasswordChallenge._({
required this.challenge,
required this.salt,
required this.costs,
required this.serverValue,
});
factory PasswordChallenge({
required _isc.UuidValue challenge,
required _idt.ByteData salt,
required _ioe6tior.PasswordCosts costs,
required _idt.ByteData serverValue,
}) = _PasswordChallengeImpl;
factory PasswordChallenge.fromJson(Map<String, dynamic> jsonSerialization) {
return PasswordChallenge(
challenge: _isc.UuidValueJsonExtension.fromJson(
jsonSerialization['challenge'],
),
salt: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['salt']),
costs: _iwgbpyo5.Protocol().deserialize<_ioe6tior.PasswordCosts>(
jsonSerialization['costs'],
),
serverValue: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['serverValue'],
),
);
}
/// Names this sign-in in the second step; SRP's identity too.
_isc.UuidValue challenge;
_idt.ByteData salt;
_ioe6tior.PasswordCosts costs;
/// SRP's B, big-endian.
_idt.ByteData serverValue;
/// Returns a shallow copy of this [PasswordChallenge]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
PasswordChallenge copyWith({
_isc.UuidValue? challenge,
_idt.ByteData? salt,
_ioe6tior.PasswordCosts? costs,
_idt.ByteData? serverValue,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.PasswordChallenge',
'challenge': challenge.toJson(),
'salt': salt.toJson(),
'costs': costs.toJson(),
'serverValue': serverValue.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.PasswordChallenge',
'challenge': challenge.toJson(),
'salt': salt.toJson(),
'costs': costs.toJsonForProtocol(),
'serverValue': serverValue.toJson(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _PasswordChallengeImpl extends PasswordChallenge {
_PasswordChallengeImpl({
required _isc.UuidValue challenge,
required _idt.ByteData salt,
required _ioe6tior.PasswordCosts costs,
required _idt.ByteData serverValue,
}) : super._(
challenge: challenge,
salt: salt,
costs: costs,
serverValue: serverValue,
);
/// Returns a shallow copy of this [PasswordChallenge]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
PasswordChallenge copyWith({
_isc.UuidValue? challenge,
_idt.ByteData? salt,
_ioe6tior.PasswordCosts? costs,
_idt.ByteData? serverValue,
}) {
return PasswordChallenge(
challenge: challenge ?? this.challenge,
salt: salt ?? this.salt.clone(),
costs: costs ?? this.costs.copyWith(),
serverValue: serverValue ?? this.serverValue.clone(),
);
}
}

View file

@ -0,0 +1,108 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// Argon2id's costs for an account's password (ADR 0017), as halkyon_keys'
/// `PasswordKdf` names them: the device refuses costs below its floor.
abstract class PasswordCosts
implements _isc.SerializableModel, _isc.ProtocolSerialization {
PasswordCosts._({
required this.algorithm,
required this.opsLimit,
required this.memLimit,
});
factory PasswordCosts({
required String algorithm,
required int opsLimit,
required int memLimit,
}) = _PasswordCostsImpl;
factory PasswordCosts.fromJson(Map<String, dynamic> jsonSerialization) {
return PasswordCosts(
algorithm: jsonSerialization['algorithm'] as String,
opsLimit: jsonSerialization['opsLimit'] as int,
memLimit: jsonSerialization['memLimit'] as int,
);
}
/// libsodium's name for the algorithm: `argon2id13`.
String algorithm;
/// Passes.
int opsLimit;
/// Memory, in bytes.
int memLimit;
/// Returns a shallow copy of this [PasswordCosts]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
PasswordCosts copyWith({
String? algorithm,
int? opsLimit,
int? memLimit,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.PasswordCosts',
'algorithm': algorithm,
'opsLimit': opsLimit,
'memLimit': memLimit,
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.PasswordCosts',
'algorithm': algorithm,
'opsLimit': opsLimit,
'memLimit': memLimit,
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _PasswordCostsImpl extends PasswordCosts {
_PasswordCostsImpl({
required String algorithm,
required int opsLimit,
required int memLimit,
}) : super._(
algorithm: algorithm,
opsLimit: opsLimit,
memLimit: memLimit,
);
/// Returns a shallow copy of this [PasswordCosts]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
PasswordCosts copyWith({
String? algorithm,
int? opsLimit,
int? memLimit,
}) {
return PasswordCosts(
algorithm: algorithm ?? this.algorithm,
opsLimit: opsLimit ?? this.opsLimit,
memLimit: memLimit ?? this.memLimit,
);
}
}

View file

@ -0,0 +1,120 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// Why something to do with a password, an authenticator or a reset was
/// refused (ADR 0017); nothing changed then.
enum PasswordRefusal implements _isc.SerializableModel {
/// This instance has no password sign-in (its operator set none of the
/// keys it needs).
unavailable,
/// The address, the password, or the code (a TOTP or a recovery code)
/// isn't right: one answer for all, so none tells which.
wrongCredentials,
/// Too many sign-ins begun for this address or from this network in the
/// last hour, or too many codes tried for this account.
tooManyAttempts,
/// The step began too long ago, or was finished already: begin again.
challengeExpired,
/// The password is right, but no authenticator was confirmed yet: finish
/// setting one up where the password was set (or, while email codes still
/// sign in, signed in with a code by mail).
setupIncomplete,
/// What the device sent isn't a password's setup: a verifier, a key, a
/// salt or costs out of range.
invalidSetup,
/// The account has a password already.
passwordExists,
/// The account has no email address yet: a password needs one, for
/// resets. A code mailed to one makes it the account's.
noAddress,
/// The address the code proved is another account's.
addressTaken,
/// The account has no password yet.
noPassword,
/// No such authenticator of the account.
unknownAuthenticator,
/// The account's last confirmed authenticator can't go: the second factor
/// is mandatory.
lastAuthenticator,
/// The account has as many authenticators as it may: remove one first.
tooManyAuthenticators,
/// The code from the authenticator isn't right.
wrongCode,
/// The reset's time hasn't come yet.
notDue,
/// No such reset is waiting, or the address isn't the account's.
noReset;
static PasswordRefusal fromJson(String name) {
switch (name) {
case 'unavailable':
return PasswordRefusal.unavailable;
case 'wrongCredentials':
return PasswordRefusal.wrongCredentials;
case 'tooManyAttempts':
return PasswordRefusal.tooManyAttempts;
case 'challengeExpired':
return PasswordRefusal.challengeExpired;
case 'setupIncomplete':
return PasswordRefusal.setupIncomplete;
case 'invalidSetup':
return PasswordRefusal.invalidSetup;
case 'passwordExists':
return PasswordRefusal.passwordExists;
case 'noAddress':
return PasswordRefusal.noAddress;
case 'addressTaken':
return PasswordRefusal.addressTaken;
case 'noPassword':
return PasswordRefusal.noPassword;
case 'unknownAuthenticator':
return PasswordRefusal.unknownAuthenticator;
case 'lastAuthenticator':
return PasswordRefusal.lastAuthenticator;
case 'tooManyAuthenticators':
return PasswordRefusal.tooManyAuthenticators;
case 'wrongCode':
return PasswordRefusal.wrongCode;
case 'notDue':
return PasswordRefusal.notDue;
case 'noReset':
return PasswordRefusal.noReset;
default:
throw ArgumentError(
'Value "$name" cannot be converted to "PasswordRefusal"',
);
}
}
@override
String toJson() => name;
@override
String toString() => name;
}

View file

@ -0,0 +1,78 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
import '../password/password_refusal.dart' as _i647hpdf;
/// Something to do with a password, an authenticator or a reset was refused
/// (ADR 0017); nothing changed.
abstract class PasswordRefusedException
implements
_isc.SerializableException,
_isc.SerializableModel,
_isc.ProtocolSerialization {
PasswordRefusedException._({required this.reason});
factory PasswordRefusedException({
required _i647hpdf.PasswordRefusal reason,
}) = _PasswordRefusedExceptionImpl;
factory PasswordRefusedException.fromJson(
Map<String, dynamic> jsonSerialization,
) {
return PasswordRefusedException(
reason: _i647hpdf.PasswordRefusal.fromJson(
(jsonSerialization['reason'] as String),
),
);
}
_i647hpdf.PasswordRefusal reason;
/// Returns a shallow copy of this [PasswordRefusedException]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
PasswordRefusedException copyWith({_i647hpdf.PasswordRefusal? reason});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.PasswordRefusedException',
'reason': reason.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.PasswordRefusedException',
'reason': reason.toJson(),
};
}
@override
String toString() {
return 'PasswordRefusedException(reason: $reason)';
}
}
class _PasswordRefusedExceptionImpl extends PasswordRefusedException {
_PasswordRefusedExceptionImpl({required _i647hpdf.PasswordRefusal reason})
: super._(reason: reason);
/// Returns a shallow copy of this [PasswordRefusedException]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
PasswordRefusedException copyWith({_i647hpdf.PasswordRefusal? reason}) {
return PasswordRefusedException(reason: reason ?? this.reason);
}
}

View file

@ -0,0 +1,174 @@
/* 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;
/// What a device sends to give an account a password (ADR 0017), all made on
/// the device: the salt and costs it derived the password's keys with, SRP's
/// verifier, the account's public keys, and its private keys wrapped under
/// the password's key and the recovery phrase's. Nothing of it signs in or
/// decrypts in the password's place.
abstract class PasswordSetup
implements _isc.SerializableModel, _isc.ProtocolSerialization {
PasswordSetup._({
required this.salt,
required this.costs,
required this.verifier,
required this.encryptionPublicKey,
required this.signingPublicKey,
required this.passwordKeys,
required this.recoveryKeys,
});
factory PasswordSetup({
required _idt.ByteData salt,
required _ioe6tior.PasswordCosts costs,
required _idt.ByteData verifier,
required _idt.ByteData encryptionPublicKey,
required _idt.ByteData signingPublicKey,
required _i2rxumte.WrappedKeys passwordKeys,
required _i2rxumte.WrappedKeys recoveryKeys,
}) = _PasswordSetupImpl;
factory PasswordSetup.fromJson(Map<String, dynamic> jsonSerialization) {
return PasswordSetup(
salt: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['salt']),
costs: _iwgbpyo5.Protocol().deserialize<_ioe6tior.PasswordCosts>(
jsonSerialization['costs'],
),
verifier: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['verifier'],
),
encryptionPublicKey: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['encryptionPublicKey'],
),
signingPublicKey: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['signingPublicKey'],
),
passwordKeys: _iwgbpyo5.Protocol().deserialize<_i2rxumte.WrappedKeys>(
jsonSerialization['passwordKeys'],
),
recoveryKeys: _iwgbpyo5.Protocol().deserialize<_i2rxumte.WrappedKeys>(
jsonSerialization['recoveryKeys'],
),
);
}
_idt.ByteData salt;
_ioe6tior.PasswordCosts costs;
/// v = g^x mod N, big-endian.
_idt.ByteData verifier;
_idt.ByteData encryptionPublicKey;
_idt.ByteData signingPublicKey;
_i2rxumte.WrappedKeys passwordKeys;
_i2rxumte.WrappedKeys recoveryKeys;
/// Returns a shallow copy of this [PasswordSetup]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
PasswordSetup copyWith({
_idt.ByteData? salt,
_ioe6tior.PasswordCosts? costs,
_idt.ByteData? verifier,
_idt.ByteData? encryptionPublicKey,
_idt.ByteData? signingPublicKey,
_i2rxumte.WrappedKeys? passwordKeys,
_i2rxumte.WrappedKeys? recoveryKeys,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.PasswordSetup',
'salt': salt.toJson(),
'costs': costs.toJson(),
'verifier': verifier.toJson(),
'encryptionPublicKey': encryptionPublicKey.toJson(),
'signingPublicKey': signingPublicKey.toJson(),
'passwordKeys': passwordKeys.toJson(),
'recoveryKeys': recoveryKeys.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.PasswordSetup',
'salt': salt.toJson(),
'costs': costs.toJsonForProtocol(),
'verifier': verifier.toJson(),
'encryptionPublicKey': encryptionPublicKey.toJson(),
'signingPublicKey': signingPublicKey.toJson(),
'passwordKeys': passwordKeys.toJsonForProtocol(),
'recoveryKeys': recoveryKeys.toJsonForProtocol(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _PasswordSetupImpl extends PasswordSetup {
_PasswordSetupImpl({
required _idt.ByteData salt,
required _ioe6tior.PasswordCosts costs,
required _idt.ByteData verifier,
required _idt.ByteData encryptionPublicKey,
required _idt.ByteData signingPublicKey,
required _i2rxumte.WrappedKeys passwordKeys,
required _i2rxumte.WrappedKeys recoveryKeys,
}) : super._(
salt: salt,
costs: costs,
verifier: verifier,
encryptionPublicKey: encryptionPublicKey,
signingPublicKey: signingPublicKey,
passwordKeys: passwordKeys,
recoveryKeys: recoveryKeys,
);
/// Returns a shallow copy of this [PasswordSetup]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
PasswordSetup copyWith({
_idt.ByteData? salt,
_ioe6tior.PasswordCosts? costs,
_idt.ByteData? verifier,
_idt.ByteData? encryptionPublicKey,
_idt.ByteData? signingPublicKey,
_i2rxumte.WrappedKeys? passwordKeys,
_i2rxumte.WrappedKeys? recoveryKeys,
}) {
return PasswordSetup(
salt: salt ?? this.salt.clone(),
costs: costs ?? this.costs.copyWith(),
verifier: verifier ?? this.verifier.clone(),
encryptionPublicKey:
encryptionPublicKey ?? this.encryptionPublicKey.clone(),
signingPublicKey: signingPublicKey ?? this.signingPublicKey.clone(),
passwordKeys: passwordKeys ?? this.passwordKeys.copyWith(),
recoveryKeys: recoveryKeys ?? this.recoveryKeys.copyWith(),
);
}
}

View file

@ -0,0 +1,233 @@
/* 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/wrapped_keys.dart' as _i2rxumte;
/// Signed in with a password (ADR 0017): SRP's proof M2, which the device
/// checks before it trusts anything else here, the account's public keys and
/// its private keys under the password's key, which the device opens, and
/// the session. With [needsAuthenticator], the device sets up an
/// authenticator before anything else (a reset of the second factor took
/// effect).
abstract class PasswordSignedIn
implements _isc.SerializableModel, _isc.ProtocolSerialization {
PasswordSignedIn._({
required this.serverProof,
required this.encryptionPublicKey,
required this.signingPublicKey,
required this.passwordKeys,
required this.needsAuthenticator,
required this.authStrategy,
required this.token,
this.tokenExpiresAt,
this.refreshToken,
required this.authUserId,
required this.scopeNames,
});
factory PasswordSignedIn({
required _idt.ByteData serverProof,
required _idt.ByteData encryptionPublicKey,
required _idt.ByteData signingPublicKey,
required _i2rxumte.WrappedKeys passwordKeys,
required bool needsAuthenticator,
required String authStrategy,
required String token,
DateTime? tokenExpiresAt,
String? refreshToken,
required _isc.UuidValue authUserId,
required Set<String> scopeNames,
}) = _PasswordSignedInImpl;
factory PasswordSignedIn.fromJson(Map<String, dynamic> jsonSerialization) {
return PasswordSignedIn(
serverProof: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['serverProof'],
),
encryptionPublicKey: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['encryptionPublicKey'],
),
signingPublicKey: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['signingPublicKey'],
),
passwordKeys: _iwgbpyo5.Protocol().deserialize<_i2rxumte.WrappedKeys>(
jsonSerialization['passwordKeys'],
),
needsAuthenticator: _isc.BoolJsonExtension.fromJson(
jsonSerialization['needsAuthenticator'],
),
authStrategy: jsonSerialization['authStrategy'] as String,
token: jsonSerialization['token'] as String,
tokenExpiresAt: jsonSerialization['tokenExpiresAt'] == null
? null
: _isc.DateTimeJsonExtension.fromJson(
jsonSerialization['tokenExpiresAt'],
),
refreshToken: jsonSerialization['refreshToken'] as String?,
authUserId: _isc.UuidValueJsonExtension.fromJson(
jsonSerialization['authUserId'],
),
scopeNames: _iwgbpyo5.Protocol().deserialize<Set<String>>(
jsonSerialization['scopeNames'],
),
);
}
_idt.ByteData serverProof;
_idt.ByteData encryptionPublicKey;
_idt.ByteData signingPublicKey;
_i2rxumte.WrappedKeys passwordKeys;
bool needsAuthenticator;
/// The session, as Serverpod's `AuthSuccess` has it (the device makes one
/// of these fields for its session manager).
String authStrategy;
String token;
DateTime? tokenExpiresAt;
String? refreshToken;
_isc.UuidValue authUserId;
Set<String> scopeNames;
/// Returns a shallow copy of this [PasswordSignedIn]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
PasswordSignedIn copyWith({
_idt.ByteData? serverProof,
_idt.ByteData? encryptionPublicKey,
_idt.ByteData? signingPublicKey,
_i2rxumte.WrappedKeys? passwordKeys,
bool? needsAuthenticator,
String? authStrategy,
String? token,
DateTime? tokenExpiresAt,
String? refreshToken,
_isc.UuidValue? authUserId,
Set<String>? scopeNames,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.PasswordSignedIn',
'serverProof': serverProof.toJson(),
'encryptionPublicKey': encryptionPublicKey.toJson(),
'signingPublicKey': signingPublicKey.toJson(),
'passwordKeys': passwordKeys.toJson(),
'needsAuthenticator': needsAuthenticator,
'authStrategy': authStrategy,
'token': token,
if (tokenExpiresAt != null) 'tokenExpiresAt': tokenExpiresAt?.toJson(),
if (refreshToken != null) 'refreshToken': refreshToken,
'authUserId': authUserId.toJson(),
'scopeNames': scopeNames.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.PasswordSignedIn',
'serverProof': serverProof.toJson(),
'encryptionPublicKey': encryptionPublicKey.toJson(),
'signingPublicKey': signingPublicKey.toJson(),
'passwordKeys': passwordKeys.toJsonForProtocol(),
'needsAuthenticator': needsAuthenticator,
'authStrategy': authStrategy,
'token': token,
if (tokenExpiresAt != null) 'tokenExpiresAt': tokenExpiresAt?.toJson(),
if (refreshToken != null) 'refreshToken': refreshToken,
'authUserId': authUserId.toJson(),
'scopeNames': scopeNames.toJson(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _Undefined {}
class _PasswordSignedInImpl extends PasswordSignedIn {
_PasswordSignedInImpl({
required _idt.ByteData serverProof,
required _idt.ByteData encryptionPublicKey,
required _idt.ByteData signingPublicKey,
required _i2rxumte.WrappedKeys passwordKeys,
required bool needsAuthenticator,
required String authStrategy,
required String token,
DateTime? tokenExpiresAt,
String? refreshToken,
required _isc.UuidValue authUserId,
required Set<String> scopeNames,
}) : super._(
serverProof: serverProof,
encryptionPublicKey: encryptionPublicKey,
signingPublicKey: signingPublicKey,
passwordKeys: passwordKeys,
needsAuthenticator: needsAuthenticator,
authStrategy: authStrategy,
token: token,
tokenExpiresAt: tokenExpiresAt,
refreshToken: refreshToken,
authUserId: authUserId,
scopeNames: scopeNames,
);
/// Returns a shallow copy of this [PasswordSignedIn]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
PasswordSignedIn copyWith({
_idt.ByteData? serverProof,
_idt.ByteData? encryptionPublicKey,
_idt.ByteData? signingPublicKey,
_i2rxumte.WrappedKeys? passwordKeys,
bool? needsAuthenticator,
String? authStrategy,
String? token,
Object? tokenExpiresAt = _Undefined,
Object? refreshToken = _Undefined,
_isc.UuidValue? authUserId,
Set<String>? scopeNames,
}) {
return PasswordSignedIn(
serverProof: serverProof ?? this.serverProof.clone(),
encryptionPublicKey:
encryptionPublicKey ?? this.encryptionPublicKey.clone(),
signingPublicKey: signingPublicKey ?? this.signingPublicKey.clone(),
passwordKeys: passwordKeys ?? this.passwordKeys.copyWith(),
needsAuthenticator: needsAuthenticator ?? this.needsAuthenticator,
authStrategy: authStrategy ?? this.authStrategy,
token: token ?? this.token,
tokenExpiresAt: tokenExpiresAt is DateTime?
? tokenExpiresAt
: this.tokenExpiresAt,
refreshToken: refreshToken is String? ? refreshToken : this.refreshToken,
authUserId: authUserId ?? this.authUserId,
scopeNames: scopeNames ?? this.scopeNames.map((e0) => e0).toSet(),
);
}
}

View file

@ -0,0 +1,70 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// A reset asked for (ADR 0017): it takes effect at [takesEffectAt], unless
/// the account's owner signs in before; a mail said so.
abstract class ResetPending
implements _isc.SerializableModel, _isc.ProtocolSerialization {
ResetPending._({required this.takesEffectAt});
factory ResetPending({required DateTime takesEffectAt}) = _ResetPendingImpl;
factory ResetPending.fromJson(Map<String, dynamic> jsonSerialization) {
return ResetPending(
takesEffectAt: _isc.DateTimeJsonExtension.fromJson(
jsonSerialization['takesEffectAt'],
),
);
}
DateTime takesEffectAt;
/// Returns a shallow copy of this [ResetPending]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
ResetPending copyWith({DateTime? takesEffectAt});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.ResetPending',
'takesEffectAt': takesEffectAt.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.ResetPending',
'takesEffectAt': takesEffectAt.toJson(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _ResetPendingImpl extends ResetPending {
_ResetPendingImpl({required DateTime takesEffectAt})
: super._(takesEffectAt: takesEffectAt);
/// Returns a shallow copy of this [ResetPending]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
ResetPending copyWith({DateTime? takesEffectAt}) {
return ResetPending(takesEffectAt: takesEffectAt ?? this.takesEffectAt);
}
}

View file

@ -0,0 +1,41 @@
/* 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 'package:serverpod_client/serverpod_client.dart' as _isc;
/// What a sign-in challenge is for.
enum SignInChallengePurpose implements _isc.SerializableModel {
/// Signing in with the password (SRP).
password,
/// Proving the recovery phrase by signing a nonce with the account's key.
keyProof;
static SignInChallengePurpose fromJson(String name) {
switch (name) {
case 'password':
return SignInChallengePurpose.password;
case 'keyProof':
return SignInChallengePurpose.keyProof;
default:
throw ArgumentError(
'Value "$name" cannot be converted to "SignInChallengePurpose"',
);
}
}
@override
String toJson() => name;
@override
String toString() => name;
}

View file

@ -0,0 +1,98 @@
/* 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;
/// An account's private keys sealed under one key (ADR 0017), as
/// halkyon_keys' `WrappedAccountKeys` has them: only a device opens them.
abstract class WrappedKeys
implements _isc.SerializableModel, _isc.ProtocolSerialization {
WrappedKeys._({
required this.nonce,
required this.cipherText,
});
factory WrappedKeys({
required _idt.ByteData nonce,
required _idt.ByteData cipherText,
}) = _WrappedKeysImpl;
factory WrappedKeys.fromJson(Map<String, dynamic> jsonSerialization) {
return WrappedKeys(
nonce: _isc.ByteDataJsonExtension.fromJson(jsonSerialization['nonce']),
cipherText: _isc.ByteDataJsonExtension.fromJson(
jsonSerialization['cipherText'],
),
);
}
/// XChaCha20-Poly1305's nonce (24 bytes).
_idt.ByteData nonce;
/// The sealed keys with their tag.
_idt.ByteData cipherText;
/// Returns a shallow copy of this [WrappedKeys]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
WrappedKeys copyWith({
_idt.ByteData? nonce,
_idt.ByteData? cipherText,
});
@override
Map<String, dynamic> toJson() {
return {
'__className__': 'halkyon_base.WrappedKeys',
'nonce': nonce.toJson(),
'cipherText': cipherText.toJson(),
};
}
@override
Map<String, dynamic> toJsonForProtocol() {
return {
'__className__': 'halkyon_base.WrappedKeys',
'nonce': nonce.toJson(),
'cipherText': cipherText.toJson(),
};
}
@override
String toString() {
return _isc.SerializationManager.encode(this);
}
}
class _WrappedKeysImpl extends WrappedKeys {
_WrappedKeysImpl({
required _idt.ByteData nonce,
required _idt.ByteData cipherText,
}) : super._(
nonce: nonce,
cipherText: cipherText,
);
/// Returns a shallow copy of this [WrappedKeys]
/// with some or all fields replaced by the given arguments.
@_isc.useResult
@override
WrappedKeys copyWith({
_idt.ByteData? nonce,
_idt.ByteData? cipherText,
}) {
return WrappedKeys(
nonce: nonce ?? this.nonce.clone(),
cipherText: cipherText ?? this.cipherText.clone(),
);
}
}

View file

@ -11,6 +11,8 @@
// ignore_for_file: dead_code, unnecessary_type_check
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:halkyon_base_client/src/protocol/password/authenticator.dart'
as _ivfmflch;
import 'package:serverpod_auth_core_client/serverpod_auth_core_client.dart'
as _iacc;
import 'package:serverpod_auth_idp_client/serverpod_auth_idp_client.dart'
@ -23,6 +25,20 @@ import 'auth/github_sign_in_refusal.dart' as _ir1gd9p5;
import 'auth/github_sign_in_refused_exception.dart' as _i0xfcu5n;
import 'auth/sign_in_ways.dart' as _ie6tbh85;
import 'instance/instance_basics.dart' as _i8jixqx6;
import 'password/account_reset_kind.dart' as _i91ka1it;
import 'password/authenticator.dart' as _icpzuvvi;
import 'password/authenticator_enrolment.dart' as _iv7tra7v;
import 'password/key_proof_challenge.dart' as _iehtx95q;
import 'password/new_password.dart' as _itvvd6m6;
import 'password/password_challenge.dart' as _iuxisac7;
import 'password/password_costs.dart' as _izp492e5;
import 'password/password_refusal.dart' as _ibfrwdhm;
import 'password/password_refused_exception.dart' as _i4froq5y;
import 'password/password_setup.dart' as _igpggy1y;
import 'password/password_signed_in.dart' as _ipk7gvzy;
import 'password/reset_pending.dart' as _i3y6qzi3;
import 'password/sign_in_challenge_purpose.dart' as _izijxzng;
import 'password/wrapped_keys.dart' as _i6v10ugm;
import 'profile/profile.dart' as _ia5j8fch;
import 'profile/profile_not_found_exception.dart' as _iim3hfcf;
import 'profile/profile_refusal.dart' as _i6j6efd1;
@ -34,6 +50,20 @@ export 'auth/github_sign_in_refusal.dart';
export 'auth/github_sign_in_refused_exception.dart';
export 'auth/sign_in_ways.dart';
export 'instance/instance_basics.dart';
export 'password/account_reset_kind.dart';
export 'password/authenticator.dart';
export 'password/authenticator_enrolment.dart';
export 'password/key_proof_challenge.dart';
export 'password/new_password.dart';
export 'password/password_challenge.dart';
export 'password/password_costs.dart';
export 'password/password_refusal.dart';
export 'password/password_refused_exception.dart';
export 'password/password_setup.dart';
export 'password/password_signed_in.dart';
export 'password/reset_pending.dart';
export 'password/sign_in_challenge_purpose.dart';
export 'password/wrapped_keys.dart';
export 'profile/profile.dart';
export 'profile/profile_not_found_exception.dart';
export 'profile/profile_refusal.dart';
@ -106,6 +136,48 @@ class Protocol extends _isc.SerializationManager {
if (t == _i8jixqx6.InstanceBasics) {
return _i8jixqx6.InstanceBasics.fromJson(data) as T;
}
if (t == _i91ka1it.AccountResetKind) {
return _i91ka1it.AccountResetKind.fromJson(data) as T;
}
if (t == _icpzuvvi.Authenticator) {
return _icpzuvvi.Authenticator.fromJson(data) as T;
}
if (t == _iv7tra7v.AuthenticatorEnrolment) {
return _iv7tra7v.AuthenticatorEnrolment.fromJson(data) as T;
}
if (t == _iehtx95q.KeyProofChallenge) {
return _iehtx95q.KeyProofChallenge.fromJson(data) as T;
}
if (t == _itvvd6m6.NewPassword) {
return _itvvd6m6.NewPassword.fromJson(data) as T;
}
if (t == _iuxisac7.PasswordChallenge) {
return _iuxisac7.PasswordChallenge.fromJson(data) as T;
}
if (t == _izp492e5.PasswordCosts) {
return _izp492e5.PasswordCosts.fromJson(data) as T;
}
if (t == _ibfrwdhm.PasswordRefusal) {
return _ibfrwdhm.PasswordRefusal.fromJson(data) as T;
}
if (t == _i4froq5y.PasswordRefusedException) {
return _i4froq5y.PasswordRefusedException.fromJson(data) as T;
}
if (t == _igpggy1y.PasswordSetup) {
return _igpggy1y.PasswordSetup.fromJson(data) as T;
}
if (t == _ipk7gvzy.PasswordSignedIn) {
return _ipk7gvzy.PasswordSignedIn.fromJson(data) as T;
}
if (t == _i3y6qzi3.ResetPending) {
return _i3y6qzi3.ResetPending.fromJson(data) as T;
}
if (t == _izijxzng.SignInChallengePurpose) {
return _izijxzng.SignInChallengePurpose.fromJson(data) as T;
}
if (t == _i6v10ugm.WrappedKeys) {
return _i6v10ugm.WrappedKeys.fromJson(data) as T;
}
if (t == _ia5j8fch.Profile) {
return _ia5j8fch.Profile.fromJson(data) as T;
}
@ -151,6 +223,65 @@ class Protocol extends _isc.SerializationManager {
return (data != null ? _i8jixqx6.InstanceBasics.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_i91ka1it.AccountResetKind?>()) {
return (data != null ? _i91ka1it.AccountResetKind.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_icpzuvvi.Authenticator?>()) {
return (data != null ? _icpzuvvi.Authenticator.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_iv7tra7v.AuthenticatorEnrolment?>()) {
return (data != null
? _iv7tra7v.AuthenticatorEnrolment.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_iehtx95q.KeyProofChallenge?>()) {
return (data != null ? _iehtx95q.KeyProofChallenge.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_itvvd6m6.NewPassword?>()) {
return (data != null ? _itvvd6m6.NewPassword.fromJson(data) : null) as T;
}
if (t == _isc.getType<_iuxisac7.PasswordChallenge?>()) {
return (data != null ? _iuxisac7.PasswordChallenge.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_izp492e5.PasswordCosts?>()) {
return (data != null ? _izp492e5.PasswordCosts.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_ibfrwdhm.PasswordRefusal?>()) {
return (data != null ? _ibfrwdhm.PasswordRefusal.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_i4froq5y.PasswordRefusedException?>()) {
return (data != null
? _i4froq5y.PasswordRefusedException.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_igpggy1y.PasswordSetup?>()) {
return (data != null ? _igpggy1y.PasswordSetup.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_ipk7gvzy.PasswordSignedIn?>()) {
return (data != null ? _ipk7gvzy.PasswordSignedIn.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_i3y6qzi3.ResetPending?>()) {
return (data != null ? _i3y6qzi3.ResetPending.fromJson(data) : null) as T;
}
if (t == _isc.getType<_izijxzng.SignInChallengePurpose?>()) {
return (data != null
? _izijxzng.SignInChallengePurpose.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_i6v10ugm.WrappedKeys?>()) {
return (data != null ? _i6v10ugm.WrappedKeys.fromJson(data) : null) as T;
}
if (t == _isc.getType<_ia5j8fch.Profile?>()) {
return (data != null ? _ia5j8fch.Profile.fromJson(data) : null) as T;
}
@ -170,6 +301,9 @@ class Protocol extends _isc.SerializationManager {
: null)
as T;
}
if (t == Set<String>) {
return (data as List).map((e) => deserialize<String>(e)).toSet() as T;
}
if (t == List<String>) {
return (data as List).map((e) => deserialize<String>(e)).toList() as T;
}
@ -182,6 +316,12 @@ class Protocol extends _isc.SerializationManager {
if (t == List<String>) {
return (data as List).map((e) => deserialize<String>(e)).toList() as T;
}
if (t == List<_ivfmflch.Authenticator>) {
return (data as List)
.map((e) => deserialize<_ivfmflch.Authenticator>(e))
.toList()
as T;
}
try {
return _iaic.Protocol().deserialize<T>(data, t);
} on _isc.DeserializationTypeNotFoundException catch (_) {}
@ -200,6 +340,20 @@ class Protocol extends _isc.SerializationManager {
_i0xfcu5n.GitHubSignInRefusedException => 'GitHubSignInRefusedException',
_ie6tbh85.SignInWays => 'SignInWays',
_i8jixqx6.InstanceBasics => 'InstanceBasics',
_i91ka1it.AccountResetKind => 'AccountResetKind',
_icpzuvvi.Authenticator => 'Authenticator',
_iv7tra7v.AuthenticatorEnrolment => 'AuthenticatorEnrolment',
_iehtx95q.KeyProofChallenge => 'KeyProofChallenge',
_itvvd6m6.NewPassword => 'NewPassword',
_iuxisac7.PasswordChallenge => 'PasswordChallenge',
_izp492e5.PasswordCosts => 'PasswordCosts',
_ibfrwdhm.PasswordRefusal => 'PasswordRefusal',
_i4froq5y.PasswordRefusedException => 'PasswordRefusedException',
_igpggy1y.PasswordSetup => 'PasswordSetup',
_ipk7gvzy.PasswordSignedIn => 'PasswordSignedIn',
_i3y6qzi3.ResetPending => 'ResetPending',
_izijxzng.SignInChallengePurpose => 'SignInChallengePurpose',
_i6v10ugm.WrappedKeys => 'WrappedKeys',
_ia5j8fch.Profile => 'Profile',
_iim3hfcf.ProfileNotFoundException => 'ProfileNotFoundException',
_i6j6efd1.ProfileRefusal => 'ProfileRefusal',
@ -235,6 +389,34 @@ class Protocol extends _isc.SerializationManager {
return 'SignInWays';
case _i8jixqx6.InstanceBasics():
return 'InstanceBasics';
case _i91ka1it.AccountResetKind():
return 'AccountResetKind';
case _icpzuvvi.Authenticator():
return 'Authenticator';
case _iv7tra7v.AuthenticatorEnrolment():
return 'AuthenticatorEnrolment';
case _iehtx95q.KeyProofChallenge():
return 'KeyProofChallenge';
case _itvvd6m6.NewPassword():
return 'NewPassword';
case _iuxisac7.PasswordChallenge():
return 'PasswordChallenge';
case _izp492e5.PasswordCosts():
return 'PasswordCosts';
case _ibfrwdhm.PasswordRefusal():
return 'PasswordRefusal';
case _i4froq5y.PasswordRefusedException():
return 'PasswordRefusedException';
case _igpggy1y.PasswordSetup():
return 'PasswordSetup';
case _ipk7gvzy.PasswordSignedIn():
return 'PasswordSignedIn';
case _i3y6qzi3.ResetPending():
return 'ResetPending';
case _izijxzng.SignInChallengePurpose():
return 'SignInChallengePurpose';
case _i6v10ugm.WrappedKeys():
return 'WrappedKeys';
case _ia5j8fch.Profile():
return 'Profile';
case _iim3hfcf.ProfileNotFoundException():
@ -274,6 +456,48 @@ class Protocol extends _isc.SerializationManager {
if (dataClassName == 'InstanceBasics') {
return deserialize<_i8jixqx6.InstanceBasics>(data['data']);
}
if (dataClassName == 'AccountResetKind') {
return deserialize<_i91ka1it.AccountResetKind>(data['data']);
}
if (dataClassName == 'Authenticator') {
return deserialize<_icpzuvvi.Authenticator>(data['data']);
}
if (dataClassName == 'AuthenticatorEnrolment') {
return deserialize<_iv7tra7v.AuthenticatorEnrolment>(data['data']);
}
if (dataClassName == 'KeyProofChallenge') {
return deserialize<_iehtx95q.KeyProofChallenge>(data['data']);
}
if (dataClassName == 'NewPassword') {
return deserialize<_itvvd6m6.NewPassword>(data['data']);
}
if (dataClassName == 'PasswordChallenge') {
return deserialize<_iuxisac7.PasswordChallenge>(data['data']);
}
if (dataClassName == 'PasswordCosts') {
return deserialize<_izp492e5.PasswordCosts>(data['data']);
}
if (dataClassName == 'PasswordRefusal') {
return deserialize<_ibfrwdhm.PasswordRefusal>(data['data']);
}
if (dataClassName == 'PasswordRefusedException') {
return deserialize<_i4froq5y.PasswordRefusedException>(data['data']);
}
if (dataClassName == 'PasswordSetup') {
return deserialize<_igpggy1y.PasswordSetup>(data['data']);
}
if (dataClassName == 'PasswordSignedIn') {
return deserialize<_ipk7gvzy.PasswordSignedIn>(data['data']);
}
if (dataClassName == 'ResetPending') {
return deserialize<_i3y6qzi3.ResetPending>(data['data']);
}
if (dataClassName == 'SignInChallengePurpose') {
return deserialize<_izijxzng.SignInChallengePurpose>(data['data']);
}
if (dataClassName == 'WrappedKeys') {
return deserialize<_i6v10ugm.WrappedKeys>(data['data']);
}
if (dataClassName == 'Profile') {
return deserialize<_ia5j8fch.Profile>(data['data']);
}

Some files were not shown because too many files have changed in this diff Show more