feat(base)!: no anonymous accounts on the server (ADR 0020, D25)
The server's half of D25: every account has a way in, and the anonymous accounts left from before go with the daily pruning. - The module signs nobody in anonymously: `anonymousIdp` and `gitHubUpgrade` are gone, and so is linking GitHub at the register. - A password is set only by someone whose address is theirs (a `firstPassword` code) or who signs in with GitHub alone (a fresh sign-in and a `signUp` code); an anonymous account is refused `wrongCredentials` before any code is used. - SimpleLogin refuses to link onto a caller without `identified` (`wrongCaller`), the member's endpoint too, so nothing turns an anonymous account into one with a way in. - `pruneAnonymousPeople` deletes every anonymous account left, however new, never one identified. Learn and Todo schedule it as `prune-accounts` and cancel the old `prune-abandoned-anonymous-people` entry once. - Learn: someone without `identified` keeps no files; `FILE_LIMIT_ANONYMOUS_MB` is gone. `minimumAppBuild` is 23, as builds up to 22 start with an anonymous account. - Learn's sync tests make their person and session by SQL in the development database, as Serverpod stores sessions. - Docs, store listings and ADRs 0010, 0014, 0016, 0017 and 0019 amended. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
5b9df73756
commit
87671208df
2 changed files with 837 additions and 1353 deletions
|
|
@ -12,7 +12,7 @@
|
|||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// The ways a person signs in, besides an anonymous account's session.
|
||||
/// The ways a person signs in, besides their sessions.
|
||||
abstract class SignInWays
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
SignInWays._({
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ import 'package:halkyon_base_client/src/protocol/simplelogin/simplelogin_return.
|
|||
import 'package:halkyon_oidc_client/halkyon_oidc_client.dart' as _ibkpwzgl;
|
||||
import 'package:serverpod_auth_core_client/serverpod_auth_core_client.dart'
|
||||
as _iacc;
|
||||
import 'package:serverpod_auth_idp_client/serverpod_auth_idp_client.dart'
|
||||
as _iaic;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// The signed-in person's account.
|
||||
|
|
@ -76,8 +74,8 @@ class EndpointAccount extends _isc.EndpointRef {
|
|||
String get name => 'halkyon_base.account';
|
||||
|
||||
/// Deletes the caller with everything they have (see [deletePerson]). The
|
||||
/// app also calls it when an anonymous account is given up (decided
|
||||
/// 2026-09-30). Their other devices learn at once that their sessions
|
||||
/// app also calls it for an anonymous account left from before, as it
|
||||
/// starts (ADR 0020, D25). Their other devices learn at once that their sessions
|
||||
/// ended. An account deletes everywhere (ADR 0016): on a member, the
|
||||
/// 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
|
||||
|
|
@ -99,8 +97,8 @@ class EndpointAccount extends _isc.EndpointRef {
|
|||
},
|
||||
);
|
||||
|
||||
/// How the caller signs in besides their sessions: with GitHub, with an
|
||||
/// email address, both, or neither (anonymous).
|
||||
/// How the caller signs in besides their sessions ([SignInWays]): with
|
||||
/// SimpleLogin, a password, an email address or GitHub.
|
||||
_ida.Future<_ifld8s4r.SignInWays> signInWays() =>
|
||||
caller.callServerEndpoint<_ifld8s4r.SignInWays>(
|
||||
'halkyon_base.account',
|
||||
|
|
@ -109,28 +107,6 @@ class EndpointAccount extends _isc.EndpointRef {
|
|||
);
|
||||
}
|
||||
|
||||
/// Signs people in anonymously; the app calls it on first launch.
|
||||
/// {@category Endpoint}
|
||||
class EndpointAnonymousIdp extends _iaic.EndpointAnonymousIdpBase {
|
||||
EndpointAnonymousIdp(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'halkyon_base.anonymousIdp';
|
||||
|
||||
/// Creates a new anonymous account and returns its session: at most 30 an
|
||||
/// hour from one network (`anonymousSignUpLimit`), counted by the
|
||||
/// visitor's address (`networkOf`) rather than as Serverpod's own limit
|
||||
/// counts them, by the connection's, which behind a proxy is the proxy's
|
||||
/// for everyone.
|
||||
@override
|
||||
_ida.Future<_iacc.AuthSuccess> login({String? token}) =>
|
||||
caller.callServerEndpoint<_iacc.AuthSuccess>(
|
||||
'halkyon_base.anonymousIdp',
|
||||
'login',
|
||||
{'token': token},
|
||||
);
|
||||
}
|
||||
|
||||
/// Codes by mail (ADR 0017): what proves an address for a password's setup,
|
||||
/// a sign-up, a setup never finished and the resets. A code signs nobody in
|
||||
/// by itself. Without a session, as signing up and getting back in have
|
||||
|
|
@ -189,34 +165,6 @@ class EndpointGitHubSignIn extends _isc.EndpointRef {
|
|||
);
|
||||
}
|
||||
|
||||
/// Links a GitHub account to the signed-in person: the lossless upgrade from
|
||||
/// an anonymous account. The person and everything they have stay
|
||||
/// where they are; only the way they sign in changes. The instance's
|
||||
/// register keeps the GitHub ID (ADR 0016).
|
||||
/// {@category Endpoint}
|
||||
class EndpointGitHubUpgrade extends _isc.EndpointRef {
|
||||
EndpointGitHubUpgrade(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'halkyon_base.gitHubUpgrade';
|
||||
|
||||
/// Links the GitHub account that [code] proves to the caller; refusals as in
|
||||
/// [linkGitHubAccount].
|
||||
_ida.Future<void> upgrade({
|
||||
required String code,
|
||||
required String codeVerifier,
|
||||
required String redirectUri,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'halkyon_base.gitHubUpgrade',
|
||||
'upgrade',
|
||||
{
|
||||
'code': code,
|
||||
'codeVerifier': codeVerifier,
|
||||
'redirectUri': redirectUri,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// What every Halkyon instance tells its apps. Public: an app asks before
|
||||
/// anyone is signed in.
|
||||
/// {@category Endpoint}
|
||||
|
|
@ -577,9 +525,8 @@ class EndpointAuthenticator extends _isc.EndpointRef {
|
|||
);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// Giving the signed-in person a password (ADR 0017): 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 {
|
||||
|
|
@ -904,8 +851,9 @@ class EndpointSimpleLogin extends _isc.EndpointRef {
|
|||
/// Begins a sign-in from this server's app, coming [back] by the loopback
|
||||
/// or the app's scheme: the attempt, whose ID the device keeps to itself,
|
||||
/// and SimpleLogin's address to open in the browser, which comes back
|
||||
/// through the forwarding page with a code for [complete]. Refusals as
|
||||
/// `beginSimpleLogin`'s.
|
||||
/// through the forwarding page with a code for [complete]. Refused for a
|
||||
/// caller signed in without `identified` (`OidcRefusal.wrongCaller`), and
|
||||
/// as `beginSimpleLogin` refuses.
|
||||
_ida.Future<_ibkpwzgl.OidcStart> begin({
|
||||
required _ihc3njmr.SimpleLoginReturn back,
|
||||
}) => caller.callServerEndpoint<_ibkpwzgl.OidcStart>(
|
||||
|
|
@ -922,8 +870,8 @@ class EndpointSimpleLogin extends _isc.EndpointRef {
|
|||
/// switched to another account. For an account, whether it has its keys
|
||||
/// (`keys.unlock` opens them; one without makes them) and its handle; and
|
||||
/// for ten minutes the attempt's ID stands for this sign-in, for a change
|
||||
/// the device asks for (ADR 0020, D20). Refusals as
|
||||
/// `completeSimpleLogin`'s.
|
||||
/// the device asks for (ADR 0020, D20). Refused as [begin] refuses its
|
||||
/// caller, and as `completeSimpleLogin` refuses.
|
||||
_ida.Future<_ianfx7qj.SimpleLoginCompleted> complete({
|
||||
required _isc.UuidValue attempt,
|
||||
required String code,
|
||||
|
|
@ -1027,10 +975,8 @@ class EndpointSimpleLogin extends _isc.EndpointRef {
|
|||
class Caller extends _isc.ModuleEndpointCaller {
|
||||
Caller(_isc.ServerpodClientShared client) : super(client) {
|
||||
account = EndpointAccount(this);
|
||||
anonymousIdp = EndpointAnonymousIdp(this);
|
||||
emailCode = EndpointEmailCode(this);
|
||||
gitHubSignIn = EndpointGitHubSignIn(this);
|
||||
gitHubUpgrade = EndpointGitHubUpgrade(this);
|
||||
instance = EndpointInstance(this);
|
||||
keys = EndpointKeys(this);
|
||||
accountRecovery = EndpointAccountRecovery(this);
|
||||
|
|
@ -1044,14 +990,10 @@ class Caller extends _isc.ModuleEndpointCaller {
|
|||
|
||||
late final EndpointAccount account;
|
||||
|
||||
late final EndpointAnonymousIdp anonymousIdp;
|
||||
|
||||
late final EndpointEmailCode emailCode;
|
||||
|
||||
late final EndpointGitHubSignIn gitHubSignIn;
|
||||
|
||||
late final EndpointGitHubUpgrade gitHubUpgrade;
|
||||
|
||||
late final EndpointInstance instance;
|
||||
|
||||
late final EndpointKeys keys;
|
||||
|
|
@ -1073,10 +1015,8 @@ class Caller extends _isc.ModuleEndpointCaller {
|
|||
@override
|
||||
Map<String, _isc.EndpointRef> get endpointRefLookup => {
|
||||
'halkyon_base.account': account,
|
||||
'halkyon_base.anonymousIdp': anonymousIdp,
|
||||
'halkyon_base.emailCode': emailCode,
|
||||
'halkyon_base.gitHubSignIn': gitHubSignIn,
|
||||
'halkyon_base.gitHubUpgrade': gitHubUpgrade,
|
||||
'halkyon_base.instance': instance,
|
||||
'halkyon_base.keys': keys,
|
||||
'halkyon_base.accountRecovery': accountRecovery,
|
||||
|
|
|
|||
Loading…
Reference in a new issue