feat: opaque session、安装/发帖 SSR 与最小 Admin 后台
浏览器登录改为 DB sessions(可吊销);敏感词与 OIDC PEM 入 settings; 落地安装向导、注册发帖与 /admin 仪表盘/板块/审核/设置。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
48
services/install.go
Normal file
48
services/install.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.iioio.com/freefire/jiang13-forum/models"
|
||||
)
|
||||
|
||||
const installLockName = "install.lock"
|
||||
|
||||
// InstallLockPath 安装锁文件路径
|
||||
func InstallLockPath(dataDir string) string {
|
||||
return filepath.Join(dataDir, installLockName)
|
||||
}
|
||||
|
||||
// IsInstalled 是否已完成安装向导
|
||||
func IsInstalled(dataDir string) bool {
|
||||
_, err := os.Stat(InstallLockPath(dataDir))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// EnsureInstallLockFromExistingData 已有用户时自动写锁(避免旧数据无法启动)
|
||||
func EnsureInstallLockFromExistingData(dataDir string) error {
|
||||
if IsInstalled(dataDir) {
|
||||
return nil
|
||||
}
|
||||
var n int64
|
||||
if err := models.DB.Model(&models.User{}).Count(&n).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
return WriteInstallLock(dataDir)
|
||||
}
|
||||
|
||||
// WriteInstallLock 写入安装锁
|
||||
func WriteInstallLock(dataDir string) error {
|
||||
if err := os.MkdirAll(dataDir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(InstallLockPath(dataDir), []byte("installed\n"), 0o644)
|
||||
}
|
||||
|
||||
// ErrAlreadyInstalled 已安装
|
||||
var ErrAlreadyInstalled = errors.New("already installed")
|
||||
Reference in New Issue
Block a user