package lkgateway // Службы модулей (bj-npr, bj-quikexport, …) — отдельные программы на локальных портах, которые // обновляются независимо от ядра. bj-server проверяет вход, права и лицензию, передаёт службе // служебный ключ (X-BJ-Module-Key) и встраивает её страницы в свой макет. Сами службы — modules/. import ( "crypto/rand" "encoding/hex" "html/template" "net/http" "os" "strings" "sync" ) const moduleKeyFile = "/var/lib/bj/.bj/module.key" var moduleKeyMu sync.Mutex // moduleKey — служебный ключ для служб модулей (создаётся один раз, читается службами от того же пользователя). func moduleKey() (string, error) { moduleKeyMu.Lock() defer moduleKeyMu.Unlock() if b, err := os.ReadFile(moduleKeyFile); err == nil && len(strings.TrimSpace(string(b))) >= 32 { return strings.TrimSpace(string(b)), nil } buf := make([]byte, 32) if _, err := rand.Read(buf); err != nil { return "", err } key := hex.EncodeToString(buf) if err := os.WriteFile(moduleKeyFile, []byte(key+"\n"), 0o600); err != nil { return "", err } return key, nil } // noRedirect — ответы служб (в т. ч. редиректы) передаются браузеру как есть. func noRedirect(*http.Request, []*http.Request) error { return http.ErrUseLastResponse } // modulePageData — страница модуля в макете bj. type modulePageData struct { page Content template.HTML } func moduleMessage(title, text, hint string) template.HTML { return template.HTML(`

` + template.HTMLEscapeString(title) + `

` + template.HTMLEscapeString(text) + `

` + `

` + template.HTMLEscapeString(hint) + `

`) } func pickStr(v, def string) string { if strings.TrimSpace(v) == "" { return def } return v }