Files
ONE/backend/internal/config/config.go
T
Sakurasan baf14ec6ca 评论登录新增 Google OAuth 与 Telegram Login Widget
- Google:授权码流程(openid email profile),handle 优先用已验证邮箱,头像取 picture
- Telegram:官方 widget 直接回传签名资料,后端按官方算法验签(secret=SHA256(bot_token),除 hash 外全字段排序比对)+ auth_date 24h 时效
- providers 列表自动按配置下发(未配置的不显示);widget 型带 bot 用户名
- 三个登录方式共用读者会话与 upsert;Telegram 走 POST 无跳转
- .env.example 补 ONE_GOOGLE_* / ONE_TELEGRAM_* 模板
2026-09-28 01:32:39 +08:00

154 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"crypto/rand"
"encoding/hex"
"log"
"os"
"path/filepath"
"strings"
)
type Config struct {
Addr string
Driver string // sqlite | postgres
DSN string
AdminUser string
AdminPass string
SessionSec string
WebDist string
DataDir string
SiteURL string
InsecureDev bool
// 评论区 GitHub 登录(OAuth App 凭据,站主在 GitHub 上创建后填入)
GitHubClientID string
GitHubClientSecret string
// 评论区 Google 登录(OAuth 客户端凭据,Google Cloud Console 创建)
GoogleClientID string
GoogleClientSecret string
// 评论区 Telegram 登录(Login Widget):Bot 是用户名(不含 @,下发给
// 前端 widget),Token 用于验签。两者都要,缺一该入口不开放。
TelegramBot string
TelegramToken string
// 对象存储(文件上传)。变量名与站主 .env 里的写法一致(站主已整理):
// S3Api = R2 的 S3 API 端点(https://<账户ID>.r2.cloudflarestorage.com,
// 控制台 R2 概览可复制),上传走它 —— 公开域名收不了上传请求
// PublicURL = 公开访问域名(r2.dev / 绑定的自定义域名),文件直链走它
// AccessKey / SecretAccessKey / Bucket = R2 凭据与桶名
// 五项齐全 → 上传走 R2、直链走 PublicURL;缺任一项回落本地磁盘
// (DataDir/uploads),并在启动日志提示一句。
StorageDriver string // r2 | local
S3Endpoint string // env: S3Api
R2Bucket string
R2AccessKey string
R2SecretKey string
UploadsPublicBase string // env: PublicURL
}
func getenv(k, def string) string {
if v := strings.TrimSpace(os.Getenv(k)); v != "" {
return v
}
return def
}
func Load() (*Config, error) {
root := getenv("ONE_ROOT", "")
if root == "" {
if wd, err := os.Getwd(); err == nil {
root = filepath.Dir(wd) // server/ -> repo root
} else {
root = "."
}
}
c := &Config{
Addr: getenv("ONE_ADDR", ":8080"),
Driver: strings.ToLower(getenv("ONE_DB_DRIVER", "sqlite")),
AdminUser: getenv("ONE_ADMIN_USER", "admin"),
AdminPass: getenv("ONE_ADMIN_PASSWORD", "admin"),
SessionSec: getenv("ONE_SECRET", ""),
WebDist: getenv("ONE_WEB_DIST", filepath.Join(root, "frontend", "dist")),
DataDir: getenv("ONE_DATA_DIR", filepath.Join(root, "data")),
SiteURL: getenv("ONE_SITE_URL", "http://localhost:8080"),
}
if c.Driver == "" {
c.Driver = "sqlite"
}
if c.Driver != "sqlite" && c.Driver != "postgres" && c.Driver != "postgresql" {
return nil, &badDriver{c.Driver}
}
if c.Driver == "postgresql" {
c.Driver = "postgres"
}
if c.DSN = getenv("ONE_DB_DSN", ""); c.DSN == "" {
if c.Driver == "sqlite" {
c.DSN = filepath.Join(c.DataDir, "one.db")
} else {
c.DSN = "postgres://localhost/one?sslmode=disable"
}
}
if c.SessionSec == "" {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return nil, err
}
c.SessionSec = hex.EncodeToString(b)
}
c.InsecureDev = os.Getenv("ONE_ADMIN_PASSWORD") == ""
// 对象存储:变量名按站主 .env 里整理好的来(无 ONE_ 前缀)。
c.UploadsPublicBase = strings.TrimRight(getenv("PublicURL", ""), "/")
c.S3Endpoint = getenv("S3Api", "")
c.R2AccessKey = getenv("AccessKey", "")
c.R2SecretKey = getenv("SecretAccessKey", "")
c.R2Bucket = getenv("Bucket", "")
if c.S3Endpoint != "" && c.R2Bucket != "" && c.R2AccessKey != "" && c.R2SecretKey != "" {
c.StorageDriver = "r2"
} else {
c.StorageDriver = "local"
// 配了一半(有凭据没端点之类)时给一句启动日志,别让站主猜。
// 只报字段名,不报值。
var missing []string
if c.S3Endpoint == "" {
missing = append(missing, "S3Api")
}
if c.R2Bucket == "" {
missing = append(missing, "Bucket")
}
if c.R2AccessKey == "" {
missing = append(missing, "AccessKey")
}
if c.R2SecretKey == "" {
missing = append(missing, "SecretAccessKey")
}
if len(missing) > 0 {
log.Printf("storage: R2 配置缺 %s,上传回落本地磁盘", strings.Join(missing, "、"))
}
}
// 评论区 GitHub 登录(OAuth App 凭据,站主在 GitHub 上创建后填入)
c.GitHubClientID = getenv("ONE_GITHUB_CLIENT_ID", "")
c.GitHubClientSecret = getenv("ONE_GITHUB_CLIENT_SECRET", "")
c.GoogleClientID = getenv("ONE_GOOGLE_CLIENT_ID", "")
c.GoogleClientSecret = getenv("ONE_GOOGLE_CLIENT_SECRET", "")
c.TelegramBot = getenv("ONE_TELEGRAM_BOT", "")
c.TelegramToken = getenv("ONE_TELEGRAM_BOT_TOKEN", "")
return c, nil
}
type badDriver struct{ d string }
func (e *badDriver) Error() string {
return "unsupported ONE_DB_DRIVER: " + e.d + " (use sqlite or postgres)"
}