Documentation
¶
Overview ¶
Package localapp is the local state of an app that runs for one OS user on one device, with no server of its own to sign people in: a desktop window (battery/desktop), a phone app serving itself in process (gofastr-mobile), a signed-in service on the user's machine. Open gives such an app its data directory's contents: the SQLite database, the session secret that keeps sessions valid across restarts, and the installation's identity.
The identity exists because owner-scoped CRUD still needs an owner id. The host puts a stable per-installation User into the request context, and the owner extractor that Install sets up reads it back.
The identity is a FALLBACK for an app with no auth battery, never an override of one. battery/auth installs the framework/owner extractor from its package init, so a foreign extractor already in place is a reliable "auth owns identity" signal, and Install reports it. A host that sees it installs no identity at all: auth's "this request is anonymous" is a decision, and handler.GetUser cannot tell a stored nil from no decision (the 2026-09-04 desktop finding pinned in battery/desktop/localuser_security_test.go).
Index ¶
Constants ¶
const ( DBFile = "app.db" SecretFile = "secret" )
The files Open keeps in the data directory.
const IdentityFile = "identity"
IdentityFile is the identity file inside the app's data directory.
Variables ¶
This section is empty.
Functions ¶
func Extractor ¶
Extractor reads the owner id off the context user. It is a named top-level function so IsExtractor can recognize it.
func Install ¶
func Install() (authOwnsIdentity bool)
Install sets Extractor as the process-wide owner extractor when no extractor is set, and reports whether a foreign one (battery/auth's, from its package init) owns identity. Extractor itself, installed earlier by another battery or another App in the same process, is not foreign: every Go test suite builds several apps per process.
func IsExtractor ¶
IsExtractor reports whether fn is Extractor. Func values are not comparable; their code pointers are, and a top-level function has exactly one.
func LoadOrMintSecret ¶
LoadOrMintSecret returns the secret stored in dir/secret, minting 32 bytes of crypto/rand (base64url) and persisting them 0600 on first run. Two processes racing the first boot converge on one secret: the file is created exclusively, and the loser reads the winner's.
func OpenDB ¶
OpenDB opens (creating if needed) the SQLite database dir/app.db. The file is created owner-only before SQLite opens it, so it never exists with the process umask's mode.
func Valid ¶
Valid reports whether id matches the grammar LoadOrMint mints with. A value read back off disk and used as a security principal is re-validated: it is what every owner-scoped query compares against, so a trailing newline or a truncated file would silently become a different owner and hide every row the app had written.
Types ¶
type Data ¶
type Data struct {
// Dir is the absolute data directory.
Dir string
// DB is app.db, opened through sqlite/stdlib. Pass it to
// framework.WithDB. The caller closes it, or calls Close.
DB *sql.DB
// Secret keeps sessions valid across restarts. Pass it to
// framework.WithSecret.
Secret string
// User is the installation's identity, the owner of every row the
// app writes for its one person.
User *User
}
Data is what a local app's data directory holds, opened.
func Open ¶
Open opens the data directory dir, creating it owner-only (0700) when it is missing, and returns its database, secret and identity, minting the secret and the identity on first run. dir must be absolute: it is the directory the platform gives the app (Application Support, an Android app's files dir), never one resolved from the working directory. An existing directory keeps its mode: Open never tightens a directory it did not create.
type User ¶
type User struct {
// contains filtered or unexported fields
}
User is the context user value. Its GetID/GetEmail/GetRoles method set satisfies battery/auth's User interface structurally, without importing battery/auth.
func ForID ¶
ForID returns the User for id, for tests and for a battery that already holds a validated id.
func LoadOrMint ¶
LoadOrMint returns the identity stored under dir, minting one (16 bytes of crypto/rand, hex) and persisting it 0600 on first run.