diff --git a/pkg/jms-sdk-go/model/terminal.go b/pkg/jms-sdk-go/model/terminal.go index 8686f6d..a71ceb7 100644 --- a/pkg/jms-sdk-go/model/terminal.go +++ b/pkg/jms-sdk-go/model/terminal.go @@ -6,6 +6,7 @@ type TerminalConfig struct { SessionKeepDuration int `json:"TERMINAL_SESSION_KEEP_DURATION"` TelnetRegex string `json:"TERMINAL_TELNET_REGEX"` MaxIdleTime int `json:"SECURITY_MAX_IDLE_TIME"` + MaxSessionTime int `json:"SECURITY_MAX_SESSION_TIME"` HeartbeatDuration int `json:"TERMINAL_HEARTBEAT_INTERVAL"` HostKey string `json:"TERMINAL_HOST_KEY"` MaxStoreFTPFileSize int `json:"FTP_FILE_MAX_STORE"` diff --git a/pkg/tunnel/conn.go b/pkg/tunnel/conn.go index 1144873..411db6c 100644 --- a/pkg/tunnel/conn.go +++ b/pkg/tunnel/conn.go @@ -241,6 +241,9 @@ func (t *Connection) Run(ctx *gin.Context) (err error) { } }(t) maxIndexTime := t.Sess.TerminalConfig.MaxIdleTime + maxSessionTimeInt := t.Sess.TerminalConfig.MaxSessionTime + maxSessionDuration := time.Duration(maxSessionTimeInt) * time.Hour + maxSessionTime := time.Now().Add(maxSessionDuration) maxIdleMinutes := time.Duration(maxIndexTime) * time.Minute activeDetectTicker := time.NewTicker(time.Minute) defer activeDetectTicker.Stop() @@ -258,6 +261,13 @@ func (t *Connection) Run(ctx *gin.Context) (err error) { case <-activeChan: latestActive = time.Now() case detectTime := <-activeDetectTicker.C: + if detectTime.After(maxSessionTime) { + errSession := NewJMSMaxSessionTimeError(t.Sess.TerminalConfig.MaxSessionTime) + _ = t.SendWsMessage(errSession.Instruction()) + logger.Errorf("Session[%s] terminated by max session time %d hour", + t, maxSessionTimeInt) + return nil + } if detectTime.After(latestActive.Add(maxIdleMinutes)) { errIdle := NewJMSIdleTimeOutError(maxIndexTime) _ = t.SendWsMessage(errIdle.Instruction()) diff --git a/pkg/tunnel/ws_error.go b/pkg/tunnel/ws_error.go index 48f11c8..67e60dd 100644 --- a/pkg/tunnel/ws_error.go +++ b/pkg/tunnel/ws_error.go @@ -44,6 +44,10 @@ func NewJMSIdleTimeOutError(min int) JMSGuacamoleError { return NewJMSGuacamoleError(1003, strconv.Itoa(min)) } +func NewJMSMaxSessionTimeError(hour int) JMSGuacamoleError { + return NewJMSGuacamoleError(1010, strconv.Itoa(hour)) +} + var ( ErrNoSession = NewJMSGuacamoleError(1000, "Not Found Session") @@ -51,11 +55,11 @@ var ( ErrBadParams = NewJMSGuacamoleError(1002, "Not session params") - ErrIdleTimeOut = NewJMSGuacamoleError(1003, "Terminated by idle timeout") + //ErrIdleTimeOut = NewJMSGuacamoleError(1003, "Terminated by idle timeout") ErrPermissionExpired = NewJMSGuacamoleError(1004, "Terminated by permission expired") - ErrTerminatedByAdmin = NewJMSGuacamoleError(1005, "Terminated by Admin") + //ErrTerminatedByAdmin = NewJMSGuacamoleError(1005, "Terminated by Admin") ErrAPIFailed = NewJMSGuacamoleError(1006, "API failed") diff --git a/ui/src/components/GuacamoleConnect.vue b/ui/src/components/GuacamoleConnect.vue index 4e2262d..a93ffa6 100644 --- a/ui/src/components/GuacamoleConnect.vue +++ b/ui/src/components/GuacamoleConnect.vue @@ -518,6 +518,9 @@ export default { case 1003: msg = msg.replace('{PLACEHOLDER}', status.message) break + case 1010: + msg = msg.replace('{PLACEHOLDER}', status.message) + break } this.$alert(msg, this.$t('ErrTitle'), { confirmButtonText: this.$t('OK'), diff --git a/ui/src/i18n/lang/cn.js b/ui/src/i18n/lang/cn.js index 5be962b..eac9ceb 100644 --- a/ui/src/i18n/lang/cn.js +++ b/ui/src/i18n/lang/cn.js @@ -20,6 +20,7 @@ const message = { JMSErrGatewayFailed: '网关连接失败', JMSErrGuacamoleServer: '无法连接 Guacamole 服务器', JMSErrDisconnected: '会话连接已断开', + JMSErrMaxSession: '超过最大会话时间{PLACEHOLDER}小时,断开连接', GuaErrUpstreamNotFound: '无法连接到远程桌面服务器(网络不可达 | 安全策略错误)', GuaErrSessionConflict: '因与另一个连接冲突,远程桌面服务器关闭了本连接。请稍后重试。', GuaErrClientUnauthorized: '用户名和密码认证错误,登录失败', diff --git a/ui/src/i18n/lang/en.js b/ui/src/i18n/lang/en.js index 905b3a4..1fb173f 100644 --- a/ui/src/i18n/lang/en.js +++ b/ui/src/i18n/lang/en.js @@ -19,6 +19,7 @@ const message = { JMSErrGatewayFailed: 'Gateway not available', JMSErrGuacamoleServer: 'Connect guacamole server failed', JMSErrDisconnected: 'Session Disconnected', + JMSErrMaxSession: 'Session connection time more than {PLACEHOLDER} hours, disconnect', GuaErrUpstreamNotFound: 'The remote desktop server does not appear to exist, or cannot be reached over the network.', GuaErrSessionConflict: 'The session has ended because it conflicts with another session.', GuaErrClientUnauthorized: 'User failed to logged in. (username and password are incorrect)', diff --git a/ui/src/utils/status.js b/ui/src/utils/status.js index b087e33..5a79fa3 100644 --- a/ui/src/utils/status.js +++ b/ui/src/utils/status.js @@ -13,7 +13,8 @@ export const ErrorStatusCodes = { 1006: 'JMSErrAPIFailed', 1007: 'JMSErrGatewayFailed', 1008: 'JMSErrGuacamoleServer', - 1009: 'JMSErrDisconnected' + 1009: 'JMSErrDisconnected', + 1010: 'JMSErrMaxSession' } export function ConvertAPIError(errMsg) {