quak login --server: log in to a self-hosted Ente server (closes #243)
check / check (push) Successful in 2m56s
check / check (push) Successful in 2m56s
`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:
1 parent
9bd7e8f099
commit
94283522e9
10 files changed
+700
-68
No files matched your search
+35
-3
@@ -2,12 +2,14 @@
|
||||
* Tests for the retry options `bin/quak.ts` loads the saved session with
|
||||
* (`quak backup` gets the unattended ones, every other command the default),
|
||||
* each with the callbacks that log its requests and retries, for `quak files`
|
||||
* taking its collection ID as an optional argument, and for `quak get` and
|
||||
* `quak get-thumb` refusing `--collection`.
|
||||
* taking its collection ID as an optional argument, for `quak get` and
|
||||
* `quak get-thumb` refusing `--collection`, and for `quak login` taking
|
||||
* `--server` and sending its first request to the server it names.
|
||||
*
|
||||
* Each test runs `bin/quak.ts`, as the smoke test does, with its session loader
|
||||
* replaced by one that records the options it is given and reports no session,
|
||||
* so the command stops before it makes any request.
|
||||
* so the command stops before it makes any request. `quak login` reads no
|
||||
* session, so its test stubs `fetch` instead and records each request.
|
||||
*
|
||||
* The first load of the sources `bin/quak.ts` imports compiles them, and the
|
||||
* first `init()` starts libsodium. On a loaded host that takes longer than a
|
||||
@@ -58,6 +60,8 @@ afterEach(() => {
|
||||
process.argv = argv;
|
||||
loaded.length = 0;
|
||||
vi.restoreAllMocks();
|
||||
vi.unstubAllGlobals();
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
@@ -117,3 +121,31 @@ describe("bin/quak.ts get and get-thumb", () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("bin/quak.ts login", () => {
|
||||
// The command refuses an address that is not a URL before it asks for
|
||||
// anything or sends any request.
|
||||
it("hands --server to the command", async () => {
|
||||
expect(await quak("login", "--server", "ente.example.com")).toMatch(
|
||||
/^Invalid server address "ente\.example\.com"/,
|
||||
);
|
||||
});
|
||||
|
||||
// `fetch` answers 404, so the login fails at its first request. A login
|
||||
// that succeeded would save its session in this user's real data
|
||||
// directory, since env-paths is not mocked here.
|
||||
it("sends its first request to the server --server names", async () => {
|
||||
const requests: string[] = [];
|
||||
vi.stubGlobal("fetch", async (input: string) => {
|
||||
const { origin, pathname } = new URL(input);
|
||||
requests.push(origin + pathname);
|
||||
return new Response("not found", { status: 404 });
|
||||
});
|
||||
vi.stubEnv("QUAK_EMAIL", "login@example.com");
|
||||
vi.stubEnv("QUAK_PASSWORD", "password");
|
||||
await quak("login", "--server", "https://ente.example.com");
|
||||
expect(requests).toEqual([
|
||||
"https://ente.example.com/users/srp/attributes",
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user