ask for the URL first, and offer what tea already knows

The form asked for a URL and a token together, on a fresh instance, while the
machine in front of it often had both on disk already — somebody had run `tea
login` by hand.

Two changes.

One thing at a time: until the platform knows where Gitea is, a token cannot be
checked, because there is nothing to check it against. So the owner names the
instance first, and only then does the page ask for — or discover — a token.
That step now probes /api/v1/version unauthenticated, since demanding a token
to validate a URL refuses a good URL for the wrong reason and sends whoever
typed it looking for a credential problem.

And it reads tea's own config when the platform has no instance yet, offering
the URL it finds. A machine that already has a working login should not be
asked to retype what it can see.

Members skip the first step entirely — the instance is the owner's.
This commit is contained in:
officer
2026-08-19 10:25:22 +00:00
parent 862512d83a
commit d4efc52447
4 changed files with 102 additions and 23 deletions
+21
View File
@@ -113,6 +113,27 @@ export type ProbeResult = { ok: boolean; version: string | null; user: string |
* 200 → both good
* Verified against the live instance: unauthenticated /version → 403, /version with a junk token → 401.
*/
/**
* Is there a Gitea at this URL at all — no token involved.
*
* Naming the instance is its own step: the owner says where Gitea is, and only then does anyone ask for
* a token for it. Probing with a token that does not exist yet would refuse a perfectly good URL for the
* wrong reason, and send whoever typed it looking for a problem with their credentials.
*
* `/api/v1/version` answers unauthenticated on every Gitea, so a 200 means "this is a Gitea and it is
* up", which is exactly what this step needs to establish.
*/
export async function reachable(base: string): Promise<ProbeResult> {
try {
const res = await fetch(`${base}/api/v1/version`, { signal: AbortSignal.timeout(8000) });
if (!res.ok) return { ok: false, version: null, user: null, error: `the server answered ${res.status}` };
const body = (await res.json().catch(() => null)) as { version?: string } | null;
return { ok: true, version: body?.version ?? null, user: null };
} catch {
return { ok: false, version: null, user: null, error: 'could not reach that URL from the server' };
}
}
export async function probe(config: GiteaConfig): Promise<ProbeResult> {
if (!config.token) return { ok: false, version: null, user: null, error: 'no access token stored' };