One sign-in, and a host app can hand the panel a session - #73
Open
DavertMik wants to merge 5 commits into
Open
Conversation
A desktop app that launches Chrome with this extension loaded drops handoff.json beside the manifest: a project token for v2, a web session for the JSON:API, and optionally the run to open. The tester pastes nothing. A file, not argv — --load-extension command lines are readable by every process on the machine. Only the project token is stored; the session token stays in memory and is re-read, like the one /api/login returns. The project is pinned, since one project's token was handed over. Disconnect cannot delete a file it does not own, so it marks that push answered and a newer one wins. Also: opening a run from a URL now reports whether it landed anywhere. A run that 404s used to leave the panel showing nothing at all.
A panel the host has just opened consumes the offer during its own boot, so the poke that follows found the run already opened and reported none. The host asked whether its run is up, so answer that.
Adopting a handoff used to delete the General token saved for that host, so closing the host's browser left the panel with nothing and the tester re-pasting a token they had already given us. Both credentials are kept side by side instead. The project token is tagged with the project it was issued for and used only there, so a switch elsewhere falls back to the account token — which also means the switcher only has to be pinned for a tester who has no token of their own. The host's name is stored with the connection, because the card has to name whose session ended after the file it came from is gone.
Authorizing at /app-auth hands back a session that both opens the web JSON:API and can read any project's own v2 key. So the panel needs one credential, not two kinds of them: it mints per-project keys as it goes and the tester never looks a key up. The paste box takes either kind. A stored session is adopted the same way a handed one is, adopt-once so an expired token degrades instead of looping; a General token still goes straight onto v2 and still exchanges at /api/login, so nobody's saved token stops working. Because a session reaches every project, the handoff's projectToken drops to an optimisation — one round trip saved — and the project switcher no longer has to be pinned for a handed-off connection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces #72, which described an earlier version of this contract.
Two things, and the second is why the first got simpler.
One credential
Authorizing at
/app-authhands back a session that opens the web JSON:API and can read any project's own v2 key. So the panel needs one credential rather than two kinds of them: it mints per-project keys as it goes, and the tester never looks a key up.Settings now leads with Open Testomat.io & authorize and takes the token that comes back. A General token still works — a stored credential starting with
eyJis adopted as a session, anything else goes onto v2 directly and still exchanges at/api/login. Nobody's saved token stops working, and that branch is deletable the day you want the old path gone.Minted keys live in memory, one per project, cleared when the instance or the credential changes.
PRIVACY.mdsays so.A host app can sign the panel in
A desktop app that launches Chrome with this extension loaded drops
handoff.jsonbeside the manifest and opens the panel, so the tester never pastes anything to run the test the app just sent them to:{ "app": "Testeiya", "baseUrl": "https://app.testomat.io", "projectId": "my-project", "jwt": "eyJ…", "runUrl": "https://app.testomat.io/projects/my-project/runs/abcd1234", "at": 1756160000000 }jwtis what the offer is made of.projectTokenmay ride along and saves the first key read, nothing more.runUrlis optional.atis milliseconds and has to grow on every push.A file rather than a command line:
--load-extensionargv is readable by every process on the machine, and these are credentials. A panel already open takes a new push throughwindow.TestomatHandoff.apply(), which answers{ok, projectId, run}; a build without that global predates the contract.The session is never stored — it is re-read from the file on every panel load, which is why the file stays until the host that wrote it deletes it. Disconnect can't delete a file it doesn't own, so it marks that
atanswered and a newer push wins.An offer overlays an ordinary sign-in rather than replacing it: a tester who had already connected keeps their credential and their preferences, and because any session reaches every project, the project switcher stays open. It closes in one case — the host closed its browser and the tester never signed in themselves, leaving a stored project token that opens that one project.
Also here
openRunFromUrlnow reports whether it actually landed the panel on a view. A run that 404s used to leave the panel showing nothing at all, reachable today through "Run in Extension".Checked
Against a real instance, watching the
Authorizationheader on live requests: a JWT-only sign-in minting atstmt_key; a project switch minting the second project's key; a handoff with a project token using it on its own project and minting elsewhere; a General token unchanged. Plus a jwt-only handoff, cold boot, a live poke switching runs in place, decline-then-newer-push, and the editor and viewer clean under a session-only sign-in.Untested: the branch for a role whose project returns no API key, and the expired-session message. Both are written; neither had an account to prove it with.
With no host involved the panel logs one
ERR_FILE_NOT_FOUNDforhandoff.jsonat boot. That is the check for the file, not a fault.🤖 Generated with Claude Code