fix: исправление 6 пунктов из ревью
Critical: - bridge: AutoGenPort=false по умолчанию, не генерируем secret если пустой → extension и bridge совпадают на port 9786 и empty secret - bridgeConfig: убрана авто-генерация secret, убран secret из BridgeInfo High: - extension/background.js + extension-firefox/background.js: все chrome.* listeners вынесены в global scope (не внутри onInstalled/onStartup) → MV3 service worker корректно перезапускается - UI: acceptBrowserEvent вызывает AcceptBrowserEvent, attachBrowserEvent вызывает AttachBrowserEventToNode (к текущему selectedNode), а не DismissBrowserEvent - watcher: при Create проверяется isUnderVault(absPath, vaultRoot) — если файл уже в vault, используется AddExternal вместо CopyIntoVault → нет дублирования файлов с timestamp-суффиксом Medium: - bridge.Event: добавлено поле DeviceID, handleEvents обогащает events из batch.DeviceID → device_id сохраняется в DB как chrome-*/firefox-*, а не evt_* - config: FileWatcher изменён на *bool — nil означает default true, false = явно выключено → старые config.json без поля file_watcher получают true
This commit is contained in:
@@ -31,7 +31,8 @@ type EventHandler func(events []Event)
|
||||
// Event represents a single browser event (page visit, note capture, etc.).
|
||||
type Event struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"` // page_visit, note_capture, screenshot
|
||||
DeviceID string `json:"device_id,omitempty"`
|
||||
Type string `json:"type"` // page_visit, note_capture, screenshot
|
||||
URL string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
Domain string `json:"domain"`
|
||||
@@ -62,7 +63,7 @@ type Config struct {
|
||||
func DefaultConfig() Config {
|
||||
return Config{
|
||||
Port: 9786,
|
||||
AutoGenPort: true,
|
||||
AutoGenPort: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,14 +77,11 @@ func GenerateSecret() string {
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
// NewServer creates a bridge server. If cfg.Secret is empty, one is generated.
|
||||
// NewServer creates a bridge server.
|
||||
// If cfg.Secret is empty, no authentication is required.
|
||||
func NewServer(cfg Config, handler EventHandler) *Server {
|
||||
secret := cfg.Secret
|
||||
if secret == "" {
|
||||
secret = GenerateSecret()
|
||||
}
|
||||
return &Server{
|
||||
secret: secret,
|
||||
secret: cfg.Secret,
|
||||
handler: handler,
|
||||
}
|
||||
}
|
||||
@@ -219,6 +217,12 @@ func (s *Server) handleEvents(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if s.handler != nil {
|
||||
// Enrich events with device_id from the batch.
|
||||
for i := range batch.Events {
|
||||
if batch.Events[i].DeviceID == "" {
|
||||
batch.Events[i].DeviceID = batch.DeviceID
|
||||
}
|
||||
}
|
||||
s.handler(batch.Events)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ type VaultAppConfig struct {
|
||||
VaultID string `json:"vault_id,omitempty"`
|
||||
CreatedAt string `json:"created_at,omitempty"`
|
||||
Sync SyncSettings `json:"sync,omitempty"`
|
||||
FileWatcher bool `json:"file_watcher"`
|
||||
FileWatcher *bool `json:"file_watcher,omitempty"`
|
||||
Bridge BridgeConfig `json:"bridge,omitempty"`
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ func DefaultAppConfig() *AppConfig {
|
||||
EnabledTemplates: []string{"folder.default", "project.default", "client.default", "document.default", "recipe.default"},
|
||||
EnabledPlugins: []string{},
|
||||
Vault: VaultAppConfig{
|
||||
FileWatcher: true,
|
||||
FileWatcher: BoolPtr(true),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -160,3 +160,8 @@ func DefaultVaultPath() (string, error) {
|
||||
}
|
||||
return filepath.Join(dir, "vault"), nil
|
||||
}
|
||||
|
||||
// BoolPtr returns a pointer to the given bool value.
|
||||
func BoolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
@@ -236,11 +236,20 @@ func (w *Watcher) handleEvent(rel, absPath string, ev fsnotify.Event) {
|
||||
}
|
||||
}
|
||||
|
||||
// New file — create record.
|
||||
_, err = w.files.CopyIntoVault(node.ID, absPath, parentDir)
|
||||
if err != nil {
|
||||
log.Printf("[watcher] auto-add file %s: %v", rel, err)
|
||||
return
|
||||
// New file — check if it's already inside the vault.
|
||||
// If absPath is under vaultRoot, don't copy — just create a record.
|
||||
if isUnderVault(absPath, w.vaultRoot) {
|
||||
_, err = w.files.AddExternal(node.ID, absPath)
|
||||
if err != nil {
|
||||
log.Printf("[watcher] auto-add in-vault file %s: %v", rel, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
_, err = w.files.CopyIntoVault(node.ID, absPath, parentDir)
|
||||
if err != nil {
|
||||
log.Printf("[watcher] auto-add file %s: %v", rel, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.logActivity(node.ID, activity.TypeFileAdded, fi.Name(), rel)
|
||||
|
||||
@@ -342,3 +351,10 @@ func hashFileFast(absPath string) (string, int64) {
|
||||
}
|
||||
return hex.EncodeToString(h.Sum(nil)), n
|
||||
}
|
||||
|
||||
// isUnderVault reports whether absPath is inside vaultRoot.
|
||||
func isUnderVault(absPath, vaultRoot string) bool {
|
||||
absPath, _ = filepath.Abs(absPath)
|
||||
vaultRoot, _ = filepath.Abs(vaultRoot)
|
||||
return strings.HasPrefix(absPath, vaultRoot+string(filepath.Separator)) || absPath == vaultRoot
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user