• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pomerium / pomerium / 19238204824

10 Nov 2025 04:14PM UTC coverage: 54.846% (-0.6%) from 55.476%
19238204824

push

github

web-flow
fix (ui): fixed content layout shift for sign-in verify countdown (#5924)

## Summary

Fixes a small ui issue where the content shifts for the countdown on the
sign-in verify page.

## Related issues

Relates to #5873

## User Explanation

Now there is no more content layout shift (CLS) when the countdown
counts down.

## Screenshots and Recordings

**Before**

![CleanShot 2025-11-10 at 10 12
38](https://github.com/user-attachments/assets/20684e9d-8120-468e-882b-28d6a53670db)

**After**

![CleanShot 2025-11-10 at 10 11
19](https://github.com/user-attachments/assets/45010d97-ad6f-45a2-9720-7457ef39a8dd)

## Checklist

- [x] reference any related issues
- [ ] updated unit tests
- [x] add appropriate label (`enhancement`, `bug`, `breaking`,
`dependencies`, `ci`)
- [x] ready for review

28702 of 52332 relevant lines covered (54.85%)

93.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.97
/pkg/ssh/cli.go
1
package ssh
2

3
import (
4
        "errors"
5
        "fmt"
6
        "io"
7
        "strings"
8

9
        tea "github.com/charmbracelet/bubbletea"
10
        "github.com/muesli/termenv"
11
        "github.com/spf13/cobra"
12

13
        "github.com/pomerium/envoy-custom/api/extensions/filters/network/ssh"
14
        "github.com/pomerium/pomerium/config"
15
        "github.com/pomerium/pomerium/pkg/ssh/tui"
16
)
17

18
type CLI struct {
19
        *cobra.Command
20
        tui      *tea.Program
21
        ptyInfo  *ssh.SSHDownstreamPTYInfo
22
        username string
23
        stdin    io.Reader
24
        stdout   io.Writer
25
        stderr   io.Writer
26
}
27

28
func NewCLI(
29
        cfg *config.Config,
30
        ctrl ChannelControlInterface,
31
        ptyInfo *ssh.SSHDownstreamPTYInfo,
32
        stdin io.Reader,
33
        stdout io.Writer,
34
        stderr io.Writer,
35
) *CLI {
33✔
36
        cmd := &cobra.Command{
33✔
37
                Use: "pomerium",
33✔
38
                PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
58✔
39
                        _, cmdIsInteractive := cmd.Annotations["interactive"]
25✔
40
                        switch {
25✔
41
                        case (ptyInfo == nil) && cmdIsInteractive:
1✔
42
                                return fmt.Errorf("\x1b[31m'%s' is an interactive command and requires a TTY (try passing '-t' to ssh)\x1b[0m", cmd.Use)
1✔
43
                        }
44
                        return nil
24✔
45
                },
46
        }
47

48
        cmd.CompletionOptions.DisableDefaultCmd = true
33✔
49
        // set a non-nil args list, otherwise it will read from os.Args by default
33✔
50
        cmd.SetArgs([]string{})
33✔
51
        cmd.SetIn(stdin)
33✔
52
        cmd.SetOut(stderr)
33✔
53
        cmd.SetErr(stderr)
33✔
54
        cmd.SilenceUsage = true
33✔
55

33✔
56
        cli := &CLI{
33✔
57
                Command:  cmd,
33✔
58
                tui:      nil,
33✔
59
                ptyInfo:  ptyInfo,
33✔
60
                username: *ctrl.Username(),
33✔
61
                stdin:    stdin,
33✔
62
                stdout:   stdout,
33✔
63
                stderr:   stderr,
33✔
64
        }
33✔
65

33✔
66
        if cfg.Options.IsRuntimeFlagSet(config.RuntimeFlagSSHRoutesPortal) {
55✔
67
                cli.AddPortalCommand(ctrl)
22✔
68
        }
22✔
69
        cli.AddTunnelCommand(ctrl)
33✔
70
        cli.AddLogoutCommand(ctrl)
33✔
71
        cli.AddWhoamiCommand(ctrl)
33✔
72

33✔
73
        return cli
33✔
74
}
75

76
func (cli *CLI) AddLogoutCommand(_ ChannelControlInterface) {
33✔
77
        cli.AddCommand(&cobra.Command{
33✔
78
                Use:           "logout",
33✔
79
                Short:         "Log out",
33✔
80
                SilenceErrors: true,
33✔
81
                RunE: func(_ *cobra.Command, _ []string) error {
43✔
82
                        _, _ = cli.stderr.Write([]byte("Logged out successfully\n"))
10✔
83
                        return ErrDeleteSessionOnExit
10✔
84
                },
10✔
85
        })
86
}
87

88
func (cli *CLI) AddWhoamiCommand(ctrl ChannelControlInterface) {
33✔
89
        cli.AddCommand(&cobra.Command{
33✔
90
                Use:   "whoami",
33✔
91
                Short: "Show details for the current session",
33✔
92
                RunE: func(cmd *cobra.Command, _ []string) error {
45✔
93
                        s, err := ctrl.FormatSession(cmd.Context())
12✔
94
                        if err != nil {
14✔
95
                                return fmt.Errorf("couldn't fetch session: %w", err)
2✔
96
                        }
2✔
97
                        _, _ = cli.stderr.Write(s)
10✔
98
                        return nil
10✔
99
                },
100
        })
101
}
102

103
type sshEnviron struct {
104
        Env map[string]string
105
}
106

107
// Environ implements termenv.Environ.
108
func (s *sshEnviron) Environ() []string {
2✔
109
        kv := make([]string, 0, len(s.Env))
2✔
110
        for k, v := range s.Env {
4✔
111
                kv = append(kv, fmt.Sprintf("%s=%s", k, v))
2✔
112
        }
2✔
113
        return kv
2✔
114
}
115

116
// Getenv implements termenv.Environ.
117
func (s *sshEnviron) Getenv(key string) string {
12✔
118
        return s.Env[key]
12✔
119
}
12✔
120

121
var _ termenv.Environ = (*sshEnviron)(nil)
122

123
const (
124
        ptyWidthMax  = 512
125
        ptyHeightMax = 512
126
)
127

128
func (cli *CLI) AddTunnelCommand(ctrl ChannelControlInterface) {
33✔
129
        cli.AddCommand(&cobra.Command{
33✔
130
                Use:    "tunnel",
33✔
131
                Short:  "tunnel status",
33✔
132
                Hidden: true,
33✔
133
                Annotations: map[string]string{
33✔
134
                        "interactive": "",
33✔
135
                },
33✔
136
                RunE: func(cmd *cobra.Command, _ []string) error {
33✔
137
                        env := &sshEnviron{
×
138
                                Env: map[string]string{
×
139
                                        "TERM": cli.ptyInfo.TermEnv,
×
140
                                },
×
141
                        }
×
142

×
143
                        prog := tui.NewTunnelStatusProgram(cmd.Context(),
×
144
                                tea.WithInput(cli.stdin),
×
145
                                tea.WithOutput(termenv.NewOutput(cli.stdout, termenv.WithEnvironment(env), termenv.WithUnsafe())),
×
146
                                tea.WithEnvironment(env.Environ()),
×
147
                        )
×
148
                        cli.tui = prog.Program
×
149

×
150
                        initDone := make(chan struct{})
×
151
                        go func() {
×
152
                                defer close(initDone)
×
153
                                cli.SendTeaMsg(tea.WindowSizeMsg{
×
154
                                        Width:  int(min(cli.ptyInfo.WidthColumns, ptyWidthMax)),
×
155
                                        Height: int(min(cli.ptyInfo.HeightRows, ptyHeightMax)),
×
156
                                })
×
157
                                ctrl.AddPortForwardUpdateListener(prog)
×
158
                        }()
×
159

160
                        _, err := prog.Run()
×
161
                        <-initDone
×
162
                        ctrl.RemovePortForwardUpdateListener(prog)
×
163
                        if err != nil {
×
164
                                return err
×
165
                        }
×
166
                        return nil
×
167
                },
168
        })
169
}
170

171
// ErrHandoff is a sentinel error to indicate that the command triggered a handoff,
172
// and we should not automatically disconnect
173
var ErrHandoff = errors.New("handoff")
174

175
// ErrDeleteSessionOnExit is a sentinel error to indicate that the authorized
176
// session should be deleted once the SSH connection ends.
177
var ErrDeleteSessionOnExit = errors.New("delete_session_on_exit")
178

179
func (cli *CLI) AddPortalCommand(ctrl ChannelControlInterface) {
22✔
180
        cli.AddCommand(&cobra.Command{
22✔
181
                Use:   "portal",
22✔
182
                Short: "Interactive route portal",
22✔
183
                Annotations: map[string]string{
22✔
184
                        "interactive": "",
22✔
185
                },
22✔
186
                RunE: func(cmd *cobra.Command, _ []string) error {
24✔
187
                        var routes []string
2✔
188
                        for r := range ctrl.AllSSHRoutes() {
6✔
189
                                routes = append(routes, fmt.Sprintf("%s@%s", *ctrl.Username(), strings.TrimPrefix(r.From, "ssh://")))
4✔
190
                        }
4✔
191
                        env := &sshEnviron{
2✔
192
                                Env: map[string]string{
2✔
193
                                        "TERM": cli.ptyInfo.TermEnv,
2✔
194
                                },
2✔
195
                        }
2✔
196
                        signedWidth := int(min(cli.ptyInfo.WidthColumns, ptyWidthMax))
2✔
197
                        signedHeight := int(min(cli.ptyInfo.HeightRows, ptyHeightMax))
2✔
198
                        prog := tui.NewPortalProgram(cmd.Context(), routes, max(0, signedWidth-2), max(0, signedHeight-2),
2✔
199
                                tea.WithInput(cli.stdin),
2✔
200
                                tea.WithOutput(termenv.NewOutput(cli.stdout, termenv.WithEnvironment(env), termenv.WithUnsafe())),
2✔
201
                                tea.WithEnvironment(env.Environ()),
2✔
202
                        )
2✔
203
                        cli.tui = prog.Program
2✔
204

2✔
205
                        cli.SendTeaMsg(tea.WindowSizeMsg{Width: signedWidth, Height: signedHeight})
2✔
206
                        choice, err := prog.Run()
2✔
207
                        if err != nil {
2✔
208
                                return err
×
209
                        }
×
210
                        if choice == "" {
3✔
211
                                return nil // quit/ctrl+c
1✔
212
                        }
1✔
213

214
                        username, hostname, _ := strings.Cut(choice, "@")
1✔
215
                        // Perform authorize check for this route
1✔
216
                        if username != cli.username {
1✔
217
                                panic("bug: username mismatch")
×
218
                        }
219
                        if hostname == "" {
1✔
220
                                panic("bug: hostname is empty")
×
221
                        }
222
                        handoffMsg, err := ctrl.PrepareHandoff(cmd.Context(), hostname, cli.ptyInfo)
1✔
223
                        if err != nil {
1✔
224
                                return err
×
225
                        }
×
226
                        if err := ctrl.SendControlAction(handoffMsg); err != nil {
1✔
227
                                return err
×
228
                        }
×
229
                        return ErrHandoff
1✔
230
                },
231
        })
232
}
233

234
func (cli *CLI) SendTeaMsg(msg tea.Msg) {
3✔
235
        if cli.tui != nil {
6✔
236
                go cli.tui.Send(msg)
3✔
237
        }
3✔
238
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc