wip
This commit is contained in:
parent
77e4feb507
commit
75c268cdfa
|
@ -8,7 +8,7 @@ import { IsNull, In, MoreThan, Not } from 'typeorm';
|
||||||
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { LocalUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js';
|
import type { BlockingsRepository, FollowingsRepository, InstancesRepository, MutingsRepository, UserListJoiningsRepository, UsersRepository } from '@/models/index.js';
|
||||||
import type { RelationshipJobData, ThinUser } from '@/queue/types.js';
|
import type { RelationshipJobData, ThinUser } from '@/queue/types.js';
|
||||||
|
|
||||||
|
@ -71,12 +71,12 @@ export class AccountMoveService {
|
||||||
* After delivering Move activity, its local followers unfollow the old account and then follow the new one.
|
* After delivering Move activity, its local followers unfollow the old account and then follow the new one.
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async moveFromLocal(src: LocalUser, dst: LocalUser | RemoteUser): Promise<unknown> {
|
public async moveFromLocal(src: MiLocalUser, dst: MiLocalUser | MiRemoteUser): Promise<unknown> {
|
||||||
const srcUri = this.userEntityService.getUserUri(src);
|
const srcUri = this.userEntityService.getUserUri(src);
|
||||||
const dstUri = this.userEntityService.getUserUri(dst);
|
const dstUri = this.userEntityService.getUserUri(dst);
|
||||||
|
|
||||||
// add movedToUri to indicate that the user has moved
|
// add movedToUri to indicate that the user has moved
|
||||||
const update = {} as Partial<LocalUser>;
|
const update = {} as Partial<MiLocalUser>;
|
||||||
update.alsoKnownAs = src.alsoKnownAs?.includes(dstUri) ? src.alsoKnownAs : src.alsoKnownAs?.concat([dstUri]) ?? [dstUri];
|
update.alsoKnownAs = src.alsoKnownAs?.includes(dstUri) ? src.alsoKnownAs : src.alsoKnownAs?.concat([dstUri]) ?? [dstUri];
|
||||||
update.movedToUri = dstUri;
|
update.movedToUri = dstUri;
|
||||||
update.movedAt = new Date();
|
update.movedAt = new Date();
|
||||||
|
@ -301,11 +301,11 @@ export class AccountMoveService {
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async validateAlsoKnownAs(
|
public async validateAlsoKnownAs(
|
||||||
dst: LocalUser | RemoteUser,
|
dst: MiLocalUser | MiRemoteUser,
|
||||||
check: (oldUser: LocalUser | RemoteUser | null, newUser: LocalUser | RemoteUser) => boolean | Promise<boolean> = () => true,
|
check: (oldUser: MiLocalUser | MiRemoteUser | null, newUser: MiLocalUser | MiRemoteUser) => boolean | Promise<boolean> = () => true,
|
||||||
instant = false,
|
instant = false,
|
||||||
): Promise<LocalUser | RemoteUser | null> {
|
): Promise<MiLocalUser | MiRemoteUser | null> {
|
||||||
let resultUser: LocalUser | RemoteUser | null = null;
|
let resultUser: MiLocalUser | MiRemoteUser | null = null;
|
||||||
|
|
||||||
if (this.userEntityService.isRemoteUser(dst)) {
|
if (this.userEntityService.isRemoteUser(dst)) {
|
||||||
if ((new Date()).getTime() - (dst.lastFetchedAt?.getTime() ?? 0) > 10 * 1000) {
|
if ((new Date()).getTime() - (dst.lastFetchedAt?.getTime() ?? 0) > 10 * 1000) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import type { BlockingsRepository, ChannelFollowingsRepository, FollowingsRepository, MutingsRepository, RenoteMutingsRepository, UserProfile, UserProfilesRepository, UsersRepository } from '@/models/index.js';
|
import type { BlockingsRepository, ChannelFollowingsRepository, FollowingsRepository, MutingsRepository, RenoteMutingsRepository, UserProfile, UserProfilesRepository, UsersRepository } from '@/models/index.js';
|
||||||
import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js';
|
import { MemoryKVCache, RedisKVCache } from '@/misc/cache.js';
|
||||||
import type { LocalUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -17,8 +17,8 @@ import type { OnApplicationShutdown } from '@nestjs/common';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CacheService implements OnApplicationShutdown {
|
export class CacheService implements OnApplicationShutdown {
|
||||||
public userByIdCache: MemoryKVCache<MiUser, MiUser | string>;
|
public userByIdCache: MemoryKVCache<MiUser, MiUser | string>;
|
||||||
public localUserByNativeTokenCache: MemoryKVCache<LocalUser | null, string | null>;
|
public localUserByNativeTokenCache: MemoryKVCache<MiLocalUser | null, string | null>;
|
||||||
public localUserByIdCache: MemoryKVCache<LocalUser>;
|
public localUserByIdCache: MemoryKVCache<MiLocalUser>;
|
||||||
public uriPersonCache: MemoryKVCache<MiUser | null, string | null>;
|
public uriPersonCache: MemoryKVCache<MiUser | null, string | null>;
|
||||||
public userProfileCache: RedisKVCache<UserProfile>;
|
public userProfileCache: RedisKVCache<UserProfile>;
|
||||||
public userMutingsCache: RedisKVCache<Set<string>>;
|
public userMutingsCache: RedisKVCache<Set<string>>;
|
||||||
|
@ -60,14 +60,14 @@ export class CacheService implements OnApplicationShutdown {
|
||||||
) {
|
) {
|
||||||
//this.onMessage = this.onMessage.bind(this);
|
//this.onMessage = this.onMessage.bind(this);
|
||||||
|
|
||||||
const localUserByIdCache = new MemoryKVCache<LocalUser>(1000 * 60 * 60 * 6 /* 6h */);
|
const localUserByIdCache = new MemoryKVCache<MiLocalUser>(1000 * 60 * 60 * 6 /* 6h */);
|
||||||
this.localUserByIdCache = localUserByIdCache;
|
this.localUserByIdCache = localUserByIdCache;
|
||||||
|
|
||||||
// ローカルユーザーならlocalUserByIdCacheにデータを追加し、こちらにはid(文字列)だけを追加する
|
// ローカルユーザーならlocalUserByIdCacheにデータを追加し、こちらにはid(文字列)だけを追加する
|
||||||
const userByIdCache = new MemoryKVCache<MiUser, MiUser | string>(1000 * 60 * 60 * 6 /* 6h */, {
|
const userByIdCache = new MemoryKVCache<MiUser, MiUser | string>(1000 * 60 * 60 * 6 /* 6h */, {
|
||||||
toMapConverter: user => {
|
toMapConverter: user => {
|
||||||
if (user.host === null) {
|
if (user.host === null) {
|
||||||
localUserByIdCache.set(user.id, user as LocalUser);
|
localUserByIdCache.set(user.id, user as MiLocalUser);
|
||||||
return user.id;
|
return user.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ export class CacheService implements OnApplicationShutdown {
|
||||||
});
|
});
|
||||||
this.userByIdCache = userByIdCache;
|
this.userByIdCache = userByIdCache;
|
||||||
|
|
||||||
this.localUserByNativeTokenCache = new MemoryKVCache<LocalUser | null, string | null>(Infinity, {
|
this.localUserByNativeTokenCache = new MemoryKVCache<MiLocalUser | null, string | null>(Infinity, {
|
||||||
toMapConverter: user => {
|
toMapConverter: user => {
|
||||||
if (user === null) return null;
|
if (user === null) return null;
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ export class CacheService implements OnApplicationShutdown {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'userTokenRegenerated': {
|
case 'userTokenRegenerated': {
|
||||||
const user = await this.usersRepository.findOneByOrFail({ id: body.id }) as LocalUser;
|
const user = await this.usersRepository.findOneByOrFail({ id: body.id }) as MiLocalUser;
|
||||||
this.localUserByNativeTokenCache.delete(body.oldToken);
|
this.localUserByNativeTokenCache.delete(body.oldToken);
|
||||||
this.localUserByNativeTokenCache.set(body.newToken, user);
|
this.localUserByNativeTokenCache.set(body.newToken, user);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { DI } from '@/di-symbols.js';
|
||||||
import type { DriveFilesRepository, UsersRepository, DriveFoldersRepository, UserProfilesRepository } from '@/models/index.js';
|
import type { DriveFilesRepository, UsersRepository, DriveFoldersRepository, UserProfilesRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import Logger from '@/logger.js';
|
import Logger from '@/logger.js';
|
||||||
import type { RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { MiDriveFile } from '@/models/entities/DriveFile.js';
|
import { MiDriveFile } from '@/models/entities/DriveFile.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
|
@ -405,7 +405,7 @@ export class DriveService {
|
||||||
|
|
||||||
// Expire oldest file (without avatar or banner) of remote user
|
// Expire oldest file (without avatar or banner) of remote user
|
||||||
@bindThis
|
@bindThis
|
||||||
private async expireOldFile(user: RemoteUser, driveCapacity: number) {
|
private async expireOldFile(user: MiRemoteUser, driveCapacity: number) {
|
||||||
const q = this.driveFilesRepository.createQueryBuilder('file')
|
const q = this.driveFilesRepository.createQueryBuilder('file')
|
||||||
.where('file.userId = :userId', { userId: user.id })
|
.where('file.userId = :userId', { userId: user.id })
|
||||||
.andWhere('file.isLink = FALSE');
|
.andWhere('file.isLink = FALSE');
|
||||||
|
@ -520,7 +520,7 @@ export class DriveService {
|
||||||
if (isLocalUser) {
|
if (isLocalUser) {
|
||||||
throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.');
|
throw new IdentifiableError('c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6', 'No free space.');
|
||||||
}
|
}
|
||||||
await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as RemoteUser, driveCapacity - info.size);
|
await this.expireOldFile(await this.usersRepository.findOneByOrFail({ id: user.id }) as MiRemoteUser, driveCapacity - info.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { IsNull } from 'typeorm';
|
import { IsNull } from 'typeorm';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import type { UsersRepository } from '@/models/index.js';
|
import type { UsersRepository } from '@/models/index.js';
|
||||||
import { MemorySingleCache } from '@/misc/cache.js';
|
import { MemorySingleCache } from '@/misc/cache.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
@ -16,7 +16,7 @@ const ACTOR_USERNAME = 'instance.actor' as const;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class InstanceActorService {
|
export class InstanceActorService {
|
||||||
private cache: MemorySingleCache<LocalUser>;
|
private cache: MemorySingleCache<MiLocalUser>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.usersRepository)
|
@Inject(DI.usersRepository)
|
||||||
|
@ -24,24 +24,24 @@ export class InstanceActorService {
|
||||||
|
|
||||||
private createSystemUserService: CreateSystemUserService,
|
private createSystemUserService: CreateSystemUserService,
|
||||||
) {
|
) {
|
||||||
this.cache = new MemorySingleCache<LocalUser>(Infinity);
|
this.cache = new MemorySingleCache<MiLocalUser>(Infinity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async getInstanceActor(): Promise<LocalUser> {
|
public async getInstanceActor(): Promise<MiLocalUser> {
|
||||||
const cached = this.cache.get();
|
const cached = this.cache.get();
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({
|
const user = await this.usersRepository.findOneBy({
|
||||||
host: IsNull(),
|
host: IsNull(),
|
||||||
username: ACTOR_USERNAME,
|
username: ACTOR_USERNAME,
|
||||||
}) as LocalUser | undefined;
|
}) as MiLocalUser | undefined;
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
this.cache.set(user);
|
this.cache.set(user);
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME) as LocalUser;
|
const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME) as MiLocalUser;
|
||||||
this.cache.set(created);
|
this.cache.set(created);
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import type { MiDriveFile } from '@/models/entities/DriveFile.js';
|
||||||
import type { MiApp } from '@/models/entities/App.js';
|
import type { MiApp } from '@/models/entities/App.js';
|
||||||
import { concat } from '@/misc/prelude/array.js';
|
import { concat } from '@/misc/prelude/array.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import type { MiUser, LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import type { IPoll } from '@/models/entities/Poll.js';
|
import type { IPoll } from '@/models/entities/Poll.js';
|
||||||
import { MiPoll } from '@/models/entities/Poll.js';
|
import { MiPoll } from '@/models/entities/Poll.js';
|
||||||
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
||||||
|
@ -62,7 +62,7 @@ class NotificationManager {
|
||||||
private notifier: { id: MiUser['id']; };
|
private notifier: { id: MiUser['id']; };
|
||||||
private note: MiNote;
|
private note: MiNote;
|
||||||
private queue: {
|
private queue: {
|
||||||
target: LocalUser['id'];
|
target: MiLocalUser['id'];
|
||||||
reason: NotificationType;
|
reason: NotificationType;
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class NotificationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public push(notifiee: LocalUser['id'], reason: NotificationType) {
|
public push(notifiee: MiLocalUser['id'], reason: NotificationType) {
|
||||||
// 自分自身へは通知しない
|
// 自分自身へは通知しない
|
||||||
if (this.notifier.id === notifiee) return;
|
if (this.notifier.id === notifiee) return;
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
// メンションされたリモートユーザーに配送
|
// メンションされたリモートユーザーに配送
|
||||||
for (const u of mentionedUsers.filter(u => this.userEntityService.isRemoteUser(u))) {
|
for (const u of mentionedUsers.filter(u => this.userEntityService.isRemoteUser(u))) {
|
||||||
dm.addDirectRecipe(u as RemoteUser);
|
dm.addDirectRecipe(u as MiRemoteUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送
|
// 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { Brackets, In } from 'typeorm';
|
import { Brackets, In } from 'typeorm';
|
||||||
import { Injectable, Inject } from '@nestjs/common';
|
import { Injectable, Inject } from '@nestjs/common';
|
||||||
import type { MiUser, LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import type { MiNote, IMentionedRemoteUsers } from '@/models/entities/Note.js';
|
import type { MiNote, IMentionedRemoteUsers } from '@/models/entities/Note.js';
|
||||||
import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/index.js';
|
import type { InstancesRepository, NotesRepository, UsersRepository } from '@/models/index.js';
|
||||||
import { RelayService } from '@/core/RelayService.js';
|
import { RelayService } from '@/core/RelayService.js';
|
||||||
|
@ -179,11 +179,11 @@ export class NoteDeleteService {
|
||||||
|
|
||||||
return await this.usersRepository.find({
|
return await this.usersRepository.find({
|
||||||
where,
|
where,
|
||||||
}) as RemoteUser[];
|
}) as MiRemoteUser[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async deliverToConcerned(user: { id: LocalUser['id']; host: null; }, note: MiNote, content: any) {
|
private async deliverToConcerned(user: { id: MiLocalUser['id']; host: null; }, note: MiNote, content: any) {
|
||||||
this.apDeliverManagerService.deliverToFollowers(user, content);
|
this.apDeliverManagerService.deliverToFollowers(user, content);
|
||||||
this.relayService.deliverToRelays(user, content);
|
this.relayService.deliverToRelays(user, content);
|
||||||
const remoteUsers = await this.getMentionedRemoteUsers(note);
|
const remoteUsers = await this.getMentionedRemoteUsers(note);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { UsersRepository } from '@/models/index.js';
|
import type { UsersRepository } from '@/models/index.js';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -21,9 +21,9 @@ export class ProxyAccountService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async fetch(): Promise<LocalUser | null> {
|
public async fetch(): Promise<MiLocalUser | null> {
|
||||||
const meta = await this.metaService.fetch();
|
const meta = await this.metaService.fetch();
|
||||||
if (meta.proxyAccountId == null) return null;
|
if (meta.proxyAccountId == null) return null;
|
||||||
return await this.usersRepository.findOneByOrFail({ id: meta.proxyAccountId }) as LocalUser;
|
return await this.usersRepository.findOneByOrFail({ id: meta.proxyAccountId }) as MiLocalUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { EmojisRepository, NoteReactionsRepository, UsersRepository, NotesRepository } from '@/models/index.js';
|
import type { EmojisRepository, NoteReactionsRepository, UsersRepository, NotesRepository } from '@/models/index.js';
|
||||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import type { RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import type { MiNote } from '@/models/entities/Note.js';
|
import type { MiNote } from '@/models/entities/Note.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import type { MiNoteReaction } from '@/models/entities/NoteReaction.js';
|
import type { MiNoteReaction } from '@/models/entities/NoteReaction.js';
|
||||||
|
@ -231,7 +231,7 @@ export class ReactionService {
|
||||||
const dm = this.apDeliverManagerService.createDeliverManager(user, content);
|
const dm = this.apDeliverManagerService.createDeliverManager(user, content);
|
||||||
if (note.userHost !== null) {
|
if (note.userHost !== null) {
|
||||||
const reactee = await this.usersRepository.findOneBy({ id: note.userId });
|
const reactee = await this.usersRepository.findOneBy({ id: note.userId });
|
||||||
dm.addDirectRecipe(reactee as RemoteUser);
|
dm.addDirectRecipe(reactee as MiRemoteUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['public', 'home', 'followers'].includes(note.visibility)) {
|
if (['public', 'home', 'followers'].includes(note.visibility)) {
|
||||||
|
@ -239,7 +239,7 @@ export class ReactionService {
|
||||||
} else if (note.visibility === 'specified') {
|
} else if (note.visibility === 'specified') {
|
||||||
const visibleUsers = await Promise.all(note.visibleUserIds.map(id => this.usersRepository.findOneBy({ id })));
|
const visibleUsers = await Promise.all(note.visibleUserIds.map(id => this.usersRepository.findOneBy({ id })));
|
||||||
for (const u of visibleUsers.filter(u => u && this.userEntityService.isRemoteUser(u))) {
|
for (const u of visibleUsers.filter(u => u && this.userEntityService.isRemoteUser(u))) {
|
||||||
dm.addDirectRecipe(u as RemoteUser);
|
dm.addDirectRecipe(u as MiRemoteUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ export class ReactionService {
|
||||||
const dm = this.apDeliverManagerService.createDeliverManager(user, content);
|
const dm = this.apDeliverManagerService.createDeliverManager(user, content);
|
||||||
if (note.userHost !== null) {
|
if (note.userHost !== null) {
|
||||||
const reactee = await this.usersRepository.findOneBy({ id: note.userId });
|
const reactee = await this.usersRepository.findOneBy({ id: note.userId });
|
||||||
dm.addDirectRecipe(reactee as RemoteUser);
|
dm.addDirectRecipe(reactee as MiRemoteUser);
|
||||||
}
|
}
|
||||||
dm.addFollowersRecipe();
|
dm.addFollowersRecipe();
|
||||||
dm.execute();
|
dm.execute();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { IsNull } from 'typeorm';
|
import { IsNull } from 'typeorm';
|
||||||
import type { LocalUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiUser } from '@/models/entities/User.js';
|
||||||
import type { RelaysRepository, UsersRepository } from '@/models/index.js';
|
import type { RelaysRepository, UsersRepository } from '@/models/index.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { MemorySingleCache } from '@/misc/cache.js';
|
import { MemorySingleCache } from '@/misc/cache.js';
|
||||||
|
@ -39,16 +39,16 @@ export class RelayService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async getRelayActor(): Promise<LocalUser> {
|
private async getRelayActor(): Promise<MiLocalUser> {
|
||||||
const user = await this.usersRepository.findOneBy({
|
const user = await this.usersRepository.findOneBy({
|
||||||
host: IsNull(),
|
host: IsNull(),
|
||||||
username: ACTOR_USERNAME,
|
username: ACTOR_USERNAME,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user) return user as LocalUser;
|
if (user) return user as MiLocalUser;
|
||||||
|
|
||||||
const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME);
|
const created = await this.createSystemUserService.createSystemUser(ACTOR_USERNAME);
|
||||||
return created as LocalUser;
|
return created as MiLocalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
|
@ -9,7 +9,7 @@ import chalk from 'chalk';
|
||||||
import { IsNull } from 'typeorm';
|
import { IsNull } from 'typeorm';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { UsersRepository } from '@/models/index.js';
|
import type { UsersRepository } from '@/models/index.js';
|
||||||
import type { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
|
@ -40,7 +40,7 @@ export class RemoteUserResolveService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async resolveUser(username: string, host: string | null): Promise<LocalUser | RemoteUser> {
|
public async resolveUser(username: string, host: string | null): Promise<MiLocalUser | MiRemoteUser> {
|
||||||
const usernameLower = username.toLowerCase();
|
const usernameLower = username.toLowerCase();
|
||||||
|
|
||||||
if (host == null) {
|
if (host == null) {
|
||||||
|
@ -51,7 +51,7 @@ export class RemoteUserResolveService {
|
||||||
} else {
|
} else {
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
}) as LocalUser;
|
}) as MiLocalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
host = this.utilityService.toPuny(host);
|
host = this.utilityService.toPuny(host);
|
||||||
|
@ -64,10 +64,10 @@ export class RemoteUserResolveService {
|
||||||
} else {
|
} else {
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
}) as LocalUser;
|
}) as MiLocalUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ usernameLower, host }) as RemoteUser | null;
|
const user = await this.usersRepository.findOneBy({ usernameLower, host }) as MiRemoteUser | null;
|
||||||
|
|
||||||
const acctLower = `${usernameLower}@${host}`;
|
const acctLower = `${usernameLower}@${host}`;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ export class RemoteUserResolveService {
|
||||||
} else {
|
} else {
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
})) as LocalUser;
|
})) as MiLocalUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ export class RemoteUserResolveService {
|
||||||
if (u == null) {
|
if (u == null) {
|
||||||
throw new Error('user not found');
|
throw new Error('user not found');
|
||||||
} else {
|
} else {
|
||||||
return u as LocalUser | RemoteUser;
|
return u as MiLocalUser | MiRemoteUser;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common';
|
import { Inject, Injectable, OnModuleInit, forwardRef } from '@nestjs/common';
|
||||||
import { ModuleRef } from '@nestjs/core';
|
import { ModuleRef } from '@nestjs/core';
|
||||||
import { IsNull } from 'typeorm';
|
import { IsNull } from 'typeorm';
|
||||||
import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
|
import PerUserFollowingChart from '@/core/chart/charts/per-user-following.js';
|
||||||
|
@ -32,16 +32,16 @@ import Logger from '../logger.js';
|
||||||
|
|
||||||
const logger = new Logger('following/create');
|
const logger = new Logger('following/create');
|
||||||
|
|
||||||
type Local = LocalUser | {
|
type Local = MiLocalUser | {
|
||||||
id: LocalUser['id'];
|
id: MiLocalUser['id'];
|
||||||
host: LocalUser['host'];
|
host: MiLocalUser['host'];
|
||||||
uri: LocalUser['uri']
|
uri: MiLocalUser['uri']
|
||||||
};
|
};
|
||||||
type Remote = RemoteUser | {
|
type Remote = MiRemoteUser | {
|
||||||
id: RemoteUser['id'];
|
id: MiRemoteUser['id'];
|
||||||
host: RemoteUser['host'];
|
host: MiRemoteUser['host'];
|
||||||
uri: RemoteUser['uri'];
|
uri: MiRemoteUser['uri'];
|
||||||
inbox: RemoteUser['inbox'];
|
inbox: MiRemoteUser['inbox'];
|
||||||
};
|
};
|
||||||
type Both = Local | Remote;
|
type Both = Local | Remote;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ export class UserFollowingService implements OnModuleInit {
|
||||||
const [follower, followee] = await Promise.all([
|
const [follower, followee] = await Promise.all([
|
||||||
this.usersRepository.findOneByOrFail({ id: _follower.id }),
|
this.usersRepository.findOneByOrFail({ id: _follower.id }),
|
||||||
this.usersRepository.findOneByOrFail({ id: _followee.id }),
|
this.usersRepository.findOneByOrFail({ id: _followee.id }),
|
||||||
]) as [LocalUser | RemoteUser, LocalUser | RemoteUser];
|
]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser];
|
||||||
|
|
||||||
// check blocking
|
// check blocking
|
||||||
const [blocking, blocked] = await Promise.all([
|
const [blocking, blocked] = await Promise.all([
|
||||||
|
@ -358,13 +358,13 @@ export class UserFollowingService implements OnModuleInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) {
|
if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) {
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as PartialLocalUser, followee as PartialRemoteUser), follower));
|
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as MiPartialLocalUser, followee as MiPartialRemoteUser), follower));
|
||||||
this.queueService.deliver(follower, content, followee.inbox, false);
|
this.queueService.deliver(follower, content, followee.inbox, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.userEntityService.isLocalUser(followee) && this.userEntityService.isRemoteUser(follower)) {
|
if (this.userEntityService.isLocalUser(followee) && this.userEntityService.isRemoteUser(follower)) {
|
||||||
// local user has null host
|
// local user has null host
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderReject(this.apRendererService.renderFollow(follower as PartialRemoteUser, followee as PartialLocalUser), followee));
|
const content = this.apRendererService.addContext(this.apRendererService.renderReject(this.apRendererService.renderFollow(follower as MiPartialRemoteUser, followee as MiPartialLocalUser), followee));
|
||||||
this.queueService.deliver(followee, content, follower.inbox, false);
|
this.queueService.deliver(followee, content, follower.inbox, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +494,7 @@ export class UserFollowingService implements OnModuleInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) {
|
if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) {
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderFollow(follower as PartialLocalUser, followee as PartialRemoteUser, requestId ?? `${this.config.url}/follows/${followRequest.id}`));
|
const content = this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiPartialLocalUser, followee as MiPartialRemoteUser, requestId ?? `${this.config.url}/follows/${followRequest.id}`));
|
||||||
this.queueService.deliver(follower, content, followee.inbox, false);
|
this.queueService.deliver(follower, content, followee.inbox, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -509,7 +509,7 @@ export class UserFollowingService implements OnModuleInit {
|
||||||
},
|
},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (this.userEntityService.isRemoteUser(followee)) {
|
if (this.userEntityService.isRemoteUser(followee)) {
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as PartialLocalUser | PartialRemoteUser, followee as PartialRemoteUser), follower));
|
const content = this.apRendererService.addContext(this.apRendererService.renderUndo(this.apRendererService.renderFollow(follower as MiPartialLocalUser | MiPartialRemoteUser, followee as MiPartialRemoteUser), follower));
|
||||||
|
|
||||||
if (this.userEntityService.isLocalUser(follower)) { // 本来このチェックは不要だけどTSに怒られるので
|
if (this.userEntityService.isLocalUser(follower)) { // 本来このチェックは不要だけどTSに怒られるので
|
||||||
this.queueService.deliver(follower, content, followee.inbox, false);
|
this.queueService.deliver(follower, content, followee.inbox, false);
|
||||||
|
@ -556,7 +556,7 @@ export class UserFollowingService implements OnModuleInit {
|
||||||
await this.insertFollowingDoc(followee, follower);
|
await this.insertFollowingDoc(followee, follower);
|
||||||
|
|
||||||
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
|
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
|
||||||
const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as PartialLocalUser, request.requestId!), followee));
|
const content = this.apRendererService.addContext(this.apRendererService.renderAccept(this.apRendererService.renderFollow(follower, followee as MiPartialLocalUser, request.requestId!), followee));
|
||||||
this.queueService.deliver(followee, content, follower.inbox, false);
|
this.queueService.deliver(followee, content, follower.inbox, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import promiseLimit from 'promise-limit';
|
import promiseLimit from 'promise-limit';
|
||||||
import type { RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { concat, unique } from '@/misc/prelude/array.js';
|
import { concat, unique } from '@/misc/prelude/array.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { getApIds } from './type.js';
|
import { getApIds } from './type.js';
|
||||||
|
@ -31,7 +31,7 @@ export class ApAudienceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async parseAudience(actor: RemoteUser, to?: ApObject, cc?: ApObject, resolver?: Resolver): Promise<AudienceInfo> {
|
public async parseAudience(actor: MiRemoteUser, to?: ApObject, cc?: ApObject, resolver?: Resolver): Promise<AudienceInfo> {
|
||||||
const toGroups = this.groupingAudience(getApIds(to), actor);
|
const toGroups = this.groupingAudience(getApIds(to), actor);
|
||||||
const ccGroups = this.groupingAudience(getApIds(cc), actor);
|
const ccGroups = this.groupingAudience(getApIds(cc), actor);
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ export class ApAudienceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private groupingAudience(ids: string[], actor: RemoteUser): GroupedAudience {
|
private groupingAudience(ids: string[], actor: MiRemoteUser): GroupedAudience {
|
||||||
const groups: GroupedAudience = {
|
const groups: GroupedAudience = {
|
||||||
public: [],
|
public: [],
|
||||||
followers: [],
|
followers: [],
|
||||||
|
@ -106,7 +106,7 @@ export class ApAudienceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private isFollowers(id: string, actor: RemoteUser): boolean {
|
private isFollowers(id: string, actor: MiRemoteUser): boolean {
|
||||||
return id === (actor.followersUri ?? `${actor.uri}/followers`);
|
return id === (actor.followersUri ?? `${actor.uri}/followers`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type { MiUserPublickey } from '@/models/entities/UserPublickey.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
import type { MiNote } from '@/models/entities/Note.js';
|
import type { MiNote } from '@/models/entities/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import { getApId } from './type.js';
|
import { getApId } from './type.js';
|
||||||
import { ApPersonService } from './models/ApPersonService.js';
|
import { ApPersonService } from './models/ApPersonService.js';
|
||||||
import type { IObject } from './type.js';
|
import type { IObject } from './type.js';
|
||||||
|
@ -98,7 +98,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
* AP Person => Misskey User in DB
|
* AP Person => Misskey User in DB
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async getUserFromApId(value: string | IObject): Promise<LocalUser | RemoteUser | null> {
|
public async getUserFromApId(value: string | IObject): Promise<MiLocalUser | MiRemoteUser | null> {
|
||||||
const parsed = this.parseUri(value);
|
const parsed = this.parseUri(value);
|
||||||
|
|
||||||
if (parsed.local) {
|
if (parsed.local) {
|
||||||
|
@ -107,12 +107,12 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
return await this.cacheService.userByIdCache.fetchMaybe(
|
return await this.cacheService.userByIdCache.fetchMaybe(
|
||||||
parsed.id,
|
parsed.id,
|
||||||
() => this.usersRepository.findOneBy({ id: parsed.id }).then(x => x ?? undefined),
|
() => this.usersRepository.findOneBy({ id: parsed.id }).then(x => x ?? undefined),
|
||||||
) as LocalUser | undefined ?? null;
|
) as MiLocalUser | undefined ?? null;
|
||||||
} else {
|
} else {
|
||||||
return await this.cacheService.uriPersonCache.fetch(
|
return await this.cacheService.uriPersonCache.fetch(
|
||||||
parsed.uri,
|
parsed.uri,
|
||||||
() => this.usersRepository.findOneBy({ uri: parsed.uri }),
|
() => this.usersRepository.findOneBy({ uri: parsed.uri }),
|
||||||
) as RemoteUser | null;
|
) as MiRemoteUser | null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async getAuthUserFromKeyId(keyId: string): Promise<{
|
public async getAuthUserFromKeyId(keyId: string): Promise<{
|
||||||
user: RemoteUser;
|
user: MiRemoteUser;
|
||||||
key: MiUserPublickey;
|
key: MiUserPublickey;
|
||||||
} | null> {
|
} | null> {
|
||||||
const key = await this.publicKeyCache.fetch(keyId, async () => {
|
const key = await this.publicKeyCache.fetch(keyId, async () => {
|
||||||
|
@ -137,7 +137,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
if (key == null) return null;
|
if (key == null) return null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user: await this.cacheService.findUserById(key.userId) as RemoteUser,
|
user: await this.cacheService.findUserById(key.userId) as MiRemoteUser,
|
||||||
key,
|
key,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -147,10 +147,10 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async getAuthUserFromApId(uri: string): Promise<{
|
public async getAuthUserFromApId(uri: string): Promise<{
|
||||||
user: RemoteUser;
|
user: MiRemoteUser;
|
||||||
key: MiUserPublickey | null;
|
key: MiUserPublickey | null;
|
||||||
} | null> {
|
} | null> {
|
||||||
const user = await this.apPersonService.resolvePerson(uri) as RemoteUser;
|
const user = await this.apPersonService.resolvePerson(uri) as MiRemoteUser;
|
||||||
|
|
||||||
const key = await this.publicKeyByUserIdCache.fetch(
|
const key = await this.publicKeyByUserIdCache.fetch(
|
||||||
user.id,
|
user.id,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { IsNull, Not } from 'typeorm';
|
import { IsNull, Not } from 'typeorm';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { FollowingsRepository } from '@/models/index.js';
|
import type { FollowingsRepository } from '@/models/index.js';
|
||||||
import type { LocalUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -24,7 +24,7 @@ interface IFollowersRecipe extends IRecipe {
|
||||||
|
|
||||||
interface IDirectRecipe extends IRecipe {
|
interface IDirectRecipe extends IRecipe {
|
||||||
type: 'Direct';
|
type: 'Direct';
|
||||||
to: RemoteUser;
|
to: MiRemoteUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFollowers = (recipe: IRecipe): recipe is IFollowersRecipe =>
|
const isFollowers = (recipe: IRecipe): recipe is IFollowersRecipe =>
|
||||||
|
@ -82,7 +82,7 @@ class DeliverManager {
|
||||||
* @param to To
|
* @param to To
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public addDirectRecipe(to: RemoteUser): void {
|
public addDirectRecipe(to: MiRemoteUser): void {
|
||||||
const recipe: IDirectRecipe = {
|
const recipe: IDirectRecipe = {
|
||||||
type: 'Direct',
|
type: 'Direct',
|
||||||
to,
|
to,
|
||||||
|
@ -165,7 +165,7 @@ export class ApDeliverManagerService {
|
||||||
* @param activity Activity
|
* @param activity Activity
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToFollowers(actor: { id: LocalUser['id']; host: null; }, activity: IActivity): Promise<void> {
|
public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity): Promise<void> {
|
||||||
const manager = new DeliverManager(
|
const manager = new DeliverManager(
|
||||||
this.userEntityService,
|
this.userEntityService,
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
|
@ -184,7 +184,7 @@ export class ApDeliverManagerService {
|
||||||
* @param to Target user
|
* @param to Target user
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToUser(actor: { id: LocalUser['id']; host: null; }, activity: IActivity, to: RemoteUser): Promise<void> {
|
public async deliverToUser(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, to: MiRemoteUser): Promise<void> {
|
||||||
const manager = new DeliverManager(
|
const manager = new DeliverManager(
|
||||||
this.userEntityService,
|
this.userEntityService,
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/index.js';
|
import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/index.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { RemoteUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js';
|
import { getApHrefNullable, getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isMove, isPost, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js';
|
||||||
import { ApNoteService } from './models/ApNoteService.js';
|
import { ApNoteService } from './models/ApNoteService.js';
|
||||||
import { ApLoggerService } from './ApLoggerService.js';
|
import { ApLoggerService } from './ApLoggerService.js';
|
||||||
|
@ -87,7 +87,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async performActivity(actor: RemoteUser, activity: IObject): Promise<void> {
|
public async performActivity(actor: MiRemoteUser, activity: IObject): Promise<void> {
|
||||||
if (isCollectionOrOrderedCollection(activity)) {
|
if (isCollectionOrOrderedCollection(activity)) {
|
||||||
const resolver = this.apResolverService.createResolver();
|
const resolver = this.apResolverService.createResolver();
|
||||||
for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) {
|
for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) {
|
||||||
|
@ -115,7 +115,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async performOneActivity(actor: RemoteUser, activity: IObject): Promise<void> {
|
public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise<void> {
|
||||||
if (actor.isSuspended) return;
|
if (actor.isSuspended) return;
|
||||||
|
|
||||||
if (isCreate(activity)) {
|
if (isCreate(activity)) {
|
||||||
|
@ -152,7 +152,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async follow(actor: RemoteUser, activity: IFollow): Promise<string> {
|
private async follow(actor: MiRemoteUser, activity: IFollow): Promise<string> {
|
||||||
const followee = await this.apDbResolverService.getUserFromApId(activity.object);
|
const followee = await this.apDbResolverService.getUserFromApId(activity.object);
|
||||||
|
|
||||||
if (followee == null) {
|
if (followee == null) {
|
||||||
|
@ -169,7 +169,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async like(actor: RemoteUser, activity: ILike): Promise<string> {
|
private async like(actor: MiRemoteUser, activity: ILike): Promise<string> {
|
||||||
const targetUri = getApId(activity.object);
|
const targetUri = getApId(activity.object);
|
||||||
|
|
||||||
const note = await this.apNoteService.fetchNote(targetUri);
|
const note = await this.apNoteService.fetchNote(targetUri);
|
||||||
|
@ -187,7 +187,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async accept(actor: RemoteUser, activity: IAccept): Promise<string> {
|
private async accept(actor: MiRemoteUser, activity: IAccept): Promise<string> {
|
||||||
const uri = activity.id ?? activity;
|
const uri = activity.id ?? activity;
|
||||||
|
|
||||||
this.logger.info(`Accept: ${uri}`);
|
this.logger.info(`Accept: ${uri}`);
|
||||||
|
@ -205,7 +205,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async acceptFollow(actor: RemoteUser, activity: IFollow): Promise<string> {
|
private async acceptFollow(actor: MiRemoteUser, activity: IFollow): Promise<string> {
|
||||||
// ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある
|
// ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある
|
||||||
|
|
||||||
const follower = await this.apDbResolverService.getUserFromApId(activity.actor);
|
const follower = await this.apDbResolverService.getUserFromApId(activity.actor);
|
||||||
|
@ -229,7 +229,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async add(actor: RemoteUser, activity: IAdd): Promise<void> {
|
private async add(actor: MiRemoteUser, activity: IAdd): Promise<void> {
|
||||||
if (actor.uri !== activity.actor) {
|
if (actor.uri !== activity.actor) {
|
||||||
throw new Error('invalid actor');
|
throw new Error('invalid actor');
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async announce(actor: RemoteUser, activity: IAnnounce): Promise<void> {
|
private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<void> {
|
||||||
const uri = getApId(activity);
|
const uri = getApId(activity);
|
||||||
|
|
||||||
this.logger.info(`Announce: ${uri}`);
|
this.logger.info(`Announce: ${uri}`);
|
||||||
|
@ -260,7 +260,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async announceNote(actor: RemoteUser, activity: IAnnounce, targetUri: string): Promise<void> {
|
private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise<void> {
|
||||||
const uri = getApId(activity);
|
const uri = getApId(activity);
|
||||||
|
|
||||||
if (actor.isSuspended) {
|
if (actor.isSuspended) {
|
||||||
|
@ -320,7 +320,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async block(actor: RemoteUser, activity: IBlock): Promise<string> {
|
private async block(actor: MiRemoteUser, activity: IBlock): Promise<string> {
|
||||||
// ※ activity.objectにブロック対象があり、それは存在するローカルユーザーのはず
|
// ※ activity.objectにブロック対象があり、それは存在するローカルユーザーのはず
|
||||||
|
|
||||||
const blockee = await this.apDbResolverService.getUserFromApId(activity.object);
|
const blockee = await this.apDbResolverService.getUserFromApId(activity.object);
|
||||||
|
@ -338,7 +338,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async create(actor: RemoteUser, activity: ICreate): Promise<void> {
|
private async create(actor: MiRemoteUser, activity: ICreate): Promise<void> {
|
||||||
const uri = getApId(activity);
|
const uri = getApId(activity);
|
||||||
|
|
||||||
this.logger.info(`Create: ${uri}`);
|
this.logger.info(`Create: ${uri}`);
|
||||||
|
@ -374,7 +374,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async createNote(resolver: Resolver, actor: RemoteUser, note: IObject, silent = false, activity?: ICreate): Promise<string> {
|
private async createNote(resolver: Resolver, actor: MiRemoteUser, note: IObject, silent = false, activity?: ICreate): Promise<string> {
|
||||||
const uri = getApId(note);
|
const uri = getApId(note);
|
||||||
|
|
||||||
if (typeof note === 'object') {
|
if (typeof note === 'object') {
|
||||||
|
@ -409,7 +409,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async delete(actor: RemoteUser, activity: IDelete): Promise<string> {
|
private async delete(actor: MiRemoteUser, activity: IDelete): Promise<string> {
|
||||||
if (actor.uri !== activity.actor) {
|
if (actor.uri !== activity.actor) {
|
||||||
throw new Error('invalid actor');
|
throw new Error('invalid actor');
|
||||||
}
|
}
|
||||||
|
@ -451,7 +451,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async deleteActor(actor: RemoteUser, uri: string): Promise<string> {
|
private async deleteActor(actor: MiRemoteUser, uri: string): Promise<string> {
|
||||||
this.logger.info(`Deleting the Actor: ${uri}`);
|
this.logger.info(`Deleting the Actor: ${uri}`);
|
||||||
|
|
||||||
if (actor.uri !== uri) {
|
if (actor.uri !== uri) {
|
||||||
|
@ -475,7 +475,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async deleteNote(actor: RemoteUser, uri: string): Promise<string> {
|
private async deleteNote(actor: MiRemoteUser, uri: string): Promise<string> {
|
||||||
this.logger.info(`Deleting the Note: ${uri}`);
|
this.logger.info(`Deleting the Note: ${uri}`);
|
||||||
|
|
||||||
const unlock = await this.appLockService.getApLock(uri);
|
const unlock = await this.appLockService.getApLock(uri);
|
||||||
|
@ -499,7 +499,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async flag(actor: RemoteUser, activity: IFlag): Promise<string> {
|
private async flag(actor: MiRemoteUser, activity: IFlag): Promise<string> {
|
||||||
// objectは `(User|Note) | (User|Note)[]` だけど、全パターンDBスキーマと対応させられないので
|
// objectは `(User|Note) | (User|Note)[]` だけど、全パターンDBスキーマと対応させられないので
|
||||||
// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
|
// 対象ユーザーは一番最初のユーザー として あとはコメントとして格納する
|
||||||
const uris = getApIds(activity.object);
|
const uris = getApIds(activity.object);
|
||||||
|
@ -527,7 +527,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async reject(actor: RemoteUser, activity: IReject): Promise<string> {
|
private async reject(actor: MiRemoteUser, activity: IReject): Promise<string> {
|
||||||
const uri = activity.id ?? activity;
|
const uri = activity.id ?? activity;
|
||||||
|
|
||||||
this.logger.info(`Reject: ${uri}`);
|
this.logger.info(`Reject: ${uri}`);
|
||||||
|
@ -545,7 +545,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async rejectFollow(actor: RemoteUser, activity: IFollow): Promise<string> {
|
private async rejectFollow(actor: MiRemoteUser, activity: IFollow): Promise<string> {
|
||||||
// ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある
|
// ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある
|
||||||
|
|
||||||
const follower = await this.apDbResolverService.getUserFromApId(activity.actor);
|
const follower = await this.apDbResolverService.getUserFromApId(activity.actor);
|
||||||
|
@ -569,7 +569,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async remove(actor: RemoteUser, activity: IRemove): Promise<void> {
|
private async remove(actor: MiRemoteUser, activity: IRemove): Promise<void> {
|
||||||
if (actor.uri !== activity.actor) {
|
if (actor.uri !== activity.actor) {
|
||||||
throw new Error('invalid actor');
|
throw new Error('invalid actor');
|
||||||
}
|
}
|
||||||
|
@ -589,7 +589,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async undo(actor: RemoteUser, activity: IUndo): Promise<string> {
|
private async undo(actor: MiRemoteUser, activity: IUndo): Promise<string> {
|
||||||
if (actor.uri !== activity.actor) {
|
if (actor.uri !== activity.actor) {
|
||||||
throw new Error('invalid actor');
|
throw new Error('invalid actor');
|
||||||
}
|
}
|
||||||
|
@ -616,7 +616,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async undoAccept(actor: RemoteUser, activity: IAccept): Promise<string> {
|
private async undoAccept(actor: MiRemoteUser, activity: IAccept): Promise<string> {
|
||||||
const follower = await this.apDbResolverService.getUserFromApId(activity.object);
|
const follower = await this.apDbResolverService.getUserFromApId(activity.object);
|
||||||
if (follower == null) {
|
if (follower == null) {
|
||||||
return 'skip: follower not found';
|
return 'skip: follower not found';
|
||||||
|
@ -638,7 +638,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async undoAnnounce(actor: RemoteUser, activity: IAnnounce): Promise<string> {
|
private async undoAnnounce(actor: MiRemoteUser, activity: IAnnounce): Promise<string> {
|
||||||
const uri = getApId(activity);
|
const uri = getApId(activity);
|
||||||
|
|
||||||
const note = await this.notesRepository.findOneBy({
|
const note = await this.notesRepository.findOneBy({
|
||||||
|
@ -653,7 +653,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async undoBlock(actor: RemoteUser, activity: IBlock): Promise<string> {
|
private async undoBlock(actor: MiRemoteUser, activity: IBlock): Promise<string> {
|
||||||
const blockee = await this.apDbResolverService.getUserFromApId(activity.object);
|
const blockee = await this.apDbResolverService.getUserFromApId(activity.object);
|
||||||
|
|
||||||
if (blockee == null) {
|
if (blockee == null) {
|
||||||
|
@ -669,7 +669,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async undoFollow(actor: RemoteUser, activity: IFollow): Promise<string> {
|
private async undoFollow(actor: MiRemoteUser, activity: IFollow): Promise<string> {
|
||||||
const followee = await this.apDbResolverService.getUserFromApId(activity.object);
|
const followee = await this.apDbResolverService.getUserFromApId(activity.object);
|
||||||
if (followee == null) {
|
if (followee == null) {
|
||||||
return 'skip: followee not found';
|
return 'skip: followee not found';
|
||||||
|
@ -707,7 +707,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async undoLike(actor: RemoteUser, activity: ILike): Promise<string> {
|
private async undoLike(actor: MiRemoteUser, activity: ILike): Promise<string> {
|
||||||
const targetUri = getApId(activity.object);
|
const targetUri = getApId(activity.object);
|
||||||
|
|
||||||
const note = await this.apNoteService.fetchNote(targetUri);
|
const note = await this.apNoteService.fetchNote(targetUri);
|
||||||
|
@ -722,7 +722,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async update(actor: RemoteUser, activity: IUpdate): Promise<string> {
|
private async update(actor: MiRemoteUser, activity: IUpdate): Promise<string> {
|
||||||
if (actor.uri !== activity.actor) {
|
if (actor.uri !== activity.actor) {
|
||||||
return 'skip: invalid actor';
|
return 'skip: invalid actor';
|
||||||
}
|
}
|
||||||
|
@ -748,7 +748,7 @@ export class ApInboxService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async move(actor: RemoteUser, activity: IMove): Promise<string> {
|
private async move(actor: MiRemoteUser, activity: IMove): Promise<string> {
|
||||||
// fetch the new and old accounts
|
// fetch the new and old accounts
|
||||||
const targetUri = getApHrefNullable(activity.target);
|
const targetUri = getApHrefNullable(activity.target);
|
||||||
if (!targetUri) return 'skip: invalid activity target';
|
if (!targetUri) return 'skip: invalid activity target';
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { In } from 'typeorm';
|
||||||
import * as mfm from 'mfm-js';
|
import * as mfm from 'mfm-js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type { PartialLocalUser, LocalUser, PartialRemoteUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiPartialLocalUser, MiLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import type { IMentionedRemoteUsers, MiNote } from '@/models/entities/Note.js';
|
import type { IMentionedRemoteUsers, MiNote } from '@/models/entities/Note.js';
|
||||||
import type { MiBlocking } from '@/models/entities/Blocking.js';
|
import type { MiBlocking } from '@/models/entities/Blocking.js';
|
||||||
import type { MiRelay } from '@/models/entities/Relay.js';
|
import type { MiRelay } from '@/models/entities/Relay.js';
|
||||||
|
@ -72,7 +72,7 @@ export class ApRendererService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderAdd(user: LocalUser, target: string | IObject | undefined, object: string | IObject): IAdd {
|
public renderAdd(user: MiLocalUser, target: string | IObject | undefined, object: string | IObject): IAdd {
|
||||||
return {
|
return {
|
||||||
type: 'Add',
|
type: 'Add',
|
||||||
actor: this.userEntityService.genLocalUserUri(user.id),
|
actor: this.userEntityService.genLocalUserUri(user.id),
|
||||||
|
@ -185,7 +185,7 @@ export class ApRendererService {
|
||||||
|
|
||||||
// to anonymise reporters, the reporting actor must be a system user
|
// to anonymise reporters, the reporting actor must be a system user
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderFlag(user: LocalUser, object: IObject | string, content: string): IFlag {
|
public renderFlag(user: MiLocalUser, object: IObject | string, content: string): IFlag {
|
||||||
return {
|
return {
|
||||||
type: 'Flag',
|
type: 'Flag',
|
||||||
actor: this.userEntityService.genLocalUserUri(user.id),
|
actor: this.userEntityService.genLocalUserUri(user.id),
|
||||||
|
@ -195,7 +195,7 @@ export class ApRendererService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderFollowRelay(relay: MiRelay, relayActor: LocalUser): IFollow {
|
public renderFollowRelay(relay: MiRelay, relayActor: MiLocalUser): IFollow {
|
||||||
return {
|
return {
|
||||||
id: `${this.config.url}/activities/follow-relay/${relay.id}`,
|
id: `${this.config.url}/activities/follow-relay/${relay.id}`,
|
||||||
type: 'Follow',
|
type: 'Follow',
|
||||||
|
@ -210,14 +210,14 @@ export class ApRendererService {
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async renderFollowUser(id: MiUser['id']): Promise<string> {
|
public async renderFollowUser(id: MiUser['id']): Promise<string> {
|
||||||
const user = await this.usersRepository.findOneByOrFail({ id: id }) as PartialLocalUser | PartialRemoteUser;
|
const user = await this.usersRepository.findOneByOrFail({ id: id }) as MiPartialLocalUser | MiPartialRemoteUser;
|
||||||
return this.userEntityService.getUserUri(user);
|
return this.userEntityService.getUserUri(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderFollow(
|
public renderFollow(
|
||||||
follower: PartialLocalUser | PartialRemoteUser,
|
follower: MiPartialLocalUser | MiPartialRemoteUser,
|
||||||
followee: PartialLocalUser | PartialRemoteUser,
|
followee: MiPartialLocalUser | MiPartialRemoteUser,
|
||||||
requestId?: string,
|
requestId?: string,
|
||||||
): IFollow {
|
): IFollow {
|
||||||
return {
|
return {
|
||||||
|
@ -248,7 +248,7 @@ export class ApRendererService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderKey(user: LocalUser, key: MiUserKeypair, postfix?: string): IKey {
|
public renderKey(user: MiLocalUser, key: MiUserKeypair, postfix?: string): IKey {
|
||||||
return {
|
return {
|
||||||
id: `${this.config.url}/users/${user.id}${postfix ?? '/publickey'}`,
|
id: `${this.config.url}/users/${user.id}${postfix ?? '/publickey'}`,
|
||||||
type: 'Key',
|
type: 'Key',
|
||||||
|
@ -284,18 +284,18 @@ export class ApRendererService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderMention(mention: PartialLocalUser | PartialRemoteUser): IApMention {
|
public renderMention(mention: MiPartialLocalUser | MiPartialRemoteUser): IApMention {
|
||||||
return {
|
return {
|
||||||
type: 'Mention',
|
type: 'Mention',
|
||||||
href: this.userEntityService.getUserUri(mention),
|
href: this.userEntityService.getUserUri(mention),
|
||||||
name: this.userEntityService.isRemoteUser(mention) ? `@${mention.username}@${mention.host}` : `@${(mention as LocalUser).username}`,
|
name: this.userEntityService.isRemoteUser(mention) ? `@${mention.username}@${mention.host}` : `@${(mention as MiLocalUser).username}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderMove(
|
public renderMove(
|
||||||
src: PartialLocalUser | PartialRemoteUser,
|
src: MiPartialLocalUser | MiPartialRemoteUser,
|
||||||
dst: PartialLocalUser | PartialRemoteUser,
|
dst: MiPartialLocalUser | MiPartialRemoteUser,
|
||||||
): IMove {
|
): IMove {
|
||||||
const actor = this.userEntityService.getUserUri(src);
|
const actor = this.userEntityService.getUserUri(src);
|
||||||
const target = this.userEntityService.getUserUri(dst);
|
const target = this.userEntityService.getUserUri(dst);
|
||||||
|
@ -376,7 +376,7 @@ export class ApRendererService {
|
||||||
}) : [];
|
}) : [];
|
||||||
|
|
||||||
const hashtagTags = note.tags.map(tag => this.renderHashtag(tag));
|
const hashtagTags = note.tags.map(tag => this.renderHashtag(tag));
|
||||||
const mentionTags = mentionedUsers.map(u => this.renderMention(u as LocalUser | RemoteUser));
|
const mentionTags = mentionedUsers.map(u => this.renderMention(u as MiLocalUser | MiRemoteUser));
|
||||||
|
|
||||||
const files = await getPromisedFiles(note.fileIds);
|
const files = await getPromisedFiles(note.fileIds);
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ export class ApRendererService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async renderPerson(user: LocalUser) {
|
public async renderPerson(user: MiLocalUser) {
|
||||||
const id = this.userEntityService.genLocalUserUri(user.id);
|
const id = this.userEntityService.genLocalUserUri(user.id);
|
||||||
const isSystem = user.username.includes('.');
|
const isSystem = user.username.includes('.');
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ export class ApRendererService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public renderVote(user: { id: MiUser['id'] }, vote: MiPollVote, note: MiNote, poll: MiPoll, pollOwner: RemoteUser): ICreate {
|
public renderVote(user: { id: MiUser['id'] }, vote: MiPollVote, note: MiNote, poll: MiPoll, pollOwner: MiRemoteUser): ICreate {
|
||||||
return {
|
return {
|
||||||
id: `${this.config.url}/users/${user.id}#votes/${vote.id}/activity`,
|
id: `${this.config.url}/users/${user.id}#votes/${vote.id}/activity`,
|
||||||
actor: this.userEntityService.genLocalUserUri(user.id),
|
actor: this.userEntityService.genLocalUserUri(user.id),
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||||
import type { NotesRepository, PollsRepository, NoteReactionsRepository, UsersRepository } from '@/models/index.js';
|
import type { NotesRepository, PollsRepository, NoteReactionsRepository, UsersRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
|
@ -23,7 +23,7 @@ import type { IObject, ICollection, IOrderedCollection } from './type.js';
|
||||||
|
|
||||||
export class Resolver {
|
export class Resolver {
|
||||||
private history: Set<string>;
|
private history: Set<string>;
|
||||||
private user?: LocalUser;
|
private user?: MiLocalUser;
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -134,7 +134,7 @@ export class Resolver {
|
||||||
});
|
});
|
||||||
case 'users':
|
case 'users':
|
||||||
return this.usersRepository.findOneByOrFail({ id: parsed.id })
|
return this.usersRepository.findOneByOrFail({ id: parsed.id })
|
||||||
.then(user => this.apRendererService.renderPerson(user as LocalUser));
|
.then(user => this.apRendererService.renderPerson(user as MiLocalUser));
|
||||||
case 'questions':
|
case 'questions':
|
||||||
// Polls are indexed by the note they are attached to.
|
// Polls are indexed by the note they are attached to.
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
|
@ -152,7 +152,7 @@ export class Resolver {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
[parsed.id, parsed.rest].map(id => this.usersRepository.findOneByOrFail({ id })),
|
[parsed.id, parsed.rest].map(id => this.usersRepository.findOneByOrFail({ id })),
|
||||||
)
|
)
|
||||||
.then(([follower, followee]) => this.apRendererService.addContext(this.apRendererService.renderFollow(follower as LocalUser | RemoteUser, followee as LocalUser | RemoteUser, url)));
|
.then(([follower, followee]) => this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiLocalUser | MiRemoteUser, followee as MiLocalUser | MiRemoteUser, url)));
|
||||||
default:
|
default:
|
||||||
throw new Error(`resolveLocal: type ${parsed.type} unhandled`);
|
throw new Error(`resolveLocal: type ${parsed.type} unhandled`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { DriveFilesRepository } from '@/models/index.js';
|
import type { DriveFilesRepository } from '@/models/index.js';
|
||||||
import type { RemoteUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
|
import type { MiDriveFile } from '@/models/entities/DriveFile.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { truncate } from '@/misc/truncate.js';
|
import { truncate } from '@/misc/truncate.js';
|
||||||
|
@ -39,7 +39,7 @@ export class ApImageService {
|
||||||
* Imageを作成します。
|
* Imageを作成します。
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async createImage(actor: RemoteUser, value: string | IObject): Promise<MiDriveFile> {
|
public async createImage(actor: MiRemoteUser, value: string | IObject): Promise<MiDriveFile> {
|
||||||
// 投稿者が凍結されていたらスキップ
|
// 投稿者が凍結されていたらスキップ
|
||||||
if (actor.isSuspended) {
|
if (actor.isSuspended) {
|
||||||
throw new Error('actor has been suspended');
|
throw new Error('actor has been suspended');
|
||||||
|
@ -90,7 +90,7 @@ export class ApImageService {
|
||||||
* リモートサーバーからフェッチしてMisskeyに登録しそれを返します。
|
* リモートサーバーからフェッチしてMisskeyに登録しそれを返します。
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async resolveImage(actor: RemoteUser, value: string | IObject): Promise<MiDriveFile> {
|
public async resolveImage(actor: MiRemoteUser, value: string | IObject): Promise<MiDriveFile> {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// リモートサーバーからフェッチしてきて登録
|
// リモートサーバーからフェッチしてきて登録
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { In } from 'typeorm';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { PollsRepository, EmojisRepository } from '@/models/index.js';
|
import type { PollsRepository, EmojisRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type { RemoteUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import type { MiNote } from '@/models/entities/Note.js';
|
import type { MiNote } from '@/models/entities/Note.js';
|
||||||
import { toArray, toSingle, unique } from '@/misc/prelude/array.js';
|
import { toArray, toSingle, unique } from '@/misc/prelude/array.js';
|
||||||
import type { MiEmoji } from '@/models/entities/Emoji.js';
|
import type { MiEmoji } from '@/models/entities/Emoji.js';
|
||||||
|
@ -147,7 +147,7 @@ export class ApNoteService {
|
||||||
throw new Error('invalid note.attributedTo: ' + note.attributedTo);
|
throw new Error('invalid note.attributedTo: ' + note.attributedTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as RemoteUser;
|
const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as MiRemoteUser;
|
||||||
|
|
||||||
// 投稿者が凍結されていたらスキップ
|
// 投稿者が凍結されていたらスキップ
|
||||||
if (actor.isSuspended) {
|
if (actor.isSuspended) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { ModuleRef } from '@nestjs/core';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { FollowingsRepository, InstancesRepository, UserProfilesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js';
|
import type { FollowingsRepository, InstancesRepository, UserProfilesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import { MiUser } from '@/models/entities/User.js';
|
import { MiUser } from '@/models/entities/User.js';
|
||||||
import { truncate } from '@/misc/truncate.js';
|
import { truncate } from '@/misc/truncate.js';
|
||||||
import type { CacheService } from '@/core/CacheService.js';
|
import type { CacheService } from '@/core/CacheService.js';
|
||||||
|
@ -201,20 +201,20 @@ export class ApPersonService implements OnModuleInit {
|
||||||
* Misskeyに対象のPersonが登録されていればそれを返し、登録がなければnullを返します。
|
* Misskeyに対象のPersonが登録されていればそれを返し、登録がなければnullを返します。
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async fetchPerson(uri: string): Promise<LocalUser | RemoteUser | null> {
|
public async fetchPerson(uri: string): Promise<MiLocalUser | MiRemoteUser | null> {
|
||||||
const cached = this.cacheService.uriPersonCache.get(uri) as LocalUser | RemoteUser | null | undefined;
|
const cached = this.cacheService.uriPersonCache.get(uri) as MiLocalUser | MiRemoteUser | null | undefined;
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
// URIがこのサーバーを指しているならデータベースからフェッチ
|
// URIがこのサーバーを指しているならデータベースからフェッチ
|
||||||
if (uri.startsWith(`${this.config.url}/`)) {
|
if (uri.startsWith(`${this.config.url}/`)) {
|
||||||
const id = uri.split('/').pop();
|
const id = uri.split('/').pop();
|
||||||
const u = await this.usersRepository.findOneBy({ id }) as LocalUser | null;
|
const u = await this.usersRepository.findOneBy({ id }) as MiLocalUser | null;
|
||||||
if (u) this.cacheService.uriPersonCache.set(uri, u);
|
if (u) this.cacheService.uriPersonCache.set(uri, u);
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region このサーバーに既に登録されていたらそれを返す
|
//#region このサーバーに既に登録されていたらそれを返す
|
||||||
const exist = await this.usersRepository.findOneBy({ uri }) as LocalUser | RemoteUser | null;
|
const exist = await this.usersRepository.findOneBy({ uri }) as MiLocalUser | MiRemoteUser | null;
|
||||||
|
|
||||||
if (exist) {
|
if (exist) {
|
||||||
this.cacheService.uriPersonCache.set(uri, exist);
|
this.cacheService.uriPersonCache.set(uri, exist);
|
||||||
|
@ -225,7 +225,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async resolveAvatarAndBanner(user: RemoteUser, icon: any, image: any): Promise<Pick<RemoteUser, 'avatarId' | 'bannerId' | 'avatarUrl' | 'bannerUrl' | 'avatarBlurhash' | 'bannerBlurhash'>> {
|
private async resolveAvatarAndBanner(user: MiRemoteUser, icon: any, image: any): Promise<Pick<MiRemoteUser, 'avatarId' | 'bannerId' | 'avatarUrl' | 'bannerUrl' | 'avatarBlurhash' | 'bannerBlurhash'>> {
|
||||||
const [avatar, banner] = await Promise.all([icon, image].map(img => {
|
const [avatar, banner] = await Promise.all([icon, image].map(img => {
|
||||||
if (img == null) return null;
|
if (img == null) return null;
|
||||||
if (user == null) throw new Error('failed to create user: user is null');
|
if (user == null) throw new Error('failed to create user: user is null');
|
||||||
|
@ -246,7 +246,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
* Personを作成します。
|
* Personを作成します。
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async createPerson(uri: string, resolver?: Resolver): Promise<RemoteUser> {
|
public async createPerson(uri: string, resolver?: Resolver): Promise<MiRemoteUser> {
|
||||||
if (typeof uri !== 'string') throw new Error('uri is not string');
|
if (typeof uri !== 'string') throw new Error('uri is not string');
|
||||||
|
|
||||||
if (uri.startsWith(this.config.url)) {
|
if (uri.startsWith(this.config.url)) {
|
||||||
|
@ -280,7 +280,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create user
|
// Create user
|
||||||
let user: RemoteUser | null = null;
|
let user: MiRemoteUser | null = null;
|
||||||
|
|
||||||
//#region カスタム絵文字取得
|
//#region カスタム絵文字取得
|
||||||
const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host)
|
const emojis = await this.apNoteService.extractEmojis(person.tag ?? [], host)
|
||||||
|
@ -318,7 +318,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
isBot,
|
isBot,
|
||||||
isCat: (person as any).isCat === true,
|
isCat: (person as any).isCat === true,
|
||||||
emojis,
|
emojis,
|
||||||
})) as RemoteUser;
|
})) as MiRemoteUser;
|
||||||
|
|
||||||
await transactionalEntityManager.save(new MiUserProfile({
|
await transactionalEntityManager.save(new MiUserProfile({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
|
@ -345,7 +345,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
const u = await this.usersRepository.findOneBy({ uri: person.id });
|
const u = await this.usersRepository.findOneBy({ uri: person.id });
|
||||||
if (u == null) throw new Error('already registered');
|
if (u == null) throw new Error('already registered');
|
||||||
|
|
||||||
user = u as RemoteUser;
|
user = u as MiRemoteUser;
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(e instanceof Error ? e : new Error(e as string));
|
this.logger.error(e instanceof Error ? e : new Error(e as string));
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -407,7 +407,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
if (uri.startsWith(`${this.config.url}/`)) return;
|
if (uri.startsWith(`${this.config.url}/`)) return;
|
||||||
|
|
||||||
//#region このサーバーに既に登録されているか
|
//#region このサーバーに既に登録されているか
|
||||||
const exist = await this.fetchPerson(uri) as RemoteUser | null;
|
const exist = await this.fetchPerson(uri) as MiRemoteUser | null;
|
||||||
if (exist === null) return;
|
if (exist === null) return;
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
@ -456,7 +456,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
alsoKnownAs: person.alsoKnownAs ?? null,
|
alsoKnownAs: person.alsoKnownAs ?? null,
|
||||||
isExplorable: person.discoverable,
|
isExplorable: person.discoverable,
|
||||||
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))),
|
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image).catch(() => ({}))),
|
||||||
} as Partial<RemoteUser> & Pick<RemoteUser, 'isBot' | 'isCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;
|
} as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;
|
||||||
|
|
||||||
const moving = ((): boolean => {
|
const moving = ((): boolean => {
|
||||||
// 移行先がない→ある
|
// 移行先がない→ある
|
||||||
|
@ -542,7 +542,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
* リモートサーバーからフェッチしてMisskeyに登録しそれを返します。
|
* リモートサーバーからフェッチしてMisskeyに登録しそれを返します。
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async resolvePerson(uri: string, resolver?: Resolver): Promise<LocalUser | RemoteUser> {
|
public async resolvePerson(uri: string, resolver?: Resolver): Promise<MiLocalUser | MiRemoteUser> {
|
||||||
//#region このサーバーに既に登録されていたらそれを返す
|
//#region このサーバーに既に登録されていたらそれを返す
|
||||||
const exist = await this.fetchPerson(uri);
|
const exist = await this.fetchPerson(uri);
|
||||||
if (exist) return exist;
|
if (exist) return exist;
|
||||||
|
@ -622,7 +622,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
* @param movePreventUris ここに列挙されたURIにsrc.movedToUriが含まれる場合、移行処理はしない(無限ループ防止)
|
* @param movePreventUris ここに列挙されたURIにsrc.movedToUriが含まれる場合、移行処理はしない(無限ループ防止)
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
private async processRemoteMove(src: RemoteUser, movePreventUris: string[] = []): Promise<string> {
|
private async processRemoteMove(src: MiRemoteUser, movePreventUris: string[] = []): Promise<string> {
|
||||||
if (!src.movedToUri) return 'skip: no movedToUri';
|
if (!src.movedToUri) return 'skip: no movedToUri';
|
||||||
if (src.uri === src.movedToUri) return 'skip: movedTo itself (src)'; // ???
|
if (src.uri === src.movedToUri) return 'skip: movedTo itself (src)'; // ???
|
||||||
if (movePreventUris.length > 10) return 'skip: too many moves';
|
if (movePreventUris.length > 10) return 'skip: too many moves';
|
||||||
|
@ -632,7 +632,7 @@ export class ApPersonService implements OnModuleInit {
|
||||||
|
|
||||||
if (dst && this.userEntityService.isLocalUser(dst)) {
|
if (dst && this.userEntityService.isLocalUser(dst)) {
|
||||||
// targetがローカルユーザーだった場合データベースから引っ張ってくる
|
// targetがローカルユーザーだった場合データベースから引っ張ってくる
|
||||||
dst = await this.usersRepository.findOneByOrFail({ uri: src.movedToUri }) as LocalUser;
|
dst = await this.usersRepository.findOneByOrFail({ uri: src.movedToUri }) as MiLocalUser;
|
||||||
} else if (dst) {
|
} else if (dst) {
|
||||||
if (movePreventUris.includes(src.movedToUri)) return 'skip: circular move';
|
if (movePreventUris.includes(src.movedToUri)) return 'skip: circular move';
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type { Packed } from '@/misc/json-schema.js';
|
||||||
import type { Promiseable } from '@/misc/prelude/await-all.js';
|
import type { Promiseable } from '@/misc/prelude/await-all.js';
|
||||||
import { awaitAll } from '@/misc/prelude/await-all.js';
|
import { awaitAll } from '@/misc/prelude/await-all.js';
|
||||||
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
|
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
|
||||||
import type { LocalUser, PartialLocalUser, PartialRemoteUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiPartialLocalUser, MiPartialRemoteUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js';
|
import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js';
|
||||||
import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, UserNotePiningsRepository, UserProfilesRepository, AnnouncementReadsRepository, AnnouncementsRepository, UserProfile, RenoteMutingsRepository, UserMemoRepository, Announcement } from '@/models/index.js';
|
import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, UserNotePiningsRepository, UserProfilesRepository, AnnouncementReadsRepository, AnnouncementsRepository, UserProfile, RenoteMutingsRepository, UserMemoRepository, Announcement } from '@/models/index.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -38,13 +38,13 @@ type IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends bo
|
||||||
const Ajv = _Ajv.default;
|
const Ajv = _Ajv.default;
|
||||||
const ajv = new Ajv();
|
const ajv = new Ajv();
|
||||||
|
|
||||||
function isLocalUser(user: MiUser): user is LocalUser;
|
function isLocalUser(user: MiUser): user is MiLocalUser;
|
||||||
function isLocalUser<T extends { host: MiUser['host'] }>(user: T): user is (T & { host: null; });
|
function isLocalUser<T extends { host: MiUser['host'] }>(user: T): user is (T & { host: null; });
|
||||||
function isLocalUser(user: MiUser | { host: MiUser['host'] }): boolean {
|
function isLocalUser(user: MiUser | { host: MiUser['host'] }): boolean {
|
||||||
return user.host == null;
|
return user.host == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isRemoteUser(user: MiUser): user is RemoteUser;
|
function isRemoteUser(user: MiUser): user is MiRemoteUser;
|
||||||
function isRemoteUser<T extends { host: MiUser['host'] }>(user: T): user is (T & { host: string; });
|
function isRemoteUser<T extends { host: MiUser['host'] }>(user: T): user is (T & { host: string; });
|
||||||
function isRemoteUser(user: MiUser | { host: MiUser['host'] }): boolean {
|
function isRemoteUser(user: MiUser | { host: MiUser['host'] }): boolean {
|
||||||
return !isLocalUser(user);
|
return !isLocalUser(user);
|
||||||
|
@ -265,7 +265,7 @@ export class UserEntityService implements OnModuleInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public getUserUri(user: LocalUser | PartialLocalUser | RemoteUser | PartialRemoteUser): string {
|
public getUserUri(user: MiLocalUser | MiPartialLocalUser | MiRemoteUser | MiPartialRemoteUser): string {
|
||||||
return this.isRemoteUser(user)
|
return this.isRemoteUser(user)
|
||||||
? user.uri : this.genLocalUserUri(user.id);
|
? user.uri : this.genLocalUserUri(user.id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,23 +253,23 @@ export class MiUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LocalUser = MiUser & {
|
export type MiLocalUser = MiUser & {
|
||||||
host: null;
|
host: null;
|
||||||
uri: null;
|
uri: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PartialLocalUser = Partial<MiUser> & {
|
export type MiPartialLocalUser = Partial<MiUser> & {
|
||||||
id: MiUser['id'];
|
id: MiUser['id'];
|
||||||
host: null;
|
host: null;
|
||||||
uri: null;
|
uri: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RemoteUser = MiUser & {
|
export type MiRemoteUser = MiUser & {
|
||||||
host: string;
|
host: string;
|
||||||
uri: string;
|
uri: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PartialRemoteUser = Partial<MiUser> & {
|
export type MiPartialRemoteUser = Partial<MiUser> & {
|
||||||
id: MiUser['id'];
|
id: MiUser['id'];
|
||||||
host: string;
|
host: string;
|
||||||
uri: string;
|
uri: string;
|
||||||
|
|
|
@ -15,7 +15,7 @@ import InstanceChart from '@/core/chart/charts/instance.js';
|
||||||
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
||||||
import FederationChart from '@/core/chart/charts/federation.js';
|
import FederationChart from '@/core/chart/charts/federation.js';
|
||||||
import { getApId } from '@/core/activitypub/type.js';
|
import { getApId } from '@/core/activitypub/type.js';
|
||||||
import type { RemoteUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import type { MiUserPublickey } from '@/models/entities/UserPublickey.js';
|
import type { MiUserPublickey } from '@/models/entities/UserPublickey.js';
|
||||||
import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js';
|
import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js';
|
||||||
import { StatusError } from '@/misc/status-error.js';
|
import { StatusError } from '@/misc/status-error.js';
|
||||||
|
@ -74,7 +74,7 @@ export class InboxProcessorService {
|
||||||
|
|
||||||
// HTTP-Signature keyIdを元にDBから取得
|
// HTTP-Signature keyIdを元にDBから取得
|
||||||
let authUser: {
|
let authUser: {
|
||||||
user: RemoteUser;
|
user: MiRemoteUser;
|
||||||
key: MiUserPublickey | null;
|
key: MiUserPublickey | null;
|
||||||
} | null = await this.apDbResolverService.getAuthUserFromKeyId(signature.keyId);
|
} | null = await this.apDbResolverService.getAuthUserFromKeyId(signature.keyId);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type Logger from '@/logger.js';
|
||||||
|
|
||||||
import type { UsersRepository } from '@/models/index.js';
|
import type { UsersRepository } from '@/models/index.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import { RelationshipJobData } from '../types.js';
|
import { RelationshipJobData } from '../types.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
|
@ -45,7 +45,7 @@ export class RelationshipProcessorService {
|
||||||
const [follower, followee] = await Promise.all([
|
const [follower, followee] = await Promise.all([
|
||||||
this.usersRepository.findOneByOrFail({ id: job.data.from.id }),
|
this.usersRepository.findOneByOrFail({ id: job.data.from.id }),
|
||||||
this.usersRepository.findOneByOrFail({ id: job.data.to.id }),
|
this.usersRepository.findOneByOrFail({ id: job.data.to.id }),
|
||||||
]) as [LocalUser | RemoteUser, LocalUser | RemoteUser];
|
]) as [MiLocalUser | MiRemoteUser, MiLocalUser | MiRemoteUser];
|
||||||
await this.userFollowingService.unfollow(follower, followee, job.data.silent);
|
await this.userFollowingService.unfollow(follower, followee, job.data.silent);
|
||||||
return 'ok';
|
return 'ok';
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import * as url from '@/misc/prelude/url.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
|
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import type { LocalUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { UserKeypairService } from '@/core/UserKeypairService.js';
|
import { UserKeypairService } from '@/core/UserKeypairService.js';
|
||||||
import type { MiFollowing } from '@/models/entities/Following.js';
|
import type { MiFollowing } from '@/models/entities/Following.js';
|
||||||
import { countIf } from '@/misc/prelude/array.js';
|
import { countIf } from '@/misc/prelude/array.js';
|
||||||
|
@ -432,7 +432,7 @@ export class ActivityPubServerService {
|
||||||
|
|
||||||
reply.header('Cache-Control', 'public, max-age=180');
|
reply.header('Cache-Control', 'public, max-age=180');
|
||||||
this.setResponseType(request, reply);
|
this.setResponseType(request, reply);
|
||||||
return (this.apRendererService.addContext(await this.apRendererService.renderPerson(user as LocalUser)));
|
return (this.apRendererService.addContext(await this.apRendererService.renderPerson(user as MiLocalUser)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -648,7 +648,7 @@ export class ActivityPubServerService {
|
||||||
id: request.params.followee,
|
id: request.params.followee,
|
||||||
host: Not(IsNull()),
|
host: Not(IsNull()),
|
||||||
}),
|
}),
|
||||||
]) as [LocalUser | RemoteUser | null, LocalUser | RemoteUser | null];
|
]) as [MiLocalUser | MiRemoteUser | null, MiLocalUser | MiRemoteUser | null];
|
||||||
|
|
||||||
if (follower == null || followee == null) {
|
if (follower == null || followee == null) {
|
||||||
reply.code(404);
|
reply.code(404);
|
||||||
|
@ -683,7 +683,7 @@ export class ActivityPubServerService {
|
||||||
id: followRequest.followeeId,
|
id: followRequest.followeeId,
|
||||||
host: Not(IsNull()),
|
host: Not(IsNull()),
|
||||||
}),
|
}),
|
||||||
]) as [LocalUser | RemoteUser | null, LocalUser | RemoteUser | null];
|
]) as [MiLocalUser | MiRemoteUser | null, MiLocalUser | MiRemoteUser | null];
|
||||||
|
|
||||||
if (follower == null || followee == null) {
|
if (follower == null || followee == null) {
|
||||||
reply.code(404);
|
reply.code(404);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import * as stream from 'node:stream/promises';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { getIpHash } from '@/misc/get-ip-hash.js';
|
import { getIpHash } from '@/misc/get-ip-hash.js';
|
||||||
import type { LocalUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiUser } from '@/models/entities/User.js';
|
||||||
import type { MiAccessToken } from '@/models/entities/AccessToken.js';
|
import type { MiAccessToken } from '@/models/entities/AccessToken.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import type { UserIpsRepository } from '@/models/index.js';
|
import type { UserIpsRepository } from '@/models/index.js';
|
||||||
|
@ -196,7 +196,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async logIp(request: FastifyRequest, user: LocalUser) {
|
private async logIp(request: FastifyRequest, user: MiLocalUser) {
|
||||||
const meta = await this.metaService.fetch();
|
const meta = await this.metaService.fetch();
|
||||||
if (!meta.enableIpLogging) return;
|
if (!meta.enableIpLogging) return;
|
||||||
const ip = request.ip;
|
const ip = request.ip;
|
||||||
|
@ -222,7 +222,7 @@ export class ApiCallService implements OnApplicationShutdown {
|
||||||
@bindThis
|
@bindThis
|
||||||
private async call(
|
private async call(
|
||||||
ep: IEndpoint & { exec: any },
|
ep: IEndpoint & { exec: any },
|
||||||
user: LocalUser | null | undefined,
|
user: MiLocalUser | null | undefined,
|
||||||
token: MiAccessToken | null | undefined,
|
token: MiAccessToken | null | undefined,
|
||||||
data: any,
|
data: any,
|
||||||
file: {
|
file: {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { AccessTokensRepository, AppsRepository, UsersRepository } from '@/models/index.js';
|
import type { AccessTokensRepository, AppsRepository, UsersRepository } from '@/models/index.js';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import type { MiAccessToken } from '@/models/entities/AccessToken.js';
|
import type { MiAccessToken } from '@/models/entities/AccessToken.js';
|
||||||
import { MemoryKVCache } from '@/misc/cache.js';
|
import { MemoryKVCache } from '@/misc/cache.js';
|
||||||
import type { MiApp } from '@/models/entities/App.js';
|
import type { MiApp } from '@/models/entities/App.js';
|
||||||
|
@ -41,14 +41,14 @@ export class AuthenticateService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async authenticate(token: string | null | undefined): Promise<[LocalUser | null, MiAccessToken | null]> {
|
public async authenticate(token: string | null | undefined): Promise<[MiLocalUser | null, MiAccessToken | null]> {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNativeToken(token)) {
|
if (isNativeToken(token)) {
|
||||||
const user = await this.cacheService.localUserByNativeTokenCache.fetch(token,
|
const user = await this.cacheService.localUserByNativeTokenCache.fetch(token,
|
||||||
() => this.usersRepository.findOneBy({ token }) as Promise<LocalUser | null>);
|
() => this.usersRepository.findOneBy({ token }) as Promise<MiLocalUser | null>);
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new AuthenticationError('user not found');
|
throw new AuthenticationError('user not found');
|
||||||
|
@ -75,7 +75,7 @@ export class AuthenticateService implements OnApplicationShutdown {
|
||||||
const user = await this.cacheService.localUserByIdCache.fetch(accessToken.userId,
|
const user = await this.cacheService.localUserByIdCache.fetch(accessToken.userId,
|
||||||
() => this.usersRepository.findOneBy({
|
() => this.usersRepository.findOneBy({
|
||||||
id: accessToken.userId,
|
id: accessToken.userId,
|
||||||
}) as Promise<LocalUser>);
|
}) as Promise<MiLocalUser>);
|
||||||
|
|
||||||
if (accessToken.appId) {
|
if (accessToken.appId) {
|
||||||
const app = await this.appCache.fetch(accessToken.appId,
|
const app = await this.appCache.fetch(accessToken.appId,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { NotesRepository, UsersRepository } from '@/models/index.js';
|
import type { NotesRepository, UsersRepository } from '@/models/index.js';
|
||||||
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import type { LocalUser, RemoteUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/entities/User.js';
|
||||||
import type { MiNote } from '@/models/entities/Note.js';
|
import type { MiNote } from '@/models/entities/Note.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -50,7 +50,7 @@ export class GetterService {
|
||||||
throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', 'No such user.');
|
throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', 'No such user.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return user as LocalUser | RemoteUser;
|
return user as MiLocalUser | MiRemoteUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { DI } from '@/di-symbols.js';
|
||||||
import type { UserSecurityKeysRepository, SigninsRepository, UserProfilesRepository, AttestationChallengesRepository, UsersRepository } from '@/models/index.js';
|
import type { UserSecurityKeysRepository, SigninsRepository, UserProfilesRepository, AttestationChallengesRepository, UsersRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { getIpHash } from '@/misc/get-ip-hash.js';
|
import { getIpHash } from '@/misc/get-ip-hash.js';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { TwoFactorAuthenticationService } from '@/core/TwoFactorAuthenticationService.js';
|
import { TwoFactorAuthenticationService } from '@/core/TwoFactorAuthenticationService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -110,7 +110,7 @@ export class SigninApiService {
|
||||||
const user = await this.usersRepository.findOneBy({
|
const user = await this.usersRepository.findOneBy({
|
||||||
usernameLower: username.toLowerCase(),
|
usernameLower: username.toLowerCase(),
|
||||||
host: IsNull(),
|
host: IsNull(),
|
||||||
}) as LocalUser;
|
}) as MiLocalUser;
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return error(404, {
|
return error(404, {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { SigninsRepository } from '@/models/index.js';
|
import type { SigninsRepository } from '@/models/index.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
import { SigninEntityService } from '@/core/entities/SigninEntityService.js';
|
import { SigninEntityService } from '@/core/entities/SigninEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
@ -26,7 +26,7 @@ export class SigninService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public signin(request: FastifyRequest, reply: FastifyReply, user: LocalUser) {
|
public signin(request: FastifyRequest, reply: FastifyReply, user: MiLocalUser) {
|
||||||
setImmediate(async () => {
|
setImmediate(async () => {
|
||||||
// Append signin history
|
// Append signin history
|
||||||
const record = await this.signinsRepository.insert({
|
const record = await this.signinsRepository.insert({
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { IdService } from '@/core/IdService.js';
|
||||||
import { SignupService } from '@/core/SignupService.js';
|
import { SignupService } from '@/core/SignupService.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { EmailService } from '@/core/EmailService.js';
|
import { EmailService } from '@/core/EmailService.js';
|
||||||
import { LocalUser } from '@/models/entities/User.js';
|
import { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
||||||
|
@ -251,7 +251,7 @@ export class SignupApiService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.signinService.signin(request, reply, account as LocalUser);
|
return this.signinService.signin(request, reply, account as MiLocalUser);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new FastifyReplyError(400, typeof err === 'string' ? err : (err as Error).toString());
|
throw new FastifyReplyError(400, typeof err === 'string' ? err : (err as Error).toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { NoteReadService } from '@/core/NoteReadService.js';
|
||||||
import { NotificationService } from '@/core/NotificationService.js';
|
import { NotificationService } from '@/core/NotificationService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
import { LocalUser } from '@/models/entities/User.js';
|
import { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import { AuthenticateService, AuthenticationError } from './AuthenticateService.js';
|
import { AuthenticateService, AuthenticationError } from './AuthenticateService.js';
|
||||||
import MainStreamConnection from './stream/index.js';
|
import MainStreamConnection from './stream/index.js';
|
||||||
import { ChannelsService } from './stream/ChannelsService.js';
|
import { ChannelsService } from './stream/ChannelsService.js';
|
||||||
|
@ -55,7 +55,7 @@ export class StreamingApiServerService {
|
||||||
|
|
||||||
const q = new URL(request.url, `http://${request.headers.host}`).searchParams;
|
const q = new URL(request.url, `http://${request.headers.host}`).searchParams;
|
||||||
|
|
||||||
let user: LocalUser | null = null;
|
let user: MiLocalUser | null = null;
|
||||||
let app: AccessToken | null = null;
|
let app: AccessToken | null = null;
|
||||||
|
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6750.html#section-2.1
|
// https://datatracker.ietf.org/doc/html/rfc6750.html#section-2.1
|
||||||
|
@ -112,7 +112,7 @@ export class StreamingApiServerService {
|
||||||
|
|
||||||
this.#wss.on('connection', async (connection: WebSocket.WebSocket, request: http.IncomingMessage, ctx: {
|
this.#wss.on('connection', async (connection: WebSocket.WebSocket, request: http.IncomingMessage, ctx: {
|
||||||
stream: MainStreamConnection,
|
stream: MainStreamConnection,
|
||||||
user: LocalUser | null;
|
user: MiLocalUser | null;
|
||||||
app: AccessToken | null
|
app: AccessToken | null
|
||||||
}) => {
|
}) => {
|
||||||
const { stream, user, app } = ctx;
|
const { stream, user, app } = ctx;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import _Ajv from 'ajv';
|
import _Ajv from 'ajv';
|
||||||
import type { Schema, SchemaType } from '@/misc/json-schema.js';
|
import type { Schema, SchemaType } from '@/misc/json-schema.js';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import type { MiAccessToken } from '@/models/entities/AccessToken.js';
|
import type { MiAccessToken } from '@/models/entities/AccessToken.js';
|
||||||
import { ApiError } from './error.js';
|
import { ApiError } from './error.js';
|
||||||
import type { IEndpointMeta } from './endpoints.js';
|
import type { IEndpointMeta } from './endpoints.js';
|
||||||
|
@ -28,16 +28,16 @@ type File = {
|
||||||
|
|
||||||
// TODO: paramsの型をT['params']のスキーマ定義から推論する
|
// TODO: paramsの型をT['params']のスキーマ定義から推論する
|
||||||
type Executor<T extends IEndpointMeta, Ps extends Schema> =
|
type Executor<T extends IEndpointMeta, Ps extends Schema> =
|
||||||
(params: SchemaType<Ps>, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: MiAccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record<string, string> | null) =>
|
(params: SchemaType<Ps>, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, cleanup?: () => any, ip?: string | null, headers?: Record<string, string> | null) =>
|
||||||
Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>;
|
Promise<T['res'] extends undefined ? Response : SchemaType<NonNullable<T['res']>>>;
|
||||||
|
|
||||||
export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
|
export abstract class Endpoint<T extends IEndpointMeta, Ps extends Schema> {
|
||||||
public exec: (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => Promise<any>;
|
public exec: (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => Promise<any>;
|
||||||
|
|
||||||
constructor(meta: T, paramDef: Ps, cb: Executor<T, Ps>) {
|
constructor(meta: T, paramDef: Ps, cb: Executor<T, Ps>) {
|
||||||
const validate = ajv.compile(paramDef);
|
const validate = ajv.compile(paramDef);
|
||||||
|
|
||||||
this.exec = (params: any, user: T['requireCredential'] extends true ? LocalUser : LocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => {
|
this.exec = (params: any, user: T['requireCredential'] extends true ? MiLocalUser : MiLocalUser | null, token: MiAccessToken | null, file?: File, ip?: string | null, headers?: Record<string, string> | null) => {
|
||||||
let cleanup: undefined | (() => void) = undefined;
|
let cleanup: undefined | (() => void) = undefined;
|
||||||
|
|
||||||
if (meta.requireFile) {
|
if (meta.requireFile) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Injectable } from '@nestjs/common';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import type { MiNote } from '@/models/entities/Note.js';
|
import type { MiNote } from '@/models/entities/Note.js';
|
||||||
import type { LocalUser, MiUser } from '@/models/entities/User.js';
|
import type { MiLocalUser, MiUser } from '@/models/entities/User.js';
|
||||||
import { isActor, isPost, getApId } from '@/core/activitypub/type.js';
|
import { isActor, isPost, getApId } from '@/core/activitypub/type.js';
|
||||||
import type { SchemaType } from '@/misc/json-schema.js';
|
import type { SchemaType } from '@/misc/json-schema.js';
|
||||||
import { ApResolverService } from '@/core/activitypub/ApResolverService.js';
|
import { ApResolverService } from '@/core/activitypub/ApResolverService.js';
|
||||||
|
@ -111,7 +111,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
* URIからUserかNoteを解決する
|
* URIからUserかNoteを解決する
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
private async fetchAny(uri: string, me: LocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> {
|
private async fetchAny(uri: string, me: MiLocalUser | null | undefined): Promise<SchemaType<typeof meta['res']> | null> {
|
||||||
// ブロックしてたら中断
|
// ブロックしてたら中断
|
||||||
const fetchedMeta = await this.metaService.fetch();
|
const fetchedMeta = await this.metaService.fetch();
|
||||||
if (this.utilityService.isBlockedHost(fetchedMeta.blockedHosts, this.utilityService.extractDbHost(uri))) return null;
|
if (this.utilityService.isBlockedHost(fetchedMeta.blockedHosts, this.utilityService.extractDbHost(uri))) return null;
|
||||||
|
@ -144,7 +144,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private async mergePack(me: LocalUser | null | undefined, user: MiUser | null | undefined, note: MiNote | null | undefined): Promise<SchemaType<typeof meta.res> | null> {
|
private async mergePack(me: MiLocalUser | null | undefined, user: MiUser | null | undefined, note: MiNote | null | undefined): Promise<SchemaType<typeof meta.res> | null> {
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
return {
|
return {
|
||||||
type: 'User',
|
type: 'User',
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ms from 'ms';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { ApiError } from '@/server/api/error.js';
|
import { ApiError } from '@/server/api/error.js';
|
||||||
|
|
||||||
import { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
import { MiLocalUser, MiRemoteUser } from '@/models/entities/User.js';
|
||||||
|
|
||||||
import { AccountMoveService } from '@/core/AccountMoveService.js';
|
import { AccountMoveService } from '@/core/AccountMoveService.js';
|
||||||
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
||||||
|
@ -100,7 +100,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
this.apiLoggerService.logger.warn(`failed to resolve remote user: ${e}`);
|
this.apiLoggerService.logger.warn(`failed to resolve remote user: ${e}`);
|
||||||
throw new ApiError(meta.errors.noSuchUser);
|
throw new ApiError(meta.errors.noSuchUser);
|
||||||
});
|
});
|
||||||
const destination = await this.getterService.getUser(moveTo.id) as LocalUser | RemoteUser;
|
const destination = await this.getterService.getUser(moveTo.id) as MiLocalUser | MiRemoteUser;
|
||||||
const newUri = this.userEntityService.getUserUri(destination);
|
const newUri = this.userEntityService.getUserUri(destination);
|
||||||
|
|
||||||
// update local db
|
// update local db
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type { UsersRepository, PollsRepository, PollVotesRepository } from '@/models/index.js';
|
import type { UsersRepository, PollsRepository, PollVotesRepository } from '@/models/index.js';
|
||||||
import type { RemoteUser } from '@/models/entities/User.js';
|
import type { MiRemoteUser } from '@/models/entities/User.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { GetterService } from '@/server/api/GetterService.js';
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
@ -164,7 +164,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
|
|
||||||
// リモート投票の場合リプライ送信
|
// リモート投票の場合リプライ送信
|
||||||
if (note.userHost != null) {
|
if (note.userHost != null) {
|
||||||
const pollOwner = await this.usersRepository.findOneByOrFail({ id: note.userId }) as RemoteUser;
|
const pollOwner = await this.usersRepository.findOneByOrFail({ id: note.userId }) as MiRemoteUser;
|
||||||
|
|
||||||
this.queueService.deliver(me, this.apRendererService.addContext(await this.apRendererService.renderVote(me, vote, note, poll, pollOwner)), pollOwner.inbox, false);
|
this.queueService.deliver(me, this.apRendererService.addContext(await this.apRendererService.renderVote(me, vote, note, poll, pollOwner)), pollOwner.inbox, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { bindThis } from '@/decorators.js';
|
||||||
import type { AccessTokensRepository, UsersRepository } from '@/models/index.js';
|
import type { AccessTokensRepository, UsersRepository } from '@/models/index.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { CacheService } from '@/core/CacheService.js';
|
import { CacheService } from '@/core/CacheService.js';
|
||||||
import type { LocalUser } from '@/models/entities/User.js';
|
import type { MiLocalUser } from '@/models/entities/User.js';
|
||||||
import { MemoryKVCache } from '@/misc/cache.js';
|
import { MemoryKVCache } from '@/misc/cache.js';
|
||||||
import { LoggerService } from '@/core/LoggerService.js';
|
import { LoggerService } from '@/core/LoggerService.js';
|
||||||
import Logger from '@/logger.js';
|
import Logger from '@/logger.js';
|
||||||
|
@ -271,7 +271,7 @@ export class OAuth2ProviderService {
|
||||||
throw new AuthorizationError('No user', 'invalid_request');
|
throw new AuthorizationError('No user', 'invalid_request');
|
||||||
}
|
}
|
||||||
const user = await this.cacheService.localUserByNativeTokenCache.fetch(token,
|
const user = await this.cacheService.localUserByNativeTokenCache.fetch(token,
|
||||||
() => this.usersRepository.findOneBy({ token }) as Promise<LocalUser | null>);
|
() => this.usersRepository.findOneBy({ token }) as Promise<MiLocalUser | null>);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new AuthorizationError('No such user', 'invalid_request');
|
throw new AuthorizationError('No such user', 'invalid_request');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue