Files
Client/lib/session/session_codec.dart
T

71 lines
2.7 KiB
Dart

import 'session.dart';
/// Keychain keys of the session. Names are frozen: installed versions and the
/// iOS AppDelegate/NSE read them, so renaming would log every user out.
abstract final class SessionKeys {
static const username = 'username';
static const password = 'password';
static const appPassword = 'nextcloud_app_password';
static const appPasswordTalk = 'nextcloud_app_password_talk';
static const loginFlow = 'nextcloud_login_flow';
static const demo = 'is_demo';
// Added with guardian accounts. Absent on installs from before — see
// [decodeSession].
static const kind = 'session_kind';
static const guardianEmail = 'guardian_email';
static const kindCredential = 'credential';
static const kindGuardian = 'guardian';
}
/// Rebuilds the session from raw keychain values. Installs from before
/// guardian accounts carry no [SessionKeys.kind]; a stored username and
/// password then mean a credential session, so existing users stay signed in.
Session? decodeSession(Map<String, String?> raw) {
final isDemo = raw[SessionKeys.demo] == 'true';
switch (raw[SessionKeys.kind]) {
case SessionKeys.kindGuardian:
final email = raw[SessionKeys.guardianEmail];
if (email == null || email.isEmpty) return null;
return GuardianSession(email: email, isDemo: isDemo);
case null:
case SessionKeys.kindCredential:
final username = raw[SessionKeys.username];
final password = raw[SessionKeys.password];
if (username == null || password == null) return null;
return CredentialSession(
username: username,
password: password,
appPassword: raw[SessionKeys.appPassword],
appPasswordTalk: raw[SessionKeys.appPasswordTalk],
usesLoginFlow: raw[SessionKeys.loginFlow] == 'true',
isDemo: isDemo,
);
default:
// Written by a newer app version; unknown here, treat as signed out.
return null;
}
}
/// Keychain values for [session], excluding the group-scoped app passwords
/// (written separately so the iOS NSE can read them). `null` = delete.
Map<String, String?> encodeSessionFields(Session session) => switch (session) {
CredentialSession() => {
SessionKeys.kind: SessionKeys.kindCredential,
SessionKeys.username: session.username,
SessionKeys.password: session.password,
SessionKeys.demo: session.isDemo ? 'true' : null,
SessionKeys.loginFlow: session.nextcloud.usesLoginFlow ? 'true' : null,
SessionKeys.guardianEmail: null,
},
GuardianSession() => {
SessionKeys.kind: SessionKeys.kindGuardian,
SessionKeys.guardianEmail: session.email,
SessionKeys.demo: session.isDemo ? 'true' : null,
SessionKeys.username: null,
SessionKeys.password: null,
SessionKeys.loginFlow: null,
},
};