158 lines
3.4 KiB
Dart
158 lines
3.4 KiB
Dart
import 'package:objectbox/objectbox.dart';
|
|
|
|
/// User entity - works for both HOME and GUEST servers
|
|
///
|
|
/// On HOME server:
|
|
/// - isLocal = true
|
|
/// - stores password, encrypted private key
|
|
/// - this is where identity lives
|
|
///
|
|
/// On GUEST server:
|
|
/// - isLocal = false
|
|
/// - homeServer contains the URL of user's home
|
|
/// - publicKey cached for verification
|
|
@Entity(uid: 3848231140411393897)
|
|
class ChatUser {
|
|
@Id()
|
|
int id = 0;
|
|
|
|
// Global identifier: "username@homeserver.com"
|
|
@Unique()
|
|
String userId;
|
|
|
|
// Basic profile
|
|
@Index()
|
|
String username;
|
|
String? displayName;
|
|
String? avatarUrl;
|
|
String? bio;
|
|
|
|
// Identity
|
|
String publicKey; // ECDSA public key, always stored
|
|
|
|
// HOME SERVER ONLY: Auth & key backup
|
|
String? passwordHash;
|
|
String? encryptedPrivateKey; // Encrypted with user's password
|
|
String? keyPairSalt;
|
|
|
|
// Server relationship
|
|
bool isLocal; // true = this is their home server
|
|
String?
|
|
homeServer; // if guest, where is their home? (e.g., "https://my.server.com")
|
|
|
|
// Server-specific
|
|
List<String> roles; // ["admin", "moderator", "member"]
|
|
|
|
@Property(type: PropertyType.date)
|
|
DateTime createdAt;
|
|
|
|
@Property(type: PropertyType.date)
|
|
DateTime? lastSyncedAt; // When profile was last refreshed from home
|
|
|
|
ChatUser({
|
|
required this.userId,
|
|
required this.username,
|
|
required this.publicKey,
|
|
required this.isLocal,
|
|
this.displayName,
|
|
this.avatarUrl,
|
|
this.bio,
|
|
this.passwordHash,
|
|
this.encryptedPrivateKey,
|
|
this.keyPairSalt,
|
|
this.homeServer,
|
|
List<String>? roles,
|
|
DateTime? createdAt,
|
|
DateTime? lastSyncedAt,
|
|
}) : roles = roles ?? ['member'],
|
|
createdAt = createdAt ?? DateTime.now(),
|
|
lastSyncedAt = lastSyncedAt;
|
|
}
|
|
|
|
@Entity(uid: 2663861829934850300)
|
|
class ChatChannel {
|
|
@Id()
|
|
int id = 0;
|
|
|
|
@Unique()
|
|
String name;
|
|
|
|
String? description;
|
|
|
|
@Property(type: PropertyType.date)
|
|
DateTime createdAt;
|
|
|
|
ChatChannel({
|
|
required this.name,
|
|
this.description,
|
|
DateTime? createdAt,
|
|
}) : createdAt = createdAt ?? DateTime.now();
|
|
}
|
|
|
|
@Entity(uid: 2697867424319168785)
|
|
class ChatMessage {
|
|
@Id()
|
|
int id = 0;
|
|
|
|
int channelId;
|
|
|
|
// Author info - includes enough for cross-server profile fetch
|
|
int authorLocalId;
|
|
String authorUserId; // "alice@homeserver.com"
|
|
String? authorHomeServer; // for profile fetching
|
|
|
|
// Cached for display (snapshot at message time)
|
|
String authorUsername;
|
|
String? authorAvatarUrl;
|
|
|
|
String content;
|
|
String componentsJson;
|
|
|
|
@Property(type: PropertyType.date)
|
|
DateTime createdAt;
|
|
|
|
@Property(type: PropertyType.date)
|
|
DateTime? editedAt;
|
|
|
|
ChatMessage({
|
|
required this.channelId,
|
|
required this.authorLocalId,
|
|
required this.authorUserId,
|
|
required this.authorUsername,
|
|
required this.content,
|
|
required this.componentsJson,
|
|
this.authorHomeServer,
|
|
this.authorAvatarUrl,
|
|
DateTime? createdAt,
|
|
this.editedAt,
|
|
}) : createdAt = createdAt ?? DateTime.now();
|
|
}
|
|
|
|
@Entity()
|
|
class ChatFile {
|
|
@Id()
|
|
int id = 0;
|
|
|
|
int uploaderId;
|
|
String path;
|
|
String mimeType;
|
|
int width;
|
|
int height;
|
|
int sizeBytes;
|
|
bool isAttached;
|
|
|
|
@Property(type: PropertyType.date)
|
|
DateTime createdAt;
|
|
|
|
ChatFile({
|
|
required this.uploaderId,
|
|
required this.path,
|
|
required this.mimeType,
|
|
required this.width,
|
|
required this.height,
|
|
required this.sizeBytes,
|
|
this.isAttached = false,
|
|
DateTime? createdAt,
|
|
}) : createdAt = createdAt ?? DateTime.now();
|
|
}
|