fix(runtime): harden application service boundaries

This commit is contained in:
edde746
2026-07-24 03:46:46 +02:00
parent 658da37b48
commit e0bf66eea8
309 changed files with 32574 additions and 4369 deletions
+52 -42
View File
@@ -45,55 +45,61 @@ class ConnectionRegistry {
/// the row's current `isDefault` (so token/metadata refreshes don't clear
/// the default flag).
Future<void> upsert(Connection connection) async {
final existing = await (_db.select(_db.connections)..where((t) => t.id.equals(connection.id))).getSingleOrNull();
final bool isDefault;
if (existing != null) {
isDefault = existing.isDefault;
} else {
final any =
await (_db.selectOnly(_db.connections)
..addColumns([_db.connections.id])
..limit(1))
.getSingleOrNull();
isDefault = any == null;
}
final protectedConfig = await CredentialVault.protectConnectionConfig(
connection.kind.id,
connection.toConfigJson(),
);
final row = ConnectionsCompanion(
id: Value(connection.id),
kind: Value(connection.kind.id),
displayName: Value(connection.displayName),
configJson: Value(jsonEncode(protectedConfig)),
isDefault: Value(isDefault),
createdAt: Value(connection.createdAt.millisecondsSinceEpoch),
lastAuthenticatedAt: Value(connection.lastAuthenticatedAt?.millisecondsSinceEpoch),
);
await _db.into(_db.connections).insertOnConflictUpdate(row);
await _db.runIdentityMutation(() async {
final existing = await (_db.select(_db.connections)..where((t) => t.id.equals(connection.id))).getSingleOrNull();
final bool isDefault;
if (existing != null) {
isDefault = existing.isDefault;
} else {
final any =
await (_db.selectOnly(_db.connections)
..addColumns([_db.connections.id])
..limit(1))
.getSingleOrNull();
isDefault = any == null;
}
final protectedConfig = await CredentialVault.protectConnectionConfig(
connection.kind.id,
connection.toConfigJson(),
);
final row = ConnectionsCompanion(
id: Value(connection.id),
kind: Value(connection.kind.id),
displayName: Value(connection.displayName),
configJson: Value(jsonEncode(protectedConfig)),
isDefault: Value(isDefault),
createdAt: Value(connection.createdAt.millisecondsSinceEpoch),
lastAuthenticatedAt: Value(connection.lastAuthenticatedAt?.millisecondsSinceEpoch),
);
await _db.into(_db.connections).insertOnConflictUpdate(row);
});
appLogger.d('ConnectionRegistry: upserted ${connection.kind.id}/${connection.id}');
}
/// Remove a stored connection. If the removed row was the default, the
/// oldest remaining connection (if any) becomes default.
Future<void> remove(String id) async {
await (_db.delete(_db.connections)..where((t) => t.id.equals(id))).go();
final remaining = await (_db.select(_db.connections)..orderBy([(t) => OrderingTerm.asc(t.createdAt)])).get();
if (remaining.isNotEmpty && !remaining.any((r) => r.isDefault)) {
await (_db.update(
_db.connections,
)..where((t) => t.id.equals(remaining.first.id))).write(const ConnectionsCompanion(isDefault: Value(true)));
}
await _db.runIdentityMutation(() async {
await (_db.delete(_db.connections)..where((t) => t.id.equals(id))).go();
final remaining = await (_db.select(_db.connections)..orderBy([(t) => OrderingTerm.asc(t.createdAt)])).get();
if (remaining.isNotEmpty && !remaining.any((r) => r.isDefault)) {
await (_db.update(
_db.connections,
)..where((t) => t.id.equals(remaining.first.id))).write(const ConnectionsCompanion(isDefault: Value(true)));
}
});
appLogger.d('ConnectionRegistry: removed $id');
}
/// Set [id] as the default connection. Clears the flag on all others.
Future<void> setDefault(String id) async {
await _db.transaction(() async {
await _db.update(_db.connections).write(const ConnectionsCompanion(isDefault: Value(false)));
await (_db.update(
_db.connections,
)..where((t) => t.id.equals(id))).write(const ConnectionsCompanion(isDefault: Value(true)));
await _db.runIdentityMutation(() async {
await _db.transaction(() async {
await _db.update(_db.connections).write(const ConnectionsCompanion(isDefault: Value(false)));
await (_db.update(
_db.connections,
)..where((t) => t.id.equals(id))).write(const ConnectionsCompanion(isDefault: Value(true)));
});
});
}
@@ -101,13 +107,17 @@ class ConnectionRegistry {
/// `lastAuthenticatedAt`). Used by the auth flow after a successful
/// silent refresh without touching the rest of the config.
Future<void> recordAuthSuccess(String id, DateTime at) async {
await (_db.update(_db.connections)..where((t) => t.id.equals(id))).write(
ConnectionsCompanion(lastAuthenticatedAt: Value(at.millisecondsSinceEpoch)),
);
await _db.runIdentityMutation(() async {
await (_db.update(_db.connections)..where((t) => t.id.equals(id))).write(
ConnectionsCompanion(lastAuthenticatedAt: Value(at.millisecondsSinceEpoch)),
);
});
}
Future<void> clear() async {
await _db.delete(_db.connections).go();
await _db.runIdentityMutation(() async {
await _db.delete(_db.connections).go();
});
}
/// All Plex accounts in insertion order. Convenience over