merge: Accept Like(Note) and Update(Note) activities where the Note isn't already cached (resolves #795 and #748) (!729)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/729

Closes #795 and #748

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
dakkar 2024-11-22 23:02:39 +00:00
commit 3ae9f4e8e6
4 changed files with 51 additions and 11 deletions

View file

@ -165,7 +165,7 @@ export class ApInboxService {
} else if (isAnnounce(activity)) {
return await this.announce(actor, activity, resolver);
} else if (isLike(activity)) {
return await this.like(actor, activity);
return await this.like(actor, activity, resolver);
} else if (isUndo(activity)) {
return await this.undo(actor, activity, resolver);
} else if (isBlock(activity)) {
@ -197,10 +197,13 @@ export class ApInboxService {
}
@bindThis
private async like(actor: MiRemoteUser, activity: ILike): Promise<string> {
private async like(actor: MiRemoteUser, activity: ILike, resolver?: Resolver): Promise<string> {
const targetUri = getApId(activity.object);
const note = await this.apNoteService.fetchNote(targetUri);
const object = fromTuple(activity.object);
if (!object) return 'skip: activity has no object property';
const note = await this.apNoteService.resolveNote(object, { resolver });
if (!note) return `skip: target note not found ${targetUri}`;
await this.apNoteService.extractEmojis(activity.tag ?? [], actor.host).catch(() => null);
@ -385,7 +388,7 @@ export class ApInboxService {
}
@bindThis
private async create(actor: MiRemoteUser, activity: ICreate, resolver?: Resolver): Promise<string | void> {
private async create(actor: MiRemoteUser, activity: ICreate | IUpdate, resolver?: Resolver): Promise<string | void> {
const uri = getApId(activity);
this.logger.info(`Create: ${uri}`);
@ -420,14 +423,14 @@ export class ApInboxService {
});
if (isPost(object)) {
await this.createNote(resolver, actor, object, false, activity);
await this.createNote(resolver, actor, object, false);
} else {
return `Unknown type: ${getApType(object)}`;
}
}
@bindThis
private async createNote(resolver: Resolver, actor: MiRemoteUser, note: IObject, silent = false, activity?: ICreate): Promise<string> {
private async createNote(resolver: Resolver, actor: MiRemoteUser, note: IObject, silent = false): Promise<string> {
const uri = getApId(note);
if (typeof note === 'object') {
@ -786,7 +789,7 @@ export class ApInboxService {
}
@bindThis
private async update(actor: MiRemoteUser, activity: IUpdate, resolver?: Resolver): Promise<string> {
private async update(actor: MiRemoteUser, activity: IUpdate, resolver?: Resolver): Promise<string | void> {
if (actor.uri !== activity.actor) {
return 'skip: invalid actor';
}
@ -805,9 +808,19 @@ export class ApInboxService {
await this.apPersonService.updatePerson(actor.uri, resolver, object);
return 'ok: Person updated';
} else if (getApType(object) === 'Question') {
// If we get an Update(Question) for a note that doesn't exist, then create it instead
if (!await this.apNoteService.hasNote(object)) {
return await this.create(actor, activity, resolver);
}
await this.apQuestionService.updateQuestion(object, actor, resolver).catch(err => console.error(err));
return 'ok: Question updated';
} else if (isPost(object)) {
// If we get an Update(Note) for a note that doesn't exist, then create it instead
if (!await this.apNoteService.hasNote(object)) {
return await this.create(actor, activity, resolver);
}
await this.apNoteService.updateNote(object, actor, resolver).catch(err => console.error(err));
return 'ok: Note updated';
} else {

View file

@ -142,6 +142,15 @@ export class ApNoteService {
return await this.apDbResolverService.getNoteFromApId(object);
}
/**
* Returns true if the provided object / ID exists in the local database.
*/
@bindThis
public async hasNote(object: string | IObject | [string | IObject]): Promise<boolean> {
const uri = getApId(object);
return await this.notesRepository.existsBy({ uri });
}
/**
* Noteを作成します
*/