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
|
|
@ -103,15 +103,16 @@ export class ActivityPubServerService {
|
|||
/**
|
||||
* Pack Create<Note> or Announce Activity
|
||||
* @param note Note
|
||||
* @param author Author of the note
|
||||
*/
|
||||
@bindThis
|
||||
private async packActivity(note: MiNote): Promise<any> {
|
||||
private async packActivity(note: MiNote, author: MiUser): Promise<any> {
|
||||
if (isRenote(note) && !isQuote(note)) {
|
||||
const renote = await this.notesRepository.findOneByOrFail({ id: note.renoteId });
|
||||
return this.apRendererService.renderAnnounce(renote.uri ? renote.uri : `${this.config.url}/notes/${renote.id}`, note);
|
||||
}
|
||||
|
||||
return this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, false), note);
|
||||
return this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, author, false), note);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
|
|
@ -506,7 +507,7 @@ export class ActivityPubServerService {
|
|||
this.notesRepository.findOneByOrFail({ id: pining.noteId }))))
|
||||
.filter(note => !note.localOnly && ['public', 'home'].includes(note.visibility));
|
||||
|
||||
const renderedNotes = await Promise.all(pinnedNotes.map(note => this.apRendererService.renderNote(note)));
|
||||
const renderedNotes = await Promise.all(pinnedNotes.map(note => this.apRendererService.renderNote(note, user)));
|
||||
|
||||
const rendered = this.apRendererService.renderOrderedCollection(
|
||||
`${this.config.url}/users/${userId}/collections/featured`,
|
||||
|
|
@ -579,7 +580,7 @@ export class ActivityPubServerService {
|
|||
|
||||
if (sinceId) notes.reverse();
|
||||
|
||||
const activities = await Promise.all(notes.map(note => this.packActivity(note)));
|
||||
const activities = await Promise.all(notes.map(note => this.packActivity(note, user)));
|
||||
const rendered = this.apRendererService.renderOrderedCollectionPage(
|
||||
`${partOf}?${url.query({
|
||||
page: 'true',
|
||||
|
|
@ -723,7 +724,9 @@ export class ActivityPubServerService {
|
|||
|
||||
if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180');
|
||||
this.setResponseType(request, reply);
|
||||
return this.apRendererService.addContext(await this.apRendererService.renderNote(note, false));
|
||||
|
||||
const author = await this.usersRepository.findOneByOrFail({ id: note.userId });
|
||||
return this.apRendererService.addContext(await this.apRendererService.renderNote(note, author, false));
|
||||
});
|
||||
|
||||
// note activity
|
||||
|
|
@ -746,7 +749,9 @@ export class ActivityPubServerService {
|
|||
|
||||
if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180');
|
||||
this.setResponseType(request, reply);
|
||||
return (this.apRendererService.addContext(await this.packActivity(note)));
|
||||
|
||||
const author = await this.usersRepository.findOneByOrFail({ id: note.userId });
|
||||
return (this.apRendererService.addContext(await this.packActivity(note, author)));
|
||||
});
|
||||
|
||||
// outbox
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export * as 'admin/avatar-decorations/list' from './endpoints/admin/avatar-decor
|
|||
export * as 'admin/avatar-decorations/update' from './endpoints/admin/avatar-decorations/update.js';
|
||||
export * as 'admin/captcha/current' from './endpoints/admin/captcha/current.js';
|
||||
export * as 'admin/captcha/save' from './endpoints/admin/captcha/save.js';
|
||||
export * as 'admin/cw-user' from './endpoints/admin/cw-user.js';
|
||||
export * as 'admin/decline-user' from './endpoints/admin/decline-user.js';
|
||||
export * as 'admin/delete-account' from './endpoints/admin/delete-account.js';
|
||||
export * as 'admin/delete-all-files-of-a-user' from './endpoints/admin/delete-all-files-of-a-user.js';
|
||||
|
|
|
|||
67
packages/backend/src/server/api/endpoints/admin/cw-user.ts
Normal file
67
packages/backend/src/server/api/endpoints/admin/cw-user.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
||||
requireCredential: true,
|
||||
requireModerator: true,
|
||||
kind: 'write:admin:cw-user',
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userId: { type: 'string', format: 'misskey:id' },
|
||||
cw: { type: 'string', nullable: true },
|
||||
},
|
||||
required: ['userId', 'cw'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private readonly usersRepository: UsersRepository,
|
||||
|
||||
private readonly globalEventService: GlobalEventService,
|
||||
private readonly cacheService: CacheService,
|
||||
private readonly moderationLogService: ModerationLogService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const user = await this.cacheService.findUserById(ps.userId);
|
||||
|
||||
// Skip if there's nothing to do
|
||||
if (user.mandatoryCW === ps.cw) return;
|
||||
|
||||
// Log event first.
|
||||
// This ensures that we don't "lose" the log if an error occurs
|
||||
await this.moderationLogService.log(me, 'setMandatoryCW', {
|
||||
newCW: ps.cw,
|
||||
oldCW: user.mandatoryCW,
|
||||
userId: user.id,
|
||||
userUsername: user.username,
|
||||
userHost: user.host,
|
||||
});
|
||||
|
||||
await this.usersRepository.update(ps.userId, {
|
||||
// Collapse empty strings to null
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
mandatoryCW: ps.cw || null,
|
||||
});
|
||||
|
||||
// Synchronize caches and other processes
|
||||
this.globalEventService.publishInternalEvent('localUserUpdated', { id: ps.userId });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import type { UsersRepository, UserProfilesRepository } from '@/models/_.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['admin'],
|
||||
|
|
@ -28,10 +29,12 @@ export const paramDef = {
|
|||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.usersRepository)
|
||||
private usersRepository: UsersRepository,
|
||||
private readonly usersRepository: UsersRepository,
|
||||
|
||||
@Inject(DI.userProfilesRepository)
|
||||
private userProfilesRepository: UserProfilesRepository,
|
||||
private readonly userProfilesRepository: UserProfilesRepository,
|
||||
|
||||
private readonly cacheService: CacheService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const user = await this.usersRepository.findOneBy({ id: ps.userId });
|
||||
|
|
@ -43,6 +46,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
await this.userProfilesRepository.update(user.id, {
|
||||
alwaysMarkNsfw: true,
|
||||
});
|
||||
|
||||
await this.cacheService.userProfileCache.refresh(ps.userId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue