swarm-ui link-account forms: keep the sent name, drop secrets, one word for forge
The success line of both link forms read the live text field, so editing the name after a link changed the sentence. The result now carries the name that was sent. The matrix form held the typed token and password after a failed submit, and kept them across a switch of credential mode. It now drops them when the request ends and when the mode changes. The linked-accounts list and the delete dialog said forgejo where the link menu and forms say forge; they now say forge.
This commit is contained in:
parent
8f8217100b
commit
ef156d9d23
6 changed files with 52 additions and 18 deletions
|
|
@ -22,7 +22,7 @@ const LABEL_PATTERN = "[a-z0-9\\-]{1,63}";
|
|||
type SubmitState =
|
||||
| { status: "idle" }
|
||||
| { status: "submitting" }
|
||||
| { status: "done"; url: string }
|
||||
| { status: "done"; label: string; url: string }
|
||||
| { status: "error"; problem: ProblemDetails };
|
||||
|
||||
export function LinkForgeAccountForm({
|
||||
|
|
@ -56,7 +56,9 @@ export function LinkForgeAccountForm({
|
|||
return;
|
||||
}
|
||||
const body = (await r.json().catch(() => ({}))) as { url?: string };
|
||||
setResult({ status: "done", url: body.url ?? url.trim() });
|
||||
// The label is stored with the result, so the success message reads
|
||||
// against what was sent even if the field is edited afterwards.
|
||||
setResult({ status: "done", label, url: body.url ?? url.trim() });
|
||||
// The store holds the token now; nothing here needs it.
|
||||
setToken("");
|
||||
} catch (err) {
|
||||
|
|
@ -114,7 +116,7 @@ export function LinkForgeAccountForm({
|
|||
</form>
|
||||
{result.status === "done" && (
|
||||
<p class="link-matrix-account-result-ok">
|
||||
linked <strong>{label}</strong> ({result.url}) to{" "}
|
||||
linked <strong>{result.label}</strong> ({result.url}) to{" "}
|
||||
<strong>{agent}</strong>
|
||||
</p>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ type SubmitState =
|
|||
// login response) and `undefined` in token mode — see
|
||||
// `PutMatrixAccountResponse`'s own doc for why token mode doesn't
|
||||
// spend a round trip resolving one.
|
||||
| { status: "done"; userId?: string }
|
||||
| { status: "done"; account: string; userId?: string }
|
||||
| { status: "error"; problem: ProblemDetails };
|
||||
|
||||
const MODE_OPTIONS = [
|
||||
|
|
@ -79,6 +79,14 @@ export function LinkMatrixAccountForm({
|
|||
const [homeserver, setHomeserver] = useState("");
|
||||
const [result, setResult] = useState<SubmitState>({ status: "idle" });
|
||||
|
||||
// A secret lives in state only while it is being typed and sent: it is
|
||||
// dropped when the request ends, whether it worked or not, and when the
|
||||
// credential mode changes.
|
||||
function clearSecrets() {
|
||||
setToken("");
|
||||
setPassword("");
|
||||
}
|
||||
|
||||
async function submit(e: Event) {
|
||||
e.preventDefault();
|
||||
setResult({ status: "submitting" });
|
||||
|
|
@ -109,6 +117,7 @@ export function LinkMatrixAccountForm({
|
|||
),
|
||||
},
|
||||
);
|
||||
clearSecrets();
|
||||
if (!r.ok) {
|
||||
setResult({ status: "error", problem: await readApiError(r) });
|
||||
return;
|
||||
|
|
@ -116,16 +125,11 @@ export function LinkMatrixAccountForm({
|
|||
const body = (await r.json().catch(() => ({}))) as {
|
||||
user_id?: string;
|
||||
};
|
||||
setResult({ status: "done", userId: body.user_id });
|
||||
// Secrets cleared on success — nothing left needing them in the
|
||||
// form once the store holds the derived credential, and a secret
|
||||
// sitting in a field after the action that used it is exactly the
|
||||
// kind of stale-credential risk the whole store exists to avoid.
|
||||
// Account name kept, so the success message below reads against
|
||||
// what actually landed.
|
||||
setToken("");
|
||||
setPassword("");
|
||||
// The account name is stored with the result, so the success message
|
||||
// reads against what was sent even if the field is edited afterwards.
|
||||
setResult({ status: "done", account, userId: body.user_id });
|
||||
} catch (err) {
|
||||
clearSecrets();
|
||||
setResult({ status: "error", problem: { detail: String(err) } });
|
||||
}
|
||||
}
|
||||
|
|
@ -163,7 +167,10 @@ export function LinkMatrixAccountForm({
|
|||
label="credential"
|
||||
value={mode}
|
||||
options={MODE_OPTIONS}
|
||||
onChange={(v) => setMode(v as Mode)}
|
||||
onChange={(v) => {
|
||||
clearSecrets();
|
||||
setMode(v as Mode);
|
||||
}}
|
||||
/>
|
||||
{mode === "token" ? (
|
||||
<TextField
|
||||
|
|
@ -218,7 +225,7 @@ export function LinkMatrixAccountForm({
|
|||
</form>
|
||||
{result.status === "done" && (
|
||||
<p class="link-matrix-account-result-ok">
|
||||
linked <strong>{account}</strong> to <strong>{agent}</strong>
|
||||
linked <strong>{result.account}</strong> to <strong>{agent}</strong>
|
||||
{result.userId ? (
|
||||
<>
|
||||
{" "}
|
||||
|
|
|
|||
Loading…
Reference in a new issue