Compare commits

...

4 commits

Author SHA1 Message Date
dakkar
7bc3d2d68d merge: try to honour user blocks on AP requests - #248 (!456)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/456
2024-04-03 11:01:14 +00:00
Marie
8c955fcce5 merge: use correct note design in favorites page - fixes #483 (!481)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/481

Closes #483

Approved-by: Amelia Yukii <amelia.yukii@shourai.de>
Approved-by: Marie <marie@kaifa.ch>
2024-04-03 09:28:01 +00:00
dakkar
bd7c4f66f3 use correct note design in favorites page - fixes #483 2024-03-27 16:03:35 +00:00
dakkar
606531a4b3 try to honour user blocks on AP requests - #248
as the comment says, this doesn't really work, because requests can be
signed by the remote instance actor instead of the real remote user

e.g. Misskey (and us) seems to always sign as the instance actor when
fetching notes ☹
2024-03-03 14:54:36 +00:00
3 changed files with 30 additions and 4 deletions

View file

@ -31,6 +31,7 @@ import type { MiNote } from '@/models/Note.js';
import { QueryService } from '@/core/QueryService.js';
import { UtilityService } from '@/core/UtilityService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { UserBlockingService } from '@/core/UserBlockingService.js';
import { bindThis } from '@/decorators.js';
import { IActivity } from '@/core/activitypub/type.js';
import { isPureRenote } from '@/misc/is-pure-renote.js';
@ -78,6 +79,7 @@ export class ActivityPubServerService {
private metaService: MetaService,
private utilityService: UtilityService,
private userEntityService: UserEntityService,
private userBlockingService: UserBlockingService,
private instanceActorService: InstanceActorService,
private apRendererService: ApRendererService,
private apDbResolverService: ApDbResolverService,
@ -206,6 +208,17 @@ export class ActivityPubServerService {
return true;
}
if (userId) {
/* this check is not really effective, because most requests we
get are signed by the remote instance user, not the user
who's requesting the information 😭 */
const blocked = await this.userBlockingService.checkBlocked(userId, authUser.user.id);
if (blocked) {
reply.code(401);
return true;
}
}
let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem);
if (!httpSignatureValidated) {
@ -706,6 +719,8 @@ export class ActivityPubServerService {
return;
}
if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return;
// リモートだったらリダイレクト
if (note.userHost != null) {
if (note.uri == null || this.utilityService.isSelfHost(note.userHost)) {
@ -739,6 +754,8 @@ export class ActivityPubServerService {
return;
}
if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return;
if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180');
this.setResponseType(request, reply);
return (this.apRendererService.addContext(await this.packActivity(note)));
@ -861,6 +878,8 @@ export class ActivityPubServerService {
return;
}
if (await this.shouldRefuseGetRequest(request, reply, note.userId)) return;
if (!this.config.checkActivityPubGetSignature) reply.header('Cache-Control', 'public, max-age=180');
this.setResponseType(request, reply);
return (this.apRendererService.addContext(await this.apRendererService.renderLike(reaction, note)));
@ -868,7 +887,7 @@ export class ActivityPubServerService {
// follow
fastify.get<{ Params: { follower: string; followee: string; } }>('/follows/:follower/:followee', async (request, reply) => {
if (await this.shouldRefuseGetRequest(request, reply)) return;
if (await this.shouldRefuseGetRequest(request, reply, request.params.follwer)) return;
// This may be used before the follow is completed, so we do not
// check if the following exists.
@ -910,6 +929,8 @@ export class ActivityPubServerService {
return;
}
if (await this.shouldRefuseGetRequest(request, reply, followRequest.followerId)) return;
const [follower, followee] = await Promise.all([
this.usersRepository.findOneBy({
id: followRequest.followerId,

View file

@ -55,8 +55,6 @@ import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js';
import { defaultStore } from '@/store.js';
console.log(defaultStore.state.noteDesign, defaultStore.state.noteDesign === 'sharkey');
const props = defineProps<{
pagination: Paging;
noGap?: boolean;

View file

@ -16,9 +16,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<template #default="{ items }">
<MkDateSeparatedList v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
<MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'misskey'"
v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
<MkNote :key="item.id" :note="item.note" :class="$style.note"/>
</MkDateSeparatedList>
<MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'sharkey'"
v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
<SkNote :key="item.id" :note="item.note" :class="$style.note"/>
</MkDateSeparatedList>
</template>
</MkPagination>
</MkSpacer>
@ -28,10 +33,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import MkPagination from '@/components/MkPagination.vue';
import MkNote from '@/components/MkNote.vue';
import SkNote from '@/components/SkNote.vue';
import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import { infoImageUrl } from '@/instance.js';
import { defaultStore } from '@/store.js';
const pagination = {
endpoint: 'i/favorites' as const,