Skip to content

Commit fd4e29f

Browse files
committed
Fix initial setup caching and container discovery defaults
1 parent 82e34f2 commit fd4e29f

File tree

4 files changed

+623
-569
lines changed

4 files changed

+623
-569
lines changed

frontend-modern/src/components/FirstRunSetup.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,23 @@ export const FirstRunSetup: Component = () => {
131131

132132
// Save credentials for display
133133
setSavedUsername(username());
134-
setSavedPassword(useCustomPassword() ? password() : generatedPassword());
134+
setSavedPassword(finalPassword);
135135
setSavedToken(token);
136136

137+
// Clear any cached credentials from prior sessions so a reload doesn't auto-submit again
138+
try {
139+
sessionStorage.removeItem('pulse_auth');
140+
sessionStorage.removeItem('pulse_auth_user');
141+
} catch (storageError) {
142+
console.warn('Unable to clear cached auth session storage', storageError);
143+
}
144+
145+
try {
146+
localStorage.removeItem('apiToken');
147+
} catch (storageError) {
148+
console.warn('Unable to clear cached API token', storageError);
149+
}
150+
137151
const bootstrapRecord: APITokenRecord = {
138152
id: 'bootstrap-token',
139153
name: 'Bootstrap token',

frontend-modern/src/components/Settings/QuickSecuritySetup.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,19 @@ export const QuickSecuritySetup: Component<QuickSecuritySetupProps> = (props) =>
117117
setCredentials(newCredentials);
118118
setShowCredentials(true);
119119

120+
try {
121+
sessionStorage.removeItem('pulse_auth');
122+
sessionStorage.removeItem('pulse_auth_user');
123+
} catch (storageError) {
124+
console.warn('Unable to clear cached auth session storage', storageError);
125+
}
126+
127+
try {
128+
localStorage.removeItem('apiToken');
129+
} catch (storageError) {
130+
console.warn('Unable to clear cached API token', storageError);
131+
}
132+
120133
// Show success message
121134
showSuccess(
122135
isRotation
Lines changed: 158 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,64 @@
11
package discovery
22

33
import (
4-
"fmt"
5-
"net"
6-
"strings"
7-
"time"
8-
9-
"github.com/rcourtman/pulse-go-rewrite/internal/config"
10-
pkgdiscovery "github.com/rcourtman/pulse-go-rewrite/pkg/discovery"
11-
"github.com/rcourtman/pulse-go-rewrite/pkg/discovery/envdetect"
4+
"fmt"
5+
"net"
6+
"strings"
7+
"time"
8+
9+
"github.com/rcourtman/pulse-go-rewrite/internal/config"
10+
pkgdiscovery "github.com/rcourtman/pulse-go-rewrite/pkg/discovery"
11+
"github.com/rcourtman/pulse-go-rewrite/pkg/discovery/envdetect"
1212
)
1313

1414
// BuildScanner creates a discovery scanner configured using the supplied discovery config.
1515
func BuildScanner(cfg config.DiscoveryConfig) (*pkgdiscovery.Scanner, error) {
16-
cfg = config.NormalizeDiscoveryConfig(cfg)
16+
cfg = config.NormalizeDiscoveryConfig(cfg)
1717

18-
profile, err := envdetect.DetectEnvironment()
19-
if err != nil {
20-
return nil, err
21-
}
18+
profile, err := envdetect.DetectEnvironment()
19+
if err != nil {
20+
return nil, err
21+
}
2222

23-
ApplyConfigToProfile(profile, cfg)
24-
return pkgdiscovery.NewScannerWithProfile(profile), nil
23+
ApplyConfigToProfile(profile, cfg)
24+
return pkgdiscovery.NewScannerWithProfile(profile), nil
2525
}
2626

2727
// ApplyConfigToProfile mutates the supplied environment profile according to the discovery config.
2828
func ApplyConfigToProfile(profile *envdetect.EnvironmentProfile, cfg config.DiscoveryConfig) {
29-
if profile == nil {
30-
return
31-
}
32-
33-
// Environment override
34-
if env, ok := environmentFromOverride(cfg.EnvironmentOverride); ok {
35-
profile.Type = env
36-
filterPhasesForEnvironment(profile, env)
37-
} else if cfg.EnvironmentOverride != "" && strings.ToLower(cfg.EnvironmentOverride) != "auto" {
38-
profile.Warnings = append(profile.Warnings, fmt.Sprintf("Unknown environment override: %s", cfg.EnvironmentOverride))
39-
}
40-
41-
// Apply subnet blocklist
42-
blocked := parseCIDRMap(cfg.SubnetBlocklist, &profile.Warnings)
43-
if len(blocked) > 0 {
44-
var filtered []envdetect.SubnetPhase
45-
for _, phase := range profile.Phases {
46-
var kept []net.IPNet
47-
for _, subnet := range phase.Subnets {
48-
if _, blocked := blocked[subnet.String()]; blocked {
49-
continue
50-
}
51-
kept = append(kept, subnet)
52-
}
53-
if len(kept) > 0 {
54-
phase.Subnets = kept
55-
filtered = append(filtered, phase)
56-
}
57-
}
58-
profile.Phases = filtered
59-
}
60-
61-
// Apply subnet allowlist as highest priority phase
29+
if profile == nil {
30+
return
31+
}
32+
33+
// Environment override
34+
if env, ok := environmentFromOverride(cfg.EnvironmentOverride); ok {
35+
profile.Type = env
36+
filterPhasesForEnvironment(profile, env)
37+
} else if cfg.EnvironmentOverride != "" && strings.ToLower(cfg.EnvironmentOverride) != "auto" {
38+
profile.Warnings = append(profile.Warnings, fmt.Sprintf("Unknown environment override: %s", cfg.EnvironmentOverride))
39+
}
40+
41+
// Apply subnet blocklist
42+
blocked := parseCIDRMap(cfg.SubnetBlocklist, &profile.Warnings)
43+
if len(blocked) > 0 {
44+
var filtered []envdetect.SubnetPhase
45+
for _, phase := range profile.Phases {
46+
var kept []net.IPNet
47+
for _, subnet := range phase.Subnets {
48+
if _, blocked := blocked[subnet.String()]; blocked {
49+
continue
50+
}
51+
kept = append(kept, subnet)
52+
}
53+
if len(kept) > 0 {
54+
phase.Subnets = kept
55+
filtered = append(filtered, phase)
56+
}
57+
}
58+
profile.Phases = filtered
59+
}
60+
61+
// Apply subnet allowlist as highest priority phase
6262
if len(cfg.SubnetAllowlist) > 0 {
6363
allowlist := parseCIDRs(cfg.SubnetAllowlist, &profile.Warnings)
6464
if len(allowlist) > 0 {
@@ -79,104 +79,126 @@ func ApplyConfigToProfile(profile *envdetect.EnvironmentProfile, cfg config.Disc
7979
Subnets: allowlist,
8080
Confidence: 1.0,
8181
Priority: 0,
82-
}
83-
profile.Phases = append([]envdetect.SubnetPhase{allowPhase}, profile.Phases...)
84-
}
85-
}
86-
87-
// Override scan policy
88-
if cfg.MaxHostsPerScan > 0 {
89-
profile.Policy.MaxHostsPerScan = cfg.MaxHostsPerScan
90-
}
91-
if cfg.MaxConcurrent > 0 {
92-
profile.Policy.MaxConcurrent = cfg.MaxConcurrent
93-
}
94-
profile.Policy.EnableReverseDNS = cfg.EnableReverseDNS
95-
profile.Policy.ScanGateways = cfg.ScanGateways
96-
97-
if cfg.DialTimeout > 0 {
98-
profile.Policy.DialTimeout = time.Duration(cfg.DialTimeout) * time.Millisecond
99-
}
100-
if cfg.HTTPTimeout > 0 {
101-
profile.Policy.HTTPTimeout = time.Duration(cfg.HTTPTimeout) * time.Millisecond
102-
}
82+
}
83+
profile.Phases = append([]envdetect.SubnetPhase{allowPhase}, profile.Phases...)
84+
}
85+
}
86+
87+
if len(cfg.SubnetAllowlist) == 0 && shouldPruneContainerNetworks(profile.Type) {
88+
pruned := make([]envdetect.SubnetPhase, 0, len(profile.Phases))
89+
for _, phase := range profile.Phases {
90+
if isLikelyContainerPhase(phase.Name) {
91+
continue
92+
}
93+
pruned = append(pruned, phase)
94+
}
95+
if len(pruned) > 0 {
96+
profile.Phases = pruned
97+
}
98+
}
99+
100+
// Override scan policy
101+
if cfg.MaxHostsPerScan > 0 {
102+
profile.Policy.MaxHostsPerScan = cfg.MaxHostsPerScan
103+
}
104+
if cfg.MaxConcurrent > 0 {
105+
profile.Policy.MaxConcurrent = cfg.MaxConcurrent
106+
}
107+
profile.Policy.EnableReverseDNS = cfg.EnableReverseDNS
108+
profile.Policy.ScanGateways = cfg.ScanGateways
109+
110+
if cfg.DialTimeout > 0 {
111+
profile.Policy.DialTimeout = time.Duration(cfg.DialTimeout) * time.Millisecond
112+
}
113+
if cfg.HTTPTimeout > 0 {
114+
profile.Policy.HTTPTimeout = time.Duration(cfg.HTTPTimeout) * time.Millisecond
115+
}
116+
}
117+
118+
func shouldPruneContainerNetworks(env envdetect.Environment) bool {
119+
return env == envdetect.DockerBridge || env == envdetect.LXCUnprivileged
120+
}
121+
122+
func isLikelyContainerPhase(name string) bool {
123+
name = strings.ToLower(strings.TrimSpace(name))
124+
return strings.Contains(name, "container")
103125
}
104126

105127
func parseCIDRs(values []string, warnings *[]string) []net.IPNet {
106-
var subnets []net.IPNet
107-
for _, value := range values {
108-
value = strings.TrimSpace(value)
109-
if value == "" {
110-
continue
111-
}
112-
_, ipNet, err := net.ParseCIDR(value)
113-
if err != nil {
114-
if warnings != nil {
115-
*warnings = append(*warnings, fmt.Sprintf("Invalid CIDR '%s' ignored", value))
116-
}
117-
continue
118-
}
119-
subnets = append(subnets, *ipNet)
120-
}
121-
return subnets
128+
var subnets []net.IPNet
129+
for _, value := range values {
130+
value = strings.TrimSpace(value)
131+
if value == "" {
132+
continue
133+
}
134+
_, ipNet, err := net.ParseCIDR(value)
135+
if err != nil {
136+
if warnings != nil {
137+
*warnings = append(*warnings, fmt.Sprintf("Invalid CIDR '%s' ignored", value))
138+
}
139+
continue
140+
}
141+
subnets = append(subnets, *ipNet)
142+
}
143+
return subnets
122144
}
123145

124146
func parseCIDRMap(values []string, warnings *[]string) map[string]struct{} {
125-
cidrs := parseCIDRs(values, warnings)
126-
result := make(map[string]struct{}, len(cidrs))
127-
for _, cidr := range cidrs {
128-
result[cidr.String()] = struct{}{}
129-
}
130-
return result
147+
cidrs := parseCIDRs(values, warnings)
148+
result := make(map[string]struct{}, len(cidrs))
149+
for _, cidr := range cidrs {
150+
result[cidr.String()] = struct{}{}
151+
}
152+
return result
131153
}
132154

133155
func environmentFromOverride(value string) (envdetect.Environment, bool) {
134-
normalized := strings.ToLower(strings.TrimSpace(value))
135-
switch normalized {
136-
case "", "auto":
137-
return envdetect.Unknown, false
138-
case "native":
139-
return envdetect.Native, true
140-
case "docker_host":
141-
return envdetect.DockerHost, true
142-
case "docker_bridge":
143-
return envdetect.DockerBridge, true
144-
case "lxc_privileged":
145-
return envdetect.LXCPrivileged, true
146-
case "lxc_unprivileged":
147-
return envdetect.LXCUnprivileged, true
148-
default:
149-
return envdetect.Unknown, false
150-
}
156+
normalized := strings.ToLower(strings.TrimSpace(value))
157+
switch normalized {
158+
case "", "auto":
159+
return envdetect.Unknown, false
160+
case "native":
161+
return envdetect.Native, true
162+
case "docker_host":
163+
return envdetect.DockerHost, true
164+
case "docker_bridge":
165+
return envdetect.DockerBridge, true
166+
case "lxc_privileged":
167+
return envdetect.LXCPrivileged, true
168+
case "lxc_unprivileged":
169+
return envdetect.LXCUnprivileged, true
170+
default:
171+
return envdetect.Unknown, false
172+
}
151173
}
152174

153175
func filterPhasesForEnvironment(profile *envdetect.EnvironmentProfile, env envdetect.Environment) {
154-
if len(profile.Phases) == 0 {
155-
return
156-
}
157-
158-
var keep []envdetect.SubnetPhase
159-
for _, phase := range profile.Phases {
160-
name := strings.ToLower(phase.Name)
161-
switch env {
162-
case envdetect.Native, envdetect.DockerHost, envdetect.LXCPrivileged:
163-
if strings.Contains(name, "local") || strings.Contains(name, "host") {
164-
keep = append(keep, phase)
165-
}
166-
case envdetect.DockerBridge:
167-
if strings.Contains(name, "container") || strings.Contains(name, "inferred") || strings.Contains(name, "host") {
168-
keep = append(keep, phase)
169-
}
170-
case envdetect.LXCUnprivileged:
171-
if strings.Contains(name, "lxc") || strings.Contains(name, "container") || strings.Contains(name, "parent") {
172-
keep = append(keep, phase)
173-
}
174-
default:
175-
keep = append(keep, phase)
176-
}
177-
}
178-
179-
if len(keep) > 0 {
180-
profile.Phases = keep
181-
}
176+
if len(profile.Phases) == 0 {
177+
return
178+
}
179+
180+
var keep []envdetect.SubnetPhase
181+
for _, phase := range profile.Phases {
182+
name := strings.ToLower(phase.Name)
183+
switch env {
184+
case envdetect.Native, envdetect.DockerHost, envdetect.LXCPrivileged:
185+
if strings.Contains(name, "local") || strings.Contains(name, "host") {
186+
keep = append(keep, phase)
187+
}
188+
case envdetect.DockerBridge:
189+
if strings.Contains(name, "container") || strings.Contains(name, "inferred") || strings.Contains(name, "host") {
190+
keep = append(keep, phase)
191+
}
192+
case envdetect.LXCUnprivileged:
193+
if strings.Contains(name, "lxc") || strings.Contains(name, "container") || strings.Contains(name, "parent") {
194+
keep = append(keep, phase)
195+
}
196+
default:
197+
keep = append(keep, phase)
198+
}
199+
}
200+
201+
if len(keep) > 0 {
202+
profile.Phases = keep
203+
}
182204
}

0 commit comments

Comments
 (0)