Add auto-login scripts (expect-style send/wait sequences)

Implement expect-style auto-login scripts for SSH and Telnet connections.
Each script is an ordered list of 'wait' (match text in output) and 'send'
(write text + newline) steps that execute sequentially after connection.

Backend:
- Add LoginScriptStep model (type, value, timeout) to models.go
- Add loginScripts field to SSHConfig and TelnetConfig
- Add loginBuf/loginDone on Session struct for output buffering
- Hook onData callbacks to feed login buffer during script execution
- executeLoginScripts() runs steps in a goroutine after connect
- waitForOutput() polls session buffer with configurable timeout

Frontend:
- Add _renderLoginScriptSection() to profile editor
- Interactive step list: add/remove/reorder wait and send steps
- Type selector, value input, timeout for wait steps
- Collect loginScripts as JSON from hidden field
- CSS for login script rows, actions, add buttons
This commit is contained in:
2026-04-17 00:00:00 +01:00
parent 63c27470f6
commit 1463394cbb
4 changed files with 459 additions and 8 deletions
+99
View File
@@ -571,3 +571,102 @@
padding: var(--space-1) var(--space-2);
height: 30px;
}
/* -----------------------------------------------------------------------
Login Script Editor — expect-style send/wait steps
----------------------------------------------------------------------- */
.form-help {
font-size: var(--text-xs);
color: var(--text-muted);
margin-bottom: var(--space-3);
line-height: 1.5;
}
.login-script-list {
display: flex;
flex-direction: column;
gap: var(--space-2);
margin-bottom: var(--space-3);
}
.login-script-empty {
font-size: var(--text-xs);
color: var(--text-muted);
font-style: italic;
padding: var(--space-2) 0;
}
.login-script-row {
display: flex;
align-items: center;
gap: var(--space-2);
background: var(--bg-base);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: var(--space-2);
}
.login-script-type {
width: 90px;
min-width: 90px;
font-size: var(--text-xs);
padding: var(--space-1) var(--space-2);
height: 30px;
}
.login-script-value {
flex: 1;
font-size: var(--text-xs);
padding: var(--space-1) var(--space-2);
height: 30px;
}
.login-script-timeout {
width: 60px;
min-width: 60px;
font-size: var(--text-xs);
padding: var(--space-1) var(--space-2);
height: 30px;
}
.login-script-timeout-label {
font-size: var(--text-xs);
color: var(--text-muted);
min-width: 10px;
}
.login-script-actions {
display: flex;
gap: 2px;
flex-shrink: 0;
}
.login-script-btn {
background: var(--bg-elevated);
color: var(--text-secondary);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-xs);
width: 24px;
height: 24px;
font-size: 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s, color 0.15s;
}
.login-script-btn:hover {
background: var(--bg-surface);
color: var(--text-primary);
}
.login-script-btn-remove:hover {
background: var(--danger);
color: #fff;
}
.login-script-add-row {
display: flex;
gap: var(--space-2);
}