/*
* Copyright (C) 2026 Fluxer Contributors
*
* This file is part of Fluxer.
*
* Fluxer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Fluxer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Fluxer. If not, see .
*/
import type {ChannelID, GuildID, MessageID, PhoneVerificationToken, UserID} from '~/BrandedTypes';
import type {
AuthSessionRow,
BetaCodeRow,
EmailRevertTokenRow,
EmailVerificationTokenRow,
GiftCodeRow,
PasswordResetTokenRow,
PaymentBySubscriptionRow,
PaymentRow,
PhoneTokenRow,
PushSubscriptionRow,
RecentMentionRow,
RelationshipRow,
UserGuildSettingsRow,
UserRow,
UserSettingsRow,
} from '~/database/CassandraTypes';
import type {
AuthSession,
BetaCode,
Channel,
EmailRevertToken,
EmailVerificationToken,
GiftCode,
MfaBackupCode,
PasswordResetToken,
Payment,
PushSubscription,
ReadState,
RecentMention,
Relationship,
SavedMessage,
User,
UserGuildSettings,
UserNote,
UserSettings,
VisionarySlot,
WebAuthnCredential,
} from '~/Models';
import {ReadStateRepository} from '~/read_state/ReadStateRepository';
import type {PrivateChannelSummary} from './IUserChannelRepository';
import type {IUserRepositoryAggregate} from './IUserRepositoryAggregate';
import {UserAccountRepository} from './UserAccountRepository';
import {UserAuthRepository} from './UserAuthRepository';
import {UserChannelRepository} from './UserChannelRepository';
import {UserContentRepository} from './UserContentRepository';
import {UserRelationshipRepository} from './UserRelationshipRepository';
import {UserSettingsRepository} from './UserSettingsRepository';
export class UserRepository implements IUserRepositoryAggregate {
private accountRepo: UserAccountRepository;
private settingsRepo: UserSettingsRepository;
private authRepo: UserAuthRepository;
private relationshipRepo: UserRelationshipRepository;
private channelRepo: UserChannelRepository;
private contentRepo: UserContentRepository;
private readStateRepo: ReadStateRepository;
constructor() {
this.accountRepo = new UserAccountRepository();
this.settingsRepo = new UserSettingsRepository();
this.authRepo = new UserAuthRepository(this.accountRepo);
this.relationshipRepo = new UserRelationshipRepository();
this.channelRepo = new UserChannelRepository();
this.contentRepo = new UserContentRepository();
this.readStateRepo = new ReadStateRepository();
}
async create(data: UserRow): Promise {
return this.accountRepo.create(data);
}
async upsert(data: UserRow, oldData?: UserRow | null): Promise {
return this.accountRepo.upsert(data, oldData);
}
async patchUpsert(userId: UserID, patchData: Partial, oldData?: UserRow | null): Promise {
return this.accountRepo.patchUpsert(userId, patchData, oldData);
}
async findUnique(userId: UserID): Promise {
return this.accountRepo.findUnique(userId);
}
async findUniqueAssert(userId: UserID): Promise {
return this.accountRepo.findUniqueAssert(userId);
}
async findByUsernameDiscriminator(username: string, discriminator: number): Promise {
return this.accountRepo.findByUsernameDiscriminator(username, discriminator);
}
async findDiscriminatorsByUsername(username: string): Promise> {
return this.accountRepo.findDiscriminatorsByUsername(username);
}
async findByEmail(email: string): Promise {
return this.accountRepo.findByEmail(email);
}
async findByPhone(phone: string): Promise {
return this.accountRepo.findByPhone(phone);
}
async findByStripeSubscriptionId(stripeSubscriptionId: string): Promise {
return this.accountRepo.findByStripeSubscriptionId(stripeSubscriptionId);
}
async findByStripeCustomerId(stripeCustomerId: string): Promise {
return this.accountRepo.findByStripeCustomerId(stripeCustomerId);
}
async listUsers(userIds: Array): Promise> {
return this.accountRepo.listUsers(userIds);
}
async listAllUsersPaginated(limit: number, lastUserId?: UserID): Promise> {
return this.accountRepo.listAllUsersPaginated(limit, lastUserId);
}
async getUserGuildIds(userId: UserID): Promise> {
return this.accountRepo.getUserGuildIds(userId);
}
async getActivityTracking(userId: UserID): Promise<{last_active_at: Date | null; last_active_ip: string | null}> {
return this.accountRepo.getActivityTracking(userId);
}
async addPendingDeletion(userId: UserID, pendingDeletionAt: Date, deletionReasonCode: number): Promise {
return this.accountRepo.addPendingDeletion(userId, pendingDeletionAt, deletionReasonCode);
}
async removePendingDeletion(userId: UserID, pendingDeletionAt: Date): Promise {
return this.accountRepo.removePendingDeletion(userId, pendingDeletionAt);
}
async findUsersPendingDeletion(now: Date): Promise> {
return this.accountRepo.findUsersPendingDeletion(now);
}
async findUsersPendingDeletionByDate(
deletionDate: string,
): Promise> {
return this.accountRepo.findUsersPendingDeletionByDate(deletionDate);
}
async isUserPendingDeletion(userId: UserID, deletionDate: string): Promise {
return this.accountRepo.isUserPendingDeletion(userId, deletionDate);
}
async scheduleDeletion(userId: UserID, pendingDeletionAt: Date, deletionReasonCode: number): Promise {
return this.accountRepo.scheduleDeletion(userId, pendingDeletionAt, deletionReasonCode);
}
async deleteUserSecondaryIndices(userId: UserID): Promise {
return this.accountRepo.deleteUserSecondaryIndices(userId);
}
async removeFromAllGuilds(userId: UserID): Promise {
return this.accountRepo.removeFromAllGuilds(userId);
}
async updateLastActiveAt(params: {userId: UserID; lastActiveAt: Date; lastActiveIp?: string}): Promise {
return this.accountRepo.updateLastActiveAt(params);
}
async findSettings(userId: UserID): Promise {
return this.settingsRepo.findSettings(userId);
}
async upsertSettings(settings: UserSettingsRow): Promise {
return this.settingsRepo.upsertSettings(settings);
}
async deleteUserSettings(userId: UserID): Promise {
return this.settingsRepo.deleteUserSettings(userId);
}
async findGuildSettings(userId: UserID, guildId: GuildID | null): Promise {
return this.settingsRepo.findGuildSettings(userId, guildId);
}
async findAllGuildSettings(userId: UserID): Promise> {
return this.settingsRepo.findAllGuildSettings(userId);
}
async upsertGuildSettings(settings: UserGuildSettingsRow): Promise {
return this.settingsRepo.upsertGuildSettings(settings);
}
async deleteGuildSettings(userId: UserID, guildId: GuildID): Promise {
return this.settingsRepo.deleteGuildSettings(userId, guildId);
}
async deleteAllUserGuildSettings(userId: UserID): Promise {
return this.settingsRepo.deleteAllUserGuildSettings(userId);
}
async listAuthSessions(userId: UserID): Promise> {
return this.authRepo.listAuthSessions(userId);
}
async getAuthSessionByToken(sessionIdHash: Buffer): Promise {
return this.authRepo.getAuthSessionByToken(sessionIdHash);
}
async createAuthSession(sessionData: AuthSessionRow): Promise {
return this.authRepo.createAuthSession(sessionData);
}
async updateAuthSessionLastUsed(sessionIdHash: Buffer): Promise {
return this.authRepo.updateAuthSessionLastUsed(sessionIdHash);
}
async deleteAuthSessions(userId: UserID, sessionIdHashes: Array): Promise {
return this.authRepo.deleteAuthSessions(userId, sessionIdHashes);
}
async revokeAuthSession(sessionIdHash: Buffer): Promise {
return this.authRepo.revokeAuthSession(sessionIdHash);
}
async deleteAllAuthSessions(userId: UserID): Promise {
return this.authRepo.deleteAllAuthSessions(userId);
}
async listMfaBackupCodes(userId: UserID): Promise> {
return this.authRepo.listMfaBackupCodes(userId);
}
async createMfaBackupCodes(userId: UserID, codes: Array): Promise> {
return this.authRepo.createMfaBackupCodes(userId, codes);
}
async clearMfaBackupCodes(userId: UserID): Promise {
return this.authRepo.clearMfaBackupCodes(userId);
}
async consumeMfaBackupCode(userId: UserID, code: string): Promise {
return this.authRepo.consumeMfaBackupCode(userId, code);
}
async deleteAllMfaBackupCodes(userId: UserID): Promise {
return this.authRepo.deleteAllMfaBackupCodes(userId);
}
async getEmailVerificationToken(token: string): Promise {
return this.authRepo.getEmailVerificationToken(token);
}
async createEmailVerificationToken(tokenData: EmailVerificationTokenRow): Promise {
return this.authRepo.createEmailVerificationToken(tokenData);
}
async deleteEmailVerificationToken(token: string): Promise {
return this.authRepo.deleteEmailVerificationToken(token);
}
async getPasswordResetToken(token: string): Promise {
return this.authRepo.getPasswordResetToken(token);
}
async createPasswordResetToken(tokenData: PasswordResetTokenRow): Promise {
return this.authRepo.createPasswordResetToken(tokenData);
}
async deletePasswordResetToken(token: string): Promise {
return this.authRepo.deletePasswordResetToken(token);
}
async getEmailRevertToken(token: string): Promise {
return this.authRepo.getEmailRevertToken(token);
}
async createEmailRevertToken(tokenData: EmailRevertTokenRow): Promise {
return this.authRepo.createEmailRevertToken(tokenData);
}
async deleteEmailRevertToken(token: string): Promise {
return this.authRepo.deleteEmailRevertToken(token);
}
async createPhoneToken(token: PhoneVerificationToken, phone: string, userId: UserID | null): Promise {
return this.authRepo.createPhoneToken(token, phone, userId);
}
async getPhoneToken(token: PhoneVerificationToken): Promise {
return this.authRepo.getPhoneToken(token);
}
async deletePhoneToken(token: PhoneVerificationToken): Promise {
return this.authRepo.deletePhoneToken(token);
}
async updateUserActivity(userId: UserID, clientIp: string): Promise {
return this.authRepo.updateUserActivity(userId, clientIp);
}
async checkIpAuthorized(userId: UserID, ip: string): Promise {
return this.authRepo.checkIpAuthorized(userId, ip);
}
async createAuthorizedIp(userId: UserID, ip: string): Promise {
return this.authRepo.createAuthorizedIp(userId, ip);
}
async createIpAuthorizationToken(userId: UserID, token: string): Promise {
return this.authRepo.createIpAuthorizationToken(userId, token);
}
async authorizeIpByToken(token: string): Promise<{userId: UserID; email: string} | null> {
return this.authRepo.authorizeIpByToken(token);
}
async getAuthorizedIps(userId: UserID): Promise> {
return this.authRepo.getAuthorizedIps(userId);
}
async deleteAllAuthorizedIps(userId: UserID): Promise {
return this.authRepo.deleteAllAuthorizedIps(userId);
}
async listWebAuthnCredentials(userId: UserID): Promise> {
return this.authRepo.listWebAuthnCredentials(userId);
}
async getWebAuthnCredential(userId: UserID, credentialId: string): Promise {
return this.authRepo.getWebAuthnCredential(userId, credentialId);
}
async createWebAuthnCredential(
userId: UserID,
credentialId: string,
publicKey: Buffer,
counter: bigint,
transports: Set | null,
name: string,
): Promise {
return this.authRepo.createWebAuthnCredential(userId, credentialId, publicKey, counter, transports, name);
}
async updateWebAuthnCredentialCounter(userId: UserID, credentialId: string, counter: bigint): Promise {
return this.authRepo.updateWebAuthnCredentialCounter(userId, credentialId, counter);
}
async updateWebAuthnCredentialLastUsed(userId: UserID, credentialId: string): Promise {
return this.authRepo.updateWebAuthnCredentialLastUsed(userId, credentialId);
}
async updateWebAuthnCredentialName(userId: UserID, credentialId: string, name: string): Promise {
return this.authRepo.updateWebAuthnCredentialName(userId, credentialId, name);
}
async deleteWebAuthnCredential(userId: UserID, credentialId: string): Promise {
return this.authRepo.deleteWebAuthnCredential(userId, credentialId);
}
async getUserIdByCredentialId(credentialId: string): Promise {
return this.authRepo.getUserIdByCredentialId(credentialId);
}
async deleteAllWebAuthnCredentials(userId: UserID): Promise {
return this.authRepo.deleteAllWebAuthnCredentials(userId);
}
async createPendingVerification(userId: UserID, createdAt: Date, metadata: Map): Promise {
return this.authRepo.createPendingVerification(userId, createdAt, metadata);
}
async deletePendingVerification(userId: UserID): Promise {
return this.authRepo.deletePendingVerification(userId);
}
async listRelationships(sourceUserId: UserID): Promise> {
return this.relationshipRepo.listRelationships(sourceUserId);
}
async getRelationship(sourceUserId: UserID, targetUserId: UserID, type: number): Promise {
return this.relationshipRepo.getRelationship(sourceUserId, targetUserId, type);
}
async upsertRelationship(relationship: RelationshipRow): Promise {
return this.relationshipRepo.upsertRelationship(relationship);
}
async deleteRelationship(sourceUserId: UserID, targetUserId: UserID, type: number): Promise {
return this.relationshipRepo.deleteRelationship(sourceUserId, targetUserId, type);
}
async deleteAllRelationships(userId: UserID): Promise {
return this.relationshipRepo.deleteAllRelationships(userId);
}
async getUserNote(sourceUserId: UserID, targetUserId: UserID): Promise {
return this.relationshipRepo.getUserNote(sourceUserId, targetUserId);
}
async getUserNotes(sourceUserId: UserID): Promise