Merge branch 'develop' into feat/hide-sensitive-from-antenna

This commit is contained in:
Nanashi. 2025-02-01 13:59:39 +09:00 committed by GitHub
commit 812c3a1e78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 44 additions and 19 deletions

View File

@ -1,13 +1,14 @@
## Unreleased ## 2025.2.0
### General ### General
- Enhance: アンテナでセンシティブなチャンネルのノートを除外できるように ( #14177 ) - Enhance: アンテナでセンシティブなチャンネルのノートを除外できるように ( #14177 )
### Client ### Client
- - Fix: 一部環境でセンシティブなファイルを含むノートの非表示が効かない問題
- Fix: データセーバー有効時にもユーザーページの「ファイル」タブで画像が読み込まれてしまう問題を修正
### Server ### Server
- - Fix: 個別お知らせページのmetaタグ出力の条件が間違っていたのを修正
## 2025.1.0 ## 2025.1.0

View File

@ -7,6 +7,11 @@ bug report to the GitHub repository.
Thanks for helping make Misskey safe for everyone. Thanks for helping make Misskey safe for everyone.
> [!note]
> CNA [requires](https://www.cve.org/ResourcesSupport/AllResources/CNARules#section_5-2_Description) that CVEs include a description in English for inclusion in the CVE Catalog.
>
> When creating a security advisory, all content must be written in English (it is acceptable to include a non-English description along with the English one).
## When create a patch ## When create a patch
If you can also create a patch to fix the vulnerability, please create a PR on the private fork. If you can also create a patch to fix the vulnerability, please create a PR on the private fork.

View File

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "2025.1.0", "version": "2025.2.0-alpha.0",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -817,6 +817,7 @@ export class ClientServerService {
fastify.get<{ Params: { announcementId: string; } }>('/announcements/:announcementId', async (request, reply) => { fastify.get<{ Params: { announcementId: string; } }>('/announcements/:announcementId', async (request, reply) => {
const announcement = await this.announcementsRepository.findOneBy({ const announcement = await this.announcementsRepository.findOneBy({
id: request.params.announcementId, id: request.params.announcementId,
userId: IsNull(),
}); });
if (announcement) { if (announcement) {

View File

@ -41,6 +41,12 @@ export async function signout() {
if (!$i) return; if (!$i) return;
waiting(); waiting();
document.cookie.split(';').forEach((cookie) => {
const cookieName = cookie.split('=')[0].trim();
if (cookieName === 'token') {
document.cookie = `${cookieName}=; max-age=0; path=/`;
}
});
miLocalStorage.removeItem('account'); miLocalStorage.removeItem('account');
await removeAccount($i.id); await removeAccount($i.id);
const accounts = await getAccounts(); const accounts = await getAccounts();
@ -101,6 +107,9 @@ export async function removeAccount(idOrToken: Account['id']) {
} }
function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Promise<Account> { function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Promise<Account> {
document.cookie = "token=; path=/; max-age=0";
document.cookie = `token=${token}; path=/queue; max-age=86400; SameSite=Strict; Secure`; // bull dashboardの認証とかで使う
return new Promise((done, fail) => { return new Promise((done, fail) => {
window.fetch(`${apiUrl}/i`, { window.fetch(`${apiUrl}/i`, {
method: 'POST', method: 'POST',
@ -213,7 +222,6 @@ export async function login(token: Account['token'], redirect?: string) {
throw reason; throw reason;
}); });
miLocalStorage.setItem('account', JSON.stringify(me)); miLocalStorage.setItem('account', JSON.stringify(me));
document.cookie = `token=${token}; path=/; max-age=31536000`; // bull dashboardの認証とかで使う
await addAccount(me.id, token); await addAccount(me.id, token);
if (redirect) { if (redirect) {

View File

@ -57,7 +57,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { defineProps, shallowRef } from 'vue'; import { shallowRef } from 'vue';
import MkLink from '@/components/MkLink.vue'; import MkLink from '@/components/MkLink.vue';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import MkModalWindow from '@/components/MkModalWindow.vue'; import MkModalWindow from '@/components/MkModalWindow.vue';

View File

@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:alt="file.name" :alt="file.name"
:title="file.name" :title="file.name"
:cover="fit !== 'contain'" :cover="fit !== 'contain'"
:forceBlurHash="forceBlurhash" :forceBlurhash="forceBlurhash"
/> />
<i v-else-if="is === 'image'" class="ti ti-photo" :class="$style.icon"></i> <i v-else-if="is === 'image'" class="ti ti-photo" :class="$style.icon"></i>
<i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i> <i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i>

View File

@ -304,16 +304,16 @@ function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string
function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute'; function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: false): Array<string | string[]> | false | 'sensitiveMute';
*/ */
function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | false | 'sensitiveMute' { function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly = false): Array<string | string[]> | false | 'sensitiveMute' {
if (mutedWords == null) return false; if (mutedWords != null) {
const result = checkWordMute(noteToCheck, $i, mutedWords);
if (Array.isArray(result)) return result;
const result = checkWordMute(noteToCheck, $i, mutedWords); const replyResult = noteToCheck.reply && checkWordMute(noteToCheck.reply, $i, mutedWords);
if (Array.isArray(result)) return result; if (Array.isArray(replyResult)) return replyResult;
const replyResult = noteToCheck.reply && checkWordMute(noteToCheck.reply, $i, mutedWords); const renoteResult = noteToCheck.renote && checkWordMute(noteToCheck.renote, $i, mutedWords);
if (Array.isArray(replyResult)) return replyResult; if (Array.isArray(renoteResult)) return renoteResult;
}
const renoteResult = noteToCheck.renote && checkWordMute(noteToCheck.renote, $i, mutedWords);
if (Array.isArray(renoteResult)) return renoteResult;
if (checkOnly) return false; if (checkOnly) return false;

View File

@ -6,7 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<template v-for="file in note.files"> <template v-for="file in note.files">
<div <div
v-if="(defaultStore.state.nsfw === 'force' || file.isSensitive) && defaultStore.state.nsfw !== 'ignore' && !showingFiles.has(file.id)" v-if="(((
(defaultStore.state.nsfw === 'force' || file.isSensitive) &&
defaultStore.state.nsfw !== 'ignore'
) || (defaultStore.state.dataSaver.media && file.type.startsWith('image/'))) &&
!showingFiles.has(file.id)
)"
:class="[$style.filePreview, { [$style.square]: square }]" :class="[$style.filePreview, { [$style.square]: square }]"
@click="showingFiles.add(file.id)" @click="showingFiles.add(file.id)"
> >
@ -20,7 +25,8 @@ SPDX-License-Identifier: AGPL-3.0-only
/> />
<div :class="$style.sensitive"> <div :class="$style.sensitive">
<div> <div>
<div><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}</div> <div v-if="file.isSensitive"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.dataSaver.media && file.size ? ` (${bytes(file.size)})` : '' }}</div>
<div v-else><i class="ti ti-photo"></i> {{ defaultStore.state.dataSaver.media && file.size ? bytes(file.size) : i18n.ts.image }}</div>
<div>{{ i18n.ts.clickToShow }}</div> <div>{{ i18n.ts.clickToShow }}</div>
</div> </div>
</div> </div>
@ -43,6 +49,7 @@ import { notePage } from '@/filters/note.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
import bytes from '@/filters/bytes.js';
import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue'; import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue';
@ -91,6 +98,9 @@ const showingFiles = ref<Set<string>>(new Set());
display: grid; display: grid;
place-items: center; place-items: center;
font-size: 0.8em; font-size: 0.8em;
text-align: center;
padding: 8px;
box-sizing: border-box;
color: #fff; color: #fff;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px); backdrop-filter: blur(5px);

View File

@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, defineProps, ref, toRefs } from 'vue'; import { computed, ref, toRefs } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';

View File

@ -1,7 +1,7 @@
{ {
"type": "module", "type": "module",
"name": "misskey-js", "name": "misskey-js",
"version": "2025.1.0", "version": "2025.2.0-alpha.0",
"description": "Misskey SDK for JavaScript", "description": "Misskey SDK for JavaScript",
"license": "MIT", "license": "MIT",
"main": "./built/index.js", "main": "./built/index.js",