-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathlogout.go
More file actions
124 lines (108 loc) · 3.35 KB
/
Copy pathlogout.go
File metadata and controls
124 lines (108 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package logout
import (
"errors"
"time"
"github.com/charmbracelet/huh"
"github.com/fosrl/cli/internal/api"
"github.com/fosrl/cli/internal/config"
"github.com/fosrl/cli/internal/logger"
"github.com/fosrl/cli/internal/olm"
"github.com/spf13/cobra"
)
func LogoutCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "logout",
Short: "Logout from Pangolin",
Long: "Logout and clear your session",
RunE: func(cmd *cobra.Command, args []string) error {
return logoutMain(cmd)
},
}
return cmd
}
func logoutMain(cmd *cobra.Command) error {
apiClient := api.FromContext(cmd.Context())
// Check if client is running before logout
olmClient := olm.NewClient("")
if olmClient.IsRunning() {
// Check that the client was started by this CLI by verifying the version
status, err := olmClient.GetStatus()
if err != nil {
logger.Warning("Failed to get client status: %v", err)
// Continue with logout even if we can't check version
} else if status.Agent == olm.AgentName {
// Only prompt and stop if client was started by this CLI
// Prompt user to confirm they want to disconnect the client
var confirm bool
confirmForm := huh.NewForm(
huh.NewGroup(
huh.NewConfirm().
Title("A client is currently running. Logging out will disconnect it.").
Description("Do you want to continue?").
Value(&confirm),
),
)
if err := confirmForm.Run(); err != nil {
logger.Error("Error: %v", err)
return err
}
if !confirm {
err := errors.New("logout cancelled")
logger.Info("%v", err)
return err
}
// Kill the client without showing TUI
_, err := olmClient.Exit()
if err != nil {
logger.Warning("Failed to send exit signal to client: %v", err)
} else {
// Wait for client to stop (poll until socket is gone)
maxWait := 10 * time.Second
pollInterval := 200 * time.Millisecond
elapsed := time.Duration(0)
for olmClient.IsRunning() && elapsed < maxWait {
time.Sleep(pollInterval)
elapsed += pollInterval
}
if olmClient.IsRunning() {
logger.Warning("Client did not stop within timeout")
}
}
}
// If version doesn't match, skip client shutdown and continue with logout
}
// Check if there's an active session in the key store
accountStore, err := config.LoadAccountStore()
if err != nil {
logger.Error("Failed to load account store: %s", err)
return err
}
if accountStore.ActiveUserID == "" {
logger.Success("Already logged out!")
return nil
}
// Try to logout from server (client is always initialized)
if err := apiClient.Logout(); err != nil {
// Ignore logout errors - we'll still clear local data
logger.Debug("Failed to logout from server: %v", err)
}
account, err := accountStore.ActiveAccount()
if err != nil {
logger.Error("Failed to get active account: %v", err)
return err
}
// Deactivate clears session token and org ID but keeps OLM credentials
if err := accountStore.Deactivate(accountStore.ActiveUserID); err != nil {
logger.Error("Failed to save account store: %v", err)
return err
}
// Print logout message with account name
displayName := account.Email
if account.Name != nil && *account.Name != "" {
displayName = *account.Name
} else if account.Username != nil && *account.Username != "" {
displayName = *account.Username
}
logger.Success("Logged out of Pangolin account %s", displayName)
return nil
}