diff options
| author | 1Step621 <86859447+1STEP621@users.noreply.github.com> | 2024-02-06 16:45:21 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-06 16:45:21 +0900 |
| commit | 74245df3829622a3cc0c880ea710b5c1c4f5c584 (patch) | |
| tree | 3f6f4f1c598f4bd75be6bbfcd1d5deee8daa5adc /packages/frontend/src/components | |
| parent | enhance(frontend): KeepAliveのページキャッシュを削除できるよ... (diff) | |
| download | misskey-74245df3829622a3cc0c880ea710b5c1c4f5c584.tar.gz misskey-74245df3829622a3cc0c880ea710b5c1c4f5c584.tar.bz2 misskey-74245df3829622a3cc0c880ea710b5c1c4f5c584.zip | |
Enhance(frontend): フロント側でもリアクション権限のチェックをするように (#13134)
* フロント側でもリアクション権限のチェックをするように
* update CHANGELOG.md
* lint fixes
* remove unrelated diffs
* deny -> reject
denyは「(信用しないことを理由に)拒否する」という意味らしい
* allow -> accept
* EmojiSimpleにlocalOnlyを含めるように
* リアクション権限のない絵文字は打てないように(ダイアログを出すのではなく)
* regenerate type definitions
* lint fix
* remove unused locales
* remove unnecessary async
Diffstat (limited to 'packages/frontend/src/components')
6 files changed, 24 insertions, 9 deletions
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 58160cdf5b..f5ab7a2e29 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -118,6 +118,7 @@ import { i18n } from '@/i18n.js'; import { defaultStore } from '@/store.js'; import { customEmojiCategories, customEmojis, customEmojisMap } from '@/custom-emojis.js'; import { $i } from '@/account.js'; +import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; const props = withDefaults(defineProps<{ showPinned?: boolean; @@ -126,6 +127,7 @@ const props = withDefaults(defineProps<{ asDrawer?: boolean; asWindow?: boolean; asReactionPicker?: boolean; // 今は使われてないが将来的に使いそう + targetNote?: Misskey.entities.Note; }>(), { showPinned: true, }); @@ -340,7 +342,7 @@ watch(q, () => { }); function filterAvailable(emoji: Misskey.entities.EmojiSimple): boolean { - return ((emoji.roleIdsThatCanBeUsedThisEmojiAsReaction == null || emoji.roleIdsThatCanBeUsedThisEmojiAsReaction.length === 0) || ($i && $i.roles.some(r => emoji.roleIdsThatCanBeUsedThisEmojiAsReaction?.includes(r.id)))) ?? false; + return !props.targetNote || checkReactionPermissions($i!, props.targetNote, emoji); } function focus() { diff --git a/packages/frontend/src/components/MkEmojiPickerDialog.vue b/packages/frontend/src/components/MkEmojiPickerDialog.vue index 6660dcf1ed..444e8a4cec 100644 --- a/packages/frontend/src/components/MkEmojiPickerDialog.vue +++ b/packages/frontend/src/components/MkEmojiPickerDialog.vue @@ -24,6 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only :showPinned="showPinned" :pinnedEmojis="pinnedEmojis" :asReactionPicker="asReactionPicker" + :targetNote="targetNote" :asDrawer="type === 'drawer'" :max-height="maxHeight" @chosen="chosen" @@ -32,6 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> +import * as Misskey from 'misskey-js'; import { shallowRef } from 'vue'; import MkModal from '@/components/MkModal.vue'; import MkEmojiPicker from '@/components/MkEmojiPicker.vue'; @@ -43,6 +45,7 @@ const props = withDefaults(defineProps<{ showPinned?: boolean; pinnedEmojis?: string[], asReactionPicker?: boolean; + targetNote?: Misskey.entities.Note; choseAndClose?: boolean; }>(), { manualShowing: null, diff --git a/packages/frontend/src/components/MkEmojiPickerWindow.vue b/packages/frontend/src/components/MkEmojiPickerWindow.vue index 1a2c55e785..2a6828f242 100644 --- a/packages/frontend/src/components/MkEmojiPickerWindow.vue +++ b/packages/frontend/src/components/MkEmojiPickerWindow.vue @@ -13,12 +13,13 @@ SPDX-License-Identifier: AGPL-3.0-only :front="true" @closed="emit('closed')" > - <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" asWindow :class="$style.picker" @chosen="chosen"/> + <MkEmojiPicker :showPinned="showPinned" :asReactionPicker="asReactionPicker" :targetNote="targetNote" asWindow :class="$style.picker" @chosen="chosen"/> </MkWindow> </template> <script lang="ts" setup> import { } from 'vue'; +import * as Misskey from 'misskey-js'; import MkWindow from '@/components/MkWindow.vue'; import MkEmojiPicker from '@/components/MkEmojiPicker.vue'; @@ -26,6 +27,7 @@ withDefaults(defineProps<{ src?: HTMLElement; showPinned?: boolean; asReactionPicker?: boolean; + targetNote?: Misskey.entities.Note }>(), { showPinned: true, }); diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 735ec86564..27e8bc45b7 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -385,7 +385,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); if (props.mock) { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index dd956b21ad..a53dd90d27 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -385,7 +385,7 @@ function react(viaKeyboard = false): void { } } else { blur(); - reactionPicker.show(reactButton.value ?? null, reaction => { + reactionPicker.show(reactButton.value ?? null, note.value, reaction => { sound.playMisskeySfx('reaction'); misskeyApi('notes/reactions/create', { diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue index ffbf62a45c..67b448ccb7 100644 --- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue +++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue @@ -32,6 +32,8 @@ import { claimAchievement } from '@/scripts/achievements.js'; import { defaultStore } from '@/store.js'; import { i18n } from '@/i18n.js'; import * as sound from '@/scripts/sound.js'; +import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; +import { customEmojis } from '@/custom-emojis.js'; const props = defineProps<{ reaction: string; @@ -48,13 +50,19 @@ const emit = defineEmits<{ const buttonEl = shallowRef<HTMLElement>(); -const canToggle = computed(() => !props.reaction.match(/@\w/) && $i); +const isCustomEmoji = computed(() => props.reaction.includes(':')); +const emoji = computed(() => isCustomEmoji.value ? customEmojis.value.find(emoji => emoji.name === props.reaction.replace(/:/g, '').replace(/@\./, '')) : null); + +const canToggle = computed(() => { + return !props.reaction.match(/@\w/) && $i + && (emoji.value && checkReactionPermissions($i, props.note, emoji.value)) + || !isCustomEmoji.value; +}); +const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':')); async function toggleReaction() { if (!canToggle.value) return; - // TODO: その絵文字を使う権限があるかどうか確認 - const oldReaction = props.note.myReaction; if (oldReaction) { const confirm = await os.confirm({ @@ -101,8 +109,8 @@ async function toggleReaction() { } async function menu(ev) { - if (!canToggle.value) return; - if (!props.reaction.includes(':')) return; + if (!canGetInfo.value) return; + os.popupMenu([{ text: i18n.ts.info, icon: 'ti ti-info-circle', |