From 5c311e8a287a10da8cfa94ee74647fdfe07b1fa1 Mon Sep 17 00:00:00 2001 From: dakkar Date: Wed, 12 Jun 2024 17:06:33 +0100 Subject: [PATCH 1/5] tweak the rate limit for `notes/create` while fixing #467 #468, we changed the rate limit from 300/hour to 5/minute some people felt it was too low: they often boost notes in quick succession so here's a different approach: back to 300/hour, but not more than 1/second; this is the same settings that `notes/delete` has, BTW --- packages/backend/src/server/api/endpoints/notes/create.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index cc4472113..fe2dafa98 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -30,8 +30,9 @@ export const meta = { prohibitMoved: true, limit: { - duration: ms('1minute'), - max: 5, + duration: ms('1hour'), + max: 300, + minInterval: ms('1sec'), }, kind: 'write:notes', From 58c77c4d5cc33d9909087ff3cead1e86e59e438f Mon Sep 17 00:00:00 2001 From: dakkar Date: Sat, 8 Jun 2024 17:30:56 +0100 Subject: [PATCH 2/5] fix accesses to `canRenote` --- packages/frontend/src/components/MkNote.vue | 2 +- packages/frontend/src/components/MkNoteDetailed.vue | 2 +- packages/frontend/src/components/SkNote.vue | 2 +- packages/frontend/src/components/SkNoteDetailed.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index a14854fba..4c18428a7 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -336,7 +336,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 55a3ff8a1..683f8f992 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -342,7 +342,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 3c5a1baff..867e9106d 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -335,7 +335,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index c1ecc7eb1..b5b8782d0 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -351,7 +351,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, From f98229d3e042a3d894462bd03d33dfb97c2adccf Mon Sep 17 00:00:00 2001 From: dakkar Date: Sat, 8 Jun 2024 17:31:56 +0100 Subject: [PATCH 3/5] semicolons --- packages/frontend/src/components/MkNote.vue | 6 +++--- packages/frontend/src/components/MkNoteDetailed.vue | 6 +++--- packages/frontend/src/components/SkNote.vue | 6 +++--- packages/frontend/src/components/SkNoteDetailed.vue | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 4c18428a7..ddd693dc7 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -336,7 +336,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, @@ -441,7 +441,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } } else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) { const el = renoteButton.value as HTMLElement | null | undefined; @@ -460,7 +460,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => renoting = false); + }).finally(() => { renoting = false; }); } } } diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 683f8f992..788d03667 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -342,7 +342,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, @@ -460,7 +460,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) { const el = renoteButton.value as HTMLElement | null | undefined; if (el) { @@ -477,7 +477,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } } diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 867e9106d..f8d41df08 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -335,7 +335,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, @@ -440,7 +440,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } } else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) { const el = renoteButton.value as HTMLElement | null | undefined; @@ -459,7 +459,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } } } diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index b5b8782d0..8749967bd 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -351,7 +351,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility) } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, @@ -469,7 +469,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } else if (!appearNote.value.channel || appearNote.value.channel.allowRenoteToExternal) { const el = renoteButton.value as HTMLElement | null | undefined; if (el) { @@ -486,7 +486,7 @@ function renote(visibility: Visibility, localOnly: boolean = false) { }).then(() => { os.toast(i18n.ts.renoted); renoted.value = true; - }).finally(() => { renoting = false }); + }).finally(() => { renoting = false; }); } } From 935cb73c0b3df02a75cf65359c169ce7e05722e4 Mon Sep 17 00:00:00 2001 From: dakkar Date: Wed, 12 Jun 2024 17:28:14 +0100 Subject: [PATCH 4/5] more robust "only one renote at a time" logic this blocks the button as well, not just the hotkey --- packages/frontend/src/components/MkNote.vue | 6 +++++- packages/frontend/src/components/MkNoteDetailed.vue | 6 +++++- packages/frontend/src/components/SkNote.vue | 6 +++++- packages/frontend/src/components/SkNoteDetailed.vue | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index ddd693dc7..60e6100a8 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -336,7 +336,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, @@ -414,6 +414,8 @@ if (!props.mock) { } function boostVisibility() { + if (renoting) return; + if (!defaultStore.state.showVisibilitySelectorOnBoost) { renote(defaultStore.state.visibilityOnBoost); } else { @@ -425,6 +427,8 @@ function renote(visibility: Visibility, localOnly: boolean = false) { pleaseLogin(); showMovedDialog(); + renoting = true; + if (appearNote.value.channel) { const el = renoteButton.value as HTMLElement | null | undefined; if (el) { diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 788d03667..ac48b7e6c 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -342,7 +342,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, @@ -434,6 +434,8 @@ useTooltip(quoteButton, async (showing) => { }); function boostVisibility() { + if (renoting) return; + if (!defaultStore.state.showVisibilitySelectorOnBoost) { renote(defaultStore.state.visibilityOnBoost); } else { @@ -445,6 +447,8 @@ function renote(visibility: Visibility, localOnly: boolean = false) { pleaseLogin(); showMovedDialog(); + renoting = true; + if (appearNote.value.channel) { const el = renoteButton.value as HTMLElement | null | undefined; if (el) { diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index f8d41df08..638a38cd1 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -335,7 +335,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, @@ -413,6 +413,8 @@ if (!props.mock) { } function boostVisibility() { + if (renoting) return; + if (!defaultStore.state.showVisibilitySelectorOnBoost) { renote(defaultStore.state.visibilityOnBoost); } else { @@ -424,6 +426,8 @@ function renote(visibility: Visibility, localOnly: boolean = false) { pleaseLogin(); showMovedDialog(); + renoting = true; + if (appearNote.value.channel) { const el = renoteButton.value as HTMLElement | null | undefined; if (el) { diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index 8749967bd..abd1650fd 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -351,7 +351,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) { renoting = true; renote(appearNote.value.visibility); } }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, @@ -443,6 +443,8 @@ useTooltip(quoteButton, async (showing) => { }); function boostVisibility() { + if (renoting) return; + if (!defaultStore.state.showVisibilitySelectorOnBoost) { renote(defaultStore.state.visibilityOnBoost); } else { @@ -454,6 +456,8 @@ function renote(visibility: Visibility, localOnly: boolean = false) { pleaseLogin(); showMovedDialog(); + renoting = true; + if (appearNote.value.channel) { const el = renoteButton.value as HTMLElement | null | undefined; if (el) { From 73323a70a331980489b866e9ac88e2070fe6d92e Mon Sep 17 00:00:00 2001 From: dakkar Date: Wed, 12 Jun 2024 17:30:20 +0100 Subject: [PATCH 5/5] use configured boost visibility, instead of note's --- packages/frontend/src/components/MkNote.vue | 2 +- packages/frontend/src/components/MkNoteDetailed.vue | 2 +- packages/frontend/src/components/SkNote.vue | 2 +- packages/frontend/src/components/SkNoteDetailed.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 60e6100a8..4d2777013 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -336,7 +336,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(defaultStore.state.visibilityOnBoost); }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index ac48b7e6c..f9fb6066c 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -342,7 +342,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(defaultStore.state.visibilityOnBoost); }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value, diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 638a38cd1..cbdaa757e 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -335,7 +335,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(defaultStore.state.visibilityOnBoost); }, 'up|k|shift+tab': focusBefore, 'down|j|tab': focusAfter, 'esc': blur, diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index abd1650fd..227479366 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -351,7 +351,7 @@ let renoting = false; const keymap = { 'r': () => reply(true), 'e|a|plus': () => react(true), - '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(appearNote.value.visibility); }, + '(q)': () => { if (canRenote.value && !renoted.value && !renoting) renote(defaultStore.state.visibilityOnBoost); }, 'esc': blur, 'm|o': () => showMenu(true), 's': () => showContent.value !== showContent.value,