Documentation
¶
Index ¶
- Constants
- Variables
- func IsSensitive(key string) bool
- func Normalize(key, value string) string
- func ParseVerificationMeta(stored string) (name, content string, err error)
- func SplitDomains(csv string) []string
- func SplitIPAllowlist(csv string) []string
- func Validate(key, value string) error
- type Store
- func (s *Store) All(ctx context.Context) (map[string]string, error)
- func (s *Store) Effective(ctx context.Context) (map[string]string, error)
- func (s *Store) Get(ctx context.Context, key string) (value string, found bool, err error)
- func (s *Store) Maintenance(ctx context.Context) (bool, error)
- func (s *Store) RateLimits(ctx context.Context) (perUser, perIP int, allowlist []string, err error)
- func (s *Store) RegistrationGate(ctx context.Context) (allow bool, domains []string, err error)
- func (s *Store) SMTPConfig(ctx context.Context) (host string, port int, user, pass, from string, err error)
- func (s *Store) Set(ctx context.Context, key, value, actor string) error
- func (s *Store) SiteVerificationMeta(ctx context.Context) (string, error)
- func (s *Store) WithSealer(secrets *sealx.Secrets) *Store
Constants ¶
const ( KeyBannerText = "banner_text" KeyBannerKind = "banner_kind" KeyMaintenanceMode = "maintenance_mode" KeyAllowSignup = "allow_signup" KeyAllowedDomains = "allowed_domains" KeyRateLimitPerUserPerMin = "rate_limit_per_user_per_min" KeyRateLimitPerIPPerMin = "rate_limit_per_ip_per_min" KeyRateLimitAllowlist = "rate_limit_allowlist" KeySMTPHost = "smtp_host" KeySMTPPort = "smtp_port" KeySMTPUser = "smtp_user" KeySMTPPass = "smtp_pass" KeySMTPFrom = "smtp_from" KeySiteVerificationMeta = "site_verification_meta" KindInfo, KindWarn = "info", "warn" FlagOff, FlagOn = "0", "1" )
const MaskedValue = "******"
MaskedValue is what sensitive keys (IsSensitive) render as in every read-back surface: the admin list response (both items and effective), the put response body and the admin.setting_change log entries. A client that submits MaskedValue back means "unchanged" — the put handler short-circuits on it without touching the store.
Variables ¶
var Defaults = map[string]string{ KeyBannerText: "", KeyBannerKind: KindInfo, KeyMaintenanceMode: FlagOff, KeyAllowSignup: FlagOn, KeyAllowedDomains: "", KeyRateLimitPerUserPerMin: "0", KeyRateLimitPerIPPerMin: "30", KeyRateLimitAllowlist: "", KeySMTPHost: "", KeySMTPPort: "587", KeySMTPUser: "", KeySMTPPass: "", KeySMTPFrom: "", KeySiteVerificationMeta: "", }
var Descriptions = map[string]string{ KeyBannerText: "站点公告文本(空 = 无公告);保存后全站顶条即时生效", KeyBannerKind: "公告样式:info = 蓝系 / warn = 橙红系", KeyMaintenanceMode: "维护模式:开启后全站顶栏显示「维护中」条(仅提示,不阻断请求)", KeyAllowSignup: "注册开关:关闭 = 邀请制(仅白名单邮箱可注册);保存后即时生效(SignupGate 热读)", KeyAllowedDomains: "注册邮箱域名白名单,逗号分隔(空 = 不限域名)", KeyRateLimitPerUserPerMin: "API 每用户限流(请求/分钟):0 = 关闭;修改后重启生效(启动期静态注入,不热重载)", KeyRateLimitPerIPPerMin: "认证路径每客户端 IP 限流(请求/分钟):0 = 关闭;修改后重启生效", KeyRateLimitAllowlist: "限流豁免名单:逗号分隔 IP 或 CIDR(如 10.0.0.5, 192.168.0.0/16);修改后重启生效", KeySMTPHost: "SMTP 服务器主机名(如 smtp.example.com;空 = 开发日志通道,邮件只写日志不外发)", KeySMTPPort: "SMTP 端口(空 = 缺省 587)", KeySMTPUser: "SMTP 认证用户名(空 = 不认证)", KeySMTPPass: "SMTP 认证密码:保存后仅以掩码回显;落库前经 PLOYKIT_SEAL_KEY 加密,未配置该环境变量时拒绝保存", KeySMTPFrom: "发件人邮箱(如 no-reply@example.com;空 = 未配置发件人)", KeySiteVerificationMeta: "站长验证:粘贴搜索引擎给的完整 <meta> 标签或 name|content 对(如 google-site-verification|abc123);清空即移除", }
Functions ¶
func IsSensitive ¶ added in v0.8.0
IsSensitive reports whether the key holds a credential that must never be echoed in plaintext — every read-back surface masks it with MaskedValue. v1 covers smtp_pass only.
func ParseVerificationMeta ¶ added in v0.8.0
ParseVerificationMeta splits the stored normalized pair back into its parts and re-validates both. Products recompose the meta tag server-side (`<meta name="…" content="…">`) from this output — the stored user input is never reflected, only the recomposed tag is.
func SplitDomains ¶
func SplitIPAllowlist ¶
Types ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) RateLimits ¶
func (*Store) RegistrationGate ¶
func (*Store) SMTPConfig ¶ added in v0.8.0
func (s *Store) SMTPConfig(ctx context.Context) (host string, port int, user, pass, from string, err error)
SMTPConfig hot-reads the outbound mail settings (same shape as Maintenance): DB row > env fallback > Defaults, with the stored smtp_pass decrypted. An empty host keeps the dev-channel semantics (log-only mailer); port defaults to 587. Meant for product hot-mailers polling on a short TTL.
func (*Store) SiteVerificationMeta ¶ added in v0.8.0
SiteVerificationMeta hot-reads the verification meta in its normalized `name|content` stored form (DB row > env SITE_VERIFICATION_META > ""). Parse the pair with ParseVerificationMeta and recompose the tag server-side — stored user input is never reflected verbatim.
func (*Store) WithSealer ¶ added in v0.8.0
WithSealer attaches the credential sealer used to encrypt sensitive keys (v1: smtp_pass) at rest. Call it once after Bootstrap/NewStore and before the first admin write; returns the store for chaining. Build the argument with sealx.NewSecretsFromEnv() (nil when PLOYKIT_SEAL_KEY is unset — sensitive writes then stay rejected and reads of stored rows error, which is the intended posture).
Sealing lives on the Store rather than on the HTTP adapter on purpose: it is a storage property, and every writer (admin UI today, product code tomorrow) gets the same guarantee.