diff --git a/sidecar/index.ts b/sidecar/index.ts index 0543c90..3a1b7d6 100644 --- a/sidecar/index.ts +++ b/sidecar/index.ts @@ -198,7 +198,14 @@ async function handleConfig(req: Request, userId: number): Promise { } const existing = await getServiceConnection(userId, 'gitea'); - if (!token && !existing?.hasSecret) return bad('an access token is required the first time'); + // NOT required on the first save any more. Naming the instance is its own step — the owner says + // where Gitea is, and the token is asked for (or found in tea's config) afterwards. This check + // predates that split and refused the URL step outright. + // + // A member is different: they set nothing but a token, so an empty save from them means nothing. + if (!owner && !token && !(await readTeaLogin(userId, base))?.hasToken) { + return bad('an access token is required'); + } // Probe with the credentials as they WILL be, so a save either stores something that works or // fails with the reason. Storing first and discovering later makes every downstream screen fail diff --git a/web/GiteaConnection.tsx b/web/GiteaConnection.tsx index 97a7564..8ca147c 100644 --- a/web/GiteaConnection.tsx +++ b/web/GiteaConnection.tsx @@ -75,7 +75,8 @@ export const GiteaConnection = ({ state, onSaved }: Props) => { // Members skip step one entirely: the instance is the owner's. const needsUrl = state.isOwner !== false && !state.instanceConfigured; - const save = async () => { + const save = async (ev?: React.FormEvent) => { + ev?.preventDefault(); setBusy(true); setError(null); try { @@ -92,7 +93,10 @@ export const GiteaConnection = ({ state, onSaved }: Props) => { }; return ( -
+ // A real
, so Enter submits. Typing a URL and pressing return is what anyone does, and a div + // full of inputs silently swallows it — the button becomes the only way in, which is a keyboard trap + // wearing a layout. +

{state.unreadable ? 'Re-enter your token' : 'Connect Gitea'}

@@ -110,10 +114,6 @@ export const GiteaConnection = ({ state, onSaved }: Props) => { )} @@ -157,26 +157,23 @@ export const GiteaConnection = ({ state, onSaved }: Props) => { {error &&

{error}

}
- {/* Only offered when there is something to test. */} {state.tea?.hasToken ? ( - ) : null} {/* Only once there is something to go back TO. */} {state.configured && !state.unreadable ? ( - ) : null}
-
+
); };