merge: Prevent "mark instance as NSFW" from producing hellspawns (!749)

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

Approved-by: Tess K <me@thvxl.se>
Approved-by: dakkar <dakkar@thenautilus.net>
This commit is contained in:
Hazelnoot 2024-11-21 05:26:41 +00:00
commit 241b186a8a
3 changed files with 42 additions and 2 deletions

View file

@ -1,5 +1,38 @@
# Upgrade Notes # Upgrade Notes
## 2024.10.0
### Hellspawns
Sharkey versions before 2024.10 suffered from a bug in the "Mark instance as NSFW" feature.
When a user from such an instance boosted a note, the boost would be converted to a hellspawn (pure renote with Content Warning).
Hellspawns are buggy and do not properly federate, so it may be desirable to correct any that already exist in the database.
The following script will correct any local or remote hellspawns in the database.
```postgresql
/* Remove "instance is marked as NSFW" hellspawns */
UPDATE "note"
SET "cw" = null
WHERE
"renoteId" IS NOT NULL
AND "text" IS NULL
AND "cw" = 'Instance is marked as NSFW'
AND "replyId" IS NULL
AND "hasPoll" = false
AND "fileIds" = '{}';
/* Fix legacy / user-created hellspawns */
UPDATE "note"
SET "text" = '.'
WHERE
"renoteId" IS NOT NULL
AND "text" IS NULL
AND "cw" IS NOT NULL
AND "replyId" IS NULL
AND "hasPoll" = false
AND "fileIds" = '{}';
```
## 2024.9.0 ## 2024.9.0
### Following Feed ### Following Feed

View file

@ -146,6 +146,8 @@ type Option = {
app?: MiApp | null; app?: MiApp | null;
}; };
export type PureRenoteOption = Option & { renote: MiNote } & ({ text?: null } | { cw?: null } | { reply?: null } | { poll?: null } | { files?: null | [] });
@Injectable() @Injectable()
export class NoteCreateService implements OnApplicationShutdown { export class NoteCreateService implements OnApplicationShutdown {
#shutdownController = new AbortController(); #shutdownController = new AbortController();
@ -412,7 +414,7 @@ export class NoteCreateService implements OnApplicationShutdown {
if (user.host && !data.cw) { if (user.host && !data.cw) {
await this.federatedInstanceService.fetch(user.host).then(async i => { await this.federatedInstanceService.fetch(user.host).then(async i => {
if (i.isNSFW) { if (i.isNSFW && !this.isPureRenote(data)) {
data.cw = 'Instance is marked as NSFW'; data.cw = 'Instance is marked as NSFW';
} }
}); });
@ -821,6 +823,11 @@ export class NoteCreateService implements OnApplicationShutdown {
if (!user.noindex) this.index(note); if (!user.noindex) this.index(note);
} }
@bindThis
public isPureRenote(note: Option): note is PureRenoteOption {
return this.isRenote(note) && !this.isQuote(note);
}
@bindThis @bindThis
private isRenote(note: Option): note is Option & { renote: MiNote } { private isRenote(note: Option): note is Option & { renote: MiNote } {
return note.renote != null; return note.renote != null;

View file

@ -442,7 +442,7 @@ export class NoteEditService implements OnApplicationShutdown {
if (user.host && !data.cw) { if (user.host && !data.cw) {
await this.federatedInstanceService.fetch(user.host).then(async i => { await this.federatedInstanceService.fetch(user.host).then(async i => {
if (i.isNSFW) { if (i.isNSFW && !this.noteCreateService.isPureRenote(data)) {
data.cw = 'Instance is marked as NSFW'; data.cw = 'Instance is marked as NSFW';
} }
}); });