Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
434aa84d40 |
No files matched your search
+2
-1
@@ -349,7 +349,8 @@ struct TelegramBody {
|
||||
|
||||
/// Connect a bot: check the token, start polling and create a pairing code.
|
||||
async fn put_telegram(Extension(user): Extension<User>, State(app): State<AppState>, Json(b): Json<TelegramBody>) -> ApiResult {
|
||||
let token = b.token.trim().to_string();
|
||||
let token = crate::telegram::extract_token(&b.token)
|
||||
.ok_or_else(|| ApiError(StatusCode::BAD_REQUEST, "that is not a bot token – it looks like 123456789:AAH… (paste only the token from @BotFather)".into()))?;
|
||||
let bot = crate::telegram::check_token(&token).await.map_err(|e| ApiError(StatusCode::BAD_REQUEST, format!("token rejected by Telegram: {e:#}")))?;
|
||||
let s = crate::telegram::Settings { token, bot, pair_code: crate::telegram::new_pair_code(), ..Default::default() };
|
||||
app.store.set_user_setting(&user.id, "telegram", &s)?;
|
||||
|
||||
@@ -149,6 +149,12 @@ impl Bot {
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the bot token in what the user pasted (also the whole BotFather message).
|
||||
pub fn extract_token(input: &str) -> Option<String> {
|
||||
let re = regex::Regex::new(r"\b(\d{5,}:[A-Za-z0-9_-]{30,})\b").unwrap();
|
||||
re.captures(input).map(|c| c[1].to_string())
|
||||
}
|
||||
|
||||
/// Check a token and return the bot's username.
|
||||
pub async fn check_token(token: &str) -> Result<String> {
|
||||
let me = Bot { token: token.to_string() }.call("getMe", json!({})).await?;
|
||||
@@ -1145,6 +1151,14 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_the_token_in_pasted_text() {
|
||||
let msg = "Done! Congratulations on your new bot.\nUse this token to access the HTTP API:\n7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw4\nKeep your token secure";
|
||||
assert_eq!(extract_token(msg).as_deref(), Some("7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw4"));
|
||||
assert_eq!(extract_token(" 7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw4 ").as_deref(), Some("7123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw4"));
|
||||
assert_eq!(extract_token("my-password-123"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn step_lines() {
|
||||
assert_eq!(step_line("bash", &json!({"command": "cargo test\nmore"})), "bash: cargo test");
|
||||
|
||||
@@ -60,7 +60,17 @@ export function Telegram() {
|
||||
<li>{t("telegram.step2")}</li>
|
||||
</ol>
|
||||
<div className="row" style={{ gap: 6 }}>
|
||||
<input type="password" value={token} placeholder="123456789:AA…" autoComplete="off" onChange={(e) => setToken(e.target.value)} style={{ flex: 1 }} />
|
||||
<input
|
||||
type="text"
|
||||
name="telegram-bot-token"
|
||||
value={token}
|
||||
placeholder="123456789:AAH…"
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
className="mono"
|
||||
onChange={(e) => setToken(e.target.value)}
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
<button className="primary" onClick={() => void connect()} disabled={busy || !token.trim()}>
|
||||
{busy ? t("telegram.checking") : t("telegram.connect")}
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user