View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/876 Closes #905 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
commit
534c35cca2
46 changed files with 843 additions and 108 deletions
|
|
@ -228,7 +228,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public async create(user: {
|
||||
public async create(user: MiUser & {
|
||||
id: MiUser['id'];
|
||||
username: MiUser['username'];
|
||||
host: MiUser['host'];
|
||||
|
|
@ -435,7 +435,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public async import(user: {
|
||||
public async import(user: MiUser & {
|
||||
id: MiUser['id'];
|
||||
username: MiUser['username'];
|
||||
host: MiUser['host'];
|
||||
|
|
@ -486,10 +486,10 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
|
||||
// should really not happen, but better safe than sorry
|
||||
if (data.reply?.id === insert.id) {
|
||||
throw new Error("A note can't reply to itself");
|
||||
throw new Error('A note can\'t reply to itself');
|
||||
}
|
||||
if (data.renote?.id === insert.id) {
|
||||
throw new Error("A note can't renote itself");
|
||||
throw new Error('A note can\'t renote itself');
|
||||
}
|
||||
|
||||
if (data.uri != null) insert.uri = data.uri;
|
||||
|
|
@ -552,7 +552,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private async postNoteCreated(note: MiNote, user: {
|
||||
private async postNoteCreated(note: MiNote, user: MiUser & {
|
||||
id: MiUser['id'];
|
||||
username: MiUser['username'];
|
||||
host: MiUser['host'];
|
||||
|
|
@ -753,7 +753,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
//#region AP deliver
|
||||
if (!data.localOnly && this.userEntityService.isLocalUser(user)) {
|
||||
(async () => {
|
||||
const noteActivity = await this.renderNoteOrRenoteActivity(data, note);
|
||||
const noteActivity = await this.renderNoteOrRenoteActivity(data, note, user);
|
||||
const dm = this.apDeliverManagerService.createDeliverManager(user, noteActivity);
|
||||
|
||||
// メンションされたリモートユーザーに配送
|
||||
|
|
@ -899,12 +899,12 @@ export class NoteCreateService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private async renderNoteOrRenoteActivity(data: Option, note: MiNote) {
|
||||
private async renderNoteOrRenoteActivity(data: Option, note: MiNote, user: MiUser) {
|
||||
if (data.localOnly) return null;
|
||||
|
||||
const content = this.isRenote(data) && !this.isQuote(data)
|
||||
? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note)
|
||||
: this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, false), note);
|
||||
: this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, user, false), note);
|
||||
|
||||
return this.apRendererService.addContext(content);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public async edit(user: {
|
||||
public async edit(user: MiUser & {
|
||||
id: MiUser['id'];
|
||||
username: MiUser['username'];
|
||||
host: MiUser['host'];
|
||||
|
|
@ -309,7 +309,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
|
||||
if (this.isRenote(data)) {
|
||||
if (data.renote.id === oldnote.id) {
|
||||
throw new Error("A note can't renote itself");
|
||||
throw new Error('A note can\'t renote itself');
|
||||
}
|
||||
|
||||
switch (data.renote.visibility) {
|
||||
|
|
@ -584,7 +584,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private async postNoteEdited(note: MiNote, oldNote: MiNote, user: {
|
||||
private async postNoteEdited(note: MiNote, oldNote: MiNote, user: MiUser & {
|
||||
id: MiUser['id'];
|
||||
username: MiUser['username'];
|
||||
host: MiUser['host'];
|
||||
|
|
@ -703,7 +703,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
//#region AP deliver
|
||||
if (!data.localOnly && this.userEntityService.isLocalUser(user)) {
|
||||
(async () => {
|
||||
const noteActivity = await this.renderNoteOrRenoteActivity(data, note);
|
||||
const noteActivity = await this.renderNoteOrRenoteActivity(data, note, user);
|
||||
const dm = this.apDeliverManagerService.createDeliverManager(user, noteActivity);
|
||||
|
||||
// メンションされたリモートユーザーに配送
|
||||
|
|
@ -834,14 +834,12 @@ export class NoteEditService implements OnApplicationShutdown {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
private async renderNoteOrRenoteActivity(data: Option, note: MiNote) {
|
||||
private async renderNoteOrRenoteActivity(data: Option, note: MiNote, user: MiUser) {
|
||||
if (data.localOnly) return null;
|
||||
const user = await this.usersRepository.findOneBy({ id: note.userId });
|
||||
if (user == null) throw new Error('user not found');
|
||||
|
||||
const content = this.isRenote(data) && !this.isQuote(data)
|
||||
? this.apRendererService.renderAnnounce(data.renote.uri ? data.renote.uri : `${this.config.url}/notes/${data.renote.id}`, note)
|
||||
: this.apRendererService.renderUpdate(await this.apRendererService.renderUpNote(note, false), user);
|
||||
: this.apRendererService.renderUpdate(await this.apRendererService.renderUpNote(note, user, false), user);
|
||||
|
||||
return this.apRendererService.addContext(content);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export class PollService {
|
|||
if (user == null) throw new Error('note not found');
|
||||
|
||||
if (this.userEntityService.isLocalUser(user)) {
|
||||
const content = this.apRendererService.addContext(this.apRendererService.renderUpdate(await this.apRendererService.renderNote(note, false), user));
|
||||
const content = this.apRendererService.addContext(this.apRendererService.renderUpdate(await this.apRendererService.renderNote(note, user, false), user));
|
||||
this.apDeliverManagerService.deliverToFollowers(user, content);
|
||||
this.relayService.deliverToRelays(user, content);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ function generateDummyUser(override?: Partial<MiUser>): MiUser {
|
|||
signupReason: null,
|
||||
noindex: false,
|
||||
enableRss: true,
|
||||
mandatoryCW: null,
|
||||
...override,
|
||||
};
|
||||
}
|
||||
|
|
@ -216,6 +217,7 @@ function toPackedUserLite(user: MiUser, override?: Packed<'UserLite'>): Packed<'
|
|||
isSystem: false,
|
||||
isSilenced: user.isSilenced,
|
||||
enableRss: true,
|
||||
mandatoryCW: null,
|
||||
...override,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFil
|
|||
import { bindThis } from '@/decorators.js';
|
||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
import { appendContentWarning } from '@/misc/append-content-warning.js';
|
||||
import { JsonLdService } from './JsonLdService.js';
|
||||
import { ApMfmService } from './ApMfmService.js';
|
||||
import { CONTEXT } from './misc/contexts.js';
|
||||
|
|
@ -339,7 +340,7 @@ export class ApRendererService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public async renderNote(note: MiNote, dive = true): Promise<IPost> {
|
||||
public async renderNote(note: MiNote, author: MiUser, dive = true): Promise<IPost> {
|
||||
const getPromisedFiles = async (ids: string[]): Promise<MiDriveFile[]> => {
|
||||
if (ids.length === 0) return [];
|
||||
const items = await this.driveFilesRepository.findBy({ id: In(ids) });
|
||||
|
|
@ -353,14 +354,14 @@ export class ApRendererService {
|
|||
inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId });
|
||||
|
||||
if (inReplyToNote != null) {
|
||||
const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } });
|
||||
const inReplyToUser = await this.usersRepository.findOneBy({ id: inReplyToNote.userId });
|
||||
|
||||
if (inReplyToUserExist) {
|
||||
if (inReplyToUser) {
|
||||
if (inReplyToNote.uri) {
|
||||
inReplyTo = inReplyToNote.uri;
|
||||
} else {
|
||||
if (dive) {
|
||||
inReplyTo = await this.renderNote(inReplyToNote, false);
|
||||
inReplyTo = await this.renderNote(inReplyToNote, inReplyToUser, false);
|
||||
} else {
|
||||
inReplyTo = `${this.config.url}/notes/${inReplyToNote.id}`;
|
||||
}
|
||||
|
|
@ -423,7 +424,12 @@ export class ApRendererService {
|
|||
apAppend += `\n\nRE: ${quote}`;
|
||||
}
|
||||
|
||||
const summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw;
|
||||
let summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw;
|
||||
|
||||
// Apply mandatory CW, if applicable
|
||||
if (author.mandatoryCW) {
|
||||
summary = appendContentWarning(summary, author.mandatoryCW);
|
||||
}
|
||||
|
||||
const { content } = this.apMfmService.getNoteHtml(note, apAppend);
|
||||
|
||||
|
|
@ -636,7 +642,7 @@ export class ApRendererService {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public async renderUpNote(note: MiNote, dive = true): Promise<IPost> {
|
||||
public async renderUpNote(note: MiNote, author: MiUser, dive = true): Promise<IPost> {
|
||||
const getPromisedFiles = async (ids: string[]): Promise<MiDriveFile[]> => {
|
||||
if (ids.length === 0) return [];
|
||||
const items = await this.driveFilesRepository.findBy({ id: In(ids) });
|
||||
|
|
@ -650,14 +656,14 @@ export class ApRendererService {
|
|||
inReplyToNote = await this.notesRepository.findOneBy({ id: note.replyId });
|
||||
|
||||
if (inReplyToNote != null) {
|
||||
const inReplyToUserExist = await this.usersRepository.exists({ where: { id: inReplyToNote.userId } });
|
||||
const inReplyToUser = await this.usersRepository.findOneBy({ id: inReplyToNote.userId });
|
||||
|
||||
if (inReplyToUserExist) {
|
||||
if (inReplyToUser) {
|
||||
if (inReplyToNote.uri) {
|
||||
inReplyTo = inReplyToNote.uri;
|
||||
} else {
|
||||
if (dive) {
|
||||
inReplyTo = await this.renderUpNote(inReplyToNote, false);
|
||||
inReplyTo = await this.renderUpNote(inReplyToNote, inReplyToUser, false);
|
||||
} else {
|
||||
inReplyTo = `${this.config.url}/notes/${inReplyToNote.id}`;
|
||||
}
|
||||
|
|
@ -720,7 +726,12 @@ export class ApRendererService {
|
|||
apAppend += `\n\nRE: ${quote}`;
|
||||
}
|
||||
|
||||
const summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw;
|
||||
let summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw;
|
||||
|
||||
// Apply mandatory CW, if applicable
|
||||
if (author.mandatoryCW) {
|
||||
summary = appendContentWarning(summary, author.mandatoryCW);
|
||||
}
|
||||
|
||||
const { content } = this.apMfmService.getNoteHtml(note, apAppend);
|
||||
|
||||
|
|
|
|||
|
|
@ -209,11 +209,12 @@ export class Resolver {
|
|||
case 'notes':
|
||||
return this.notesRepository.findOneByOrFail({ id: parsed.id })
|
||||
.then(async note => {
|
||||
const author = await this.usersRepository.findOneByOrFail({ id: note.userId });
|
||||
if (parsed.rest === 'activity') {
|
||||
// this refers to the create activity and not the note itself
|
||||
return this.apRendererService.addContext(this.apRendererService.renderCreate(await this.apRendererService.renderNote(note), note));
|
||||
return this.apRendererService.addContext(this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, author), note));
|
||||
} else {
|
||||
return this.apRendererService.renderNote(note);
|
||||
return this.apRendererService.renderNote(note, author);
|
||||
}
|
||||
});
|
||||
case 'users':
|
||||
|
|
|
|||
|
|
@ -592,6 +592,7 @@ export class UserEntityService implements OnModuleInit {
|
|||
isCat: user.isCat,
|
||||
noindex: user.noindex,
|
||||
enableRss: user.enableRss,
|
||||
mandatoryCW: user.mandatoryCW,
|
||||
isSilenced: user.isSilenced || this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote),
|
||||
speakAsCat: user.speakAsCat ?? false,
|
||||
approved: user.approved,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue