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:
parent
200a2df32f
commit
a3a8ed3890
1 changed files with 22557 additions and 60 deletions
|
|
@ -148,9 +148,136 @@ abstract interface class AccountRegister {
|
|||
/// for none.
|
||||
Future<UuidValue?> accountWithGitHub(Session session, String gitHubUserId);
|
||||
|
||||
/// How [person] signs in: with GitHub, an email address, both or neither.
|
||||
/// How [person] signs in: with GitHub, an email address, a password and
|
||||
/// whether an authenticator is confirmed.
|
||||
Future<SignInWays> signInWaysOf(Session session, UuidValue person);
|
||||
|
||||
/// Whether people sign in with a password and TOTP (ADR 0017): the
|
||||
/// register holds the keys it needs.
|
||||
Future<bool> passwordSignInOffered(Session session);
|
||||
|
||||
/// Gives [person] the password [setup] describes, with the address [code]
|
||||
/// proves for [request] unless they have one. Refusals as `setPassword`'s.
|
||||
Future<void> setPassword(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required PasswordSetup setup,
|
||||
UuidValue? request,
|
||||
String? code,
|
||||
});
|
||||
|
||||
/// A password sign-in's first step for [address], the sign-ins begun from
|
||||
/// [network] counted. Refusals as `beginPasswordSignIn`'s.
|
||||
Future<PasswordChallenge> beginPasswordSignIn(
|
||||
Session session, {
|
||||
required String address,
|
||||
required String network,
|
||||
});
|
||||
|
||||
/// A password sign-in's second step: the account it proved, for the
|
||||
/// caller's session. Refusals as `completePasswordSignIn`'s.
|
||||
Future<PasswordProof> completePasswordSignIn(
|
||||
Session session, {
|
||||
required UuidValue challenge,
|
||||
required ByteData clientValue,
|
||||
required ByteData clientProof,
|
||||
String? totpCode,
|
||||
String? recoveryCode,
|
||||
});
|
||||
|
||||
/// A new authenticator of [person]. Refusals as `enrolAuthenticator`'s.
|
||||
Future<AuthenticatorEnrolment> enrolAuthenticator(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required String name,
|
||||
required String label,
|
||||
});
|
||||
|
||||
/// Confirms [person]'s [authenticator]; the first one's recovery codes.
|
||||
/// Refusals as `confirmAuthenticator`'s.
|
||||
Future<List<String>> confirmAuthenticator(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required UuidValue authenticator,
|
||||
required String code,
|
||||
});
|
||||
|
||||
/// [person]'s authenticators, the oldest first.
|
||||
Future<List<Authenticator>> authenticatorsOf(
|
||||
Session session,
|
||||
UuidValue person,
|
||||
);
|
||||
|
||||
/// Removes [person]'s [authenticator]. Refusals as
|
||||
/// `removeAuthenticator`'s.
|
||||
Future<void> removeAuthenticator(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required UuidValue authenticator,
|
||||
String? code,
|
||||
});
|
||||
|
||||
/// New recovery codes for [person]. Refusals as `newRecoveryCodes`'.
|
||||
Future<List<String>> newRecoveryCodes(
|
||||
Session session, {
|
||||
required UuidValue person,
|
||||
required String code,
|
||||
});
|
||||
|
||||
/// Asks for the reset of a lost authenticator. Refusals as
|
||||
/// `resetAuthenticator`'s.
|
||||
Future<ResetPending> resetAuthenticator(
|
||||
Session session, {
|
||||
required UuidValue challenge,
|
||||
required ByteData clientValue,
|
||||
required ByteData clientProof,
|
||||
required String address,
|
||||
required String language,
|
||||
UuidValue? request,
|
||||
String? code,
|
||||
UuidValue? keyChallenge,
|
||||
ByteData? signature,
|
||||
});
|
||||
|
||||
/// The first step of proving the recovery phrase for [address], the
|
||||
/// proofs begun from [network] counted. Refusals as `beginKeyProof`'s.
|
||||
Future<KeyProofChallenge> beginKeyProof(
|
||||
Session session, {
|
||||
required String address,
|
||||
required String network,
|
||||
});
|
||||
|
||||
/// Sets a new password with the recovery phrase's proof; the account, for
|
||||
/// the caller's session. Refusals as `resetPasswordWithPhrase`'s.
|
||||
Future<UuidValue> resetPasswordWithPhrase(
|
||||
Session session, {
|
||||
required UuidValue challenge,
|
||||
required ByteData signature,
|
||||
required NewPassword password,
|
||||
String? totpCode,
|
||||
String? recoveryCode,
|
||||
});
|
||||
|
||||
/// Asks for the reset of a whole account. Refusals as
|
||||
/// `startAccountReset`'s.
|
||||
Future<ResetPending> startAccountReset(
|
||||
Session session, {
|
||||
required String address,
|
||||
required String language,
|
||||
required UuidValue request,
|
||||
required String code,
|
||||
});
|
||||
|
||||
/// Carries out the reset of a whole account; the account, for the
|
||||
/// caller's session. Refusals as `completeAccountReset`'s.
|
||||
Future<UuidValue> completeAccountReset(
|
||||
Session session, {
|
||||
required String address,
|
||||
required UuidValue request,
|
||||
required String code,
|
||||
required PasswordSetup setup,
|
||||
});
|
||||
|
||||
/// Deletes the account [person] with everything the register's server has
|
||||
/// of them, and has every member of the instance delete theirs.
|
||||
Future<void> deleteAccount(Session session, UuidValue person);
|
||||
|
|
|
|||
Loading…
Reference in a new issue