Refuse a bot token without a channel

Saving a token and leaving the channel empty produced a state that could
neither send nor delete, and only said so at the next attempt.
This commit is contained in:
Matthias G
2026-08-03 12:59:34 +02:00
parent 768bbca59c
commit 7a10754e70
4 changed files with 21 additions and 5 deletions
+4 -2
View File
@@ -298,7 +298,8 @@
"tokenInvalid": "Ein Bot-Token beginnt mit xoxb oder xoxp.",
"runNotSent": "Bei diesem Lauf ging keine Nachricht raus.",
"runNoChannel": "Es ist kein Kanal hinterlegt.",
"runNotFound": "Im Kanal war keine passende Nachricht zu finden. Braucht der Bot noch das Recht channels:history?"
"runNotFound": "Im Kanal war keine passende Nachricht zu finden. Braucht der Bot noch das Recht channels:history?",
"channelRequired": "Zum Bot-Token gehört ein Kanal, sonst weiß Logbuch nicht, wohin."
},
"errors": {
"nameRequired": "Trag einen Namen ein.",
@@ -759,7 +760,8 @@
},
"errors": {
"webhookInvalid": "Das sieht nicht nach einer Slack-Webhook-Adresse aus.",
"tokenInvalid": "Ein Bot-Token beginnt mit xoxb oder xoxp."
"tokenInvalid": "Ein Bot-Token beginnt mit xoxb oder xoxp.",
"channelRequired": "Zum Bot-Token gehört ein Kanal."
},
"tokenStored": "Hinterlegt, wird nicht mehr angezeigt.",
"replaceToken": "Anderen Token eintragen",
+4 -2
View File
@@ -298,7 +298,8 @@
"tokenInvalid": "A bot token starts with xoxb or xoxp.",
"runNotSent": "That run sent no message.",
"runNoChannel": "No channel is stored.",
"runNotFound": "No matching message found in the channel. Does the bot still need channels:history?"
"runNotFound": "No matching message found in the channel. Does the bot still need channels:history?",
"channelRequired": "A bot token needs a channel, otherwise Logbuch has no target."
},
"errors": {
"nameRequired": "Enter a name.",
@@ -759,7 +760,8 @@
},
"errors": {
"webhookInvalid": "That does not look like a Slack webhook address.",
"tokenInvalid": "A bot token starts with xoxb or xoxp."
"tokenInvalid": "A bot token starts with xoxb or xoxp.",
"channelRequired": "A bot token needs a channel."
},
"tokenStored": "Stored, no longer shown.",
"replaceToken": "Enter a different token",
+6 -1
View File
@@ -64,7 +64,12 @@ export function SlackForm({ hasWebhook, hasBot, channel, fromEnv, includeInterna
</AdminField>
)}
<AdminField id="channel" label={t('fields.channel')} hint={t('hints.channel')}>
<AdminField
id="channel"
label={t('fields.channel')}
hint={t('hints.channel')}
error={state.fields?.channel ? t(`errors.${state.fields.channel}`) : undefined}
>
<input
id="channel"
name="channel"
+7
View File
@@ -36,6 +36,13 @@ export async function performSaveSlack(viewer: Viewer, formData: FormData): Prom
return invalid('tokenInvalid', undefined, { botToken: 'tokenInvalid' })
}
const stored = await readSettings(['slack.botToken'])
const withToken = keepToken ? Boolean(stored.get('slack.botToken')) : token !== ''
if (withToken && channel === '') {
return invalid('channelRequired', undefined, { channel: 'channelRequired' })
}
if (!keep) {
if (webhook === '') {
await clearSetting('slack.webhook')