diff --git a/packages/backend/src/core/ProxyAccountService.ts b/packages/backend/src/core/ProxyAccountService.ts index c3ff2a68d3..f776d72405 100644 --- a/packages/backend/src/core/ProxyAccountService.ts +++ b/packages/backend/src/core/ProxyAccountService.ts @@ -4,25 +4,54 @@ */ import { Inject, Injectable } from '@nestjs/common'; +import { IsNull } from 'typeorm'; import type { MiMeta, UsersRepository } from '@/models/_.js'; import type { MiLocalUser } from '@/models/User.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; +import { CreateSystemUserService } from '@/core/CreateSystemUserService.js'; +import { MemorySingleCache } from '@/misc/cache.js'; +import { MetaService } from '@/core/MetaService.js'; + +const ACTOR_USERNAME = 'proxy.actor' as const; @Injectable() export class ProxyAccountService { + private cache: MemorySingleCache; + constructor( @Inject(DI.meta) private meta: MiMeta, @Inject(DI.usersRepository) private usersRepository: UsersRepository, + + private createSystemUserService: CreateSystemUserService, + private metaService: MetaService, ) { + this.cache = new MemorySingleCache(Infinity); } @bindThis public async fetch(): Promise { - if (this.meta.proxyAccountId == null) return null; - return await this.usersRepository.findOneByOrFail({ id: this.meta.proxyAccountId }) as MiLocalUser; + const cached = this.cache.get(); + if (cached) return cached; + + const user = await this.usersRepository.findOneBy({ + host: IsNull(), + username: ACTOR_USERNAME, + }) as MiLocalUser | undefined; + + if (user) { + this.cache.set(user); + return user; + } else { + const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME) as MiLocalUser; + this.cache.set(created); + const set = {} as Partial; + set.proxyAccountId = created.id; + await this.metaService.update(set); + return created; + } } }