mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
refactor(api): collapse single-impl interfaces and facades (#3382)
This commit is contained in:
1 parent
e7b13fd19f
commit
c16d414d93
426 files changed
+2085
-6445
No files matched your search
@@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {AdminAuditLog, BannedIpEntry, BannedIpKind, IAdminRepository} from '@app/api/admin/IAdminRepository';
|
||||
import {createUserID} from '@app/api/BrandedTypes';
|
||||
import {createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
|
||||
import {ContentBlocklistCategory} from '@app/api/constants/ContentModeration';
|
||||
import {
|
||||
@@ -35,6 +34,27 @@ import {parseIpBanEntry, tryParseSingleIp} from '@app/api/utils/IpRangeUtils';
|
||||
import {canonicalizeStoredPhrase} from '@app/api/utils/PhraseBlocklistNormalization';
|
||||
import {getSameIpDecisionKey} from '@fluxer/ip_utils/src/IpAddress';
|
||||
|
||||
export interface AdminAuditLog {
|
||||
logId: bigint;
|
||||
adminUserId: UserID;
|
||||
targetType: string;
|
||||
targetId: bigint;
|
||||
action: string;
|
||||
auditLogReason: string | null;
|
||||
metadata: Map<string, string>;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
export type BannedIpKind = 'permanent' | 'temporary_24h';
|
||||
|
||||
export interface BannedIpEntry {
|
||||
ip: string;
|
||||
kind: BannedIpKind;
|
||||
reason: string | null;
|
||||
expiresAt: Date | null;
|
||||
createdAt: Date | null;
|
||||
}
|
||||
|
||||
const FETCH_AUDIT_LOG_BY_ID_QUERY = AdminAuditLogs.select({
|
||||
where: AdminAuditLogs.where.eq('log_id'),
|
||||
});
|
||||
@@ -84,7 +104,7 @@ function canonicalizeBannedIpEntry(value: string): string {
|
||||
return parseIpBanEntry(value)?.canonical ?? value;
|
||||
}
|
||||
|
||||
export class AdminRepository implements IAdminRepository {
|
||||
export class AdminRepository {
|
||||
async createAuditLog(log: AdminAuditLogRow): Promise<AdminAuditLog> {
|
||||
await upsertOne(AdminAuditLogs.insert(log));
|
||||
return this.mapRowToAuditLog(log);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {ApiContext} from '@app/api/ApiContext';
|
||||
import type {IAdminRepository} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminRepository} from '@app/api/admin/AdminRepository';
|
||||
import {AdminApplicationService} from '@app/api/admin/services/AdminApplicationService';
|
||||
import {AdminAssetPurgeService} from '@app/api/admin/services/AdminAssetPurgeService';
|
||||
import {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
|
||||
@@ -18,9 +18,9 @@ import {AdminUserService} from '@app/api/admin/services/AdminUserService';
|
||||
import {AdminVoiceService} from '@app/api/admin/services/AdminVoiceService';
|
||||
import {ReporterResolutionNotifier} from '@app/api/admin/services/ReporterResolutionNotifier';
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import type {ChannelService} from '@app/api/channel/services/ChannelService';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {GuildService} from '@app/api/guild/services/GuildService';
|
||||
import type {IDiscriminatorService} from '@app/api/infrastructure/DiscriminatorService';
|
||||
import type {EntityAssetService} from '@app/api/infrastructure/EntityAssetService';
|
||||
@@ -29,10 +29,10 @@ import type {IStorageService} from '@app/api/infrastructure/IStorageService';
|
||||
import type {KVBulkMessageDeletionQueueService} from '@app/api/infrastructure/KVBulkMessageDeletionQueueService';
|
||||
import type {UserCacheService} from '@app/api/infrastructure/UserCacheService';
|
||||
import type {InviteRepository} from '@app/api/invite/InviteRepository';
|
||||
import type {IJobLedgerRepository} from '@app/api/jobs/IJobLedgerRepository';
|
||||
import {JobAdminService} from '@app/api/jobs/JobAdminService';
|
||||
import type {JobLedgerRepository} from '@app/api/jobs/JobLedgerRepository';
|
||||
import {getGuildDiscoveryRepository, getKVAccountDeletionQueue} from '@app/api/middleware/ServiceSingletons';
|
||||
import type {IApplicationRepository} from '@app/api/oauth/repositories/IApplicationRepository';
|
||||
import type {ApplicationRepository} from '@app/api/oauth/repositories/ApplicationRepository';
|
||||
import type {ReportService} from '@app/api/report/ReportService';
|
||||
import type {StoreEntitlementService} from '@app/api/store_billing/StoreEntitlementService';
|
||||
import type {UserService} from '@app/api/user/services/UserService';
|
||||
@@ -59,9 +59,9 @@ export class AdminService {
|
||||
|
||||
constructor(
|
||||
private readonly apiContext: ApiContext,
|
||||
private readonly guildRepository: IGuildRepositoryAggregate,
|
||||
private readonly channelRepository: IChannelRepository,
|
||||
private readonly adminRepository: IAdminRepository,
|
||||
private readonly guildRepository: GuildRepository,
|
||||
private readonly channelRepository: ChannelRepository,
|
||||
private readonly adminRepository: AdminRepository,
|
||||
private readonly inviteRepository: InviteRepository,
|
||||
private readonly discriminatorService: IDiscriminatorService,
|
||||
private readonly guildService: GuildService,
|
||||
@@ -74,16 +74,16 @@ export class AdminService {
|
||||
private readonly reportService: ReportService,
|
||||
private readonly voiceRepository: VoiceRepository,
|
||||
private readonly bulkMessageDeletionQueue: KVBulkMessageDeletionQueueService,
|
||||
private readonly applicationRepository: IApplicationRepository,
|
||||
private readonly applicationRepository: ApplicationRepository,
|
||||
private readonly stripe: Stripe | null = null,
|
||||
private readonly jobLedger: IJobLedgerRepository,
|
||||
private readonly jobLedger: JobLedgerRepository,
|
||||
private readonly storeEntitlementService: StoreEntitlementService,
|
||||
) {
|
||||
const {users, gateway, worker, snowflake} = this.apiContext.services;
|
||||
this.auditService = new AdminAuditService(this.adminRepository, snowflake, {
|
||||
userRepository: users,
|
||||
guildRepository: this.guildRepository,
|
||||
channelRepository: this.channelRepository,
|
||||
channelRepository: this.channelRepository.channelData,
|
||||
});
|
||||
this.banManagementService = new AdminBanManagementService({
|
||||
apiContext: this.apiContext,
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import type {
|
||||
AdminAuditLogRow,
|
||||
BannedAvatarHashRow,
|
||||
BannedFileShaRow,
|
||||
BannedProfileSubstringRow,
|
||||
BannedProfileSubstringScope,
|
||||
BannedUrlDomainRow,
|
||||
BannedUrlRow,
|
||||
} from '@app/api/database/types/AdminArchiveTypes';
|
||||
|
||||
export interface AdminAuditLog {
|
||||
logId: bigint;
|
||||
adminUserId: UserID;
|
||||
targetType: string;
|
||||
targetId: bigint;
|
||||
action: string;
|
||||
auditLogReason: string | null;
|
||||
metadata: Map<string, string>;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
export type BannedIpKind = 'permanent' | 'temporary_24h';
|
||||
|
||||
export interface BannedIpEntry {
|
||||
ip: string;
|
||||
kind: BannedIpKind;
|
||||
reason: string | null;
|
||||
expiresAt: Date | null;
|
||||
createdAt: Date | null;
|
||||
}
|
||||
|
||||
export abstract class IAdminRepository {
|
||||
abstract createAuditLog(log: AdminAuditLogRow): Promise<AdminAuditLog>;
|
||||
|
||||
abstract getAuditLog(logId: bigint): Promise<AdminAuditLog | null>;
|
||||
|
||||
abstract listAuditLogsByIds(logIds: Array<bigint>): Promise<Array<AdminAuditLog>>;
|
||||
|
||||
abstract listAllAuditLogsPaginated(limit: number, lastLogId?: bigint): Promise<Array<AdminAuditLog>>;
|
||||
|
||||
abstract isIpBanned(ip: string): Promise<boolean>;
|
||||
|
||||
abstract banIp(ip: string, ttlSeconds?: number | null): Promise<void>;
|
||||
|
||||
abstract banIpTemp(ip: string, ttlSeconds: number): Promise<void>;
|
||||
|
||||
abstract unbanIp(ip: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedIpEntries(): Promise<Array<BannedIpEntry>>;
|
||||
|
||||
abstract isEmailBanned(email: string): Promise<boolean>;
|
||||
|
||||
abstract banEmail(email: string): Promise<void>;
|
||||
|
||||
abstract unbanEmail(email: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedEmails(): Promise<Array<string>>;
|
||||
|
||||
abstract banPhrase(phrase: string): Promise<void>;
|
||||
|
||||
abstract unbanPhrase(phrase: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedPhrases(): Promise<Array<string>>;
|
||||
|
||||
abstract loadAllBannedIps(): Promise<Set<string>>;
|
||||
|
||||
abstract banUrl(row: BannedUrlRow): Promise<void>;
|
||||
|
||||
abstract unbanUrl(url: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedUrls(): Promise<Array<BannedUrlRow>>;
|
||||
|
||||
abstract banUrlDomain(row: BannedUrlDomainRow): Promise<void>;
|
||||
|
||||
abstract unbanUrlDomain(domain: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedUrlDomains(): Promise<Array<BannedUrlDomainRow>>;
|
||||
|
||||
abstract banFileSha(row: BannedFileShaRow): Promise<void>;
|
||||
|
||||
abstract unbanFileSha(sha256Hex: string): Promise<void>;
|
||||
|
||||
abstract unbanFeedFileSha(sha256Hex: string): Promise<boolean>;
|
||||
|
||||
abstract loadAllBannedFileShas(): Promise<Array<BannedFileShaRow>>;
|
||||
|
||||
abstract banAvatarHash(row: BannedAvatarHashRow): Promise<void>;
|
||||
|
||||
abstract unbanAvatarHash(hashShort: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedAvatarHashes(): Promise<Array<BannedAvatarHashRow>>;
|
||||
|
||||
abstract banProfileSubstring(row: BannedProfileSubstringRow): Promise<void>;
|
||||
|
||||
abstract unbanProfileSubstring(scope: BannedProfileSubstringScope, substring: string): Promise<void>;
|
||||
|
||||
abstract loadAllBannedProfileSubstrings(): Promise<Array<BannedProfileSubstringRow>>;
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import {OpenAPI} from '@app/api/middleware/ResponseTypeMiddleware';
|
||||
import type {User} from '@app/api/models/User';
|
||||
import {RateLimitConfigs} from '@app/api/RateLimitConfig';
|
||||
import type {HonoApp} from '@app/api/types/HonoEnv';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import {Validator} from '@app/api/Validator';
|
||||
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
|
||||
import {DiscoveryApplicationStatus, DiscoveryCategoryLabels} from '@fluxer/constants/src/DiscoveryConstants';
|
||||
@@ -65,13 +65,13 @@ interface GuildEnrichment {
|
||||
async function enrichGuilds(
|
||||
rows: ReadonlyArray<GuildDiscoveryRow>,
|
||||
guildService: GuildService,
|
||||
userRepository: IUserRepository,
|
||||
userRepository: UserRepository,
|
||||
): Promise<Map<string, GuildEnrichment>> {
|
||||
const map = new Map<string, GuildEnrichment>();
|
||||
const guilds = await Promise.all(
|
||||
rows.map(async (row) => {
|
||||
try {
|
||||
return await guildService.data.getGuildSystem(row.guild_id);
|
||||
return await guildService.data.operations.getGuildSystem(row.guild_id);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ export function ThreadAdminController(app: HonoApp) {
|
||||
}),
|
||||
async (ctx) => {
|
||||
const channelId = createChannelID(ctx.req.valid('param').channel_id);
|
||||
const thread = await ctx.get('channelRepository').findUnique(channelId);
|
||||
const thread = await ctx.get('channelRepository').channelData.findUnique(channelId);
|
||||
if (!thread) throw new UnknownChannelError();
|
||||
if (!thread.isThread()) throw new InvalidChannelTypeError();
|
||||
const adminUserId = ctx.get('adminUserId');
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {
|
||||
CreateAdminApiKeyData,
|
||||
IAdminApiKeyRepository,
|
||||
UpdateAdminApiKeyData,
|
||||
} from '@app/api/admin/repositories/IAdminApiKeyRepository';
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import {
|
||||
BatchBuilder,
|
||||
@@ -19,12 +14,23 @@ import {AdminApiKey} from '@app/api/models/AdminApiKey';
|
||||
import {AdminApiKeys, AdminApiKeysByCreator} from '@app/api/Tables';
|
||||
import {hashPassword} from '@app/api/utils/PasswordUtils';
|
||||
|
||||
export interface CreateAdminApiKeyData {
|
||||
name: string;
|
||||
expiresAt: Date | null;
|
||||
acls: Set<string>;
|
||||
}
|
||||
|
||||
export interface UpdateAdminApiKeyData {
|
||||
name?: string;
|
||||
acls?: Set<string>;
|
||||
}
|
||||
|
||||
function computeTtlSeconds(expiresAt: Date): number {
|
||||
const diffSeconds = Math.floor((expiresAt.getTime() - Date.now()) / 1000);
|
||||
return Math.max(diffSeconds, 1);
|
||||
}
|
||||
|
||||
export class AdminApiKeyRepository implements IAdminApiKeyRepository {
|
||||
export class AdminApiKeyRepository {
|
||||
async create(data: CreateAdminApiKeyData, createdBy: UserID, keyId: bigint, rawKey: string): Promise<AdminApiKey> {
|
||||
const keyHash = await hashPassword(rawKey);
|
||||
const createdAt = new Date();
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import type {AdminApiKey} from '@app/api/models/AdminApiKey';
|
||||
|
||||
export interface CreateAdminApiKeyData {
|
||||
name: string;
|
||||
expiresAt: Date | null;
|
||||
acls: Set<string>;
|
||||
}
|
||||
|
||||
export interface UpdateAdminApiKeyData {
|
||||
name?: string;
|
||||
acls?: Set<string>;
|
||||
}
|
||||
|
||||
export interface IAdminApiKeyRepository {
|
||||
create(data: CreateAdminApiKeyData, createdBy: UserID, keyId: bigint, rawKey: string): Promise<AdminApiKey>;
|
||||
findById(keyId: bigint): Promise<AdminApiKey | null>;
|
||||
update(apiKey: AdminApiKey, data: UpdateAdminApiKeyData): Promise<AdminApiKey>;
|
||||
listByCreator(createdBy: UserID): Promise<Array<AdminApiKey>>;
|
||||
updateLastUsed(keyId: bigint, expiresAt: Date | null): Promise<void>;
|
||||
revoke(keyId: bigint, createdBy: UserID): Promise<void>;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {randomInt} from 'node:crypto';
|
||||
import type {IAdminApiKeyRepository} from '@app/api/admin/repositories/IAdminApiKeyRepository';
|
||||
import type {AdminApiKeyRepository} from '@app/api/admin/repositories/AdminApiKeyRepository';
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import type {ISnowflakeService} from '@app/api/infrastructure/ISnowflakeService';
|
||||
import type {AdminApiKey} from '@app/api/models/AdminApiKey';
|
||||
@@ -39,7 +39,7 @@ export interface AdminApiKeyView {
|
||||
|
||||
export class AdminApiKeyService {
|
||||
constructor(
|
||||
private readonly adminApiKeyRepository: IAdminApiKeyRepository,
|
||||
private readonly adminApiKeyRepository: AdminApiKeyRepository,
|
||||
private readonly snowflakeService: ISnowflakeService,
|
||||
) {}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import type {ApiContext} from '@app/api/ApiContext';
|
||||
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
|
||||
import {type ApplicationID, createApplicationID, createUserID, type GuildID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {Application} from '@app/api/models/Application';
|
||||
import type {IApplicationRepository} from '@app/api/oauth/repositories/IApplicationRepository';
|
||||
import type {ApplicationRepository} from '@app/api/oauth/repositories/ApplicationRepository';
|
||||
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
|
||||
import {UnknownApplicationError} from '@fluxer/errors/src/domains/oauth/UnknownApplicationError';
|
||||
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
|
||||
@@ -18,9 +18,9 @@ import type {
|
||||
|
||||
interface AdminApplicationServiceDeps {
|
||||
apiContext: ApiContext;
|
||||
applicationRepository: IApplicationRepository;
|
||||
applicationRepository: ApplicationRepository;
|
||||
auditService: AdminAuditService;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
}
|
||||
|
||||
interface UserDisplay {
|
||||
|
||||
@@ -4,10 +4,10 @@ import {AdminArchive} from '@app/api/admin/models/AdminArchiveModel';
|
||||
import type {AdminArchiveRepository} from '@app/api/admin/repositories/AdminArchiveRepository';
|
||||
import type {GuildID, UserID} from '@app/api/BrandedTypes';
|
||||
import {Config} from '@app/api/Config';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {ISnowflakeService} from '@app/api/infrastructure/ISnowflakeService';
|
||||
import type {IStorageService} from '@app/api/infrastructure/IStorageService';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import type {WorkerTaskName} from '@app/api/worker/WorkerLaneConfig';
|
||||
import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidationError';
|
||||
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
|
||||
@@ -35,8 +35,8 @@ interface ListArchivesParams {
|
||||
export class AdminArchiveService {
|
||||
constructor(
|
||||
private readonly adminArchiveRepository: AdminArchiveRepository,
|
||||
private readonly userRepository: IUserRepository,
|
||||
private readonly guildRepository: IGuildRepositoryAggregate,
|
||||
private readonly userRepository: UserRepository,
|
||||
private readonly guildRepository: GuildRepository,
|
||||
private readonly storageService: IStorageService,
|
||||
private readonly snowflakeService: ISnowflakeService,
|
||||
private readonly workerService: IWorkerService<WorkerTaskName>,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
|
||||
import {createEmojiID, createStickerID, type GuildID, type UserID} from '@app/api/BrandedTypes';
|
||||
import {mapGuildEmojiToResponse, mapGuildStickerToResponse} from '@app/api/guild/GuildModel';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import {ExpressionAssetPurger} from '@app/api/guild/services/content/ExpressionAssetPurger';
|
||||
import type {IAssetDeletionQueue} from '@app/api/infrastructure/IAssetDeletionQueue';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
@@ -15,7 +15,7 @@ import type {
|
||||
} from '@fluxer/schema/src/domains/admin/AdminSchemas';
|
||||
|
||||
interface AdminAssetPurgeServiceDeps {
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
gatewayService: IGatewayService;
|
||||
assetDeletionQueue: IAssetDeletionQueue;
|
||||
auditService: AdminAuditService;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {ADMIN_AUDIT_READ_ACTIONS, getAdminAuditAccess} from '@app/api/admin/AdminAuditActions';
|
||||
import type {AdminAuditLog, IAdminRepository} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminAuditLog, AdminRepository} from '@app/api/admin/AdminRepository';
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import {createChannelID, createGuildID, createUserID} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {ChannelDataRepository} from '@app/api/channel/repositories/ChannelDataRepository';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {ISnowflakeService} from '@app/api/infrastructure/ISnowflakeService';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import type {Channel} from '@app/api/models/Channel';
|
||||
import type {Guild} from '@app/api/models/Guild';
|
||||
import type {User} from '@app/api/models/User';
|
||||
import {getAuditLogSearchService} from '@app/api/SearchFactory';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import type {AuditLogSearchFilters} from '@fluxer/schema/src/contracts/search/SearchDocumentTypes';
|
||||
import type {
|
||||
AdminAuditAccess,
|
||||
@@ -34,7 +34,7 @@ interface CreateAdminAuditLogParams {
|
||||
|
||||
export class AdminAuditService {
|
||||
constructor(
|
||||
private readonly adminRepository: IAdminRepository,
|
||||
private readonly adminRepository: AdminRepository,
|
||||
private readonly snowflakeService: ISnowflakeService,
|
||||
private readonly enrichmentDeps: AuditLogEnrichmentDeps = {},
|
||||
) {}
|
||||
@@ -341,9 +341,9 @@ function accessFilters(access: AdminAuditAccess | undefined): AuditLogSearchFilt
|
||||
}
|
||||
|
||||
interface AuditLogEnrichmentDeps {
|
||||
userRepository?: Pick<IUserRepository, 'findUnique'>;
|
||||
guildRepository?: Pick<IGuildRepositoryAggregate, 'findUnique'>;
|
||||
channelRepository?: Pick<IChannelRepository, 'findUnique'>;
|
||||
userRepository?: Pick<UserRepository, 'findUnique'>;
|
||||
guildRepository?: Pick<GuildRepository, 'findUnique'>;
|
||||
channelRepository?: Pick<ChannelDataRepository, 'findUnique'>;
|
||||
}
|
||||
|
||||
interface AuditLogEnrichment {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {ApiContext} from '@app/api/ApiContext';
|
||||
import type {IAdminRepository} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminRepository} from '@app/api/admin/AdminRepository';
|
||||
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
|
||||
import {createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import {isIpBanExempt} from '@app/api/ban/IpBanExemptions';
|
||||
@@ -36,7 +36,7 @@ import type {AdminBlocklistListType} from '@fluxer/schema/src/domains/admin/Admi
|
||||
|
||||
interface AdminBanManagementServiceDeps {
|
||||
apiContext: ApiContext;
|
||||
adminRepository: IAdminRepository;
|
||||
adminRepository: AdminRepository;
|
||||
auditService: AdminAuditService;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import type {GiftCodeDurationType, GiftCodeRow} from '@app/api/database/types/PaymentTypes';
|
||||
import {mapGiftCodeDurationToMonths} from '@app/api/models/GiftCode';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import * as RandomUtils from '@app/api/utils/RandomUtils';
|
||||
|
||||
const CODE_LENGTH = 32;
|
||||
@@ -19,7 +19,7 @@ interface GenerateGiftCodesOptions {
|
||||
}
|
||||
|
||||
export class AdminCodeGenerationService {
|
||||
constructor(private readonly userRepository: IUserRepository) {}
|
||||
constructor(private readonly userRepository: UserRepository) {}
|
||||
|
||||
async generateGiftCodes(options: GenerateGiftCodesOptions): Promise<Array<string>> {
|
||||
const {count, durationType, durationQuantity, createdByUserId} = this.validateOptions(options);
|
||||
|
||||
@@ -8,27 +8,27 @@ import {AdminGuildUpdatePropagator} from '@app/api/admin/services/guild/AdminGui
|
||||
import {AdminGuildUpdateService} from '@app/api/admin/services/guild/AdminGuildUpdateService';
|
||||
import {AdminGuildVanityService} from '@app/api/admin/services/guild/AdminGuildVanityService';
|
||||
import {createGuildID, createUserID} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {IGuildDiscoveryRepository} from '@app/api/guild/repositories/GuildDiscoveryRepository';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import type {GuildDiscoveryRepository} from '@app/api/guild/repositories/GuildDiscoveryRepository';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {GuildService} from '@app/api/guild/services/GuildService';
|
||||
import type {EntityAssetService} from '@app/api/infrastructure/EntityAssetService';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
import type {InviteRepository} from '@app/api/invite/InviteRepository';
|
||||
import {createRequestCache} from '@app/api/middleware/RequestCacheMiddleware';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import type {ListGuildAuditLogsRequest} from '@fluxer/schema/src/domains/admin/AdminGuildSchemas';
|
||||
|
||||
interface AdminGuildServiceDeps {
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
userRepository: IUserRepository;
|
||||
channelRepository: IChannelRepository;
|
||||
guildRepository: GuildRepository;
|
||||
userRepository: UserRepository;
|
||||
channelRepository: ChannelRepository;
|
||||
inviteRepository: InviteRepository;
|
||||
guildService: GuildService;
|
||||
gatewayService: IGatewayService;
|
||||
entityAssetService: EntityAssetService;
|
||||
auditService: AdminAuditService;
|
||||
discoveryRepository: IGuildDiscoveryRepository;
|
||||
discoveryRepository: GuildDiscoveryRepository;
|
||||
}
|
||||
|
||||
export class AdminGuildService {
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService'
|
||||
import type {AdminMessageShredService} from '@app/api/admin/services/AdminMessageShredService';
|
||||
import type {ChannelID, MessageID, UserID} from '@app/api/BrandedTypes';
|
||||
import {createUserID} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import type {
|
||||
DeleteAllUserMessagesRequest,
|
||||
@@ -12,7 +12,7 @@ import type {
|
||||
} from '@fluxer/schema/src/domains/admin/AdminMessageSchemas';
|
||||
|
||||
interface AdminMessageDeletionServiceDeps {
|
||||
channelRepository: IChannelRepository;
|
||||
channelRepository: ChannelRepository;
|
||||
messageShredService: AdminMessageShredService;
|
||||
auditService: AdminAuditService;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ export class AdminMessageDeletionService {
|
||||
let messageCount = 0;
|
||||
let channelCount = 0;
|
||||
while (true) {
|
||||
const messageRefs = await this.deps.channelRepository.listMessagesByAuthor(
|
||||
const messageRefs = await this.deps.channelRepository.messages.listMessagesByAuthor(
|
||||
authorId,
|
||||
FETCH_CHUNK_SIZE,
|
||||
lastMessageId,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
type MessageID,
|
||||
type UserID,
|
||||
} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import {withThreadContext} from '@app/api/channel/services/ChannelGatewayDispatch';
|
||||
import {
|
||||
enqueueCrosspostFamilyPurgeFromCopies,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
messageResponseAccessForGuild,
|
||||
} from '@app/api/channel/services/message/MessageResponseDataService';
|
||||
import {resolveNsfwScopeChannel} from '@app/api/channel/utils/ThreadNsfwScope';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import {getPurgeQueue, getStorageService} from '@app/api/middleware/ServiceSingletons';
|
||||
import {getMessageSearchService} from '@app/api/SearchFactory';
|
||||
import {deleteMessageSearchDocuments} from '@app/api/search/MessageSearchIndexCleanup';
|
||||
@@ -44,8 +44,8 @@ import type {MessageResponse} from '@fluxer/schema/src/domains/message/MessageRe
|
||||
|
||||
interface AdminMessageServiceDeps {
|
||||
apiContext: ApiContext;
|
||||
channelRepository: IChannelRepository;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
channelRepository: ChannelRepository;
|
||||
guildRepository: GuildRepository;
|
||||
auditService: AdminAuditService;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ export class AdminMessageService {
|
||||
async lookupMessageByAttachment(data: LookupMessageByAttachmentRequest) {
|
||||
const channelId = createChannelID(data.channel_id);
|
||||
const attachmentId = createAttachmentID(data.attachment_id);
|
||||
const messageId = await this.deps.channelRepository.lookupAttachmentByChannelAndFilename(
|
||||
const messageId = await this.deps.channelRepository.messages.lookupAttachmentByChannelAndFilename(
|
||||
channelId,
|
||||
attachmentId,
|
||||
data.filename,
|
||||
@@ -113,11 +113,11 @@ export class AdminMessageService {
|
||||
const {gateway: gatewayService, worker: workerService} = this.deps.apiContext.services;
|
||||
const channelId = createChannelID(data.channel_id);
|
||||
const messageId = createMessageID(data.message_id);
|
||||
const channel = await channelRepository.findUnique(channelId);
|
||||
const message = await channelRepository.getMessage(channelId, messageId);
|
||||
const channel = await channelRepository.channelData.findUnique(channelId);
|
||||
const message = await channelRepository.messages.getMessage(channelId, messageId);
|
||||
if (message) {
|
||||
await purgeMessageAttachments(message, getStorageService(), getPurgeQueue());
|
||||
await channelRepository.deleteMessage(
|
||||
await channelRepository.messages.deleteMessage(
|
||||
channelId,
|
||||
messageId,
|
||||
message.authorId || createUserID(0n),
|
||||
@@ -227,7 +227,7 @@ export class AdminMessageService {
|
||||
}
|
||||
|
||||
private async getMessageResponseAccessForAdmin(channelId: ChannelID): Promise<MessageResponseAccessContext> {
|
||||
const channel = await this.deps.channelRepository.findUnique(channelId);
|
||||
const channel = await this.deps.channelRepository.channelData.findUnique(channelId);
|
||||
const access = channel ? messageResponseAccessForChannel(channel) : messageResponseAccessForGuild(null);
|
||||
return {...access, includeHidden: true};
|
||||
}
|
||||
@@ -283,7 +283,7 @@ export class AdminMessageService {
|
||||
|
||||
private async getChannelNsfwContext(channelId: ChannelID): Promise<ChannelNsfwContext> {
|
||||
const {channelRepository, guildRepository} = this.deps;
|
||||
const channel = await channelRepository.findUnique(channelId);
|
||||
const channel = await channelRepository.channelData.findUnique(channelId);
|
||||
if (!channel) {
|
||||
return {
|
||||
channelNsfw: null,
|
||||
@@ -304,7 +304,7 @@ export class AdminMessageService {
|
||||
}
|
||||
const [guild, scope] = await Promise.all([
|
||||
guildRepository.findUnique(channel.guildId),
|
||||
resolveNsfwScopeChannel(channel, (id) => channelRepository.findUnique(id)),
|
||||
resolveNsfwScopeChannel(channel, (id) => channelRepository.channelData.findUnique(id)),
|
||||
]);
|
||||
return {
|
||||
channelNsfw: scope.isNsfw,
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
type UserID,
|
||||
} from '@app/api/BrandedTypes';
|
||||
import {Config} from '@app/api/Config';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import {makeAttachmentCdnKey} from '@app/api/channel/services/message/MessageHelpers';
|
||||
import {
|
||||
createMessageResponseDataService,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
} from '@app/api/channel/services/message/MessageResponseDataService';
|
||||
import {resolveNsfwScopeChannel} from '@app/api/channel/utils/ThreadNsfwScope';
|
||||
import type {MessageAttachment} from '@app/api/database/types/MessageTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {IStorageService} from '@app/api/infrastructure/IStorageService';
|
||||
import type {UserCacheService} from '@app/api/infrastructure/UserCacheService';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
@@ -33,7 +33,7 @@ import type {RequestCache} from '@app/api/middleware/RequestCacheMiddleware';
|
||||
import {createRequestCache} from '@app/api/middleware/RequestCacheMiddleware';
|
||||
import {describeReportFlowAnswers} from '@app/api/report/flows/ReportFlowRegistry';
|
||||
import {findReportReason, listReportReasons} from '@app/api/report/flows/ReportReasonCatalog';
|
||||
import type {IARMessageContext, IARSubmission} from '@app/api/report/IReportRepository';
|
||||
import type {IARMessageContext, IARSubmission} from '@app/api/report/ReportModels';
|
||||
import type {ReportService} from '@app/api/report/ReportService';
|
||||
import {getReportSearchService} from '@app/api/SearchFactory';
|
||||
import {isHiddenPartial} from '@app/api/user/ProfileVisibility';
|
||||
@@ -57,8 +57,8 @@ import {seconds} from 'itty-time';
|
||||
interface AdminReportServiceDeps {
|
||||
apiContext: ApiContext;
|
||||
reportService: ReportService;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
channelRepository: IChannelRepository;
|
||||
guildRepository: GuildRepository;
|
||||
channelRepository: ChannelRepository;
|
||||
storageService: IStorageService;
|
||||
auditService: AdminAuditService;
|
||||
userCacheService: UserCacheService;
|
||||
@@ -541,7 +541,7 @@ export class AdminReportService {
|
||||
}
|
||||
|
||||
private async getMessageResponseAccessForAdmin(channelId: ChannelID): Promise<MessageResponseAccessContext> {
|
||||
const channel = await this.deps.channelRepository.findUnique(channelId);
|
||||
const channel = await this.deps.channelRepository.channelData.findUnique(channelId);
|
||||
const access = channel ? messageResponseAccessForChannel(channel) : messageResponseAccessForGuild(null);
|
||||
return {...access, includeHidden: true};
|
||||
}
|
||||
@@ -628,9 +628,9 @@ export class AdminReportService {
|
||||
if (reportLookupCache.channelNsfwByChannelId.has(channelIdString)) {
|
||||
return reportLookupCache.channelNsfwByChannelId.get(channelIdString) ?? null;
|
||||
}
|
||||
const channel = await this.deps.channelRepository.findUnique(channelId);
|
||||
const channel = await this.deps.channelRepository.channelData.findUnique(channelId);
|
||||
const scope = channel
|
||||
? await resolveNsfwScopeChannel(channel, (id) => this.deps.channelRepository.findUnique(id))
|
||||
? await resolveNsfwScopeChannel(channel, (id) => this.deps.channelRepository.channelData.findUnique(id))
|
||||
: null;
|
||||
const channelNsfw = scope?.isNsfw ?? null;
|
||||
reportLookupCache.channelNsfwByChannelId.set(channelIdString, channelNsfw);
|
||||
@@ -665,7 +665,7 @@ export class AdminReportService {
|
||||
if (!channelId) {
|
||||
return null;
|
||||
}
|
||||
const channel = await this.deps.channelRepository.findUnique(channelId);
|
||||
const channel = await this.deps.channelRepository.channelData.findUnique(channelId);
|
||||
if (!channel?.guildId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService'
|
||||
import {createGuildID, createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import {isSyntheticUserId} from '@app/api/constants/Core';
|
||||
import {channelThreadsEnabled} from '@app/api/experiment/ChannelThreadsGate';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import {getGuildSearchService, getUserSearchService} from '@app/api/SearchFactory';
|
||||
import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes';
|
||||
@@ -36,7 +36,7 @@ interface RefreshSearchIndexJobPayload extends WorkerJobPayload {
|
||||
|
||||
interface AdminSearchServiceDeps {
|
||||
apiContext: ApiContext;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
auditService: AdminAuditService;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import type {KVAccountDeletionQueueService} from '@app/api/infrastructure/KVAcco
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import type {User} from '@app/api/models/User';
|
||||
import type {OAuth2TokenRepository} from '@app/api/oauth/repositories/OAuth2TokenRepository';
|
||||
import {type IARSubmission, ReportStatus} from '@app/api/report/IReportRepository';
|
||||
import {type IARSubmission, ReportStatus} from '@app/api/report/ReportModels';
|
||||
import type {ReportService} from '@app/api/report/ReportService';
|
||||
import {getReportSearchService} from '@app/api/SearchFactory';
|
||||
import type {StoreEntitlementService} from '@app/api/store_billing/StoreEntitlementService';
|
||||
|
||||
@@ -5,7 +5,7 @@ import {mapUserToAdminResponse} from '@app/api/admin/models/UserTypes';
|
||||
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
|
||||
import type {AdminUserUpdatePropagator} from '@app/api/admin/services/AdminUserUpdatePropagator';
|
||||
import {createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import {GuildMemberSearchIndexService} from '@app/api/guild/services/member/GuildMemberSearchIndexService';
|
||||
import type {IDiscriminatorService} from '@app/api/infrastructure/DiscriminatorService';
|
||||
import type {EntityAssetService, PreparedAssetUpload} from '@app/api/infrastructure/EntityAssetService';
|
||||
@@ -37,7 +37,7 @@ interface AdminUserProfileServiceDeps {
|
||||
entityAssetService: EntityAssetService;
|
||||
auditService: AdminAuditService;
|
||||
updatePropagator: AdminUserUpdatePropagator;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
}
|
||||
|
||||
export class AdminUserProfileService {
|
||||
|
||||
@@ -12,8 +12,8 @@ import {AdminUserSecurityService} from '@app/api/admin/services/AdminUserSecurit
|
||||
import {AdminUserUpdatePropagator} from '@app/api/admin/services/AdminUserUpdatePropagator';
|
||||
import {ReporterResolutionNotifier} from '@app/api/admin/services/ReporterResolutionNotifier';
|
||||
import {createChannelID, createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {IDiscriminatorService} from '@app/api/infrastructure/DiscriminatorService';
|
||||
import type {EntityAssetService} from '@app/api/infrastructure/EntityAssetService';
|
||||
import type {KVAccountDeletionQueueService} from '@app/api/infrastructure/KVAccountDeletionQueueService';
|
||||
@@ -23,7 +23,7 @@ import {getBillingRepository} from '@app/api/middleware/ServiceRegistry';
|
||||
import {OAuth2TokenRepository} from '@app/api/oauth/repositories/OAuth2TokenRepository';
|
||||
import type {ReportService} from '@app/api/report/ReportService';
|
||||
import type {StoreEntitlementService} from '@app/api/store_billing/StoreEntitlementService';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import type {UserContactChangeLogService} from '@app/api/user/services/UserContactChangeLogService';
|
||||
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
|
||||
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
|
||||
@@ -38,8 +38,8 @@ import type Stripe from 'stripe';
|
||||
|
||||
interface AdminUserServiceDeps {
|
||||
apiContext: ApiContext;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
channelRepository: IChannelRepository;
|
||||
guildRepository: GuildRepository;
|
||||
channelRepository: ChannelRepository;
|
||||
discriminatorService: IDiscriminatorService;
|
||||
entityAssetService: EntityAssetService;
|
||||
auditService: AdminAuditService;
|
||||
@@ -62,9 +62,9 @@ export class AdminUserService {
|
||||
private readonly updatePropagator: AdminUserUpdatePropagator;
|
||||
private readonly contactChangeLogService: UserContactChangeLogService;
|
||||
private readonly auditService: AdminAuditService;
|
||||
private readonly userRepository: IUserRepository;
|
||||
private readonly guildRepository: IGuildRepositoryAggregate;
|
||||
private readonly channelRepository: IChannelRepository;
|
||||
private readonly userRepository: UserRepository;
|
||||
private readonly guildRepository: GuildRepository;
|
||||
private readonly channelRepository: ChannelRepository;
|
||||
private readonly bulkMessageDeletionQueue: KVBulkMessageDeletionQueueService;
|
||||
private readonly cacheService: ICacheService;
|
||||
|
||||
@@ -132,7 +132,9 @@ export class AdminUserService {
|
||||
beforeChannelId: data.before ? createChannelID(data.before) : undefined,
|
||||
afterChannelId: data.after ? createChannelID(data.after) : undefined,
|
||||
});
|
||||
const channelModels = await this.channelRepository.listChannels(channels.map((channel) => channel.channelId));
|
||||
const channelModels = await this.channelRepository.channelData.listChannels(
|
||||
channels.map((channel) => channel.channelId),
|
||||
);
|
||||
const channelModelById = new Map(
|
||||
channelModels.filter((c): c is NonNullable<typeof c> => c != null).map((c) => [c.id, c]),
|
||||
);
|
||||
@@ -234,7 +236,9 @@ export class AdminUserService {
|
||||
if (groupDmSummaries.length === 0) {
|
||||
return {channels: []};
|
||||
}
|
||||
const channelModels = await this.channelRepository.listChannels(groupDmSummaries.map((s) => s.channelId));
|
||||
const channelModels = await this.channelRepository.channelData.listChannels(
|
||||
groupDmSummaries.map((s) => s.channelId),
|
||||
);
|
||||
const allUserIds = new Set<UserID>();
|
||||
for (const model of channelModels) {
|
||||
if (model) {
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {UserID} from '@app/api/BrandedTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
import type {UserCacheService} from '@app/api/infrastructure/UserCacheService';
|
||||
import type {User} from '@app/api/models/User';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import {BaseUserUpdatePropagator} from '@app/api/user/services/BaseUserUpdatePropagator';
|
||||
import {propagatePartialUserChange} from '@app/api/user/services/PartialUserChangePropagation';
|
||||
import {hasPartialUserFieldsChanged} from '@app/api/user/UserMappers';
|
||||
|
||||
interface AdminUserUpdatePropagatorDeps {
|
||||
userCacheService: UserCacheService;
|
||||
userRepository: IUserRepository;
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
userRepository: UserRepository;
|
||||
guildRepository: GuildRepository;
|
||||
gatewayService: IGatewayService;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import {getInstanceProductName} from '@app/api/instance/ProductName';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import {createRequestCache} from '@app/api/middleware/RequestCacheMiddleware';
|
||||
import type {User} from '@app/api/models/User';
|
||||
import type {IARSubmission} from '@app/api/report/IReportRepository';
|
||||
import type {IARSubmission} from '@app/api/report/ReportModels';
|
||||
import type {UserChannelService} from '@app/api/user/services/UserChannelService';
|
||||
import {UserFlags} from '@fluxer/constants/src/UserConstants';
|
||||
import {getEmailTemplate} from '@pkgs/email/src/email_i18n/EmailI18n';
|
||||
|
||||
@@ -4,11 +4,11 @@ import {mapGuildsToAdminResponse} from '@app/api/admin/models/GuildTypes';
|
||||
import type {GuildID} from '@app/api/BrandedTypes';
|
||||
import {createGuildID, createUserID} from '@app/api/BrandedTypes';
|
||||
import {Config} from '@app/api/Config';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import {mapGuildFeatures} from '@app/api/guild/GuildFeatureUtils';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import {MEDIA_PROXY_ICON_SIZE_DEFAULT} from '@fluxer/constants/src/MediaProxyAssetSizes';
|
||||
import type {MediaProxyImageSize} from '@fluxer/constants/src/MediaProxyImageSizes';
|
||||
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
|
||||
@@ -22,9 +22,9 @@ import type {ListGuildEmojisResponse, ListGuildStickersResponse} from '@fluxer/s
|
||||
const ADMIN_STICKER_MEDIA_RUNG: MediaProxyImageSize = 320;
|
||||
|
||||
interface AdminGuildLookupServiceDeps {
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
userRepository: IUserRepository;
|
||||
channelRepository: IChannelRepository;
|
||||
guildRepository: GuildRepository;
|
||||
userRepository: UserRepository;
|
||||
channelRepository: ChannelRepository;
|
||||
gatewayService: IGatewayService;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export class AdminGuildLookupService {
|
||||
return {guild: null};
|
||||
}
|
||||
const [channels, roles, ownerUser] = await Promise.all([
|
||||
channelRepository.listGuildChannels(guildId, 'maintenance'),
|
||||
channelRepository.channelData.listGuildChannels(guildId, 'maintenance'),
|
||||
guildRepository.listRoles(guildId),
|
||||
userRepository.findUnique(guild.ownerId),
|
||||
]);
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService';
|
||||
import {createGuildID, type GuildID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {GuildService} from '@app/api/guild/services/GuildService';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
|
||||
import type {SuccessResponse} from '@fluxer/schema/src/domains/common/CommonParamSchemas';
|
||||
|
||||
interface AdminGuildManagementServiceDeps {
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
gatewayService: IGatewayService;
|
||||
guildService: GuildService;
|
||||
auditService: AdminAuditService;
|
||||
@@ -63,7 +63,7 @@ export class AdminGuildManagementService {
|
||||
async deleteGuild(guildIdRaw: bigint, adminUserId: UserID, auditLogReason: string | null): Promise<SuccessResponse> {
|
||||
const {guildService, auditService} = this.deps;
|
||||
const guildId = createGuildID(guildIdRaw);
|
||||
await guildService.data.deleteGuildForAdmin(guildId, auditLogReason);
|
||||
await guildService.data.operations.deleteGuildById(guildId);
|
||||
await auditService.createAuditLog({
|
||||
adminUserId,
|
||||
targetType: 'guild',
|
||||
|
||||
@@ -4,7 +4,7 @@ import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService'
|
||||
import {createGuildID, createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {GuildService} from '@app/api/guild/services/GuildService';
|
||||
import type {RequestCache} from '@app/api/middleware/RequestCacheMiddleware';
|
||||
import type {IUserRepository} from '@app/api/user/IUserRepository';
|
||||
import type {UserRepository} from '@app/api/user/repositories/UserRepository';
|
||||
import {JoinSourceTypes} from '@fluxer/constants/src/GuildConstants';
|
||||
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
|
||||
import type {
|
||||
@@ -15,7 +15,7 @@ import type {
|
||||
import type {SuccessResponse} from '@fluxer/schema/src/domains/common/CommonParamSchemas';
|
||||
|
||||
interface AdminGuildMembershipServiceDeps {
|
||||
userRepository: IUserRepository;
|
||||
userRepository: UserRepository;
|
||||
guildService: GuildService;
|
||||
auditService: AdminAuditService;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import type {GuildID, UserID} from '@app/api/BrandedTypes';
|
||||
import {mapGuildToGuildResponse} from '@app/api/guild/GuildModel';
|
||||
import type {IGuildDiscoveryRepository} from '@app/api/guild/repositories/GuildDiscoveryRepository';
|
||||
import type {GuildDiscoveryRepository} from '@app/api/guild/repositories/GuildDiscoveryRepository';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import type {Guild} from '@app/api/models/Guild';
|
||||
@@ -13,7 +13,7 @@ import {GuildFeatures} from '@fluxer/constants/src/GuildConstants';
|
||||
|
||||
interface AdminGuildUpdatePropagatorDeps {
|
||||
gatewayService: IGatewayService;
|
||||
discoveryRepository: IGuildDiscoveryRepository;
|
||||
discoveryRepository: GuildDiscoveryRepository;
|
||||
}
|
||||
|
||||
interface AdminGuildUpdateDispatchOptions {
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {AdminAuditService} from '@app/api/admin/services/AdminAuditService'
|
||||
import type {AdminGuildUpdatePropagator} from '@app/api/admin/services/guild/AdminGuildUpdatePropagator';
|
||||
import {createGuildID, createUserID, type GuildID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {GuildRow} from '@app/api/database/types/GuildTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {EntityAssetService, PreparedAssetUpload} from '@app/api/infrastructure/EntityAssetService';
|
||||
import {Logger} from '@app/api/Logger';
|
||||
import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildError';
|
||||
@@ -17,7 +17,7 @@ import type {
|
||||
} from '@fluxer/schema/src/domains/admin/AdminGuildSchemas';
|
||||
|
||||
interface AdminGuildUpdateServiceDeps {
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
entityAssetService: EntityAssetService;
|
||||
auditService: AdminAuditService;
|
||||
updatePropagator: AdminGuildUpdatePropagator;
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
type UserID,
|
||||
vanityCodeToInviteCode,
|
||||
} from '@app/api/BrandedTypes';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import type {InviteRepository} from '@app/api/invite/InviteRepository';
|
||||
import {InviteTypes} from '@fluxer/constants/src/ChannelConstants';
|
||||
import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes';
|
||||
@@ -19,7 +19,7 @@ import {UnknownGuildError} from '@fluxer/errors/src/domains/guild/UnknownGuildEr
|
||||
import type {UpdateGuildVanityRequest} from '@fluxer/schema/src/domains/admin/AdminGuildSchemas';
|
||||
|
||||
interface AdminGuildVanityServiceDeps {
|
||||
guildRepository: IGuildRepositoryAggregate;
|
||||
guildRepository: GuildRepository;
|
||||
inviteRepository: InviteRepository;
|
||||
auditService: AdminAuditService;
|
||||
updatePropagator: AdminGuildUpdatePropagator;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {AdminAuditLog} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminAuditLog} from '@app/api/admin/AdminRepository';
|
||||
import {createTestAccount, setUserACLs, type TestAccount} from '@app/api/auth/tests/AuthTestUtils';
|
||||
import {decodeHeaderUtf8} from '@app/api/middleware/AuditLogMiddleware';
|
||||
import {getAdminRepository} from '@app/api/middleware/ServiceSingletons';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {AdminRepository} from '@app/api/admin/AdminRepository';
|
||||
import type {AdminAuditLog} from '@app/api/admin/IAdminRepository';
|
||||
import {type AdminAuditLog, AdminRepository} from '@app/api/admin/AdminRepository';
|
||||
import {createTestAccount, setUserACLs, type TestAccount} from '@app/api/auth/tests/AuthTestUtils';
|
||||
import {ipBanCache} from '@app/api/middleware/IpBanMiddleware';
|
||||
import {getAdminRepository} from '@app/api/middleware/ServiceSingletons';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {AdminAuditLog} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminAuditLog} from '@app/api/admin/AdminRepository';
|
||||
import {createTestAccount, setUserACLs, type TestAccount} from '@app/api/auth/tests/AuthTestUtils';
|
||||
import {
|
||||
createAttachmentID,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {createGuildID, createUserID, type UserID} from '@app/api/BrandedTypes';
|
||||
import type {IChannelRepository} from '@app/api/channel/IChannelRepository';
|
||||
import type {ChannelRepository} from '@app/api/channel/ChannelRepository';
|
||||
import type {CrosspostWorkerService} from '@app/api/channel/services/message/CrosspostPropagation';
|
||||
import {UserMessageDeletionService} from '@app/api/channel/services/message/UserMessageDeletionService';
|
||||
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
|
||||
import type {GuildRepository} from '@app/api/guild/repositories/GuildRepository';
|
||||
import {GuildMemberOperationsService} from '@app/api/guild/services/member/GuildMemberOperationsService';
|
||||
import type {IPurgeQueue} from '@app/api/infrastructure/CachePurgeQueue';
|
||||
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
|
||||
@@ -34,7 +34,7 @@ function unusableDependency(): object {
|
||||
function createMessageDeletionService(): UserMessageDeletionService {
|
||||
const unusable = unusableDependency();
|
||||
return new UserMessageDeletionService({
|
||||
channelRepository: unusable as IChannelRepository,
|
||||
channelRepository: unusable as ChannelRepository,
|
||||
gatewayService: unusable as IGatewayService,
|
||||
storageService: unusable as IStorageService,
|
||||
purgeQueue: unusable as IPurgeQueue,
|
||||
@@ -50,7 +50,7 @@ function createGuildMemberOperationsService(): GuildMemberOperationsService {
|
||||
async getMember() {
|
||||
return null;
|
||||
},
|
||||
} as unknown as IGuildRepositoryAggregate;
|
||||
} as unknown as GuildRepository;
|
||||
const unusable = unusableDependency();
|
||||
return new GuildMemberOperationsService(
|
||||
guildRepository,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {AdminAuditLog} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminAuditLog} from '@app/api/admin/AdminRepository';
|
||||
import type {TestAccount} from '@app/api/auth/tests/AuthTestUtils';
|
||||
import {createTestAccount, setUserACLs} from '@app/api/auth/tests/AuthTestUtils';
|
||||
import {setCassandraQueryExecutorForTesting} from '@app/api/database/CassandraQueryExecution';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {getAdminAuditAccess} from '@app/api/admin/AdminAuditActions';
|
||||
import type {AdminAuditLog} from '@app/api/admin/IAdminRepository';
|
||||
import type {AdminAuditLog} from '@app/api/admin/AdminRepository';
|
||||
import {createTestAccount, setUserACLs, type TestAccount} from '@app/api/auth/tests/AuthTestUtils';
|
||||
import {getAdminRepository} from '@app/api/middleware/ServiceSingletons';
|
||||
import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness';
|
||||
|
||||
Reference in new issue
Block a user