Skip to content

Commit

Permalink
fix(federation): AnnounceのobjectがLike出なかったらキューにためない
Browse files Browse the repository at this point in the history
Fix #13552
  • Loading branch information
tamaina committed Mar 9, 2024
1 parent dbc4fd3 commit 1c70074
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 31 deletions.
56 changes: 31 additions & 25 deletions packages/backend/src/core/activitypub/ApInboxService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,15 @@ export class ApInboxService {
}

@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)) {
const reasons = [] as [string, string | void][];
const resolver = this.apResolverService.createResolver();
for (const item of toArray(isCollection(activity) ? activity.items : activity.orderedItems)) {
const act = await resolver.resolve(item);
try {
await this.performOneActivity(actor, act);
reasons.push([getApId(item), await this.performOneActivity(actor, act)]);
} catch (err) {
if (err instanceof Error || typeof err === 'string') {
this.logger.error(err);
Expand All @@ -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 {
await this.performOneActivity(actor, activity);
reason = await this.performOneActivity(actor, activity);
}

// ついでにリモートユーザーの情報が古かったら更新しておく
if (actor.uri) {
if (actor.lastFetchedAt == null || Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
setImmediate(() => {
this.apPersonService.updatePerson(actor.uri);
});
await this.apPersonService.updatePerson(actor.uri);
}
}
return reason;
}

@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 (isCreate(activity)) {
await this.create(actor, activity);
return await this.create(actor, activity);
} else if (isDelete(activity)) {
await this.delete(actor, activity);
return await this.delete(actor, activity);
} else if (isUpdate(activity)) {
await this.update(actor, activity);
return await this.update(actor, activity);
} else if (isFollow(activity)) {
await this.follow(actor, activity);
return await this.follow(actor, activity);
} else if (isAccept(activity)) {
await this.accept(actor, activity);
return await this.accept(actor, activity);
} else if (isReject(activity)) {
await this.reject(actor, activity);
return await this.reject(actor, 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)) {
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)) {
await this.announce(actor, activity);
return await this.announce(actor, activity);
} else if (isLike(activity)) {
await this.like(actor, activity);
return await this.like(actor, activity);
} else if (isUndo(activity)) {
await this.undo(actor, activity);
return await this.undo(actor, activity);
} else if (isBlock(activity)) {
await this.block(actor, activity);
return await this.block(actor, activity);
} else if (isFlag(activity)) {
await this.flag(actor, activity);
return await this.flag(actor, activity);
} else if (isMove(activity)) {
await this.move(actor, activity);
return await this.move(actor, activity);
} else {
this.logger.warn(`unrecognized activity type: ${activity.type}`);
}
Expand Down Expand Up @@ -254,18 +260,18 @@ export class ApInboxService {
}

@bindThis
private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<void> {
private async announce(actor: MiRemoteUser, activity: IAnnounce): Promise<string | void> {
const uri = getApId(activity);

this.logger.info(`Announce: ${uri}`);

const targetUri = getApId(activity.object);

await this.announceNote(actor, activity, targetUri);
return await this.announceNote(actor, activity, targetUri);
}

@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);

if (actor.isSuspended) {
Expand All @@ -289,7 +295,7 @@ export class ApInboxService {
let renote;
try {
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) {
// 対象が4xxならスキップ
if (err instanceof StatusError) {
Expand Down
8 changes: 4 additions & 4 deletions packages/backend/src/core/activitypub/models/ApNoteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,20 @@ export class ApNoteService {
const expectHost = this.utilityService.extractDbHost(uri);

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) {
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));
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())) {
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;
Expand Down
12 changes: 10 additions & 2 deletions packages/backend/src/queue/processors/InboxProcessorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,21 @@ export class InboxProcessorService {

// アクティビティを処理
try {
await this.apInboxService.performActivity(authUser.user, activity);
const reason = await this.apInboxService.performActivity(authUser.user, activity);
if (reason) {
return reason;
}
} catch (e) {
if (e instanceof IdentifiableError) {
if (e.id === '689ee33f-f97c-479a-ac49-1b9f8140af99') {
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;
}
Expand Down

0 comments on commit 1c70074

Please sign in to comment.