Documentation
¶
Overview ¶
Package fxewatch is the server's own record of a rewritten single encrypted file (`.fxe`): an audit row for every rewrite of one, and — when the rewrite changed its password or recovery slot — the deletion of the older versions that still open the file with the old secret.
A `.fxe` password change happens in the browser: a new header, the body carried over byte for byte (docs/E2E-ENCRYPTION.md → "Single encrypted files"). The web UI announces it (POST /api/files/e2e/password-changed), but an announcement is only as good as the client that makes it. This watch sees the rewrite itself, on every surface that writes a file, and compares the header with the version the pre-write guard just kept (e2e.DiffFileHeaders).
⚠ What it deletes, and why only that. After a password change the version the overwrite kept holds the OLD header over the SAME file key: whoever knows the old password opens the file's current contents with it. Those versions (e2e.RetiredSecret: the same file key under a password or recovery slot the file no longer uses) go. A version holding different content under a different key is history the owner may want, and it opens only what it always opened; so is one under the password still in use. Both stay.
⚠ And only for a writer who may (e2e/slotchange): the file's owner or an administrator. Anybody else who may write the file may also upload a header that names its file key under a password slot of their own; that rewrite keeps every version, and the owner is told.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Audit ¶
type Audit interface {
InsertAuditEntry(ctx context.Context, e *model.AuditEntry) error
}
Audit is the narrow store surface the watch needs.
type Versions ¶
type Versions interface {
List(ctx context.Context, nodeID int64) ([]*model.NodeVersion, error)
HardDeleteVersion(ctx context.Context, versionID int64) error
}
Versions is the narrow versioning surface the watch needs (versioning.Service satisfies it).
type Watch ¶
type Watch struct {
Audit Audit
Versions Versions // nil: nothing to compare against, nothing to delete
Resolver func(storageID int64) (storage.Driver, error)
// Owners answers who owns the file and who wrote (db.Store). nil: no
// owner is known, so only an administrator's rewrite deletes anything.
Owners slotchange.Store
// Notify tells the owner (nil: nobody is told; the audit rows stay).
Notify notify.Service
}
Watch turns a rewritten `.fxe` into an audit row, and a retired secret into deleted versions. Wired as a writehook after-write observer.
func (*Watch) OnWritten ¶
func (w *Watch) OnWritten(ctx context.Context, storageID int64, node *model.Node, origin string, replaced bool)
OnWritten is called after every file write. It acts only on a file named like a `.fxe` that REPLACED another one: a new `.fxe` is a new encrypted file, not an event of its own.