fix(federation): AnnounceのobjectがLike出なかったらキューにためない

Fix https://github.com/misskey-dev/misskey/issues/13552
This commit is contained in:
tamaina 2024-03-09 08:50:52 +00:00
parent dbc4fd3e93
commit 1c7007449d
3 changed files with 45 additions and 31 deletions

View File

@ -90,13 +90,15 @@ export class ApInboxService {
} }
@bindThis @bindThis
public async performActivity(actor: MiRemoteUser, activity: IObject): Promise<void> { public async performActivity(actor: MiRemoteUser, activity: IObject): Promise<string | void> {
let reason = undefined as string | void;
if (isCollectionOrOrderedCollection(activity)) { if (isCollectionOrOrderedCollection(activity)) {
const reasons = [] as [string, string | void][];
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)) {
const act = await resolver.resolve(item); const act = await resolver.resolve(item);
try { try {
await this.performOneActivity(actor, act); reasons.push([getApId(item), await this.performOneActivity(actor, act)]);
} catch (err) { } catch (err) {
if (err instanceof Error || typeof err === 'string') { if (err instanceof Error || typeof err === 'string') {
this.logger.error(err); this.logger.error(err);
@ -105,52 +107,56 @@ export class ApInboxService {
} }
} }
} }
const hasReason = reasons.some(([, reason]) => reason != null);
if (hasReason) {
reason = reasons.map(([id, reason]) => `${id}: ${reason}`).join('\n');
}
} else { } else {
await this.performOneActivity(actor, activity); reason = await this.performOneActivity(actor, activity);
} }
// ついでにリモートユーザーの情報が古かったら更新しておく // ついでにリモートユーザーの情報が古かったら更新しておく
if (actor.uri) { if (actor.uri) {
if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) { if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
setImmediate(() => { await this.apPersonService.updatePerson(actor.uri);
this.apPersonService.updatePerson(actor.uri);
});
} }
} }
return reason;
} }
@bindThis @bindThis
public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise<void> { public async performOneActivity(actor: MiRemoteUser, activity: IObject): Promise<string | void> {
if (actor.isSuspended) return; if (actor.isSuspended) return;
if (isCreate(activity)) { if (isCreate(activity)) {
await this.create(actor, activity); return await this.create(actor, activity);
} else if (isDelete(activity)) { } else if (isDelete(activity)) {
await this.delete(actor, activity); return await this.delete(actor, activity);
} else if (isUpdate(activity)) { } else if (isUpdate(activity)) {
await this.update(actor, activity); return await this.update(actor, activity);
} else if (isFollow(activity)) { } else if (isFollow(activity)) {
await this.follow(actor, activity); return await this.follow(actor, activity);
} else if (isAccept(activity)) { } else if (isAccept(activity)) {
await this.accept(actor, activity); return await this.accept(actor, activity);
} else if (isReject(activity)) { } else if (isReject(activity)) {
await this.reject(actor, activity); return await this.reject(actor, activity);
} else if (isAdd(activity)) { } else if (isAdd(activity)) {
await this.add(actor, activity).catch(err => this.logger.error(err)); return await this.add(actor, activity).catch(err => this.logger.error(err));
} else if (isRemove(activity)) { } else if (isRemove(activity)) {
await this.remove(actor, activity).catch(err => this.logger.error(err)); return await this.remove(actor, activity).catch(err => this.logger.error(err));
} else if (isAnnounce(activity)) { } else if (isAnnounce(activity)) {
await this.announce(actor, activity); return await this.announce(actor, activity);
} else if (isLike(activity)) { } else if (isLike(activity)) {
await this.like(actor, activity); return await this.like(actor, activity);
} else if (isUndo(activity)) { } else if (isUndo(activity)) {
await this.undo(actor, activity); return await this.undo(actor, activity);
} else if (isBlock(activity)) { } else if (isBlock(activity)) {
await this.block(actor, activity); return await this.block(actor, activity);
} else if (isFlag(activity)) { } else if (isFlag(activity)) {
await this.flag(actor, activity); return await this.flag(actor, activity);
} else if (isMove(activity)) { } else if (isMove(activity)) {
await this.move(actor, activity); return await this.move(actor, activity);
} else { } else {
this.logger.warn(`unrecognized activity type: ${activity.type}`); this.logger.warn(`unrecognized activity type: ${activity.type}`);
} }
@ -254,18 +260,18 @@ export class ApInboxService {
} }
@bindThis @bindThis
private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<void> { private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<string | void> {
const uri = getApId(activity); const uri = getApId(activity);
this.logger.info(`Announce: ${uri}`); this.logger.info(`Announce: ${uri}`);
const targetUri = getApId(activity.object); const targetUri = getApId(activity.object);
await this.announceNote(actor, activity, targetUri); return await this.announceNote(actor, activity, targetUri);
} }
@bindThis @bindThis
private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise<void> { private async announceNote(actor: MiRemoteUser, activity: IAnnounce, targetUri: string): Promise<string | void> {
const uri = getApId(activity); const uri = getApId(activity);
if (actor.isSuspended) { if (actor.isSuspended) {
@ -289,7 +295,7 @@ export class ApInboxService {
let renote; let renote;
try { try {
renote = await this.apNoteService.resolveNote(targetUri); renote = await this.apNoteService.resolveNote(targetUri);
if (renote == null) throw new Error('announce target is null'); if (renote == null) return 'announce target is null';
} catch (err) { } catch (err) {
// 対象が4xxならスキップ // 対象が4xxならスキップ
if (err instanceof StatusError) { if (err instanceof StatusError) {

View File

@ -82,20 +82,20 @@ export class ApNoteService {
const expectHost = this.utilityService.extractDbHost(uri); const expectHost = this.utilityService.extractDbHost(uri);
if (!validPost.includes(getApType(object))) { if (!validPost.includes(getApType(object))) {
return new Error(`invalid Note: invalid object type ${getApType(object)}`); return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: invalid object type ${getApType(object)}`);
} }
if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) { if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) {
return new Error(`invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`); return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
} }
const actualHost = object.attributedTo && this.utilityService.extractDbHost(getOneApId(object.attributedTo)); const actualHost = object.attributedTo && this.utilityService.extractDbHost(getOneApId(object.attributedTo));
if (object.attributedTo && actualHost !== expectHost) { if (object.attributedTo && actualHost !== expectHost) {
return new Error(`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`); return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
} }
if (object.published && !this.idService.isSafeT(new Date(object.published).valueOf())) { if (object.published && !this.idService.isSafeT(new Date(object.published).valueOf())) {
return new Error('invalid Note: published timestamp is malformed'); return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', 'invalid Note: published timestamp is malformed');
} }
return null; return null;

View File

@ -182,13 +182,21 @@ export class InboxProcessorService {
// アクティビティを処理 // アクティビティを処理
try { try {
await this.apInboxService.performActivity(authUser.user, activity); const reason = await this.apInboxService.performActivity(authUser.user, activity);
if (reason) {
return reason;
}
} catch (e) { } catch (e) {
if (e instanceof IdentifiableError) { if (e instanceof IdentifiableError) {
if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') { if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') {
return 'blocked notes with prohibited words'; return 'blocked notes with prohibited words';
} }
if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') return 'actor has been suspended'; if (e.id === '85ab9bd7-3a41-4530-959d-f07073900109') {
return 'actor has been suspended';
}
if (e.id === 'd450b8a9-48e4-4dab-ae36-f4db763fda7c') { // invalid Note
return e.message;
}
} }
throw e; throw e;
} }