diff --git a/apps/m9zCtrlTty/config/config.json b/apps/m9zCtrlTty/config/config.json index 2f9c657..d33a737 100644 --- a/apps/m9zCtrlTty/config/config.json +++ b/apps/m9zCtrlTty/config/config.json @@ -3,6 +3,9 @@ "port": "8089", "static": "./wwwroot" }, + "password": { + "enabled": true + }, "logger": { "path": "logs", "file": "{Y-m-d}.log", @@ -26,7 +29,7 @@ "baudRate": "9600" }, "deviceInfo": { - "deviceId": "TGK", + "deviceId": "862809072815088", "version": "1.0.2", "meterAddr": "0x04" }, @@ -51,5 +54,9 @@ "compress": true, "compress-level": 9, "check-interval": "30m" + }, + "mainControllerClient": { + "server_host": "wss://iotserver.ruixininfo.com/jsonrpc/websocket", + "secret_key": "viFuv4G2XJMxO4GIIsVfbJ2eKwy6QyuWLXmqZY69dy0G9iTY" } } diff --git a/apps/m9zCtrlTty/m9zCtrlTty.go b/apps/m9zCtrlTty/m9zCtrlTty.go index f26a41f..a7ae422 100644 --- a/apps/m9zCtrlTty/m9zCtrlTty.go +++ b/apps/m9zCtrlTty/m9zCtrlTty.go @@ -7,18 +7,17 @@ import ( "github.com/towgo/towgo/lib/system" "github.com/towgo/towgo/lib/www" "go.uber.org/zap" - "tgk-touch/internal/core" - g "tgk-touch/internal/global" - "tgk-touch/internal/initialize" - licenseterminal "tgk-touch/internal/module/license_terminal" - "tgk-touch/internal/module/maincontrollerClient" - "log" "os" "os/exec" "os/user" "path/filepath" "strings" + "tgk-touch/internal/core" + g "tgk-touch/internal/global" + "tgk-touch/internal/initialize" + licenseterminal "tgk-touch/internal/module/license_terminal" + "tgk-touch/internal/module/maincontrollerClient" "time" "github.com/towgo/towgo/errors/tcode" @@ -167,15 +166,14 @@ func runClient(port int) { os.Setenv("XAUTHORITY", xauthPath) // 关键:这组参数 = 完全关闭密码管理器 + 禁止保存/填充/弹窗 args := []string{ - /*"--kiosk", + "--kiosk", "--noerrdialogs", "--no-first-run", "--new-instance", // 👇 下面这 3 个就是禁密码弹窗的核心 "--disable-features=PasswordManager", "--pref=signon.rememberSignons=false", - "--pref=signon.autofillForms=false",*/ - + "--pref=signon.autofillForms=false", "http://127.0.0.1:" + fmt.Sprintf("%d", port), } // 启动Firefox diff --git a/internal/model/config/config.go b/internal/model/config/config.go index 91f8b99..aaa9900 100644 --- a/internal/model/config/config.go +++ b/internal/model/config/config.go @@ -7,6 +7,7 @@ import "github.com/gogf/gf/v2/database/gdb" type ( AppConfig struct { Server Server `json:"server" mapstructure:"server"` + Password Password `json:"password" mapstructure:"password"` Databases Databases `json:"databases" mapstructure:"databases"` MainControllerClient MainControllerClient `json:"mainControllerClient" mapstructure:"mainControllerClient"` Togocdn Togocdn `json:"togocdn" mapstructure:"togocdn"` @@ -26,6 +27,12 @@ type ( } ) +type ( + Password struct { + Enabled bool `json:"enabled" mapstructure:"enabled"` + } +) + type ( Server struct { Port int `json:"port" mapstructure:"port"` diff --git a/internal/module/m9zTtyApi/read.go b/internal/module/m9zTtyApi/read.go index 7b7129d..db2b79a 100644 --- a/internal/module/m9zTtyApi/read.go +++ b/internal/module/m9zTtyApi/read.go @@ -6,7 +6,6 @@ import ( "math" "sort" "sync" - "tgk-touch/internal/global" "tgk-touch/internal/library/m9z" "time" @@ -154,11 +153,7 @@ func getDeviceStatus2(rpc towgo.JsonRpcConnection) { loop.Index = i loop.IsOpen = read.Relays[i] loop.Pwm = int(read.PWMOutputs[i]) - parametersRead, err := m9z.SubLoopParametersRead(cuid, uint(i)) - if err != nil { - g.Log().Error(err) - return - } + parametersRead, _ := m9z.SubLoopParametersRead(cuid, uint(i)) if parametersRead != nil { kw := float32(0.0) loop.V = (parametersRead.DCVoltage * 10) / 10 diff --git a/internal/module/m9zTtyPwd/init.go b/internal/module/m9zTtyPwd/init.go index d24ace2..90d6312 100644 --- a/internal/module/m9zTtyPwd/init.go +++ b/internal/module/m9zTtyPwd/init.go @@ -28,6 +28,7 @@ var ( manager *PasswordManager = &PasswordManager{ verifiedSessions: make(map[string]time.Time), } + passwordEnabled bool ) var noInterceptor bool @@ -36,6 +37,9 @@ var ( whiteListMethods = map[string]bool{ "/m9z/password/verify": true, "/m9z/password/change": true, + //"/m9z/password/enable": true, + //"/m9z/password/disable": true, + "/m9z/password/status": true, // 实时监控 "/m9z/touchdisplay/getDeviceID": true, "/m9z/getDeviceStatus2": true, @@ -55,12 +59,14 @@ type PasswordManager struct { mu sync.RWMutex hashedPwd string salt string + enabledState int verifiedSessions map[string]time.Time } type PasswordData struct { HashedPassword string `json:"hashed_password"` Salt string `json:"salt"` + Enabled int `json:"enabled"` } func getPwdFilePath() string { @@ -97,6 +103,16 @@ func (m *PasswordManager) loadFromFile() error { m.hashedPwd = pwdData.HashedPassword m.salt = pwdData.Salt + m.enabledState = pwdData.Enabled + switch pwdData.Enabled { + case 1: + passwordEnabled = true + case 2: + passwordEnabled = false + default: + passwordEnabled = g.Config().Password.Enabled + m.enabledState = 0 + } return nil } @@ -107,9 +123,20 @@ func (m *PasswordManager) saveToFile() error { return err } + var enabledState int + switch { + case passwordEnabled: + enabledState = 1 + case !passwordEnabled && m.enabledState != 0: + enabledState = 2 + default: + enabledState = m.enabledState + } + pwdData := PasswordData{ HashedPassword: m.hashedPwd, Salt: m.salt, + Enabled: enabledState, } data, err := json.Marshal(pwdData) @@ -126,6 +153,24 @@ func (m *PasswordManager) verify(pwd string) bool { return m.hashedPwd == hashPassword(pwd, m.salt) } +func (m *PasswordManager) enabled() bool { + m.mu.RLock() + defer m.mu.RUnlock() + return passwordEnabled +} + +func (m *PasswordManager) setEnabled(enabled bool) error { + m.mu.Lock() + defer m.mu.Unlock() + passwordEnabled = enabled + if enabled { + m.enabledState = 1 + } else { + m.enabledState = 2 + } + return m.saveToFile() +} + func (m *PasswordManager) change(newPwd string) error { m.mu.Lock() defer m.mu.Unlock() @@ -203,11 +248,15 @@ func Init() { g.GVA_LOG.Sugar().Warnf("load password data failed: %v, using default", err) manager.hashedPwd = hashPassword(DefaultPassword, DefaultSalt) manager.salt = DefaultSalt + manager.enabledState = 0 manager.saveToFile() } towgo.SetFunc("/m9z/password/verify", verifyPwd) towgo.SetFunc("/m9z/password/change", changePwd) + towgo.SetFunc("/m9z/password/enable", enablePassword) + towgo.SetFunc("/m9z/password/disable", disablePassword) + towgo.SetFunc("/m9z/password/status", getPasswordStatus) towgo.SetFunc("/m9z/system/getTime", getSystemTime) towgo.SetFunc("/m9z/system/setTime", setSystemTime) @@ -277,7 +326,7 @@ func changePwd(rpcConn towgo.JsonRpcConnection) { } func pwdInterceptor(conn towgo.JsonRpcConnection) error { - if noInterceptor { + if noInterceptor || !passwordEnabled { return nil } @@ -365,3 +414,31 @@ func setSystemTime(rpcConn towgo.JsonRpcConnection) { "unix_time": unixTime, }) } + +func enablePassword(rpcConn towgo.JsonRpcConnection) { + if err := manager.setEnabled(true); err != nil { + rpcConn.WriteError(500, "save failed: "+err.Error()) + return + } + rpcConn.WriteResult(map[string]interface{}{ + "success": true, + "message": "password enabled", + }) +} + +func disablePassword(rpcConn towgo.JsonRpcConnection) { + if err := manager.setEnabled(false); err != nil { + rpcConn.WriteError(500, "save failed: "+err.Error()) + return + } + rpcConn.WriteResult(map[string]interface{}{ + "success": true, + "message": "password disabled", + }) +} + +func getPasswordStatus(rpcConn towgo.JsonRpcConnection) { + rpcConn.WriteResult(map[string]interface{}{ + "enabled": passwordEnabled, + }) +} diff --git a/internal/module/maincontrollerClient/mainControllerClient.go b/internal/module/maincontrollerClient/mainControllerClient.go index 8c73597..5ecbd5c 100644 --- a/internal/module/maincontrollerClient/mainControllerClient.go +++ b/internal/module/maincontrollerClient/mainControllerClient.go @@ -7,6 +7,7 @@ import ( "github.com/gogf/gf/v2/errors/gerror" "github.com/towgo/towgo/towgo" "go.uber.org/zap" + "sync" g "tgk-touch/internal/global" ) @@ -91,6 +92,7 @@ func DeviceCallByDeviceID(deviceID, method, token string, params, destResult any logEntry := New(deviceID, params, destResult) if err != nil { + zap.S().Errorf("%+v", err) logEntry.Error = err.Error() } @@ -164,20 +166,22 @@ func isPrintableASCII(b []byte) bool { return true } +var pushLock sync.Mutex = sync.Mutex{} + func deviceCallByDeviceID(deviceID, method, token string, params, destResult any) error { if serialPortMode { + pushLock.Lock() + defer pushLock.Unlock() b, err := ToBytes(params) if err != nil { return err } result, err := serialPort.BIO(b) if err != nil { - g.Log().Error("serialPort.BIO err:", err.Error()) return gerror.Wrap(err, "serialPort.BIO result err") } b, err = json.Marshal(result) if err != nil { - g.Log().Error("serialPort.BIO json.Marshal(result) err:", err.Error()) return gerror.Wrap(err, "json.Marshal(result) err") } diff --git a/internal/module/maincontrollerClient/serialport.go b/internal/module/maincontrollerClient/serialport.go index be9ecae..cf80426 100644 --- a/internal/module/maincontrollerClient/serialport.go +++ b/internal/module/maincontrollerClient/serialport.go @@ -112,7 +112,10 @@ func (sp *SerialPort) BIO(data []byte) ([]byte, error) { sp.bioWriteLock.Lock() defer sp.bioWriteLock.Unlock() sp.SetisBIO(true) - sp.port.Write(data) + _, err := sp.port.Write(data) + if err != nil { + return nil, gerror.New("数据写入失败") + } timer := time.NewTimer(time.Second * 3) select { case <-timer.C: