diff --git a/README.md b/README.md index e68cebc..f5c7f96 100644 --- a/README.md +++ b/README.md @@ -305,14 +305,13 @@ Available in any chat; no authentication required. These commands require signing in as a Federation operator first, and run with that operator's own permissions rather than the bot's. -| Command | Description | -|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `/auth ` | Sign in as a Federation operator with an access token | -| `/authinfo` | Show your current operator identity and permissions | -| `/deauth` | Sign out | -| `/blacklist ` (no reply) | Blacklist an entity without creating a supporting report | -| `/blacklist ` (reply) | Create a supporting report for the replied-to message's author, then blacklist them. Give an existing `` before the type to blacklist against it instead, or the full ` ` to skip the reply entirely | -| `/link ` | Record a relationship (`alternative`, `proxy`, or `child`) between two Federation entities | +| Command | Description | +|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `/auth ` | Sign in as a Federation operator with an access token, in a private chat with the bot | +| `/authinfo` | Show your current operator identity and permissions | +| `/deauth` | Sign out | +| `/blacklist ` (reply) | Create a supporting report for the replied-to message's author, then blacklist them. Give an existing `` before the type to blacklist against it instead, or the full ` ` to skip the reply entirely | +| `/link ` | Record a relationship (`alternative`, `proxy`, or `child`) between two Federation entities | ## Adding a Language diff --git a/src/main/java/net/nosial/spb/handlers/operators/AuthenticationHandler.java b/src/main/java/net/nosial/spb/handlers/operators/AuthenticationHandler.java index bb0f5b5..1f367ee 100644 --- a/src/main/java/net/nosial/spb/handlers/operators/AuthenticationHandler.java +++ b/src/main/java/net/nosial/spb/handlers/operators/AuthenticationHandler.java @@ -14,6 +14,7 @@ import net.nosial.spb.objects.context.HandlerContext; import net.nosial.spb.objects.database.OperatorIdentity; import net.nosial.spb.utilities.HtmlEscape; +import net.nosial.spb.utilities.ModerationActions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.telegram.telegrambots.meta.api.objects.message.Message; @@ -24,8 +25,9 @@ /** * Handles an individual Telegram user's Federation operator credentials. * - *

{@code /auth } validates a token with the Federation server before - * atomically persisting it against the caller's Telegram user id. {@code /deauth} removes that + *

{@code /auth } validates a token with the Federation server before atomically + * persisting it against the caller's Telegram user id. It is only accepted in a private chat, since + * anywhere else the token would be visible to the whole chat. {@code /deauth} removes that * persisted credential. {@code /authinfo} creates a short-lived client with the caller's stored * credential and returns the current operator record from {@code getSelf()}. The process-wide * Federation client is never mutated, so one user's command cannot authenticate another user's @@ -73,6 +75,23 @@ else if (isCommand(context.update(), "deauth")) */ private static void authenticate(HandlerContext context, Message message, Language lang) throws TelegramApiException { + if (!isPrivateChat(message)) + { + if (getMessagePayload(message) == null) + { + sendReply(context, message, context.languages().get(lang, "authentication", "private_only")); + } + else if (ModerationActions.deleteMessage(context, message)) + { + sendReply(context, message, context.languages().get(lang, "authentication", "token_deleted")); + } + else + { + sendReply(context, message, context.languages().get(lang, "authentication", "token_not_deleted")); + } + return; + } + if (!context.federation().isAvailable()) { sendReply(context, message, context.languages().get(lang, "authentication", "unavailable")); diff --git a/src/main/resources/languages/en.yml b/src/main/resources/languages/en.yml index 48eca04..f606c37 100644 --- a/src/main/resources/languages/en.yml +++ b/src/main/resources/languages/en.yml @@ -402,6 +402,9 @@ blacklist: authentication: unavailable: "Authentication Unavailable\n\nFederation is not configured." usage: "Usage: /auth <access_token>" + private_only: "Private Chat Only\n\nSend /auth in a private chat with me, so your access token stays secret." + token_deleted: "Access Token Exposed\n\nYour access token was visible to this chat, so I deleted your message and did not use the token. Generate a new token on the Federation server, then send /auth in a private chat with me." + token_not_deleted: "Access Token Exposed\n\nYour access token is visible to this chat and I could not delete your message, so I did not use the token. Delete the message, generate a new token on the Federation server, then send /auth in a private chat with me." authenticated: "Authenticated\n\nSigned in as {0} ({1}).\n\nUse /authinfo to view your current operator permissions." rejected: "Authentication Failed\n\nThe access token was rejected by the Federation server." credential_store_failed: "Authentication Failed\n\nCould not store your credential. Please try again." diff --git a/src/main/resources/languages/es.yml b/src/main/resources/languages/es.yml index 3f5e90c..2b2318b 100644 --- a/src/main/resources/languages/es.yml +++ b/src/main/resources/languages/es.yml @@ -402,6 +402,9 @@ blacklist: authentication: unavailable: "Autenticación no disponible\n\nLa Federación no está configurada." usage: "Uso: /auth <access_token>" + private_only: "Solo en chat privado\n\nEnvíe /auth en un chat privado conmigo para que su token de acceso siga siendo secreto." + token_deleted: "Token de acceso expuesto\n\nSu token de acceso era visible en este chat, por lo que eliminé su mensaje y no usé el token. Genere un token nuevo en el servidor de la Federación y luego envíe /auth en un chat privado conmigo." + token_not_deleted: "Token de acceso expuesto\n\nSu token de acceso es visible en este chat y no pude eliminar su mensaje, por lo que no usé el token. Elimine el mensaje, genere un token nuevo en el servidor de la Federación y luego envíe /auth en un chat privado conmigo." authenticated: "Autenticado\n\nInició sesión como {0} ({1}).\n\nUse /authinfo para ver sus permisos de operador actuales." rejected: "Error de autenticación\n\nEl token de acceso fue rechazado por el servidor de la Federación." credential_store_failed: "Error de autenticación\n\nNo se pudo guardar su credencial. Por favor, inténtelo de nuevo." diff --git a/src/main/resources/languages/ru.yml b/src/main/resources/languages/ru.yml index ba65d3e..a3b5ca9 100644 --- a/src/main/resources/languages/ru.yml +++ b/src/main/resources/languages/ru.yml @@ -402,6 +402,9 @@ blacklist: authentication: unavailable: "Авторизация недоступна\n\nФедерация не настроена." usage: "Использование: /auth <access_token>" + private_only: "Только в личном чате\n\nОтправляйте /auth в личном чате со мной, чтобы ваш токен доступа оставался секретным." + token_deleted: "Токен доступа раскрыт\n\nВаш токен доступа был виден в этом чате, поэтому я удалил ваше сообщение и не использовал токен. Создайте новый токен на сервере Федерации, затем отправьте /auth в личном чате со мной." + token_not_deleted: "Токен доступа раскрыт\n\nВаш токен доступа виден в этом чате, а удалить ваше сообщение не удалось, поэтому токен не использован. Удалите сообщение, создайте новый токен на сервере Федерации, затем отправьте /auth в личном чате со мной." authenticated: "Авторизация успешна\n\nВы вошли как {0} ({1}).\n\nИспользуйте /authinfo для просмотра текущих прав оператора." rejected: "Ошибка авторизации\n\nТокен доступа отклонен сервером Федерации." credential_store_failed: "Ошибка авторизации\n\nНе удалось сохранить учетные данные. Попробуйте еще раз." diff --git a/src/main/resources/languages/zh.yml b/src/main/resources/languages/zh.yml index 4409872..ed54548 100644 --- a/src/main/resources/languages/zh.yml +++ b/src/main/resources/languages/zh.yml @@ -402,6 +402,9 @@ blacklist: authentication: unavailable: "身份验证不可用\n\n未配置联邦。" usage: "用法:/auth <access_token>" + private_only: "仅限私聊\n\n请在与我的私聊中发送 /auth,以确保您的访问令牌保密。" + token_deleted: "访问令牌已泄露\n\n您的访问令牌在此聊天中可见,因此我已删除您的消息,并且没有使用该令牌。请在联邦服务器上生成新令牌,然后在与我的私聊中发送 /auth。" + token_not_deleted: "访问令牌已泄露\n\n您的访问令牌在此聊天中可见,而我无法删除您的消息,因此没有使用该令牌。请删除该消息,在联邦服务器上生成新令牌,然后在与我的私聊中发送 /auth。" authenticated: "已身份验证\n\n已作为 {0} ({1}) 登录。\n\n使用 /authinfo 查看您当前的操作员权限。" rejected: "身份验证失败\n\n访问令牌被联邦服务器拒绝。" credential_store_failed: "身份验证失败\n\n无法存储您的凭据。请再试一次。"