Public Access
Исправил постинг токена в ссылках
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
@@ -81,6 +84,58 @@ func NewBridge(telegramToken, discordToken, vkToken string) (*Bridge, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// signMediaToken создаёт подписанный токен для filePath (HMAC-SHA256), чтобы не светить токен бота в ссылках.
|
||||
func signMediaToken(filePath, secret string) string {
|
||||
mac := hmac.New(sha256.New, []byte(secret))
|
||||
mac.Write([]byte(filePath))
|
||||
sig := mac.Sum(nil)
|
||||
// payload.base64(sig) — в URL без padding
|
||||
enc := base64.URLEncoding.WithPadding(base64.NoPadding)
|
||||
return enc.EncodeToString([]byte(filePath)) + "." + enc.EncodeToString(sig)
|
||||
}
|
||||
|
||||
// verifyMediaToken проверяет подпись и возвращает filePath. secret должен совпадать с тем, что при подписи.
|
||||
func verifyMediaToken(token, secret string) (filePath string, ok bool) {
|
||||
enc := base64.URLEncoding.WithPadding(base64.NoPadding)
|
||||
idx := strings.LastIndex(token, ".")
|
||||
if idx == -1 {
|
||||
return "", false
|
||||
}
|
||||
payloadB, err1 := enc.DecodeString(token[:idx])
|
||||
sigB, err2 := enc.DecodeString(token[idx+1:])
|
||||
if err1 != nil || err2 != nil || len(sigB) != sha256.Size {
|
||||
return "", false
|
||||
}
|
||||
filePath = string(payloadB)
|
||||
mac := hmac.New(sha256.New, []byte(secret))
|
||||
mac.Write([]byte(filePath))
|
||||
expected := mac.Sum(nil)
|
||||
if !hmac.Equal(sigB, expected) {
|
||||
return "", false
|
||||
}
|
||||
return filePath, true
|
||||
}
|
||||
|
||||
// GetTelegramFileProxyURL возвращает публичный URL прокси для файла Telegram (без токена в ссылке).
|
||||
// В конец URL добавлено имя файла с расширением, чтобы ссылка в чате показывала .jpg и т.д.
|
||||
func (b *Bridge) GetTelegramFileProxyURL(filePath string) string {
|
||||
publicURL := strings.TrimSuffix(os.Getenv("PUBLIC_URL"), "/")
|
||||
secret := os.Getenv("MEDIA_PROXY_SECRET")
|
||||
if publicURL == "" || secret == "" {
|
||||
return ""
|
||||
}
|
||||
fileName := path.Base(filePath)
|
||||
if fileName == "" || fileName == "." {
|
||||
fileName = "file"
|
||||
}
|
||||
return publicURL + "/media/" + signMediaToken(filePath, secret) + "/" + url.PathEscape(fileName)
|
||||
}
|
||||
|
||||
// GetTelegramFileDirectURL возвращает прямую ссылку на файл Telegram (только для внутреннего использования на сервере).
|
||||
func (b *Bridge) GetTelegramFileDirectURL(filePath string) string {
|
||||
return fmt.Sprintf("https://api.telegram.org/file/bot%s/%s", b.Telegram.Token, filePath)
|
||||
}
|
||||
|
||||
// Отправка сообщения в Telegram
|
||||
func (b *Bridge) SendToTelegram(chatID int64, text string) error {
|
||||
msg := tgbotapi.NewMessage(chatID, text)
|
||||
|
||||
Reference in New Issue
Block a user