diff --git a/agent/cmd/agent/main.go b/agent/cmd/agent/main.go index a8346c0..bb0d3d4 100644 --- a/agent/cmd/agent/main.go +++ b/agent/cmd/agent/main.go @@ -74,6 +74,22 @@ var firefoxNotifyConfig = notify.Config{ Message: "Firefox policies have been updated. Please restart Firefox for all changes to take effect.", } +// thunderbirdCache maps policy ID → proto policy for all active Thunderbird policies. +var thunderbirdCache = make(map[string]*pb.ThunderbirdPolicy) + +// thunderbirdSnapshotStaging accumulates Thunderbird proto policies during a SNAPSHOT. +var thunderbirdSnapshotStaging map[string]*pb.ThunderbirdPolicy + +// thunderbirdNotifier handles desktop notifications for Thunderbird policy changes. +var thunderbirdNotifier = notify.New() + +// thunderbirdNotifyConfig holds Thunderbird-specific notification settings. +var thunderbirdNotifyConfig = notify.Config{ + Enabled: true, + Cooldown: 5 * time.Minute, + Message: "Thunderbird policies have been updated. Please restart Thunderbird for all changes to take effect.", +} + // chromeCache maps policy ID → proto policy for all active Chrome policies. var chromeCache = make(map[string]*pb.ChromePolicy) @@ -411,6 +427,11 @@ func runStreamingLoop(ctx context.Context, client *policyclient.Client, cfg *con Cooldown: time.Duration(agentCfg.NotifyCooldown) * time.Second, Message: agentCfg.NotifyMessageChrome, } + thunderbirdNotifyConfig = notify.Config{ + Enabled: agentCfg.NotifyUsers, + Cooldown: time.Duration(agentCfg.NotifyCooldown) * time.Second, + Message: agentCfg.NotifyMessageThunderbird, + } packageNotifyConfig = notify.Config{ Enabled: agentCfg.NotifyUsers, Cooldown: time.Duration(agentCfg.NotifyCooldown) * time.Second, @@ -511,12 +532,15 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c if snapshotComplete { log.Println("Received empty snapshot (no policies assigned)") firefoxChanged := len(firefoxCache) > 0 + thunderbirdChanged := len(thunderbirdCache) > 0 hadKconfigPolicies := len(kconfigCache) > 0 chromeChanged := len(chromeCache) > 0 kconfigCache = make(map[string]*pb.KConfigPolicy) kconfigSnapshotStaging = nil firefoxCache = make(map[string]*pb.FirefoxPolicy) firefoxSnapshotStaging = nil + thunderbirdCache = make(map[string]*pb.ThunderbirdPolicy) + thunderbirdSnapshotStaging = nil chromeCache = make(map[string]*pb.ChromePolicy) chromeSnapshotStaging = nil dconfCache = make(map[string]dconfCacheEntry) @@ -527,6 +551,7 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c packageSnapshotStaging = nil syncAllKConfig(ctx, client, cfg) syncAllFirefox(ctx, client, cfg) + syncAllThunderbird(ctx, client, cfg) syncAllChrome(ctx, client, cfg) syncAllDConf(ctx, client, cfg) syncAllPolkit(ctx, client, cfg) @@ -538,6 +563,9 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c if firefoxChanged { firefoxNotifier.ScheduleNotification(firefoxNotifyConfig, map[string]bool{"policies.json": true}) } + if thunderbirdChanged { + thunderbirdNotifier.ScheduleNotification(thunderbirdNotifyConfig, map[string]bool{"policies.json": true}) + } if chromeChanged { chromeNotifier.ScheduleNotification(chromeNotifyConfig, map[string]bool{"bor_managed.json": true}) } @@ -556,6 +584,11 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c firefoxSnapshotStaging = make(map[string]*pb.FirefoxPolicy) } firefoxSnapshotStaging[pi.ID] = pi.FirefoxPolicy + case "Thunderbird": + if thunderbirdSnapshotStaging == nil { + thunderbirdSnapshotStaging = make(map[string]*pb.ThunderbirdPolicy) + } + thunderbirdSnapshotStaging[pi.ID] = pi.ThunderbirdPolicy case "Chrome": if chromeSnapshotStaging == nil { chromeSnapshotStaging = make(map[string]*pb.ChromePolicy) @@ -588,8 +621,9 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c } if snapshotComplete { - // Compare Firefox and Chrome content before swapping to detect changes. + // Compare Firefox, Thunderbird and Chrome content before swapping to detect changes. firefoxChanged := !firefoxCachesEqual(firefoxCache, firefoxSnapshotStaging) + thunderbirdChanged := !thunderbirdCachesEqual(thunderbirdCache, thunderbirdSnapshotStaging) chromeChanged := !chromeCachesEqual(chromeCache, chromeSnapshotStaging) // Swap KConfig staging into cache. @@ -608,6 +642,14 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c } firefoxSnapshotStaging = nil + // Swap Thunderbird staging into cache. + if thunderbirdSnapshotStaging != nil { + thunderbirdCache = thunderbirdSnapshotStaging + } else { + thunderbirdCache = make(map[string]*pb.ThunderbirdPolicy) + } + thunderbirdSnapshotStaging = nil + // Swap Chrome staging into cache. if chromeSnapshotStaging != nil { chromeCache = chromeSnapshotStaging @@ -642,6 +684,7 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c kconfigChanged := syncAllKConfig(ctx, client, cfg) syncAllFirefox(ctx, client, cfg) + syncAllThunderbird(ctx, client, cfg) syncAllChrome(ctx, client, cfg) syncAllDConf(ctx, client, cfg) syncAllPolkit(ctx, client, cfg) @@ -655,6 +698,9 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c if firefoxChanged { firefoxNotifier.ScheduleNotification(firefoxNotifyConfig, map[string]bool{"policies.json": true}) } + if thunderbirdChanged { + thunderbirdNotifier.ScheduleNotification(thunderbirdNotifyConfig, map[string]bool{"policies.json": true}) + } if chromeChanged { chromeNotifier.ScheduleNotification(chromeNotifyConfig, map[string]bool{"bor_managed.json": true}) } @@ -675,6 +721,11 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c if syncAllFirefox(ctx, client, cfg) { firefoxNotifier.ScheduleNotification(firefoxNotifyConfig, map[string]bool{"policies.json": true}) } + case "Thunderbird": + thunderbirdCache[pi.ID] = pi.ThunderbirdPolicy + if syncAllThunderbird(ctx, client, cfg) { + thunderbirdNotifier.ScheduleNotification(thunderbirdNotifyConfig, map[string]bool{"policies.json": true}) + } case "Chrome": chromeCache[pi.ID] = pi.ChromePolicy if syncAllChrome(ctx, client, cfg) { @@ -717,6 +768,11 @@ func handlePolicyUpdate(ctx context.Context, client *policyclient.Client, cfg *c if syncAllFirefox(ctx, client, cfg) { firefoxNotifier.ScheduleNotification(firefoxNotifyConfig, map[string]bool{"policies.json": true}) } + } else if _, ok := thunderbirdCache[pi.ID]; ok { + delete(thunderbirdCache, pi.ID) + if syncAllThunderbird(ctx, client, cfg) { + thunderbirdNotifier.ScheduleNotification(thunderbirdNotifyConfig, map[string]bool{"policies.json": true}) + } } else if _, ok := chromeCache[pi.ID]; ok { delete(chromeCache, pi.ID) if syncAllChrome(ctx, client, cfg) { @@ -910,6 +966,66 @@ func syncAllFirefox(ctx context.Context, client *policyclient.Client, cfg *confi return true } +// thunderbirdCachesEqual returns true when two Thunderbird policy caches contain +// identical policy IDs and proto content. Used to detect whether a SNAPSHOT +// resync actually changed the Thunderbird policy set. +func thunderbirdCachesEqual(a, b map[string]*pb.ThunderbirdPolicy) bool { + if len(a) != len(b) { + return false + } + for id, pa := range a { + pb2, ok := b[id] + if !ok { + return false + } + if !proto.Equal(pa, pb2) { + return false + } + } + return true +} + +// syncAllThunderbird re-merges all cached Thunderbird proto policies and syncs +// the resulting policies.json to disk. When the cache is empty, +// SyncThunderbirdPoliciesFromProto restores the original file from backup. +// +// Returns true when the sync succeeded (for notification scheduling). +func syncAllThunderbird(ctx context.Context, client *policyclient.Client, cfg *config.Config) bool { + var policies []*pb.ThunderbirdPolicy + var ids []string + for id, pol := range thunderbirdCache { + policies = append(policies, pol) + ids = append(ids, id) + } + + suppressManagedWrites(cfg, cfg.Thunderbird.PoliciesPath, cfg.Thunderbird.FlatpakPoliciesPath) + defer updateWatcher(cfg) + + if err := policy.SyncThunderbirdPoliciesFromProto(cfg.Thunderbird.PoliciesPath, policies); err != nil { + log.Printf("Error syncing Thunderbird policies: %v", err) + for _, id := range ids { + _ = client.ReportCompliance(ctx, id, false, "failed to sync Thunderbird policies: "+err.Error()) + } + return false + } + + // Flatpak Thunderbird: write to the system-wide extension directory. + // This is best-effort — Flatpak Thunderbird may not be installed. + if cfg.Thunderbird.FlatpakPoliciesPath != "" { + if err := policy.SyncThunderbirdFlatpakPoliciesFromProto(cfg.Thunderbird.FlatpakPoliciesPath, policies); err != nil { + log.Printf("Warning: failed to sync Flatpak Thunderbird policies: %v", err) + } else { + log.Printf("Flatpak Thunderbird policies synced to %s", cfg.Thunderbird.FlatpakPoliciesPath) + } + } + + log.Printf("Thunderbird policies synced to %s (%d policies)", cfg.Thunderbird.PoliciesPath, len(ids)) + for _, id := range ids { + _ = client.ReportCompliance(ctx, id, true, "Deployed") + } + return true +} + // sendHeartbeat collects current system metadata and sends it to the server. func sendHeartbeat(ctx context.Context, client *policyclient.Client) { si := sysinfo.Collect() @@ -1430,6 +1546,16 @@ func getManagedPaths(cfg *config.Config) []string { } } + // Thunderbird. + if len(thunderbirdCache) > 0 { + if cfg.Thunderbird.PoliciesPath != "" { + paths = append(paths, cfg.Thunderbird.PoliciesPath) + } + if cfg.Thunderbird.FlatpakPoliciesPath != "" { + paths = append(paths, cfg.Thunderbird.FlatpakPoliciesPath) + } + } + // Chrome. if len(chromeCache) > 0 { for _, dir := range []string{ @@ -1530,6 +1656,8 @@ func onTamperedFile(ctx context.Context, client *policyclient.Client, cfg *confi syncAllKConfig(ctx, client, cfg) case path == cfg.Firefox.PoliciesPath || path == cfg.Firefox.FlatpakPoliciesPath: syncAllFirefox(ctx, client, cfg) + case path == cfg.Thunderbird.PoliciesPath || path == cfg.Thunderbird.FlatpakPoliciesPath: + syncAllThunderbird(ctx, client, cfg) case strings.HasPrefix(path, "/etc/dconf/"): syncAllDConf(ctx, client, cfg) case strings.HasPrefix(path, policy.PolkitRulesDir+string(filepath.Separator)): diff --git a/agent/internal/config/config.go b/agent/internal/config/config.go index d2577f3..40b5aa8 100644 --- a/agent/internal/config/config.go +++ b/agent/internal/config/config.go @@ -15,13 +15,14 @@ import ( // Config holds the agent configuration. type Config struct { - Server ServerConfig `yaml:"server"` - Agent AgentConfig `yaml:"agent"` - Firefox FirefoxConfig `yaml:"firefox"` - Chrome ChromeConfig `yaml:"chrome"` - KConfig KConfigConfig `yaml:"kconfig"` - Enrollment EnrollmentConfig `yaml:"enrollment"` - Kerberos KerberosConfig `yaml:"kerberos"` + Server ServerConfig `yaml:"server"` + Agent AgentConfig `yaml:"agent"` + Firefox FirefoxConfig `yaml:"firefox"` + Thunderbird ThunderbirdConfig `yaml:"thunderbird"` + Chrome ChromeConfig `yaml:"chrome"` + KConfig KConfigConfig `yaml:"kconfig"` + Enrollment EnrollmentConfig `yaml:"enrollment"` + Kerberos KerberosConfig `yaml:"kerberos"` } // ServerConfig holds server connection settings. @@ -57,6 +58,12 @@ type FirefoxConfig struct { FlatpakPoliciesPath string `yaml:"flatpak_policies_path"` } +// ThunderbirdConfig holds Thunderbird policy file settings. +type ThunderbirdConfig struct { + PoliciesPath string `yaml:"policies_path"` + FlatpakPoliciesPath string `yaml:"flatpak_policies_path"` +} + // ChromeConfig holds Chrome/Chromium policy directory settings. // The agent writes bor_managed.json into each configured directory. type ChromeConfig struct { @@ -130,6 +137,10 @@ func DefaultConfig() *Config { PoliciesPath: "/etc/firefox/policies/policies.json", FlatpakPoliciesPath: "/var/lib/flatpak/extension/org.mozilla.firefox.systemconfig/" + flatpakArch() + "/stable/policies/policies.json", }, + Thunderbird: ThunderbirdConfig{ + PoliciesPath: "/etc/thunderbird/policies/policies.json", + FlatpakPoliciesPath: "/var/lib/flatpak/extension/net.thunderbird.Thunderbird.systemconfig/" + flatpakArch() + "/stable/policies/policies.json", + }, Chrome: ChromeConfig{ ChromePoliciesPath: "/etc/opt/chrome/policies/managed", ChromiumPoliciesPath: "/etc/chromium/policies/managed", diff --git a/agent/internal/policy/thunderbird.go b/agent/internal/policy/thunderbird.go new file mode 100644 index 0000000..5451f3f --- /dev/null +++ b/agent/internal/policy/thunderbird.go @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2026 Vute Tech LTD +// Copyright (C) 2026 Bor contributors + +package policy + +import ( + "encoding/json" + "fmt" + "os" + + pb "github.com/VuteTech/Bor/server/pkg/grpc/policy" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" +) + +// ThunderbirdManagedComment is written into policies.json when the file is +// under Bor management. Thunderbird ignores unknown root-level keys, so this +// is safe to include and serves as a human-visible marker. +const ThunderbirdManagedComment = "This file is managed by Bor. Do not edit manually. Changes will be overwritten by policy enforcement." + +// MergeThunderbirdProtos merges multiple ThunderbirdPolicy proto messages into one. +// Uses proto.Merge semantics: singular optional fields from later policies +// overwrite earlier ones; repeated fields are appended. +func MergeThunderbirdProtos(policies []*pb.ThunderbirdPolicy) *pb.ThunderbirdPolicy { + merged := &pb.ThunderbirdPolicy{} + for _, p := range policies { + if p != nil { + proto.Merge(merged, p) + } + } + return merged +} + +// SyncThunderbirdPoliciesFromProto merges the given proto policies and writes +// policies.json to targetPath. When policies is empty, restores the original. +func SyncThunderbirdPoliciesFromProto(targetPath string, policies []*pb.ThunderbirdPolicy) error { + if len(policies) == 0 { + return RestoreOriginal(targetPath) + } + if err := BackupOriginal(targetPath); err != nil { + return fmt.Errorf("failed to backup Thunderbird policies: %w", err) + } + data, err := marshalThunderbirdPolicies(policies) + if err != nil { + return err + } + return WriteFileAtomically(targetPath, data) +} + +// SyncThunderbirdFlatpakPoliciesFromProto writes merged Thunderbird policies +// to the Flatpak extension directory. No backup/restore — Bor owns this file. +func SyncThunderbirdFlatpakPoliciesFromProto(targetPath string, policies []*pb.ThunderbirdPolicy) error { + if len(policies) == 0 { + if err := os.Remove(targetPath); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to remove Flatpak Thunderbird policies: %w", err) + } + return nil + } + data, err := marshalThunderbirdPolicies(policies) + if err != nil { + return err + } + return WriteFileAtomically(targetPath, data) +} + +// marshalThunderbirdPolicies merges the given policies and marshals them into +// the policies.json format Thunderbird expects: {"_comment": "...", "policies": {...}}. +func marshalThunderbirdPolicies(policies []*pb.ThunderbirdPolicy) ([]byte, error) { + merged := MergeThunderbirdProtos(policies) + + opts := protojson.MarshalOptions{EmitUnpopulated: false} + jsonBytes, err := opts.Marshal(merged) + if err != nil { + return nil, fmt.Errorf("failed to marshal Thunderbird policy proto: %w", err) + } + + var policiesMap map[string]interface{} + if unmarshalErr := json.Unmarshal(jsonBytes, &policiesMap); unmarshalErr != nil { + return nil, fmt.Errorf("failed to parse marshalled Thunderbird policy: %w", unmarshalErr) + } + + managed := struct { + Comment string `json:"_comment"` + Policies map[string]interface{} `json:"policies"` + }{ + Comment: ThunderbirdManagedComment, + Policies: policiesMap, + } + + data, err := json.MarshalIndent(managed, "", " ") + if err != nil { + return nil, fmt.Errorf("failed to marshal Thunderbird policies: %w", err) + } + return append(data, '\n'), nil +} diff --git a/agent/internal/policyclient/client.go b/agent/internal/policyclient/client.go index 3f1b583..8ff0020 100644 --- a/agent/internal/policyclient/client.go +++ b/agent/internal/policyclient/client.go @@ -99,18 +99,19 @@ func (c *Client) Close() error { // PolicyInfo holds the policy data returned from the server. type PolicyInfo struct { - ID string - Name string - Type string - Content string // kept for compatibility / fallback - Version int32 - Priority int32 // max binding priority across enabled bindings for this node - KConfigPolicy *pb.KConfigPolicy // populated from typed_content for Kconfig type - FirefoxPolicy *pb.FirefoxPolicy // populated from typed_content for Firefox type - ChromePolicy *pb.ChromePolicy // populated from typed_content for Chrome type - DConfPolicy *pb.DConfPolicy // populated from typed_content for Dconf type - PolkitPolicy *pb.PolkitPolicy // populated from typed_content for Polkit type - PackagePolicy *pb.PackagePolicy // populated from typed_content for Package type + ID string + Name string + Type string + Content string // kept for compatibility / fallback + Version int32 + Priority int32 // max binding priority across enabled bindings for this node + KConfigPolicy *pb.KConfigPolicy // populated from typed_content for Kconfig type + FirefoxPolicy *pb.FirefoxPolicy // populated from typed_content for Firefox type + ChromePolicy *pb.ChromePolicy // populated from typed_content for Chrome type + DConfPolicy *pb.DConfPolicy // populated from typed_content for Dconf type + PolkitPolicy *pb.PolkitPolicy // populated from typed_content for Polkit type + PackagePolicy *pb.PackagePolicy // populated from typed_content for Package type + ThunderbirdPolicy *pb.ThunderbirdPolicy // populated from typed_content for Thunderbird type } // ReportCompliance sends a compliance report for a policy back to the server. @@ -138,11 +139,12 @@ func (c *Client) ReportCompliance(ctx context.Context, policyID string, complian // AgentConfig holds agent configuration retrieved from the server. type AgentConfig struct { - NotifyUsers bool - NotifyCooldown int32 - NotifyMessage string - NotifyMessageFirefox string - NotifyMessageChrome string + NotifyUsers bool + NotifyCooldown int32 + NotifyMessage string + NotifyMessageFirefox string + NotifyMessageChrome string + NotifyMessageThunderbird string } // GetAgentConfig fetches agent configuration (notification settings) @@ -162,11 +164,12 @@ func (c *Client) GetAgentConfig(ctx context.Context) (*AgentConfig, error) { } return &AgentConfig{ - NotifyUsers: cfg.GetNotifyUsers(), - NotifyCooldown: cfg.GetNotifyCooldownSeconds(), - NotifyMessage: cfg.GetNotifyMessage(), - NotifyMessageFirefox: cfg.GetNotifyMessageFirefox(), - NotifyMessageChrome: cfg.GetNotifyMessageChrome(), + NotifyUsers: cfg.GetNotifyUsers(), + NotifyCooldown: cfg.GetNotifyCooldownSeconds(), + NotifyMessage: cfg.GetNotifyMessage(), + NotifyMessageFirefox: cfg.GetNotifyMessageFirefox(), + NotifyMessageChrome: cfg.GetNotifyMessageChrome(), + NotifyMessageThunderbird: cfg.GetNotifyMessageThunderbird(), }, nil } @@ -302,6 +305,9 @@ func (c *Client) SubscribePolicyUpdates(ctx context.Context, lastKnownRevision i if pkgp := p.GetPackagePolicy(); pkgp != nil { pi.PackagePolicy = pkgp } + if tbp := p.GetThunderbirdPolicy(); tbp != nil { + pi.ThunderbirdPolicy = tbp + } } cb(update.GetType().String(), pi, update.GetRevision(), update.GetSnapshotComplete()) diff --git a/proto/policy/policy.proto b/proto/policy/policy.proto index ff73aca..d9db42b 100644 --- a/proto/policy/policy.proto +++ b/proto/policy/policy.proto @@ -11,6 +11,7 @@ import "firefox.proto"; import "kconfig.proto"; import "package.proto"; import "polkit.proto"; +import "thunderbird.proto"; // PolicyService manages desktop policies service PolicyService { @@ -85,8 +86,9 @@ message Policy { KConfigPolicy kconfig_policy = 11; ChromePolicy chrome_policy = 12; DConfPolicy dconf_policy = 13; - PolkitPolicy polkit_policy = 15; - PackagePolicy package_policy = 16; + PolkitPolicy polkit_policy = 15; + PackagePolicy package_policy = 16; + ThunderbirdPolicy thunderbird_policy = 17; } // Binding priority delivered to the agent. Equals the maximum priority @@ -235,8 +237,9 @@ message AgentConfig { bool notify_users = 1; int32 notify_cooldown_seconds = 2; string notify_message = 3; - string notify_message_firefox = 4; - string notify_message_chrome = 5; + string notify_message_firefox = 4; + string notify_message_chrome = 5; + string notify_message_thunderbird = 6; } // ─── Heartbeat messages ───────────────────────────────────────────────────── diff --git a/server/internal/database/settings.go b/server/internal/database/settings.go index a93b115..ee6c875 100644 --- a/server/internal/database/settings.go +++ b/server/internal/database/settings.go @@ -25,7 +25,7 @@ func NewSettingsRepository(db *DB) *SettingsRepository { // GetAgentNotificationSettings retrieves the current agent notification settings func (r *SettingsRepository) GetAgentNotificationSettings(ctx context.Context) (*models.AgentNotificationSettings, error) { - query := `SELECT key, value FROM agent_settings WHERE key IN ('notify_users', 'notify_cooldown', 'notify_message', 'notify_message_firefox', 'notify_message_chrome')` + query := `SELECT key, value FROM agent_settings WHERE key IN ('notify_users', 'notify_cooldown', 'notify_message', 'notify_message_firefox', 'notify_message_chrome', 'notify_message_thunderbird')` rows, err := r.db.QueryContext(ctx, query) if err != nil { @@ -34,11 +34,12 @@ func (r *SettingsRepository) GetAgentNotificationSettings(ctx context.Context) ( defer func() { _ = rows.Close() }() settings := &models.AgentNotificationSettings{ - NotifyUsers: true, - NotifyCooldown: 300, - NotifyMessage: "Desktop policies have been updated. Please log out and log back in for all changes to take effect.", - NotifyMessageFirefox: "Firefox policies have been updated. Please restart Firefox for all changes to take effect.", - NotifyMessageChrome: "Chrome/Chromium policies have been updated. Please restart your browser for all changes to take effect.", + NotifyUsers: true, + NotifyCooldown: 300, + NotifyMessage: "Desktop policies have been updated. Please log out and log back in for all changes to take effect.", + NotifyMessageFirefox: "Firefox policies have been updated. Please restart Firefox for all changes to take effect.", + NotifyMessageChrome: "Chrome/Chromium policies have been updated. Please restart your browser for all changes to take effect.", + NotifyMessageThunderbird: "Thunderbird policies have been updated. Please restart Thunderbird for all changes to take effect.", } for rows.Next() { @@ -60,6 +61,8 @@ func (r *SettingsRepository) GetAgentNotificationSettings(ctx context.Context) ( settings.NotifyMessageFirefox = value case "notify_message_chrome": settings.NotifyMessageChrome = value + case "notify_message_thunderbird": + settings.NotifyMessageThunderbird = value } } @@ -106,6 +109,7 @@ func (r *SettingsRepository) UpdateAgentNotificationSettings(ctx context.Context {"notify_message", settings.NotifyMessage}, {"notify_message_firefox", settings.NotifyMessageFirefox}, {"notify_message_chrome", settings.NotifyMessageChrome}, + {"notify_message_thunderbird", settings.NotifyMessageThunderbird}, } for _, p := range pairs { diff --git a/server/internal/grpc/server.go b/server/internal/grpc/server.go index 16d5bd6..88e8c71 100644 --- a/server/internal/grpc/server.go +++ b/server/internal/grpc/server.go @@ -360,11 +360,12 @@ func (s *PolicyServer) GetAgentConfig(ctx context.Context, _ *pb.GetAgentConfigR return &pb.GetAgentConfigResponse{ Config: &pb.AgentConfig{ - NotifyUsers: settings.NotifyUsers, - NotifyCooldownSeconds: int32(settings.NotifyCooldown), //nolint:gosec // G115: value capped to int32 range at parse time - NotifyMessage: settings.NotifyMessage, - NotifyMessageFirefox: settings.NotifyMessageFirefox, - NotifyMessageChrome: settings.NotifyMessageChrome, + NotifyUsers: settings.NotifyUsers, + NotifyCooldownSeconds: int32(settings.NotifyCooldown), //nolint:gosec // G115: value capped to int32 range at parse time + NotifyMessage: settings.NotifyMessage, + NotifyMessageFirefox: settings.NotifyMessageFirefox, + NotifyMessageChrome: settings.NotifyMessageChrome, + NotifyMessageThunderbird: settings.NotifyMessageThunderbird, }, }, nil } @@ -552,6 +553,13 @@ func modelToProto(p *models.Policy) *pb.Policy { } else { pol.TypedContent = &pb.Policy_PackagePolicy{PackagePolicy: &pkgPol} } + case "Thunderbird": + var tbPol pb.ThunderbirdPolicy + if err := (protojson.UnmarshalOptions{DiscardUnknown: true}).Unmarshal([]byte(p.Content), &tbPol); err != nil { + log.Printf("WARNING: failed to unmarshal Thunderbird typed_content for policy %s: %v", p.ID, err) + } else { + pol.TypedContent = &pb.Policy_ThunderbirdPolicy{ThunderbirdPolicy: &tbPol} + } } return pol diff --git a/server/internal/models/models.go b/server/internal/models/models.go index 6398bec..05a591f 100644 --- a/server/internal/models/models.go +++ b/server/internal/models/models.go @@ -346,11 +346,12 @@ type EnrollmentToken struct { // AgentNotificationSettings holds the notification configuration for agents type AgentNotificationSettings struct { - NotifyUsers bool `json:"notify_users"` - NotifyCooldown int `json:"notify_cooldown"` - NotifyMessage string `json:"notify_message"` - NotifyMessageFirefox string `json:"notify_message_firefox"` - NotifyMessageChrome string `json:"notify_message_chrome"` + NotifyUsers bool `json:"notify_users"` + NotifyCooldown int `json:"notify_cooldown"` + NotifyMessage string `json:"notify_message"` + NotifyMessageFirefox string `json:"notify_message_firefox"` + NotifyMessageChrome string `json:"notify_message_chrome"` + NotifyMessageThunderbird string `json:"notify_message_thunderbird"` } // AuditLog represents an audit log entry diff --git a/server/internal/services/policy.go b/server/internal/services/policy.go index 75d33ee..5e4053e 100644 --- a/server/internal/services/policy.go +++ b/server/internal/services/policy.go @@ -250,6 +250,8 @@ func validatePolicyContent(policyType, content string) error { return ValidateDConfPolicy(content) case "Package": return ValidatePackagePolicy(content) + case "Thunderbird": + return ValidateThunderbirdContent(content) } return nil } diff --git a/server/internal/services/settings.go b/server/internal/services/settings.go index f84bbae..56d47ab 100644 --- a/server/internal/services/settings.go +++ b/server/internal/services/settings.go @@ -41,6 +41,9 @@ func (s *SettingsService) UpdateAgentNotificationSettings(ctx context.Context, s if settings.NotifyMessageChrome == "" { return fmt.Errorf("notify_message_chrome must not be empty") } + if settings.NotifyMessageThunderbird == "" { + return fmt.Errorf("notify_message_thunderbird must not be empty") + } return s.repo.UpdateAgentNotificationSettings(ctx, settings) } diff --git a/server/internal/services/thunderbird.go b/server/internal/services/thunderbird.go new file mode 100644 index 0000000..9ffa4ac --- /dev/null +++ b/server/internal/services/thunderbird.go @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2026 Vute Tech LTD +// Copyright (C) 2026 Bor contributors + +package services + +import ( + "fmt" + + pb "github.com/VuteTech/Bor/server/pkg/grpc/policy" + "google.golang.org/protobuf/encoding/protojson" +) + +// ValidateThunderbirdContent parses content JSON into pb.ThunderbirdPolicy and validates it. +func ValidateThunderbirdContent(content string) error { + if content == "" || content == "{}" { + return nil + } + var tp pb.ThunderbirdPolicy + if err := (protojson.UnmarshalOptions{DiscardUnknown: true}).Unmarshal([]byte(content), &tp); err != nil { + return fmt.Errorf("invalid thunderbird policy JSON: %w", err) + } + return validateThunderbirdProto(&tp) +} + +func validateThunderbirdProto(p *pb.ThunderbirdPolicy) error { + if p.SSLVersionMin != nil && !validSSLVersions[*p.SSLVersionMin] { + return fmt.Errorf("invalid SSLVersionMin: %q", *p.SSLVersionMin) + } + if p.SSLVersionMax != nil && !validSSLVersions[*p.SSLVersionMax] { + return fmt.Errorf("invalid SSLVersionMax: %q", *p.SSLVersionMax) + } + + if p.Proxy != nil && p.Proxy.Mode != "" { + if !validProxyModes[p.Proxy.Mode] { + return fmt.Errorf("invalid Proxy.Mode: %q", p.Proxy.Mode) + } + } + + if p.DNSOverHTTPS != nil && p.DNSOverHTTPS.ProviderURL != "" { + if err := validateSafeURL(p.DNSOverHTTPS.ProviderURL); err != nil { + return fmt.Errorf("invalid DNSOverHTTPS.ProviderURL: %w", err) + } + } + + return nil +} diff --git a/server/pkg/grpc/policy/policy.pb.go b/server/pkg/grpc/policy/policy.pb.go index 5d2ef3e..8251da6 100644 --- a/server/pkg/grpc/policy/policy.pb.go +++ b/server/pkg/grpc/policy/policy.pb.go @@ -174,6 +174,7 @@ type Policy struct { // *Policy_DconfPolicy // *Policy_PolkitPolicy // *Policy_PackagePolicy + // *Policy_ThunderbirdPolicy TypedContent isPolicy_TypedContent `protobuf_oneof:"typed_content"` // Binding priority delivered to the agent. Equals the maximum priority // across all enabled bindings that associate this policy with the node's @@ -338,6 +339,15 @@ func (x *Policy) GetPackagePolicy() *PackagePolicy { return nil } +func (x *Policy) GetThunderbirdPolicy() *ThunderbirdPolicy { + if x != nil { + if x, ok := x.TypedContent.(*Policy_ThunderbirdPolicy); ok { + return x.ThunderbirdPolicy + } + } + return nil +} + func (x *Policy) GetPriority() int32 { if x != nil { return x.Priority @@ -373,6 +383,10 @@ type Policy_PackagePolicy struct { PackagePolicy *PackagePolicy `protobuf:"bytes,16,opt,name=package_policy,json=packagePolicy,proto3,oneof"` } +type Policy_ThunderbirdPolicy struct { + ThunderbirdPolicy *ThunderbirdPolicy `protobuf:"bytes,17,opt,name=thunderbird_policy,json=thunderbirdPolicy,proto3,oneof"` +} + func (*Policy_FirefoxPolicy) isPolicy_TypedContent() {} func (*Policy_KconfigPolicy) isPolicy_TypedContent() {} @@ -385,6 +399,8 @@ func (*Policy_PolkitPolicy) isPolicy_TypedContent() {} func (*Policy_PackagePolicy) isPolicy_TypedContent() {} +func (*Policy_ThunderbirdPolicy) isPolicy_TypedContent() {} + // GetPolicyRequest requests a specific policy type GetPolicyRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1041,14 +1057,15 @@ func (x *GetAgentConfigResponse) GetConfig() *AgentConfig { } type AgentConfig struct { - state protoimpl.MessageState `protogen:"open.v1"` - NotifyUsers bool `protobuf:"varint,1,opt,name=notify_users,json=notifyUsers,proto3" json:"notify_users,omitempty"` - NotifyCooldownSeconds int32 `protobuf:"varint,2,opt,name=notify_cooldown_seconds,json=notifyCooldownSeconds,proto3" json:"notify_cooldown_seconds,omitempty"` - NotifyMessage string `protobuf:"bytes,3,opt,name=notify_message,json=notifyMessage,proto3" json:"notify_message,omitempty"` - NotifyMessageFirefox string `protobuf:"bytes,4,opt,name=notify_message_firefox,json=notifyMessageFirefox,proto3" json:"notify_message_firefox,omitempty"` - NotifyMessageChrome string `protobuf:"bytes,5,opt,name=notify_message_chrome,json=notifyMessageChrome,proto3" json:"notify_message_chrome,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NotifyUsers bool `protobuf:"varint,1,opt,name=notify_users,json=notifyUsers,proto3" json:"notify_users,omitempty"` + NotifyCooldownSeconds int32 `protobuf:"varint,2,opt,name=notify_cooldown_seconds,json=notifyCooldownSeconds,proto3" json:"notify_cooldown_seconds,omitempty"` + NotifyMessage string `protobuf:"bytes,3,opt,name=notify_message,json=notifyMessage,proto3" json:"notify_message,omitempty"` + NotifyMessageFirefox string `protobuf:"bytes,4,opt,name=notify_message_firefox,json=notifyMessageFirefox,proto3" json:"notify_message_firefox,omitempty"` + NotifyMessageChrome string `protobuf:"bytes,5,opt,name=notify_message_chrome,json=notifyMessageChrome,proto3" json:"notify_message_chrome,omitempty"` + NotifyMessageThunderbird string `protobuf:"bytes,6,opt,name=notify_message_thunderbird,json=notifyMessageThunderbird,proto3" json:"notify_message_thunderbird,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AgentConfig) Reset() { @@ -1116,6 +1133,13 @@ func (x *AgentConfig) GetNotifyMessageChrome() string { return "" } +func (x *AgentConfig) GetNotifyMessageThunderbird() string { + if x != nil { + return x.NotifyMessageThunderbird + } + return "" +} + // NodeInfo contains metadata reported by an agent node. type NodeInfo struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1592,291 +1616,301 @@ var file_policy_proto_rawDesc = []byte{ 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0d, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x70, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x05, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x45, 0x0a, - 0x0e, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0e, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, - 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x42, 0x0a, 0x0d, 0x63, - 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, - 0x00, 0x52, 0x0c, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, - 0x3f, 0x0a, 0x0c, 0x64, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x43, 0x6f, 0x6e, 0x66, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x63, 0x6f, 0x6e, 0x66, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x12, 0x42, 0x0a, 0x0d, 0x70, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, - 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x61, - 0x63, 0x6b, 0x61, 0x67, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, - 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x42, 0x0f, 0x0a, 0x0d, 0x74, 0x79, 0x70, 0x65, 0x64, - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, 0x22, 0x42, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, - 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x8f, 0x01, - 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, - 0x92, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x6f, 0x72, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, - 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x6c, 0x0a, 0x1d, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, - 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0xa8, 0x02, 0x0a, 0x0c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x26, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x2d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x22, 0x64, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, - 0x0b, 0x0a, 0x07, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, - 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x4e, 0x41, - 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x45, 0x54, 0x41, 0x44, - 0x41, 0x54, 0x41, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x05, 0x22, 0x98, 0x01, - 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x74, 0x65, 0x6d, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xbc, 0x02, 0x0a, 0x17, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x39, 0x0a, 0x05, - 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x6f, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc4, 0x06, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x45, 0x0a, 0x0e, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, + 0x78, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0e, 0x6b, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x4b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, + 0x0d, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x42, + 0x0a, 0x0d, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x64, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x43, 0x6f, 0x6e, 0x66, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x63, 0x6f, 0x6e, 0x66, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x42, 0x0a, 0x0d, 0x70, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x6f, 0x72, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x6b, 0x69, + 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x6f, 0x6c, 0x6b, 0x69, + 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, + 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x51, + 0x0a, 0x12, 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x6f, 0x72, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x11, + 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x42, 0x0f, 0x0a, + 0x0d, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2f, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, 0x22, + 0x42, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x22, 0x8f, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, + 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x92, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, + 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, + 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x6c, 0x0a, 0x1d, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, + 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa8, 0x02, 0x0a, 0x0c, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x73, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x22, 0x64, 0x0a, + 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, + 0x0c, 0x0a, 0x08, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x04, 0x12, 0x14, 0x0a, + 0x10, 0x4d, 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, + 0x54, 0x10, 0x05, 0x22, 0x98, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, + 0x63, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x34, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x17, 0x0a, - 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x32, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x22, 0xf9, 0x01, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x6f, 0x74, 0x69, - 0x66, 0x79, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x79, 0x5f, 0x63, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, - 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x43, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, - 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x12, 0x32, 0x0a, 0x15, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, - 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x6e, 0x6f, 0x74, - 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, - 0x22, 0xdc, 0x01, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x71, 0x64, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x64, - 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, - 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x6b, - 0x74, 0x6f, 0x70, 0x5f, 0x65, 0x6e, 0x76, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x76, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x22, - 0x5c, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, - 0x12, 0x2b, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4e, - 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x2f, 0x0a, - 0x11, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x22, 0x4d, - 0x0a, 0x11, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x6d, 0x6d, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x6d, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0xd1, 0x01, - 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xbc, + 0x02, 0x0a, 0x17, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, + 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x3b, 0x0a, 0x0b, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x12, 0x3e, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, - 0x73, 0x22, 0x35, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, 0x70, 0x65, - 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x32, 0x0a, 0x17, 0x52, 0x65, 0x6e, 0x65, - 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x73, 0x72, 0x5f, 0x70, 0x65, 0x6d, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x73, 0x72, 0x50, 0x65, 0x6d, 0x22, 0x42, 0x0a, 0x18, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, + 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x0b, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x62, 0x6f, 0x72, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, + 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x39, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x74, 0x65, 0x6d, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x34, 0x0a, + 0x18, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4c, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb7, 0x02, 0x0a, 0x0b, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x36, 0x0a, + 0x17, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x63, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, 0x6e, + 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x6f, 0x6c, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x16, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, + 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x72, 0x65, 0x66, + 0x6f, 0x78, 0x12, 0x32, 0x0a, 0x15, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x5f, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x13, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x43, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x1a, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x62, 0x69, 0x72, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x6e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x62, 0x69, 0x72, 0x64, 0x22, 0xdc, 0x01, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x64, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x66, 0x71, 0x64, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x70, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, + 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x65, 0x6e, 0x76, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x45, 0x6e, 0x76, 0x73, 0x12, + 0x23, 0x0a, 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x49, 0x64, 0x22, 0x5c, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x22, 0x2f, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x22, 0x4d, 0x0a, 0x11, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x6d, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x6d, 0x6d, 0x12, 0x12, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x22, 0xd1, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, 0x70, + 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3b, 0x0a, 0x0b, 0x64, 0x65, 0x74, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x64, 0x65, 0x74, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3e, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x35, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, + 0x61, 0x6d, 0x70, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x32, 0x0a, 0x17, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x50, 0x65, 0x6d, - 0x2a, 0xb8, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, - 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, - 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, - 0x41, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, - 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x4e, 0x5f, 0x43, - 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, - 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x49, 0x4e, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x1b, - 0x0a, 0x17, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x32, 0xe8, 0x07, 0x0a, 0x0d, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1f, 0x2e, 0x62, 0x6f, 0x72, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x6f, - 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, - 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x22, 0x2e, - 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, - 0x12, 0x2c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, - 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, 0x01, 0x12, 0x63, 0x0a, - 0x10, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, - 0x65, 0x12, 0x26, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x6f, 0x72, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x62, 0x6f, 0x72, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x1f, - 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x48, - 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x73, 0x72, 0x5f, 0x70, + 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x73, 0x72, 0x50, 0x65, 0x6d, + 0x22, 0x42, 0x0a, 0x18, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x70, 0x65, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x65, 0x72, + 0x74, 0x50, 0x65, 0x6d, 0x2a, 0xb8, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, + 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, + 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x4f, 0x4d, 0x50, + 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, + 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, 0x4d, + 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, + 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x22, + 0x0a, 0x1e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x41, 0x50, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x42, 0x4c, 0x45, + 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x43, 0x45, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x32, + 0xe8, 0x07, 0x0a, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1f, + 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x66, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, 0x70, 0x65, - 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, - 0x70, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x10, 0x52, 0x65, 0x6e, - 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x26, 0x2e, + 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x12, 0x22, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x16, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x30, + 0x01, 0x12, 0x63, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x6e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, - 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x61, - 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x6b, - 0x69, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x62, 0x6f, + 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, + 0x61, 0x74, 0x12, 0x1f, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, + 0x61, 0x6d, 0x70, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x2e, 0x62, 0x6f, 0x72, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x6d, 0x70, 0x65, 0x72, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, + 0x10, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x26, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x62, 0x6f, 0x72, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x65, 0x77, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, + 0x72, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, - 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x56, 0x75, 0x74, 0x65, 0x54, 0x65, 0x63, 0x68, 0x2f, 0x42, 0x6f, - 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x50, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x12, + 0x2b, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x43, 0x61, 0x74, 0x61, + 0x6c, 0x6f, 0x67, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x62, + 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x6b, 0x69, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x56, 0x75, 0x74, 0x65, 0x54, 0x65, 0x63, + 0x68, 0x2f, 0x42, 0x6f, 0x72, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3b, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1924,10 +1958,11 @@ var file_policy_proto_goTypes = []any{ (*DConfPolicy)(nil), // 27: bor.policy.v1.DConfPolicy (*PolkitPolicy)(nil), // 28: bor.policy.v1.PolkitPolicy (*PackagePolicy)(nil), // 29: bor.policy.v1.PackagePolicy - (*ReportSchemaCatalogueRequest)(nil), // 30: bor.policy.v1.ReportSchemaCatalogueRequest - (*ReportPolkitCatalogueRequest)(nil), // 31: bor.policy.v1.ReportPolkitCatalogueRequest - (*ReportSchemaCatalogueResponse)(nil), // 32: bor.policy.v1.ReportSchemaCatalogueResponse - (*ReportPolkitCatalogueResponse)(nil), // 33: bor.policy.v1.ReportPolkitCatalogueResponse + (*ThunderbirdPolicy)(nil), // 30: bor.policy.v1.ThunderbirdPolicy + (*ReportSchemaCatalogueRequest)(nil), // 31: bor.policy.v1.ReportSchemaCatalogueRequest + (*ReportPolkitCatalogueRequest)(nil), // 32: bor.policy.v1.ReportPolkitCatalogueRequest + (*ReportSchemaCatalogueResponse)(nil), // 33: bor.policy.v1.ReportSchemaCatalogueResponse + (*ReportPolkitCatalogueResponse)(nil), // 34: bor.policy.v1.ReportPolkitCatalogueResponse } var file_policy_proto_depIdxs = []int32{ 23, // 0: bor.policy.v1.Policy.created_at:type_name -> google.protobuf.Timestamp @@ -1938,43 +1973,44 @@ var file_policy_proto_depIdxs = []int32{ 27, // 5: bor.policy.v1.Policy.dconf_policy:type_name -> bor.policy.v1.DConfPolicy 28, // 6: bor.policy.v1.Policy.polkit_policy:type_name -> bor.policy.v1.PolkitPolicy 29, // 7: bor.policy.v1.Policy.package_policy:type_name -> bor.policy.v1.PackagePolicy - 2, // 8: bor.policy.v1.GetPolicyResponse.policy:type_name -> bor.policy.v1.Policy - 2, // 9: bor.policy.v1.ListPoliciesResponse.policies:type_name -> bor.policy.v1.Policy - 1, // 10: bor.policy.v1.PolicyUpdate.type:type_name -> bor.policy.v1.PolicyUpdate.UpdateType - 2, // 11: bor.policy.v1.PolicyUpdate.policy:type_name -> bor.policy.v1.Policy - 0, // 12: bor.policy.v1.ComplianceItemResult.status:type_name -> bor.policy.v1.ComplianceStatus - 23, // 13: bor.policy.v1.ReportComplianceRequest.reported_at:type_name -> google.protobuf.Timestamp - 0, // 14: bor.policy.v1.ReportComplianceRequest.status:type_name -> bor.policy.v1.ComplianceStatus - 9, // 15: bor.policy.v1.ReportComplianceRequest.items:type_name -> bor.policy.v1.ComplianceItemResult - 14, // 16: bor.policy.v1.GetAgentConfigResponse.config:type_name -> bor.policy.v1.AgentConfig - 15, // 17: bor.policy.v1.HeartbeatRequest.info:type_name -> bor.policy.v1.NodeInfo - 23, // 18: bor.policy.v1.ReportTamperEventRequest.detected_at:type_name -> google.protobuf.Timestamp - 18, // 19: bor.policy.v1.ReportTamperEventRequest.processes:type_name -> bor.policy.v1.TamperProcessInfo - 3, // 20: bor.policy.v1.PolicyService.GetPolicy:input_type -> bor.policy.v1.GetPolicyRequest - 5, // 21: bor.policy.v1.PolicyService.ListPolicies:input_type -> bor.policy.v1.ListPoliciesRequest - 7, // 22: bor.policy.v1.PolicyService.SubscribePolicyUpdates:input_type -> bor.policy.v1.SubscribePolicyUpdatesRequest - 10, // 23: bor.policy.v1.PolicyService.ReportCompliance:input_type -> bor.policy.v1.ReportComplianceRequest - 12, // 24: bor.policy.v1.PolicyService.GetAgentConfig:input_type -> bor.policy.v1.GetAgentConfigRequest - 16, // 25: bor.policy.v1.PolicyService.Heartbeat:input_type -> bor.policy.v1.HeartbeatRequest - 19, // 26: bor.policy.v1.PolicyService.ReportTamperEvent:input_type -> bor.policy.v1.ReportTamperEventRequest - 21, // 27: bor.policy.v1.PolicyService.RenewCertificate:input_type -> bor.policy.v1.RenewCertificateRequest - 30, // 28: bor.policy.v1.PolicyService.ReportSchemaCatalogue:input_type -> bor.policy.v1.ReportSchemaCatalogueRequest - 31, // 29: bor.policy.v1.PolicyService.ReportPolkitCatalogue:input_type -> bor.policy.v1.ReportPolkitCatalogueRequest - 4, // 30: bor.policy.v1.PolicyService.GetPolicy:output_type -> bor.policy.v1.GetPolicyResponse - 6, // 31: bor.policy.v1.PolicyService.ListPolicies:output_type -> bor.policy.v1.ListPoliciesResponse - 8, // 32: bor.policy.v1.PolicyService.SubscribePolicyUpdates:output_type -> bor.policy.v1.PolicyUpdate - 11, // 33: bor.policy.v1.PolicyService.ReportCompliance:output_type -> bor.policy.v1.ReportComplianceResponse - 13, // 34: bor.policy.v1.PolicyService.GetAgentConfig:output_type -> bor.policy.v1.GetAgentConfigResponse - 17, // 35: bor.policy.v1.PolicyService.Heartbeat:output_type -> bor.policy.v1.HeartbeatResponse - 20, // 36: bor.policy.v1.PolicyService.ReportTamperEvent:output_type -> bor.policy.v1.ReportTamperEventResponse - 22, // 37: bor.policy.v1.PolicyService.RenewCertificate:output_type -> bor.policy.v1.RenewCertificateResponse - 32, // 38: bor.policy.v1.PolicyService.ReportSchemaCatalogue:output_type -> bor.policy.v1.ReportSchemaCatalogueResponse - 33, // 39: bor.policy.v1.PolicyService.ReportPolkitCatalogue:output_type -> bor.policy.v1.ReportPolkitCatalogueResponse - 30, // [30:40] is the sub-list for method output_type - 20, // [20:30] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 30, // 8: bor.policy.v1.Policy.thunderbird_policy:type_name -> bor.policy.v1.ThunderbirdPolicy + 2, // 9: bor.policy.v1.GetPolicyResponse.policy:type_name -> bor.policy.v1.Policy + 2, // 10: bor.policy.v1.ListPoliciesResponse.policies:type_name -> bor.policy.v1.Policy + 1, // 11: bor.policy.v1.PolicyUpdate.type:type_name -> bor.policy.v1.PolicyUpdate.UpdateType + 2, // 12: bor.policy.v1.PolicyUpdate.policy:type_name -> bor.policy.v1.Policy + 0, // 13: bor.policy.v1.ComplianceItemResult.status:type_name -> bor.policy.v1.ComplianceStatus + 23, // 14: bor.policy.v1.ReportComplianceRequest.reported_at:type_name -> google.protobuf.Timestamp + 0, // 15: bor.policy.v1.ReportComplianceRequest.status:type_name -> bor.policy.v1.ComplianceStatus + 9, // 16: bor.policy.v1.ReportComplianceRequest.items:type_name -> bor.policy.v1.ComplianceItemResult + 14, // 17: bor.policy.v1.GetAgentConfigResponse.config:type_name -> bor.policy.v1.AgentConfig + 15, // 18: bor.policy.v1.HeartbeatRequest.info:type_name -> bor.policy.v1.NodeInfo + 23, // 19: bor.policy.v1.ReportTamperEventRequest.detected_at:type_name -> google.protobuf.Timestamp + 18, // 20: bor.policy.v1.ReportTamperEventRequest.processes:type_name -> bor.policy.v1.TamperProcessInfo + 3, // 21: bor.policy.v1.PolicyService.GetPolicy:input_type -> bor.policy.v1.GetPolicyRequest + 5, // 22: bor.policy.v1.PolicyService.ListPolicies:input_type -> bor.policy.v1.ListPoliciesRequest + 7, // 23: bor.policy.v1.PolicyService.SubscribePolicyUpdates:input_type -> bor.policy.v1.SubscribePolicyUpdatesRequest + 10, // 24: bor.policy.v1.PolicyService.ReportCompliance:input_type -> bor.policy.v1.ReportComplianceRequest + 12, // 25: bor.policy.v1.PolicyService.GetAgentConfig:input_type -> bor.policy.v1.GetAgentConfigRequest + 16, // 26: bor.policy.v1.PolicyService.Heartbeat:input_type -> bor.policy.v1.HeartbeatRequest + 19, // 27: bor.policy.v1.PolicyService.ReportTamperEvent:input_type -> bor.policy.v1.ReportTamperEventRequest + 21, // 28: bor.policy.v1.PolicyService.RenewCertificate:input_type -> bor.policy.v1.RenewCertificateRequest + 31, // 29: bor.policy.v1.PolicyService.ReportSchemaCatalogue:input_type -> bor.policy.v1.ReportSchemaCatalogueRequest + 32, // 30: bor.policy.v1.PolicyService.ReportPolkitCatalogue:input_type -> bor.policy.v1.ReportPolkitCatalogueRequest + 4, // 31: bor.policy.v1.PolicyService.GetPolicy:output_type -> bor.policy.v1.GetPolicyResponse + 6, // 32: bor.policy.v1.PolicyService.ListPolicies:output_type -> bor.policy.v1.ListPoliciesResponse + 8, // 33: bor.policy.v1.PolicyService.SubscribePolicyUpdates:output_type -> bor.policy.v1.PolicyUpdate + 11, // 34: bor.policy.v1.PolicyService.ReportCompliance:output_type -> bor.policy.v1.ReportComplianceResponse + 13, // 35: bor.policy.v1.PolicyService.GetAgentConfig:output_type -> bor.policy.v1.GetAgentConfigResponse + 17, // 36: bor.policy.v1.PolicyService.Heartbeat:output_type -> bor.policy.v1.HeartbeatResponse + 20, // 37: bor.policy.v1.PolicyService.ReportTamperEvent:output_type -> bor.policy.v1.ReportTamperEventResponse + 22, // 38: bor.policy.v1.PolicyService.RenewCertificate:output_type -> bor.policy.v1.RenewCertificateResponse + 33, // 39: bor.policy.v1.PolicyService.ReportSchemaCatalogue:output_type -> bor.policy.v1.ReportSchemaCatalogueResponse + 34, // 40: bor.policy.v1.PolicyService.ReportPolkitCatalogue:output_type -> bor.policy.v1.ReportPolkitCatalogueResponse + 31, // [31:41] is the sub-list for method output_type + 21, // [21:31] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_policy_proto_init() } @@ -1988,6 +2024,7 @@ func file_policy_proto_init() { file_kconfig_proto_init() file_package_proto_init() file_polkit_proto_init() + file_thunderbird_proto_init() file_policy_proto_msgTypes[0].OneofWrappers = []any{ (*Policy_FirefoxPolicy)(nil), (*Policy_KconfigPolicy)(nil), @@ -1995,6 +2032,7 @@ func file_policy_proto_init() { (*Policy_DconfPolicy)(nil), (*Policy_PolkitPolicy)(nil), (*Policy_PackagePolicy)(nil), + (*Policy_ThunderbirdPolicy)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/server/pkg/grpc/policy/thunderbird.pb.go b/server/pkg/grpc/policy/thunderbird.pb.go new file mode 100644 index 0000000..25d2ea9 --- /dev/null +++ b/server/pkg/grpc/policy/thunderbird.pb.go @@ -0,0 +1,1348 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2026 Vute Tech LTD +// Copyright (C) 2026 Bor contributors + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.3 +// protoc v7.34.1 +// source: thunderbird.proto + +package policy + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ThunderbirdPolicy is the canonical schema for a Thunderbird enterprise +// policy on Linux. It maps directly to the "policies" key in policies.json. +// Field json_name annotations preserve PascalCase so protojson round-trips +// with the key names Thunderbird expects. +type ThunderbirdPolicy struct { + state protoimpl.MessageState `protogen:"open.v1"` + // ── Updates ─────────────────────────────────────────────────────────────── + DisableAppUpdate *bool `protobuf:"varint,1,opt,name=DisableAppUpdate,proto3,oneof" json:"DisableAppUpdate,omitempty"` + AppAutoUpdate *bool `protobuf:"varint,2,opt,name=AppAutoUpdate,proto3,oneof" json:"AppAutoUpdate,omitempty"` + BackgroundAppUpdate *bool `protobuf:"varint,3,opt,name=BackgroundAppUpdate,proto3,oneof" json:"BackgroundAppUpdate,omitempty"` + ManualAppUpdateOnly *bool `protobuf:"varint,4,opt,name=ManualAppUpdateOnly,proto3,oneof" json:"ManualAppUpdateOnly,omitempty"` + AppUpdatePin *string `protobuf:"bytes,5,opt,name=AppUpdatePin,proto3,oneof" json:"AppUpdatePin,omitempty"` + AppUpdateURL *string `protobuf:"bytes,6,opt,name=AppUpdateURL,proto3,oneof" json:"AppUpdateURL,omitempty"` + // ── Privacy & Telemetry ─────────────────────────────────────────────────── + DisableTelemetry *bool `protobuf:"varint,10,opt,name=DisableTelemetry,proto3,oneof" json:"DisableTelemetry,omitempty"` + // ── Security ────────────────────────────────────────────────────────────── + DisablePasswordReveal *bool `protobuf:"varint,20,opt,name=DisablePasswordReveal,proto3,oneof" json:"DisablePasswordReveal,omitempty"` + DisableMasterPasswordCreation *bool `protobuf:"varint,21,opt,name=DisableMasterPasswordCreation,proto3,oneof" json:"DisableMasterPasswordCreation,omitempty"` + PrimaryPassword *bool `protobuf:"varint,22,opt,name=PrimaryPassword,proto3,oneof" json:"PrimaryPassword,omitempty"` + PasswordManagerEnabled *bool `protobuf:"varint,23,opt,name=PasswordManagerEnabled,proto3,oneof" json:"PasswordManagerEnabled,omitempty"` + OfferToSaveLogins *bool `protobuf:"varint,24,opt,name=OfferToSaveLogins,proto3,oneof" json:"OfferToSaveLogins,omitempty"` + OfferToSaveLoginsDefault *bool `protobuf:"varint,25,opt,name=OfferToSaveLoginsDefault,proto3,oneof" json:"OfferToSaveLoginsDefault,omitempty"` + DisableSecurityBypass *bool `protobuf:"varint,26,opt,name=DisableSecurityBypass,proto3,oneof" json:"DisableSecurityBypass,omitempty"` + SSLVersionMin *string `protobuf:"bytes,27,opt,name=SSLVersionMin,proto3,oneof" json:"SSLVersionMin,omitempty"` + SSLVersionMax *string `protobuf:"bytes,28,opt,name=SSLVersionMax,proto3,oneof" json:"SSLVersionMax,omitempty"` + // ── Restrictions ────────────────────────────────────────────────────────── + BlockAboutAddons *bool `protobuf:"varint,30,opt,name=BlockAboutAddons,proto3,oneof" json:"BlockAboutAddons,omitempty"` + BlockAboutConfig *bool `protobuf:"varint,31,opt,name=BlockAboutConfig,proto3,oneof" json:"BlockAboutConfig,omitempty"` + BlockAboutProfiles *bool `protobuf:"varint,32,opt,name=BlockAboutProfiles,proto3,oneof" json:"BlockAboutProfiles,omitempty"` + BlockAboutSupport *bool `protobuf:"varint,33,opt,name=BlockAboutSupport,proto3,oneof" json:"BlockAboutSupport,omitempty"` + DisableSafeMode *bool `protobuf:"varint,34,opt,name=DisableSafeMode,proto3,oneof" json:"DisableSafeMode,omitempty"` + // ── Developer Tools ─────────────────────────────────────────────────────── + DisableDeveloperTools *bool `protobuf:"varint,40,opt,name=DisableDeveloperTools,proto3,oneof" json:"DisableDeveloperTools,omitempty"` + // ── Add-ons / Extensions ────────────────────────────────────────────────── + DisableSystemAddonUpdate *bool `protobuf:"varint,50,opt,name=DisableSystemAddonUpdate,proto3,oneof" json:"DisableSystemAddonUpdate,omitempty"` + ExtensionUpdate *bool `protobuf:"varint,51,opt,name=ExtensionUpdate,proto3,oneof" json:"ExtensionUpdate,omitempty"` + // ── Network ─────────────────────────────────────────────────────────────── + HardwareAcceleration *bool `protobuf:"varint,60,opt,name=HardwareAcceleration,proto3,oneof" json:"HardwareAcceleration,omitempty"` + NetworkPrediction *bool `protobuf:"varint,61,opt,name=NetworkPrediction,proto3,oneof" json:"NetworkPrediction,omitempty"` + CaptivePortal *bool `protobuf:"varint,62,opt,name=CaptivePortal,proto3,oneof" json:"CaptivePortal,omitempty"` + // ── General ─────────────────────────────────────────────────────────────── + PromptForDownloadLocation *bool `protobuf:"varint,70,opt,name=PromptForDownloadLocation,proto3,oneof" json:"PromptForDownloadLocation,omitempty"` + DefaultDownloadDirectory *string `protobuf:"bytes,71,opt,name=DefaultDownloadDirectory,proto3,oneof" json:"DefaultDownloadDirectory,omitempty"` + DownloadDirectory *string `protobuf:"bytes,72,opt,name=DownloadDirectory,proto3,oneof" json:"DownloadDirectory,omitempty"` + DisableBuiltinPDFViewer *bool `protobuf:"varint,73,opt,name=DisableBuiltinPDFViewer,proto3,oneof" json:"DisableBuiltinPDFViewer,omitempty"` + // ── Locale ──────────────────────────────────────────────────────────────── + RequestedLocales []string `protobuf:"bytes,80,rep,name=RequestedLocales,proto3" json:"RequestedLocales,omitempty"` + // ── Object / composite policies ─────────────────────────────────────────── + DNSOverHTTPS *ThunderbirdDNSOverHTTPS `protobuf:"bytes,90,opt,name=DNSOverHTTPS,proto3,oneof" json:"DNSOverHTTPS,omitempty"` + Cookies *ThunderbirdCookies `protobuf:"bytes,91,opt,name=Cookies,proto3,oneof" json:"Cookies,omitempty"` + Extensions *ThunderbirdExtensions `protobuf:"bytes,92,opt,name=Extensions,proto3,oneof" json:"Extensions,omitempty"` + Proxy *ThunderbirdProxy `protobuf:"bytes,93,opt,name=Proxy,proto3,oneof" json:"Proxy,omitempty"` + Authentication *ThunderbirdAuthentication `protobuf:"bytes,94,opt,name=Authentication,proto3,oneof" json:"Authentication,omitempty"` + SearchEngines *ThunderbirdSearchEngines `protobuf:"bytes,95,opt,name=SearchEngines,proto3,oneof" json:"SearchEngines,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdPolicy) Reset() { + *x = ThunderbirdPolicy{} + mi := &file_thunderbird_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdPolicy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdPolicy) ProtoMessage() {} + +func (x *ThunderbirdPolicy) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdPolicy.ProtoReflect.Descriptor instead. +func (*ThunderbirdPolicy) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{0} +} + +func (x *ThunderbirdPolicy) GetDisableAppUpdate() bool { + if x != nil && x.DisableAppUpdate != nil { + return *x.DisableAppUpdate + } + return false +} + +func (x *ThunderbirdPolicy) GetAppAutoUpdate() bool { + if x != nil && x.AppAutoUpdate != nil { + return *x.AppAutoUpdate + } + return false +} + +func (x *ThunderbirdPolicy) GetBackgroundAppUpdate() bool { + if x != nil && x.BackgroundAppUpdate != nil { + return *x.BackgroundAppUpdate + } + return false +} + +func (x *ThunderbirdPolicy) GetManualAppUpdateOnly() bool { + if x != nil && x.ManualAppUpdateOnly != nil { + return *x.ManualAppUpdateOnly + } + return false +} + +func (x *ThunderbirdPolicy) GetAppUpdatePin() string { + if x != nil && x.AppUpdatePin != nil { + return *x.AppUpdatePin + } + return "" +} + +func (x *ThunderbirdPolicy) GetAppUpdateURL() string { + if x != nil && x.AppUpdateURL != nil { + return *x.AppUpdateURL + } + return "" +} + +func (x *ThunderbirdPolicy) GetDisableTelemetry() bool { + if x != nil && x.DisableTelemetry != nil { + return *x.DisableTelemetry + } + return false +} + +func (x *ThunderbirdPolicy) GetDisablePasswordReveal() bool { + if x != nil && x.DisablePasswordReveal != nil { + return *x.DisablePasswordReveal + } + return false +} + +func (x *ThunderbirdPolicy) GetDisableMasterPasswordCreation() bool { + if x != nil && x.DisableMasterPasswordCreation != nil { + return *x.DisableMasterPasswordCreation + } + return false +} + +func (x *ThunderbirdPolicy) GetPrimaryPassword() bool { + if x != nil && x.PrimaryPassword != nil { + return *x.PrimaryPassword + } + return false +} + +func (x *ThunderbirdPolicy) GetPasswordManagerEnabled() bool { + if x != nil && x.PasswordManagerEnabled != nil { + return *x.PasswordManagerEnabled + } + return false +} + +func (x *ThunderbirdPolicy) GetOfferToSaveLogins() bool { + if x != nil && x.OfferToSaveLogins != nil { + return *x.OfferToSaveLogins + } + return false +} + +func (x *ThunderbirdPolicy) GetOfferToSaveLoginsDefault() bool { + if x != nil && x.OfferToSaveLoginsDefault != nil { + return *x.OfferToSaveLoginsDefault + } + return false +} + +func (x *ThunderbirdPolicy) GetDisableSecurityBypass() bool { + if x != nil && x.DisableSecurityBypass != nil { + return *x.DisableSecurityBypass + } + return false +} + +func (x *ThunderbirdPolicy) GetSSLVersionMin() string { + if x != nil && x.SSLVersionMin != nil { + return *x.SSLVersionMin + } + return "" +} + +func (x *ThunderbirdPolicy) GetSSLVersionMax() string { + if x != nil && x.SSLVersionMax != nil { + return *x.SSLVersionMax + } + return "" +} + +func (x *ThunderbirdPolicy) GetBlockAboutAddons() bool { + if x != nil && x.BlockAboutAddons != nil { + return *x.BlockAboutAddons + } + return false +} + +func (x *ThunderbirdPolicy) GetBlockAboutConfig() bool { + if x != nil && x.BlockAboutConfig != nil { + return *x.BlockAboutConfig + } + return false +} + +func (x *ThunderbirdPolicy) GetBlockAboutProfiles() bool { + if x != nil && x.BlockAboutProfiles != nil { + return *x.BlockAboutProfiles + } + return false +} + +func (x *ThunderbirdPolicy) GetBlockAboutSupport() bool { + if x != nil && x.BlockAboutSupport != nil { + return *x.BlockAboutSupport + } + return false +} + +func (x *ThunderbirdPolicy) GetDisableSafeMode() bool { + if x != nil && x.DisableSafeMode != nil { + return *x.DisableSafeMode + } + return false +} + +func (x *ThunderbirdPolicy) GetDisableDeveloperTools() bool { + if x != nil && x.DisableDeveloperTools != nil { + return *x.DisableDeveloperTools + } + return false +} + +func (x *ThunderbirdPolicy) GetDisableSystemAddonUpdate() bool { + if x != nil && x.DisableSystemAddonUpdate != nil { + return *x.DisableSystemAddonUpdate + } + return false +} + +func (x *ThunderbirdPolicy) GetExtensionUpdate() bool { + if x != nil && x.ExtensionUpdate != nil { + return *x.ExtensionUpdate + } + return false +} + +func (x *ThunderbirdPolicy) GetHardwareAcceleration() bool { + if x != nil && x.HardwareAcceleration != nil { + return *x.HardwareAcceleration + } + return false +} + +func (x *ThunderbirdPolicy) GetNetworkPrediction() bool { + if x != nil && x.NetworkPrediction != nil { + return *x.NetworkPrediction + } + return false +} + +func (x *ThunderbirdPolicy) GetCaptivePortal() bool { + if x != nil && x.CaptivePortal != nil { + return *x.CaptivePortal + } + return false +} + +func (x *ThunderbirdPolicy) GetPromptForDownloadLocation() bool { + if x != nil && x.PromptForDownloadLocation != nil { + return *x.PromptForDownloadLocation + } + return false +} + +func (x *ThunderbirdPolicy) GetDefaultDownloadDirectory() string { + if x != nil && x.DefaultDownloadDirectory != nil { + return *x.DefaultDownloadDirectory + } + return "" +} + +func (x *ThunderbirdPolicy) GetDownloadDirectory() string { + if x != nil && x.DownloadDirectory != nil { + return *x.DownloadDirectory + } + return "" +} + +func (x *ThunderbirdPolicy) GetDisableBuiltinPDFViewer() bool { + if x != nil && x.DisableBuiltinPDFViewer != nil { + return *x.DisableBuiltinPDFViewer + } + return false +} + +func (x *ThunderbirdPolicy) GetRequestedLocales() []string { + if x != nil { + return x.RequestedLocales + } + return nil +} + +func (x *ThunderbirdPolicy) GetDNSOverHTTPS() *ThunderbirdDNSOverHTTPS { + if x != nil { + return x.DNSOverHTTPS + } + return nil +} + +func (x *ThunderbirdPolicy) GetCookies() *ThunderbirdCookies { + if x != nil { + return x.Cookies + } + return nil +} + +func (x *ThunderbirdPolicy) GetExtensions() *ThunderbirdExtensions { + if x != nil { + return x.Extensions + } + return nil +} + +func (x *ThunderbirdPolicy) GetProxy() *ThunderbirdProxy { + if x != nil { + return x.Proxy + } + return nil +} + +func (x *ThunderbirdPolicy) GetAuthentication() *ThunderbirdAuthentication { + if x != nil { + return x.Authentication + } + return nil +} + +func (x *ThunderbirdPolicy) GetSearchEngines() *ThunderbirdSearchEngines { + if x != nil { + return x.SearchEngines + } + return nil +} + +// ThunderbirdDNSOverHTTPS configures DNS-over-HTTPS settings. +type ThunderbirdDNSOverHTTPS struct { + state protoimpl.MessageState `protogen:"open.v1"` + Enabled bool `protobuf:"varint,1,opt,name=Enabled,proto3" json:"Enabled,omitempty"` + ProviderURL string `protobuf:"bytes,2,opt,name=ProviderURL,proto3" json:"ProviderURL,omitempty"` + Locked bool `protobuf:"varint,3,opt,name=Locked,proto3" json:"Locked,omitempty"` + ExcludedDomains []string `protobuf:"bytes,4,rep,name=ExcludedDomains,proto3" json:"ExcludedDomains,omitempty"` + Fallback bool `protobuf:"varint,5,opt,name=Fallback,proto3" json:"Fallback,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdDNSOverHTTPS) Reset() { + *x = ThunderbirdDNSOverHTTPS{} + mi := &file_thunderbird_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdDNSOverHTTPS) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdDNSOverHTTPS) ProtoMessage() {} + +func (x *ThunderbirdDNSOverHTTPS) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdDNSOverHTTPS.ProtoReflect.Descriptor instead. +func (*ThunderbirdDNSOverHTTPS) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{1} +} + +func (x *ThunderbirdDNSOverHTTPS) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *ThunderbirdDNSOverHTTPS) GetProviderURL() string { + if x != nil { + return x.ProviderURL + } + return "" +} + +func (x *ThunderbirdDNSOverHTTPS) GetLocked() bool { + if x != nil { + return x.Locked + } + return false +} + +func (x *ThunderbirdDNSOverHTTPS) GetExcludedDomains() []string { + if x != nil { + return x.ExcludedDomains + } + return nil +} + +func (x *ThunderbirdDNSOverHTTPS) GetFallback() bool { + if x != nil { + return x.Fallback + } + return false +} + +// ThunderbirdCookies configures cookie behaviour. +type ThunderbirdCookies struct { + state protoimpl.MessageState `protogen:"open.v1"` + Allow []string `protobuf:"bytes,1,rep,name=Allow,proto3" json:"Allow,omitempty"` + Block []string `protobuf:"bytes,2,rep,name=Block,proto3" json:"Block,omitempty"` + AllowSession []string `protobuf:"bytes,3,rep,name=AllowSession,proto3" json:"AllowSession,omitempty"` + Behavior string `protobuf:"bytes,4,opt,name=Behavior,proto3" json:"Behavior,omitempty"` + BehaviorPrivateBrowsing string `protobuf:"bytes,5,opt,name=BehaviorPrivateBrowsing,proto3" json:"BehaviorPrivateBrowsing,omitempty"` + Locked bool `protobuf:"varint,6,opt,name=Locked,proto3" json:"Locked,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdCookies) Reset() { + *x = ThunderbirdCookies{} + mi := &file_thunderbird_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdCookies) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdCookies) ProtoMessage() {} + +func (x *ThunderbirdCookies) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdCookies.ProtoReflect.Descriptor instead. +func (*ThunderbirdCookies) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{2} +} + +func (x *ThunderbirdCookies) GetAllow() []string { + if x != nil { + return x.Allow + } + return nil +} + +func (x *ThunderbirdCookies) GetBlock() []string { + if x != nil { + return x.Block + } + return nil +} + +func (x *ThunderbirdCookies) GetAllowSession() []string { + if x != nil { + return x.AllowSession + } + return nil +} + +func (x *ThunderbirdCookies) GetBehavior() string { + if x != nil { + return x.Behavior + } + return "" +} + +func (x *ThunderbirdCookies) GetBehaviorPrivateBrowsing() string { + if x != nil { + return x.BehaviorPrivateBrowsing + } + return "" +} + +func (x *ThunderbirdCookies) GetLocked() bool { + if x != nil { + return x.Locked + } + return false +} + +// ThunderbirdExtensions manages extension install/uninstall/lock lists. +type ThunderbirdExtensions struct { + state protoimpl.MessageState `protogen:"open.v1"` + Install []string `protobuf:"bytes,1,rep,name=Install,proto3" json:"Install,omitempty"` + Uninstall []string `protobuf:"bytes,2,rep,name=Uninstall,proto3" json:"Uninstall,omitempty"` + Locked []string `protobuf:"bytes,3,rep,name=Locked,proto3" json:"Locked,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdExtensions) Reset() { + *x = ThunderbirdExtensions{} + mi := &file_thunderbird_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdExtensions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdExtensions) ProtoMessage() {} + +func (x *ThunderbirdExtensions) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdExtensions.ProtoReflect.Descriptor instead. +func (*ThunderbirdExtensions) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{3} +} + +func (x *ThunderbirdExtensions) GetInstall() []string { + if x != nil { + return x.Install + } + return nil +} + +func (x *ThunderbirdExtensions) GetUninstall() []string { + if x != nil { + return x.Uninstall + } + return nil +} + +func (x *ThunderbirdExtensions) GetLocked() []string { + if x != nil { + return x.Locked + } + return nil +} + +// ThunderbirdProxy configures proxy settings. +type ThunderbirdProxy struct { + state protoimpl.MessageState `protogen:"open.v1"` + Mode string `protobuf:"bytes,1,opt,name=Mode,proto3" json:"Mode,omitempty"` + Locked bool `protobuf:"varint,2,opt,name=Locked,proto3" json:"Locked,omitempty"` + HTTPProxy string `protobuf:"bytes,3,opt,name=HTTPProxy,proto3" json:"HTTPProxy,omitempty"` + HTTPPort int32 `protobuf:"varint,4,opt,name=HTTPPort,proto3" json:"HTTPPort,omitempty"` + UseHTTPProxyForAllProtocols bool `protobuf:"varint,5,opt,name=UseHTTPProxyForAllProtocols,proto3" json:"UseHTTPProxyForAllProtocols,omitempty"` + SSLProxy string `protobuf:"bytes,6,opt,name=SSLProxy,proto3" json:"SSLProxy,omitempty"` + SSLPort int32 `protobuf:"varint,7,opt,name=SSLPort,proto3" json:"SSLPort,omitempty"` + SOCKSProxy string `protobuf:"bytes,8,opt,name=SOCKSProxy,proto3" json:"SOCKSProxy,omitempty"` + SOCKSPort int32 `protobuf:"varint,9,opt,name=SOCKSPort,proto3" json:"SOCKSPort,omitempty"` + SOCKSVersion int32 `protobuf:"varint,10,opt,name=SOCKSVersion,proto3" json:"SOCKSVersion,omitempty"` + Passthrough string `protobuf:"bytes,11,opt,name=Passthrough,proto3" json:"Passthrough,omitempty"` + AutoConfigURL string `protobuf:"bytes,12,opt,name=AutoConfigURL,proto3" json:"AutoConfigURL,omitempty"` + AutoLogin bool `protobuf:"varint,13,opt,name=AutoLogin,proto3" json:"AutoLogin,omitempty"` + UseProxyForDNS bool `protobuf:"varint,14,opt,name=UseProxyForDNS,proto3" json:"UseProxyForDNS,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdProxy) Reset() { + *x = ThunderbirdProxy{} + mi := &file_thunderbird_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdProxy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdProxy) ProtoMessage() {} + +func (x *ThunderbirdProxy) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdProxy.ProtoReflect.Descriptor instead. +func (*ThunderbirdProxy) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{4} +} + +func (x *ThunderbirdProxy) GetMode() string { + if x != nil { + return x.Mode + } + return "" +} + +func (x *ThunderbirdProxy) GetLocked() bool { + if x != nil { + return x.Locked + } + return false +} + +func (x *ThunderbirdProxy) GetHTTPProxy() string { + if x != nil { + return x.HTTPProxy + } + return "" +} + +func (x *ThunderbirdProxy) GetHTTPPort() int32 { + if x != nil { + return x.HTTPPort + } + return 0 +} + +func (x *ThunderbirdProxy) GetUseHTTPProxyForAllProtocols() bool { + if x != nil { + return x.UseHTTPProxyForAllProtocols + } + return false +} + +func (x *ThunderbirdProxy) GetSSLProxy() string { + if x != nil { + return x.SSLProxy + } + return "" +} + +func (x *ThunderbirdProxy) GetSSLPort() int32 { + if x != nil { + return x.SSLPort + } + return 0 +} + +func (x *ThunderbirdProxy) GetSOCKSProxy() string { + if x != nil { + return x.SOCKSProxy + } + return "" +} + +func (x *ThunderbirdProxy) GetSOCKSPort() int32 { + if x != nil { + return x.SOCKSPort + } + return 0 +} + +func (x *ThunderbirdProxy) GetSOCKSVersion() int32 { + if x != nil { + return x.SOCKSVersion + } + return 0 +} + +func (x *ThunderbirdProxy) GetPassthrough() string { + if x != nil { + return x.Passthrough + } + return "" +} + +func (x *ThunderbirdProxy) GetAutoConfigURL() string { + if x != nil { + return x.AutoConfigURL + } + return "" +} + +func (x *ThunderbirdProxy) GetAutoLogin() bool { + if x != nil { + return x.AutoLogin + } + return false +} + +func (x *ThunderbirdProxy) GetUseProxyForDNS() bool { + if x != nil { + return x.UseProxyForDNS + } + return false +} + +// ThunderbirdAuthentication configures SPNEGO / NTLM authentication. +type ThunderbirdAuthentication struct { + state protoimpl.MessageState `protogen:"open.v1"` + SPNEGO []string `protobuf:"bytes,1,rep,name=SPNEGO,proto3" json:"SPNEGO,omitempty"` + Delegated []string `protobuf:"bytes,2,rep,name=Delegated,proto3" json:"Delegated,omitempty"` + NTLM []string `protobuf:"bytes,3,rep,name=NTLM,proto3" json:"NTLM,omitempty"` + AllowNonFQDN bool `protobuf:"varint,4,opt,name=AllowNonFQDN,proto3" json:"AllowNonFQDN,omitempty"` + AllowProxies bool `protobuf:"varint,5,opt,name=AllowProxies,proto3" json:"AllowProxies,omitempty"` + Locked bool `protobuf:"varint,6,opt,name=Locked,proto3" json:"Locked,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdAuthentication) Reset() { + *x = ThunderbirdAuthentication{} + mi := &file_thunderbird_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdAuthentication) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdAuthentication) ProtoMessage() {} + +func (x *ThunderbirdAuthentication) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdAuthentication.ProtoReflect.Descriptor instead. +func (*ThunderbirdAuthentication) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{5} +} + +func (x *ThunderbirdAuthentication) GetSPNEGO() []string { + if x != nil { + return x.SPNEGO + } + return nil +} + +func (x *ThunderbirdAuthentication) GetDelegated() []string { + if x != nil { + return x.Delegated + } + return nil +} + +func (x *ThunderbirdAuthentication) GetNTLM() []string { + if x != nil { + return x.NTLM + } + return nil +} + +func (x *ThunderbirdAuthentication) GetAllowNonFQDN() bool { + if x != nil { + return x.AllowNonFQDN + } + return false +} + +func (x *ThunderbirdAuthentication) GetAllowProxies() bool { + if x != nil { + return x.AllowProxies + } + return false +} + +func (x *ThunderbirdAuthentication) GetLocked() bool { + if x != nil { + return x.Locked + } + return false +} + +// ThunderbirdSearchEngine describes a search engine to add. +type ThunderbirdSearchEngine struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + IconURL string `protobuf:"bytes,2,opt,name=IconURL,proto3" json:"IconURL,omitempty"` + Alias string `protobuf:"bytes,3,opt,name=Alias,proto3" json:"Alias,omitempty"` + Description string `protobuf:"bytes,4,opt,name=Description,proto3" json:"Description,omitempty"` + Method string `protobuf:"bytes,5,opt,name=Method,proto3" json:"Method,omitempty"` + URL string `protobuf:"bytes,6,opt,name=URL,proto3" json:"URL,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdSearchEngine) Reset() { + *x = ThunderbirdSearchEngine{} + mi := &file_thunderbird_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdSearchEngine) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdSearchEngine) ProtoMessage() {} + +func (x *ThunderbirdSearchEngine) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdSearchEngine.ProtoReflect.Descriptor instead. +func (*ThunderbirdSearchEngine) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{6} +} + +func (x *ThunderbirdSearchEngine) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ThunderbirdSearchEngine) GetIconURL() string { + if x != nil { + return x.IconURL + } + return "" +} + +func (x *ThunderbirdSearchEngine) GetAlias() string { + if x != nil { + return x.Alias + } + return "" +} + +func (x *ThunderbirdSearchEngine) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ThunderbirdSearchEngine) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *ThunderbirdSearchEngine) GetURL() string { + if x != nil { + return x.URL + } + return "" +} + +// ThunderbirdSearchEngines configures search engine management. +type ThunderbirdSearchEngines struct { + state protoimpl.MessageState `protogen:"open.v1"` + Add []*ThunderbirdSearchEngine `protobuf:"bytes,1,rep,name=Add,proto3" json:"Add,omitempty"` + Default string `protobuf:"bytes,2,opt,name=Default,proto3" json:"Default,omitempty"` + PreventInstalls bool `protobuf:"varint,3,opt,name=PreventInstalls,proto3" json:"PreventInstalls,omitempty"` + Remove []string `protobuf:"bytes,4,rep,name=Remove,proto3" json:"Remove,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThunderbirdSearchEngines) Reset() { + *x = ThunderbirdSearchEngines{} + mi := &file_thunderbird_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThunderbirdSearchEngines) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThunderbirdSearchEngines) ProtoMessage() {} + +func (x *ThunderbirdSearchEngines) ProtoReflect() protoreflect.Message { + mi := &file_thunderbird_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThunderbirdSearchEngines.ProtoReflect.Descriptor instead. +func (*ThunderbirdSearchEngines) Descriptor() ([]byte, []int) { + return file_thunderbird_proto_rawDescGZIP(), []int{7} +} + +func (x *ThunderbirdSearchEngines) GetAdd() []*ThunderbirdSearchEngine { + if x != nil { + return x.Add + } + return nil +} + +func (x *ThunderbirdSearchEngines) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + +func (x *ThunderbirdSearchEngines) GetPreventInstalls() bool { + if x != nil { + return x.PreventInstalls + } + return false +} + +func (x *ThunderbirdSearchEngines) GetRemove() []string { + if x != nil { + return x.Remove + } + return nil +} + +var File_thunderbird_proto protoreflect.FileDescriptor + +var file_thunderbird_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x74, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x76, 0x31, 0x22, 0xa2, 0x17, 0x0a, 0x11, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, + 0x72, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2f, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x00, 0x52, 0x10, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x70, 0x70, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0d, 0x41, 0x70, 0x70, + 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x48, 0x01, 0x52, 0x0d, 0x41, 0x70, 0x70, 0x41, 0x75, 0x74, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x48, 0x02, 0x52, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x41, + 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x12, 0x35, 0x0a, 0x13, 0x4d, + 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, + 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x13, 0x4d, 0x61, 0x6e, 0x75, + 0x61, 0x6c, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x88, + 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x0c, 0x41, 0x70, 0x70, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x69, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x27, 0x0a, 0x0c, 0x41, + 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x52, 0x4c, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x05, 0x52, 0x0c, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x52, + 0x4c, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x06, + 0x52, 0x10, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x18, 0x14, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x07, 0x52, 0x15, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x88, 0x01, 0x01, + 0x12, 0x49, 0x0a, 0x1d, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, + 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x48, 0x08, 0x52, 0x1d, 0x44, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x0f, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x16, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x09, 0x52, 0x0f, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x16, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x48, 0x0a, 0x52, 0x16, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x11, 0x4f, 0x66, 0x66, 0x65, 0x72, + 0x54, 0x6f, 0x53, 0x61, 0x76, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x18, 0x18, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x0b, 0x52, 0x11, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x61, 0x76, + 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x3f, 0x0a, 0x18, 0x4f, 0x66, + 0x66, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x61, 0x76, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x48, 0x0c, 0x52, 0x18, + 0x4f, 0x66, 0x66, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x61, 0x76, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x15, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x42, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x0d, 0x52, 0x15, 0x44, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x42, 0x79, 0x70, + 0x61, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0d, 0x53, 0x53, 0x4c, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0e, 0x52, + 0x0d, 0x53, 0x53, 0x4c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x88, 0x01, + 0x01, 0x12, 0x29, 0x0a, 0x0d, 0x53, 0x53, 0x4c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, + 0x61, 0x78, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x0f, 0x52, 0x0d, 0x53, 0x53, 0x4c, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x78, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x10, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, + 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x48, 0x10, 0x52, 0x10, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, + 0x62, 0x6f, 0x75, 0x74, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, + 0x10, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x48, 0x11, 0x52, 0x10, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x41, 0x62, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x12, 0x33, + 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x48, 0x12, 0x52, 0x12, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, + 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x48, 0x13, + 0x52, 0x11, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x53, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x61, 0x66, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x14, 0x52, 0x0f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x61, 0x66, 0x65, 0x4d, 0x6f, + 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x28, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x15, 0x52, 0x15, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x88, 0x01, 0x01, + 0x12, 0x3f, 0x0a, 0x18, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x32, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x16, 0x52, 0x18, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x88, 0x01, + 0x01, 0x12, 0x2d, 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x33, 0x20, 0x01, 0x28, 0x08, 0x48, 0x17, 0x52, 0x0f, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, + 0x12, 0x37, 0x0a, 0x14, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x63, 0x63, 0x65, + 0x6c, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x08, 0x48, 0x18, + 0x52, 0x14, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x63, 0x63, 0x65, 0x6c, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x11, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x3d, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x19, 0x52, 0x11, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, + 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0d, + 0x43, 0x61, 0x70, 0x74, 0x69, 0x76, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x18, 0x3e, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x1a, 0x52, 0x0d, 0x43, 0x61, 0x70, 0x74, 0x69, 0x76, 0x65, 0x50, 0x6f, + 0x72, 0x74, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x41, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x46, 0x6f, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x46, 0x20, 0x01, 0x28, 0x08, 0x48, 0x1b, 0x52, 0x19, 0x50, 0x72, + 0x6f, 0x6d, 0x70, 0x74, 0x46, 0x6f, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x3f, 0x0a, 0x18, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x47, 0x20, 0x01, 0x28, 0x09, 0x48, 0x1c, 0x52, 0x18, + 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x11, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x18, 0x48, 0x20, 0x01, 0x28, 0x09, 0x48, 0x1d, 0x52, 0x11, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, + 0x61, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x3d, + 0x0a, 0x17, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, + 0x50, 0x44, 0x46, 0x56, 0x69, 0x65, 0x77, 0x65, 0x72, 0x18, 0x49, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x1e, 0x52, 0x17, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, + 0x6e, 0x50, 0x44, 0x46, 0x56, 0x69, 0x65, 0x77, 0x65, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2a, 0x0a, + 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, + 0x73, 0x18, 0x50, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x65, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x0c, 0x44, 0x4e, 0x53, + 0x4f, 0x76, 0x65, 0x72, 0x48, 0x54, 0x54, 0x50, 0x53, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x26, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x44, 0x4e, 0x53, 0x4f, 0x76, + 0x65, 0x72, 0x48, 0x54, 0x54, 0x50, 0x53, 0x48, 0x1f, 0x52, 0x0c, 0x44, 0x4e, 0x53, 0x4f, 0x76, + 0x65, 0x72, 0x48, 0x54, 0x54, 0x50, 0x53, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x07, 0x43, 0x6f, + 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x6f, + 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x48, 0x20, + 0x52, 0x07, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x88, 0x01, 0x01, 0x12, 0x49, 0x0a, 0x0a, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x21, 0x52, 0x0a, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x3a, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, + 0x18, 0x5d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, + 0x72, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x48, 0x22, 0x52, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, + 0x88, 0x01, 0x01, 0x12, 0x55, 0x0a, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x5e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x62, 0x6f, + 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x23, 0x52, 0x0e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x52, 0x0a, 0x0d, 0x53, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x5f, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x48, 0x24, 0x52, 0x0d, 0x53, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x88, 0x01, 0x01, 0x42, 0x13, + 0x0a, 0x11, 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x41, 0x70, 0x70, 0x41, 0x75, 0x74, 0x6f, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x16, 0x0a, + 0x14, 0x5f, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x41, 0x70, 0x70, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x69, 0x6e, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x41, 0x70, 0x70, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x52, 0x4c, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x44, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x42, 0x18, 0x0a, 0x16, + 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x52, 0x65, 0x76, 0x65, 0x61, 0x6c, 0x42, 0x20, 0x0a, 0x1e, 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x19, 0x0a, 0x17, + 0x5f, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x4f, 0x66, 0x66, 0x65, + 0x72, 0x54, 0x6f, 0x53, 0x61, 0x76, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x73, 0x42, 0x1b, 0x0a, + 0x19, 0x5f, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x54, 0x6f, 0x53, 0x61, 0x76, 0x65, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x44, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x42, 0x79, + 0x70, 0x61, 0x73, 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x53, 0x53, 0x4c, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x53, 0x53, 0x4c, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x78, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x42, 0x13, 0x0a, + 0x11, 0x5f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, + 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x42, + 0x12, 0x0a, 0x10, 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x61, 0x66, 0x65, 0x4d, + 0x6f, 0x64, 0x65, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x42, 0x1b, 0x0a, + 0x19, 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41, + 0x64, 0x64, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x17, + 0x0a, 0x15, 0x5f, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x41, 0x63, 0x63, 0x65, 0x6c, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x10, 0x0a, + 0x0e, 0x5f, 0x43, 0x61, 0x70, 0x74, 0x69, 0x76, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x42, + 0x1c, 0x0a, 0x1a, 0x5f, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x46, 0x6f, 0x72, 0x44, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x1b, 0x0a, + 0x19, 0x5f, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x42, 0x1a, 0x0a, 0x18, 0x5f, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x75, 0x69, 0x6c, + 0x74, 0x69, 0x6e, 0x50, 0x44, 0x46, 0x56, 0x69, 0x65, 0x77, 0x65, 0x72, 0x42, 0x0f, 0x0a, 0x0d, + 0x5f, 0x44, 0x4e, 0x53, 0x4f, 0x76, 0x65, 0x72, 0x48, 0x54, 0x54, 0x50, 0x53, 0x42, 0x0a, 0x0a, + 0x08, 0x5f, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x22, 0xb3, 0x01, 0x0a, 0x17, 0x54, 0x68, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x44, 0x4e, 0x53, 0x4f, 0x76, 0x65, 0x72, 0x48, 0x54, + 0x54, 0x50, 0x53, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, + 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x52, 0x4c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x52, 0x4c, 0x12, + 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x45, 0x78, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0f, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x22, 0xd2, 0x01, + 0x0a, 0x12, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x43, 0x6f, 0x6f, + 0x6b, 0x69, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, + 0x12, 0x38, 0x0a, 0x17, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x17, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x50, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, + 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x6b, + 0x65, 0x64, 0x22, 0x67, 0x0a, 0x15, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, + 0x64, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x22, 0xe0, 0x03, 0x0a, 0x10, + 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, + 0x12, 0x12, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x48, 0x54, 0x54, 0x50, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x48, 0x54, 0x54, 0x50, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x54, + 0x54, 0x50, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x48, 0x54, + 0x54, 0x50, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x40, 0x0a, 0x1b, 0x55, 0x73, 0x65, 0x48, 0x54, 0x54, + 0x50, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x46, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x55, 0x73, 0x65, + 0x48, 0x54, 0x54, 0x50, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x46, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x53, 0x4c, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x53, 0x53, 0x4c, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x53, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x53, 0x53, 0x4c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, + 0x0a, 0x0a, 0x53, 0x4f, 0x43, 0x4b, 0x53, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x53, 0x4f, 0x43, 0x4b, 0x53, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1c, + 0x0a, 0x09, 0x53, 0x4f, 0x43, 0x4b, 0x53, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x09, 0x53, 0x4f, 0x43, 0x4b, 0x53, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, + 0x53, 0x4f, 0x43, 0x4b, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0c, 0x53, 0x4f, 0x43, 0x4b, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x41, 0x75, 0x74, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x55, 0x52, 0x4c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x41, 0x75, 0x74, 0x6f, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x55, 0x52, 0x4c, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x6f, + 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x41, 0x75, 0x74, + 0x6f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x46, 0x6f, 0x72, 0x44, 0x4e, 0x53, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x55, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x46, 0x6f, 0x72, 0x44, 0x4e, 0x53, 0x22, 0xc5, + 0x01, 0x0a, 0x19, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x41, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, + 0x53, 0x50, 0x4e, 0x45, 0x47, 0x4f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x53, 0x50, + 0x4e, 0x45, 0x47, 0x4f, 0x12, 0x1c, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x54, 0x4c, 0x4d, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x54, 0x4c, 0x4d, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, + 0x6f, 0x6e, 0x46, 0x51, 0x44, 0x4e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x41, 0x6c, + 0x6c, 0x6f, 0x77, 0x4e, 0x6f, 0x6e, 0x46, 0x51, 0x44, 0x4e, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x6c, + 0x6c, 0x6f, 0x77, 0x50, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x22, 0xa9, 0x01, 0x0a, 0x17, 0x54, 0x68, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x63, 0x6f, 0x6e, 0x55, 0x52, + 0x4c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x49, 0x63, 0x6f, 0x6e, 0x55, 0x52, 0x4c, + 0x12, 0x14, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, + 0x52, 0x4c, 0x22, 0xb0, 0x01, 0x0a, 0x18, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, + 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x12, + 0x38, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x62, + 0x6f, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x68, 0x75, + 0x6e, 0x64, 0x65, 0x72, 0x62, 0x69, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x45, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x52, 0x03, 0x41, 0x64, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x50, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x50, 0x72, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x56, 0x75, 0x74, 0x65, 0x54, 0x65, 0x63, 0x68, 0x2f, 0x42, 0x6f, 0x72, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, + 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3b, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_thunderbird_proto_rawDescOnce sync.Once + file_thunderbird_proto_rawDescData = file_thunderbird_proto_rawDesc +) + +func file_thunderbird_proto_rawDescGZIP() []byte { + file_thunderbird_proto_rawDescOnce.Do(func() { + file_thunderbird_proto_rawDescData = protoimpl.X.CompressGZIP(file_thunderbird_proto_rawDescData) + }) + return file_thunderbird_proto_rawDescData +} + +var file_thunderbird_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_thunderbird_proto_goTypes = []any{ + (*ThunderbirdPolicy)(nil), // 0: bor.policy.v1.ThunderbirdPolicy + (*ThunderbirdDNSOverHTTPS)(nil), // 1: bor.policy.v1.ThunderbirdDNSOverHTTPS + (*ThunderbirdCookies)(nil), // 2: bor.policy.v1.ThunderbirdCookies + (*ThunderbirdExtensions)(nil), // 3: bor.policy.v1.ThunderbirdExtensions + (*ThunderbirdProxy)(nil), // 4: bor.policy.v1.ThunderbirdProxy + (*ThunderbirdAuthentication)(nil), // 5: bor.policy.v1.ThunderbirdAuthentication + (*ThunderbirdSearchEngine)(nil), // 6: bor.policy.v1.ThunderbirdSearchEngine + (*ThunderbirdSearchEngines)(nil), // 7: bor.policy.v1.ThunderbirdSearchEngines +} +var file_thunderbird_proto_depIdxs = []int32{ + 1, // 0: bor.policy.v1.ThunderbirdPolicy.DNSOverHTTPS:type_name -> bor.policy.v1.ThunderbirdDNSOverHTTPS + 2, // 1: bor.policy.v1.ThunderbirdPolicy.Cookies:type_name -> bor.policy.v1.ThunderbirdCookies + 3, // 2: bor.policy.v1.ThunderbirdPolicy.Extensions:type_name -> bor.policy.v1.ThunderbirdExtensions + 4, // 3: bor.policy.v1.ThunderbirdPolicy.Proxy:type_name -> bor.policy.v1.ThunderbirdProxy + 5, // 4: bor.policy.v1.ThunderbirdPolicy.Authentication:type_name -> bor.policy.v1.ThunderbirdAuthentication + 7, // 5: bor.policy.v1.ThunderbirdPolicy.SearchEngines:type_name -> bor.policy.v1.ThunderbirdSearchEngines + 6, // 6: bor.policy.v1.ThunderbirdSearchEngines.Add:type_name -> bor.policy.v1.ThunderbirdSearchEngine + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_thunderbird_proto_init() } +func file_thunderbird_proto_init() { + if File_thunderbird_proto != nil { + return + } + file_thunderbird_proto_msgTypes[0].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_thunderbird_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_thunderbird_proto_goTypes, + DependencyIndexes: file_thunderbird_proto_depIdxs, + MessageInfos: file_thunderbird_proto_msgTypes, + }.Build() + File_thunderbird_proto = out.File + file_thunderbird_proto_rawDesc = nil + file_thunderbird_proto_goTypes = nil + file_thunderbird_proto_depIdxs = nil +} diff --git a/server/web/frontend/src/apiClient/settingsApi.ts b/server/web/frontend/src/apiClient/settingsApi.ts index afa8e93..1bae484 100644 --- a/server/web/frontend/src/apiClient/settingsApi.ts +++ b/server/web/frontend/src/apiClient/settingsApi.ts @@ -25,6 +25,7 @@ export interface AgentNotificationSettings { notify_message: string; notify_message_firefox: string; notify_message_chrome: string; + notify_message_thunderbird: string; } export async function fetchAgentNotificationSettings(): Promise { diff --git a/server/web/frontend/src/generated/proto/policy.ts b/server/web/frontend/src/generated/proto/policy.ts index 5cadde9..5fe546f 100644 --- a/server/web/frontend/src/generated/proto/policy.ts +++ b/server/web/frontend/src/generated/proto/policy.ts @@ -11,6 +11,7 @@ import type { FirefoxPolicy } from "./firefox"; import type { KConfigPolicy } from "./kconfig"; import type { PackagePolicy } from "./package"; import type { PolkitPolicy } from "./polkit"; +import type { ThunderbirdPolicy } from "./thunderbird"; export const protobufPackage = "bor.policy.v1"; @@ -58,8 +59,9 @@ export interface Policy { chrome_policy?: ChromePolicy | undefined; dconf_policy?: DConfPolicy | undefined; polkit_policy?: PolkitPolicy | undefined; - package_policy?: - | PackagePolicy + package_policy?: PackagePolicy | undefined; + thunderbird_policy?: + | ThunderbirdPolicy | undefined; /** * Binding priority delivered to the agent. Equals the maximum priority @@ -201,6 +203,7 @@ export interface AgentConfig { notify_message: string; notify_message_firefox: string; notify_message_chrome: string; + notify_message_thunderbird: string; } /** NodeInfo contains metadata reported by an agent node. */ diff --git a/server/web/frontend/src/generated/proto/thunderbird.ts b/server/web/frontend/src/generated/proto/thunderbird.ts new file mode 100644 index 0000000..a4486d2 --- /dev/null +++ b/server/web/frontend/src/generated/proto/thunderbird.ts @@ -0,0 +1,154 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.11.8 +// protoc v7.34.1 +// source: thunderbird.proto + +/* eslint-disable */ + +export const protobufPackage = "bor.policy.v1"; + +/** + * ThunderbirdPolicy is the canonical schema for a Thunderbird enterprise + * policy on Linux. It maps directly to the "policies" key in policies.json. + * Field json_name annotations preserve PascalCase so protojson round-trips + * with the key names Thunderbird expects. + */ +export interface ThunderbirdPolicy { + /** ── Updates ─────────────────────────────────────────────────────────────── */ + DisableAppUpdate?: boolean | undefined; + AppAutoUpdate?: boolean | undefined; + BackgroundAppUpdate?: boolean | undefined; + ManualAppUpdateOnly?: boolean | undefined; + AppUpdatePin?: string | undefined; + AppUpdateURL?: + | string + | undefined; + /** ── Privacy & Telemetry ─────────────────────────────────────────────────── */ + DisableTelemetry?: + | boolean + | undefined; + /** ── Security ────────────────────────────────────────────────────────────── */ + DisablePasswordReveal?: boolean | undefined; + DisableMasterPasswordCreation?: boolean | undefined; + PrimaryPassword?: boolean | undefined; + PasswordManagerEnabled?: boolean | undefined; + OfferToSaveLogins?: boolean | undefined; + OfferToSaveLoginsDefault?: boolean | undefined; + DisableSecurityBypass?: boolean | undefined; + SSLVersionMin?: string | undefined; + SSLVersionMax?: + | string + | undefined; + /** ── Restrictions ────────────────────────────────────────────────────────── */ + BlockAboutAddons?: boolean | undefined; + BlockAboutConfig?: boolean | undefined; + BlockAboutProfiles?: boolean | undefined; + BlockAboutSupport?: boolean | undefined; + DisableSafeMode?: + | boolean + | undefined; + /** ── Developer Tools ─────────────────────────────────────────────────────── */ + DisableDeveloperTools?: + | boolean + | undefined; + /** ── Add-ons / Extensions ────────────────────────────────────────────────── */ + DisableSystemAddonUpdate?: boolean | undefined; + ExtensionUpdate?: + | boolean + | undefined; + /** ── Network ─────────────────────────────────────────────────────────────── */ + HardwareAcceleration?: boolean | undefined; + NetworkPrediction?: boolean | undefined; + CaptivePortal?: + | boolean + | undefined; + /** ── General ─────────────────────────────────────────────────────────────── */ + PromptForDownloadLocation?: boolean | undefined; + DefaultDownloadDirectory?: string | undefined; + DownloadDirectory?: string | undefined; + DisableBuiltinPDFViewer?: + | boolean + | undefined; + /** ── Locale ──────────────────────────────────────────────────────────────── */ + RequestedLocales: string[]; + /** ── Object / composite policies ─────────────────────────────────────────── */ + DNSOverHTTPS?: ThunderbirdDNSOverHTTPS | undefined; + Cookies?: ThunderbirdCookies | undefined; + Extensions?: ThunderbirdExtensions | undefined; + Proxy?: ThunderbirdProxy | undefined; + Authentication?: ThunderbirdAuthentication | undefined; + SearchEngines?: ThunderbirdSearchEngines | undefined; +} + +/** ThunderbirdDNSOverHTTPS configures DNS-over-HTTPS settings. */ +export interface ThunderbirdDNSOverHTTPS { + Enabled: boolean; + ProviderURL: string; + Locked: boolean; + ExcludedDomains: string[]; + Fallback: boolean; +} + +/** ThunderbirdCookies configures cookie behaviour. */ +export interface ThunderbirdCookies { + Allow: string[]; + Block: string[]; + AllowSession: string[]; + Behavior: string; + BehaviorPrivateBrowsing: string; + Locked: boolean; +} + +/** ThunderbirdExtensions manages extension install/uninstall/lock lists. */ +export interface ThunderbirdExtensions { + Install: string[]; + Uninstall: string[]; + Locked: string[]; +} + +/** ThunderbirdProxy configures proxy settings. */ +export interface ThunderbirdProxy { + Mode: string; + Locked: boolean; + HTTPProxy: string; + HTTPPort: number; + UseHTTPProxyForAllProtocols: boolean; + SSLProxy: string; + SSLPort: number; + SOCKSProxy: string; + SOCKSPort: number; + SOCKSVersion: number; + Passthrough: string; + AutoConfigURL: string; + AutoLogin: boolean; + UseProxyForDNS: boolean; +} + +/** ThunderbirdAuthentication configures SPNEGO / NTLM authentication. */ +export interface ThunderbirdAuthentication { + SPNEGO: string[]; + Delegated: string[]; + NTLM: string[]; + AllowNonFQDN: boolean; + AllowProxies: boolean; + Locked: boolean; +} + +/** ThunderbirdSearchEngine describes a search engine to add. */ +export interface ThunderbirdSearchEngine { + Name: string; + IconURL: string; + Alias: string; + Description: string; + Method: string; + URL: string; +} + +/** ThunderbirdSearchEngines configures search engine management. */ +export interface ThunderbirdSearchEngines { + Add: ThunderbirdSearchEngine[]; + Default: string; + PreventInstalls: boolean; + Remove: string[]; +} diff --git a/server/web/frontend/src/views/Policies/PoliciesPage.tsx b/server/web/frontend/src/views/Policies/PoliciesPage.tsx index 8460dad..8c50b59 100644 --- a/server/web/frontend/src/views/Policies/PoliciesPage.tsx +++ b/server/web/frontend/src/views/Policies/PoliciesPage.tsx @@ -41,7 +41,7 @@ import { PolicyDetailsModal } from "./PolicyDetailsModal"; /* ── Filter options ── */ -const TYPE_OPTIONS = ["Kconfig", "Dconf", "Firefox", "Polkit", "Chrome", "Package"]; +const TYPE_OPTIONS = ["Kconfig", "Dconf", "Firefox", "Thunderbird", "Polkit", "Chrome", "Package"]; const STATUS_OPTIONS = ["draft", "released", "archived"]; const statusLabelColor = (status: string): "green" | "red" | "blue" | "orange" | "grey" => { diff --git a/server/web/frontend/src/views/Policies/PolicyDetailsModal.tsx b/server/web/frontend/src/views/Policies/PolicyDetailsModal.tsx index 97df586..e64909f 100644 --- a/server/web/frontend/src/views/Policies/PolicyDetailsModal.tsx +++ b/server/web/frontend/src/views/Policies/PolicyDetailsModal.tsx @@ -42,6 +42,7 @@ import { Table, Thead, Tbody, Tr, Th, Td } from "@patternfly/react-table"; import type { Policy, CreatePolicyRequest, UpdatePolicyRequest } from "../../apiClient/policiesApi"; import { createPolicy, updatePolicy, setPolicyState, deletePolicy } from "../../apiClient/policiesApi"; import type { FirefoxPolicy } from "../../generated/proto/firefox"; +import type { ThunderbirdPolicy } from "../../generated/proto/thunderbird"; import { DConfPolicyEditor } from "./DConfPolicyEditor"; import { PackagePolicyEditor } from "./PackagePolicyEditor"; import { PolkitPolicyEditor } from "./PolkitPolicyEditor"; @@ -52,6 +53,7 @@ const POLICY_TYPES: { value: string; label: string; isDisabled?: boolean }[] = [ { value: "Kconfig", label: "Kconfig" }, { value: "Dconf", label: "Dconf" }, { value: "Firefox", label: "Firefox" }, + { value: "Thunderbird", label: "Thunderbird" }, { value: "Polkit", label: "Polkit" }, { value: "Chrome", label: "Chrome" }, { value: "Package", label: "Package" }, @@ -199,6 +201,101 @@ function buildFirefoxTree(): Map { return groups; } +/* ── Thunderbird policy model (matches Protobuf schema) ── */ + +interface ThunderbirdPolicyDef { + key: keyof ThunderbirdPolicy; + label: string; + group: string; + type: "boolean" | "string" | "select" | "object" | "stringlist"; + selectOptions?: string[]; + objectFields?: { key: string; label: string; fieldType: "boolean" | "string" | "select" | "stringlist"; selectOptions?: string[] }[]; +} + +const THUNDERBIRD_ALL_POLICIES: ThunderbirdPolicyDef[] = [ + // Updates + { key: "DisableAppUpdate", label: "Disable App Update", group: "Updates", type: "boolean" }, + { key: "AppAutoUpdate", label: "App Auto Update", group: "Updates", type: "boolean" }, + { key: "BackgroundAppUpdate", label: "Background App Update", group: "Updates", type: "boolean" }, + { key: "ManualAppUpdateOnly", label: "Manual App Update Only", group: "Updates", type: "boolean" }, + { key: "AppUpdatePin", label: "App Update Pin Version", group: "Updates", type: "string" }, + { key: "AppUpdateURL", label: "App Update URL", group: "Updates", type: "string" }, + // Privacy & Telemetry + { key: "DisableTelemetry", label: "Disable Telemetry", group: "Privacy & Telemetry", type: "boolean" }, + // Security + { key: "DisablePasswordReveal", label: "Disable Password Reveal", group: "Security", type: "boolean" }, + { key: "DisableMasterPasswordCreation", label: "Disable Master Password Creation", group: "Security", type: "boolean" }, + { key: "PrimaryPassword", label: "Require Primary Password", group: "Security", type: "boolean" }, + { key: "PasswordManagerEnabled", label: "Enable Password Manager", group: "Security", type: "boolean" }, + { key: "OfferToSaveLogins", label: "Offer to Save Logins", group: "Security", type: "boolean" }, + { key: "OfferToSaveLoginsDefault", label: "Offer to Save Logins (Default)", group: "Security", type: "boolean" }, + { key: "DisableSecurityBypass", label: "Disable Security Bypass", group: "Security", type: "boolean" }, + { key: "SSLVersionMin", label: "SSL Version Minimum", group: "Security", type: "select", selectOptions: ["tls1", "tls1.1", "tls1.2", "tls1.3"] }, + { key: "SSLVersionMax", label: "SSL Version Maximum", group: "Security", type: "select", selectOptions: ["tls1", "tls1.1", "tls1.2", "tls1.3"] }, + // Restrictions + { key: "BlockAboutAddons", label: "Block about:addons", group: "Restrictions", type: "boolean" }, + { key: "BlockAboutConfig", label: "Block about:config", group: "Restrictions", type: "boolean" }, + { key: "BlockAboutProfiles", label: "Block about:profiles", group: "Restrictions", type: "boolean" }, + { key: "BlockAboutSupport", label: "Block about:support", group: "Restrictions", type: "boolean" }, + { key: "DisableSafeMode", label: "Disable Safe Mode", group: "Restrictions", type: "boolean" }, + // Developer Tools + { key: "DisableDeveloperTools", label: "Disable Developer Tools", group: "Developer Tools", type: "boolean" }, + // Add-ons + { key: "DisableSystemAddonUpdate", label: "Disable System Add-on Updates", group: "Add-ons", type: "boolean" }, + { key: "ExtensionUpdate", label: "Allow Extension Updates", group: "Add-ons", type: "boolean" }, + { key: "Extensions", label: "Extensions", group: "Add-ons", type: "object", objectFields: [ + { key: "Install", label: "Install (URLs or extension IDs)", fieldType: "stringlist" }, + { key: "Uninstall", label: "Uninstall (extension IDs)", fieldType: "stringlist" }, + { key: "Locked", label: "Locked (extension IDs)", fieldType: "stringlist" }, + ]}, + // Network + { key: "HardwareAcceleration", label: "Enable Hardware Acceleration", group: "Network", type: "boolean" }, + { key: "NetworkPrediction", label: "Enable Network Prediction", group: "Network", type: "boolean" }, + { key: "CaptivePortal", label: "Enable Captive Portal Detection", group: "Network", type: "boolean" }, + { key: "DNSOverHTTPS", label: "DNS over HTTPS", group: "Network", type: "object", objectFields: [ + { key: "Enabled", label: "Enabled", fieldType: "boolean" }, + { key: "ProviderURL", label: "Provider URL", fieldType: "string" }, + { key: "Locked", label: "Locked", fieldType: "boolean" }, + { key: "Fallback", label: "Fallback", fieldType: "boolean" }, + { key: "ExcludedDomains", label: "Excluded Domains", fieldType: "stringlist" }, + ]}, + // General + { key: "PromptForDownloadLocation", label: "Prompt for Download Location", group: "General", type: "boolean" }, + { key: "DefaultDownloadDirectory", label: "Default Download Directory", group: "General", type: "string" }, + { key: "DownloadDirectory", label: "Download Directory", group: "General", type: "string" }, + { key: "DisableBuiltinPDFViewer", label: "Disable Built-in PDF Viewer", group: "General", type: "boolean" }, + { key: "RequestedLocales", label: "Requested Locales", group: "General", type: "stringlist" }, + // Cookies + { key: "Cookies", label: "Cookies", group: "Cookies", type: "object", objectFields: [ + { key: "Behavior", label: "Behavior", fieldType: "select", selectOptions: ["accept", "reject-foreign", "reject-all", "limit-foreign", "reject-tracker", "reject-tracker-and-partition-foreign"] }, + { key: "BehaviorPrivateBrowsing", label: "Behavior (Private Browsing)", fieldType: "select", selectOptions: ["accept", "reject-foreign", "reject-all", "limit-foreign", "reject-tracker", "reject-tracker-and-partition-foreign"] }, + { key: "Allow", label: "Allow Origins", fieldType: "stringlist" }, + { key: "Block", label: "Block Origins", fieldType: "stringlist" }, + { key: "AllowSession", label: "Allow Session Origins", fieldType: "stringlist" }, + { key: "Locked", label: "Locked", fieldType: "boolean" }, + ]}, + // Authentication + { key: "Authentication", label: "Authentication", group: "Authentication", type: "object", objectFields: [ + { key: "SPNEGO", label: "SPNEGO Hosts", fieldType: "stringlist" }, + { key: "Delegated", label: "Delegated Hosts", fieldType: "stringlist" }, + { key: "NTLM", label: "NTLM Hosts", fieldType: "stringlist" }, + { key: "AllowNonFQDN", label: "Allow Non-FQDN", fieldType: "boolean" }, + { key: "AllowProxies", label: "Allow Proxies", fieldType: "boolean" }, + { key: "Locked", label: "Locked", fieldType: "boolean" }, + ]}, +]; + +// Build category groups for the Thunderbird tree view. +function buildThunderbirdTree(): Map { + const groups = new Map(); + for (const p of THUNDERBIRD_ALL_POLICIES) { + const arr = groups.get(p.group) || []; + arr.push(p); + groups.set(p.group, arr); + } + return groups; +} + /* ── Chrome/Chromium policy model ── */ interface ChromePolicyDef { @@ -1110,6 +1207,36 @@ function buildSettingsRows(policyType: string, content: string): SettingsRow[] { return rows; } + if (policyType === "Thunderbird") { + const parsed = raw as Record; + for (const policyDef of THUNDERBIRD_ALL_POLICIES) { + if (!(policyDef.key in parsed)) continue; + const val = parsed[policyDef.key]; + + if (policyDef.type === "object" && typeof val === "object" && val !== null) { + const objVal = val as Record; + const lockedVal = "Locked" in objVal + ? (objVal["Locked"] === true ? "Yes" : "No") + : null; + for (const field of policyDef.objectFields || []) { + if (field.key === "Locked") continue; + rows.push({ + setting: `${policyDef.label} › ${field.label}`, + value: formatDisplayValue(objVal[field.key]), + locked: lockedVal, + }); + } + } else { + rows.push({ + setting: policyDef.label, + value: formatDisplayValue(val), + locked: null, + }); + } + } + return rows; + } + if (policyType === "Chrome") { const parsed = raw as Record; for (const policyDef of CHROME_ALL_POLICIES) { @@ -1333,6 +1460,11 @@ export const PolicyDetailsModal: React.FC = ({ const [firefoxValue, setFirefoxValue] = useState(undefined); const [firefoxExpandedGroups, setFirefoxExpandedGroups] = useState>(new Set()); + // Thunderbird-specific state: selected policy key + its value + const [thunderbirdSelectedKey, setThunderbirdSelectedKey] = useState(null); + const [thunderbirdValue, setThunderbirdValue] = useState(undefined); + const [thunderbirdExpandedGroups, setThunderbirdExpandedGroups] = useState>(new Set()); + // KConfig-specific state: selected policy key, value + enforced const [kconfigSelectedKey, setKconfigSelectedKey] = useState(null); const [kconfigValue, setKconfigValue] = useState(""); @@ -1429,6 +1561,22 @@ export const PolicyDetailsModal: React.FC = ({ setChromeValue(undefined); setChromeExpandedGroups(new Set()); } + } else if (policy.type === "Thunderbird") { + const configuredKeys = detectFirefoxConfiguredKeys(policy.content); + if (configuredKeys.length > 0) { + setThunderbirdSelectedKey(configuredKeys[0]); + setThunderbirdValue(extractFirefoxValue(policy.content, configuredKeys[0])); + const groups = new Set(); + for (const key of configuredKeys) { + const def = THUNDERBIRD_ALL_POLICIES.find(p => p.key === key); + if (def) groups.add(def.group); + } + setThunderbirdExpandedGroups(groups); + } else { + setThunderbirdSelectedKey(null); + setThunderbirdValue(undefined); + setThunderbirdExpandedGroups(new Set()); + } } else if (policy.type === "Dconf") { // Dconf editor reads contentRaw directly — nothing extra to initialise. } else if (policy.type === "Polkit") { @@ -1455,6 +1603,9 @@ export const PolicyDetailsModal: React.FC = ({ setFirefoxSelectedKey(null); setFirefoxValue(undefined); setFirefoxExpandedGroups(new Set()); + setThunderbirdSelectedKey(null); + setThunderbirdValue(undefined); + setThunderbirdExpandedGroups(new Set()); setKconfigSelectedKey(null); setKconfigValue(""); setKconfigEnforced(false); @@ -1483,6 +1634,11 @@ export const PolicyDetailsModal: React.FC = ({ setFirefoxValue(undefined); setContentRaw("{}"); setFirefoxExpandedGroups(new Set()); + } else if (newType === "Thunderbird") { + setThunderbirdSelectedKey(null); + setThunderbirdValue(undefined); + setContentRaw("{}"); + setThunderbirdExpandedGroups(new Set()); } else if (newType === "Kconfig") { setKconfigSelectedKey(null); setKconfigValue(""); @@ -1519,7 +1675,7 @@ export const PolicyDetailsModal: React.FC = ({ setContentRaw(raw); try { const parsed = JSON.parse(raw); - if (policyType !== "Firefox") { + if (policyType !== "Firefox" && policyType !== "Thunderbird") { if (Array.isArray(parsed)) { setStructuredFieldsList(parsed.map(flattenForForm)); } else { @@ -1610,6 +1766,64 @@ export const PolicyDetailsModal: React.FC = ({ }); }; + // Thunderbird: select a policy from the tree and set its default value + const handleThunderbirdSelectPolicy = (policyDef: ThunderbirdPolicyDef) => { + setThunderbirdSelectedKey(policyDef.key); + const existing = extractFirefoxValue(contentRaw, policyDef.key); + if (existing !== undefined) { + setThunderbirdValue(existing); + } else { + let defaultValue: unknown; + if (policyDef.type === "boolean") { + defaultValue = true; + } else if (policyDef.type === "string") { + defaultValue = ""; + } else if (policyDef.type === "select") { + defaultValue = policyDef.selectOptions?.[0] || ""; + } else if (policyDef.type === "stringlist") { + defaultValue = []; + } else if (policyDef.type === "object") { + const obj: Record = {}; + for (const f of policyDef.objectFields || []) { + if (f.fieldType === "boolean") obj[f.key] = false; + else if (f.fieldType === "string" || f.fieldType === "select") obj[f.key] = ""; + else if (f.fieldType === "stringlist") obj[f.key] = []; + } + defaultValue = obj; + } + setThunderbirdValue(defaultValue); + setContentRaw(buildFirefoxContent(policyDef.key, defaultValue, contentRaw)); + } + }; + + // Thunderbird: remove a policy from the content + const handleThunderbirdRemovePolicy = (key: string) => { + const newContent = removeFirefoxContentKey(key, contentRaw); + setContentRaw(newContent); + if (thunderbirdSelectedKey === key) { + setThunderbirdSelectedKey(null); + setThunderbirdValue(undefined); + } + }; + + // Thunderbird: update the value for the currently selected policy + const updateThunderbirdValue = (newValue: unknown) => { + setThunderbirdValue(newValue); + if (thunderbirdSelectedKey) { + setContentRaw(buildFirefoxContent(thunderbirdSelectedKey, newValue, contentRaw)); + } + }; + + // Thunderbird: toggle a group in the tree + const toggleThunderbirdGroup = (group: string) => { + setThunderbirdExpandedGroups(prev => { + const next = new Set(prev); + if (next.has(group)) next.delete(group); + else next.add(group); + return next; + }); + }; + // KConfig: select a policy from the tree const handleKconfigSelectPolicy = (policyDef: KConfigPolicyDef) => { setKconfigSelectedKey(policyDef.key); @@ -1763,6 +1977,22 @@ export const PolicyDetailsModal: React.FC = ({ setSaving(false); return; } + } else if (policyType === "Thunderbird") { + if (thunderbirdSelectedKey) { + finalContent = buildFirefoxContent(thunderbirdSelectedKey, thunderbirdValue, contentRaw); + } + try { + const parsed = JSON.parse(finalContent); + if (Object.keys(parsed).length === 0) { + setError("At least one Thunderbird policy setting must be selected and configured before saving"); + setSaving(false); + return; + } + } catch { + setError("Thunderbird policy content is not valid JSON"); + setSaving(false); + return; + } } else if (policyType === "Kconfig") { // Save the current selection into content before validating if (kconfigSelectedKey === "urlRestrictions") { @@ -2123,6 +2353,230 @@ export const PolicyDetailsModal: React.FC = ({ ); }; + /* ── Thunderbird: property editor for selected policy ── */ + const renderThunderbirdPropertyEditor = () => { + if (!thunderbirdSelectedKey) { + return ( +
+ Select a Thunderbird policy +

Choose a policy from the tree on the left to configure its properties.

+
+ ); + } + + const policyDef = THUNDERBIRD_ALL_POLICIES.find(p => p.key === thunderbirdSelectedKey); + if (!policyDef) return null; + + return ( +
+ {policyDef.label} +
+ {policyDef.type === "boolean" && ( + + updateThunderbirdValue(checked)} + label="Enabled" + labelOff="Disabled" + /> + + )} + {policyDef.type === "string" && ( + + updateThunderbirdValue(val)} + /> + + )} + {policyDef.type === "select" && ( + + updateThunderbirdValue(val)} + > + + {(policyDef.selectOptions || []).map(v => ( + + ))} + + + )} + {policyDef.type === "stringlist" && ( + +