common

package
v1.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: Apache-2.0 Imports: 43 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppConfigResp

type AppConfigResp struct {
	RSAPublicKey                   string
	Version                        int
	WelcomeMessage                 string // 登录欢迎语
	NewUserJoinSystemGroup         int    // 新用户是否加入系统群聊
	SearchByPhone                  int    // 是否可通过手机号搜索
	RegisterInviteOn               int    // 是否开启注册邀请
	SendWelcomeMessageOn           int    // 是否发送登录欢迎语
	InviteSystemAccountJoinGroupOn int    // 是否允许邀请系统账号进入群聊
	RegisterUserMustCompleteInfoOn int    // 是否要求注册用户必须填写完整信息
	ChannelPinnedMessageMaxCount   int    // 频道置顶消息最大数量
	DestroyCoolingOffDays          int    // 注销冷静期天数(默认 7)
}

AppConfigResp returns safe configuration info, excluding sensitive fields such as SuperToken.

type Common

type Common struct {
	log.Log
	// contains filtered or unexported fields
}

Common Common

func New

func New(ctx *config.Context) *Common

New New

func (*Common) Route

func (cn *Common) Route(r *wkhttp.WKHttp)

Route 路由配置

func (*Common) SystemSettings added in v1.3.0

func (cn *Common) SystemSettings() *SystemSettings

SystemSettings exposes the shared admin-tunable settings reader for callers that already hold a *Common. New consumers in other packages should prefer common.EnsureSystemSettings(ctx) directly.

type Country

type Country struct {
	Code string `json:"code"`
	Icon string `json:"icon"`
	Name string `json:"name"`
}

Country Country

func Countrys

func Countrys() []*Country

Countrys Countrys

type IService

type IService interface {
	GetAppConfig() (*AppConfigResp, error)
	// 获取短编号
	GetShortno() (string, error)
	SetShortnoUsed(shortno string, business string) error
}

IService IService

func NewService

func NewService(ctx *config.Context) IService

NewService NewService

type Manager

type Manager struct {
	log.Log
	// contains filtered or unexported fields
}

Manager 通用后台管理api

func NewManager

func NewManager(ctx *config.Context) *Manager

NewManager NewManager

func (*Manager) Route

func (m *Manager) Route(r *wkhttp.WKHttp)

Route 配置路由规则

type SystemSettings added in v1.3.0

type SystemSettings struct {
	log.Log
	// contains filtered or unexported fields
}

SystemSettings is the read path for admin-tunable global config.

Lookup model:

  • Snapshot is an immutable map[string]string ("category.key" → value), swapped atomically by Load / Reload. Readers go through atomic.Pointer and never take a lock; SMTP send (high-frequency) does not block on admin writes.
  • Empty DB value means "not configured" and falls back to the matching yaml field on *config.Config.
  • Encrypted values are decrypted at snapshot-build time and cached in plaintext form in the map; the high-frequency read path never calls the cipher. Decryption failure logs an error and skips the entry, so the getter falls back to yaml rather than serving a corrupt value.

func EnsureSystemSettings added in v1.3.0

func EnsureSystemSettings(ctx *config.Context) *SystemSettings

EnsureSystemSettings returns the process-wide SystemSettings instance, constructing it on first call. Safe to call from any goroutine.

Failed initial Load is non-fatal: an empty-snapshot instance is stored and the background auto-reload (started here) will retry every reloadTTL. Until then all getters fall back to yaml — degraded mode, not a hard failure. A successful subsequent reload self-heals.

func NewSystemSettings added in v1.3.0

func NewSystemSettings(ctx *config.Context, db *systemSettingDB) *SystemSettings

NewSystemSettings builds a helper with an empty initial snapshot. Callers must invoke Load() once at startup before serving traffic; Reload() is safe to call at any time (admin write path uses it).

func (*SystemSettings) AppBotAuthCacheTTLSeconds added in v1.7.0

func (s *SystemSettings) AppBotAuthCacheTTLSeconds() int

AppBotAuthCacheTTLSeconds is the safety-net TTL (seconds) written with each shared App Bot auth cache key. Read from system_setting (category "app_bot", key "auth_cache_ttl_seconds"); hot-reloaded with the rest of the snapshot, so an operator can retune it without a deploy. Out-of-range values fall back to the code default rather than being served verbatim (defence in depth).

func (*SystemSettings) DocsEnabled added in v1.8.1

func (s *SystemSettings) DocsEnabled() bool

DocsEnabled reports whether clients should surface the docs module (backed by the new octo-docs-backend service). This is a presentation toggle only: it gates client-side display of the docs entry and does not itself grant or enforce any server-side authorization. Default false so the module stays hidden until octo-docs-backend is live and the admin flips docs.enabled for a controlled rollout. Value source: system_setting docs.enabled (DB, hot-reloaded).

func (*SystemSettings) IncomingWebhookEnabled added in v1.6.0

func (s *SystemSettings) IncomingWebhookEnabled() bool

IncomingWebhookEnabled 是群入站 Webhook 功能的总开关。关闭后 push 端点返回 404、 管理写操作(create/update/delete/regenerate)被拒绝,仅保留 list 只读。 回退链:DB → env(DM_INCOMINGWEBHOOK_ENABLED) → 默认开启(true)。

func (*SystemSettings) IncomingWebhookMaxPerCreator added in v1.6.1

func (s *SystemSettings) IncomingWebhookMaxPerCreator() int

IncomingWebhookMaxPerCreator 单个普通成员/bot 在一个群内可创建的 webhook 数量 上限(群主/管理员豁免,仅受群级 max_per_group 约束)。DB → env → 默认 5。 读侧防御:≤0 回退默认(同 max_per_group,避免误配成"任何成员都建不了"的暗关)。

func (*SystemSettings) IncomingWebhookMaxPerGroup added in v1.6.0

func (s *SystemSettings) IncomingWebhookMaxPerGroup() int

IncomingWebhookMaxPerGroup 单个群可创建的 webhook 数量上限。DB → env → 默认 10。 读侧防御:≤0 回退默认(max_per_group=0 会让每次 create 都 ErrQuotaExceeded,是 总开关之外一种更难诊断的「暗关」)。

func (*SystemSettings) IncomingWebhookMemberCanBroadcast added in v1.7.0

func (s *SystemSettings) IncomingWebhookMemberCanBroadcast() bool

IncomingWebhookMemberCanBroadcast 控制【非管理员成员】创建的 webhook 是否可使用广播型 @(@所有人 / @所有 AI)。关闭后,成员建的 webhook 即便已置 allow_mention_* 能力位,其 广播也在 push 读路径被剥离(mention_ignored 回报);【管理员创建】的 webhook 不受影响。 因为是 push 读侧 AND(参见 incomingwebhook.buildMention),翻此开关可【即时收回】全部成员 广播、无需迁移存量列。回退链:DB → env(OCTO_INCOMINGWEBHOOK_MEMBER_CAN_BROADCAST) → 默认开启(true)。

func (*SystemSettings) IncomingWebhookPerWebhookBurst added in v1.6.0

func (s *SystemSettings) IncomingWebhookPerWebhookBurst() int

IncomingWebhookPerWebhookBurst 单个 webhook 令牌桶突发上限。DB → env → 默认 10。 读侧防御:≤0 回退默认(同 RPS,避免 `burst<=0` 短路静默关掉限流器)。

func (*SystemSettings) IncomingWebhookPerWebhookRPS added in v1.6.0

func (s *SystemSettings) IncomingWebhookPerWebhookRPS() float64

IncomingWebhookPerWebhookRPS 单个 webhook 令牌桶速率(rps)。DB → env → 默认 5。

读侧防御(D-289 同型,覆盖直接改库的旁路):rps 必须是正有限值;NaN/±Inf/≤0 一律 回退到 env/默认。否则 allowPerWebhook 的 `rps<=0` 短路会把限流器静默关掉,NaN 还会 让 Redis Lua 脚本报错而 fail-open——正是这个 getter 要兜住的。写侧也已拒绝 (settingTypeFloat + Positive,见 api_manager_system_setting.go),此处是纵深防御。

func (*SystemSettings) Load added in v1.3.0

func (s *SystemSettings) Load() error

Load reads every row from system_setting and atomically replaces the snapshot. Used at startup and by Reload (which is just an alias for "load now" with logging semantics).

func (*SystemSettings) LocalLoginOff added in v1.4.0

func (s *SystemSettings) LocalLoginOff() bool

LocalLoginOff returns whether local-account login entry points should be disabled. When true, frontend hides the local login UI and backend rejects requests to /v1/user/login, /v1/user/usernamelogin, /v1/user/emaillogin and their companion code-send endpoints. Password-recovery flows and third-party /SSO (GitHub, Gitee, OIDC) are not affected — this toggle is meant for deployments that have adopted SSO and want to force users through it.

Default false (no yaml fallback): plain self-hosted deployments without DB override keep the historical "local login enabled" behavior.

Safety override: even if the DB says local_off=1, this getter returns false when no third-party login (OIDC / GitHub / Gitee) is actually configured. Without the override an admin who flips the switch before wiring up an IdP would lock everyone — including themselves — out of the system. The override always picks "open" so the deployment stays accessible while ops fixes the missing SSO config. The hazard is surfaced via startup log (logLocalLoginOffSafetyOverride) so it isn't silently swallowed.

func (*SystemSettings) LogLocalLoginOffSafetyOverrideIfActive added in v1.4.0

func (s *SystemSettings) LogLocalLoginOffSafetyOverrideIfActive(localOff bool)

LogLocalLoginOffSafetyOverrideIfActive emits a single error-level log entry when local_off is intended to be on but no third-party login is configured — the exact state where LocalLoginOff() silently returns false to keep the deployment from locking itself. The log is the only signal ops have that the admin's intent is currently being overridden; without it the inconsistency is invisible until someone wonders why local login still works after flipping the switch.

Why localOff is a parameter, not read from snapshot here:

Callers know the intended value with stronger guarantees than the
shared snapshot. The manager-write path can pass the just-validated
request value (independent of whether Reload succeeded — PR #104 P2
from yujiawei). Startup passes the freshly-loaded snapshot value.
Reading the snapshot directly inside this method would silently miss
the warning when Reload fails right after a write, exactly when ops
most needs the signal.

Callers: invoke once at server startup (Common.Route) after Load completes, and from the manager update handler after a write that touched login.local_off (passing the plan's value).

func (*SystemSettings) RawLocalLoginOffFromSnapshot added in v1.4.0

func (s *SystemSettings) RawLocalLoginOffFromSnapshot() bool

RawLocalLoginOffFromSnapshot returns the snapshot's raw DB value for login.local_off without applying the SSO-safety override. Used by callers that need to feed LogLocalLoginOffSafetyOverrideIfActive at startup (the snapshot has just been loaded, so freshness isn't a concern). Exposed publicly because the field-level `getBool` is package-private and the only external need is this one logging path.

func (*SystemSettings) RegisterEmailOn added in v1.3.0

func (s *SystemSettings) RegisterEmailOn() bool

RegisterEmailOn returns whether email-based registration / login is enabled.

func (*SystemSettings) RegisterOff added in v1.3.0

func (s *SystemSettings) RegisterOff() bool

RegisterOff returns whether registration is globally disabled. DB value wins over cfg.Register.Off when set.

func (*SystemSettings) RegisterOnlyChina added in v1.3.0

func (s *SystemSettings) RegisterOnlyChina() bool

RegisterOnlyChina returns whether only China-region phone numbers may register.

func (*SystemSettings) RegisterUsernameOn added in v1.3.0

func (s *SystemSettings) RegisterUsernameOn() bool

RegisterUsernameOn returns whether username-based registration is enabled.

func (*SystemSettings) Reload added in v1.3.0

func (s *SystemSettings) Reload() error

Reload is the admin-write hook: after the manager API upserts new values it calls this so the change is visible on this instance immediately (other instances pick it up within reloadTTL).

func (*SystemSettings) SidebarRecentFilterGroupDays added in v1.6.0

func (s *SystemSettings) SidebarRecentFilterGroupDays() int

SidebarRecentFilterGroupDays returns the recent-tab activity window for group conversations, in days. 0 disables the window (all groups returned). Defaults to defaultSidebarRecentFilterGroupDays (3) — today's hard-coded behaviour.

func (*SystemSettings) SidebarRecentFilterPersonDays added in v1.6.0

func (s *SystemSettings) SidebarRecentFilterPersonDays() int

SidebarRecentFilterPersonDays returns the recent-tab activity window for DM conversations, in days. Defaults to 0, which keeps today's "DMs are always shown regardless of age" behaviour; the per-type default makes the historical hard-coded `!isDM` exemption data-driven.

func (*SystemSettings) SidebarRecentFilterThreadDays added in v1.6.0

func (s *SystemSettings) SidebarRecentFilterThreadDays() int

SidebarRecentFilterThreadDays returns the recent-tab activity window for thread (community topic) conversations, in days. 0 disables the window.

func (*SystemSettings) SpaceDisableUserCreate added in v1.5.0

func (s *SystemSettings) SpaceDisableUserCreate() bool

SpaceDisableUserCreate reports whether the user-facing「创建空间」入口应被 关闭。完整 fallback 链(按优先级):

  1. DB 行存在且 value 非空 → 走 getBool 解析(1/true/TRUE → true; 0/false/FALSE → false; 未知字面量 → false)。**不再回退到 env** —— 与 其他 bool 设置一致,未知字面量等同 "admin 不希望关闭"。
  2. DB 行不存在,或 value="" → env DM_SPACE_DISABLE_USER_CREATE
  3. 都缺失 → false (保持开放)

注:manager 写接口对 bool 值已做规范化(只接受 0/1/true/false 及大小写 变体),正常路径不会出现未知字面量;此规则覆盖的是有人绕过 API 直接改 DB 的边缘场景。

DB 是单一真源:admin 在管理台显式 toggle 立刻生效(Reload 内存快照), 多实例 60s 内收敛。env 仅作历史部署兼容入口;新部署应直接走 system_setting。

与 modules/space/api.go:IsUserCreateDisabled 保持等价语义 —— 后者仍是 env-only 的低层解析器,留给没有 ctx 的调用方与 yaml 模式;实际请求路径走本 方法(modules/space/api.go:createSpace)。

实现细节:DB 路径委托给 getBool 以与其他 bool 设置共享解析规则,避免双写 字面量集合(reviewer H1)。"DB 行是否存在"由独立 lookup 决定,从而区分 "DB 缺行 → env" 与 "DB 值=0 → 强制 false 压制 env" 两个语义。

func (*SystemSettings) StartAutoReload added in v1.3.0

func (s *SystemSettings) StartAutoReload(ctx context.Context)

StartAutoReload kicks off a goroutine that re-loads the snapshot every reloadTTL until ctx is canceled. Intended to be called once at startup (with a long-lived context). Errors are logged but do not stop the loop.

Production callers pass context.Background() — the goroutine therefore runs for the lifetime of the process and shuts down with it. The ctx.Done() arm exists to make this swappable: if a server-shutdown context is ever plumbed through, no code change is needed here. The defer ticker.Stop() is reached only on that future cancellation; with context.Background() it is unreachable but kept so the function stays correct under either invocation.

func (*SystemSettings) StickerCustomEnabled added in v1.8.0

func (s *SystemSettings) StickerCustomEnabled() bool

StickerCustomEnabled reports whether clients should show the custom-sticker management entry. This is a presentation toggle only; server-side CRUD authorization remains governed by the /v1/sticker/user route middleware and handler checks. Default false supports a controlled client rollout.

func (*SystemSettings) StickerHandleRequired added in v1.8.0

func (s *SystemSettings) StickerHandleRequired() bool

StickerHandleRequired reports whether custom-sticker registration must reject a missing upload handle (POST /v1/sticker/user). This is the enforcement POLICY, deliberately independent of the signing CAPABILITY (OCTO_MASTER_KEY): it lives in system_setting (DB, hot-reloaded) so it can be toggled from the admin console and converge across replicas within the snapshot TTL — a gradual, reversible rollout without a redeploy/restart. Default false (backward compatible: missing handles are allowed through during the compat window and only recorded). See modules/sticker classifyStickerPath and the appconfig sticker_handle_required bit.

func (*SystemSettings) StickerUserMaxCount added in v1.8.0

func (s *SystemSettings) StickerUserMaxCount() int

StickerUserMaxCount is the maximum number of custom stickers a single user may keep. Read-side defence: a non-positive value (only reachable via a direct DB edit — the admin write path enforces Positive) falls back to the default rather than silently locking the user out of adding any sticker.

func (*SystemSettings) SupportEmail added in v1.3.0

func (s *SystemSettings) SupportEmail() string

SupportEmail returns the From address used by the SMTP sender.

func (*SystemSettings) SupportEmailPwd added in v1.3.0

func (s *SystemSettings) SupportEmailPwd() string

SupportEmailPwd returns the (decrypted) SMTP password. If the stored ciphertext fails to decrypt at Load time, the snapshot omits the key and this getter returns the yaml fallback.

func (*SystemSettings) SupportEmailSmtp added in v1.3.0

func (s *SystemSettings) SupportEmailSmtp() string

SupportEmailSmtp returns the SMTP host:port endpoint.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL