quak login --server: log in to a self-hosted Ente server (closes #243)
check / check (push) Successful in 3m29s

`quak login` takes the server's API address from `--server` or
`QUAK_SERVER`. `isServerAddress` refuses anything but an http or https
URL with no query or fragment, there and in `Client.fromJSON`. The
client's snapshot keeps a non-default `apiOrigin`, so the session file
names the server and every later command uses it.

Two servers can give two accounts, and two files, the same ID. A
self-hosted account's default cache directory therefore names the
server, and `metadata.json` records it: `Library.open` deletes a cache
from another server whole. `originalOf` and `thumbnailOf` record the
account in a cache that names none before storing a file, and `open`
treats a cache with no collection as empty. This fixes
#254 (closes #254).

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-13 21:19:24 +00:00
1 parent 9bd7e8f099
commit 6f8f85fff5
10 files changed
+768 -68

No files matched your search

+11 -2
View File
@@ -74,7 +74,11 @@ const context = (): CliContext => ({
sessionDir: paths.data,
cacheDir: program.opts<ProgramOptions>().cacheDir,
loadSession: (path) => loadSession(path, logRequests(log())),
login: (opts) => Client.login({ ...opts, apiOptions: logRequests(log()) }),
login: (opts) =>
Client.login({
...opts,
apiOptions: { ...opts.apiOptions, ...logRequests(log()) },
}),
prompt: (message) => input({ message }),
promptSecret: (message) => password({ message, mask: true }),
});
@@ -85,7 +89,12 @@ const run = (command: Promise<number>): Promise<void> =>
program
.command("login")
.description("Log in to an Ente account and save the session")
.action(() => run(loginCommand(context())));
.option(
"--server <url>",
"Address of a self-hosted Ente server's API, saved with the session " +
"(default: QUAK_SERVER, then Ente's hosted service)",
)
.action((opts: { server?: string }) => run(loginCommand(context(), opts)));
program
.command("whoami")