Fix OAuth-secret reveal modal race in the resource modal (#123)

saveResource() called app.modal.close() then, after an intervening
await loadResources(), conditionally app.modal.open() to show a newly
created OAuth client's secret. app.modal is a singleton -- close()
immediately followed by open() in the same tick collides with Bootstrap's
hide-transition guard (show() silently no-ops while _isTransitioning is
still true from the just-started hide()). The await made this race
unlikely to lose in practice, but not guaranteed to -- found while fixing
the same bug (with no such await, so guaranteed to lose) in jump-host and
proxy's API-token create flows.

Now the resource-edit modal is only closed when we're NOT about to
immediately show the OAuth secret; app.modal.open() alone already
overwrites the (already-visible) modal's content in place, no close()
needed first.
This commit is contained in:
2026-07-28 20:49:06 -04:00
committed by GitHub
parent b54da5c64c
commit 42a61f8868
+9 -1
View File
@@ -756,11 +756,19 @@
res = await app.api.post('directory-admin/resources', data);
}
app.modal.close();
await loadResources();
if (!id && data.kind === 'oauth' && res.results && res.results._raw_secret) {
// Deliberately no app.modal.close() before this -- app.modal is a
// singleton, and close() immediately followed by open() in the same
// tick collides with Bootstrap's hide-transition guard (show()
// silently no-ops while _isTransitioning is still true from the
// just-started hide()). open() alone already overwrites the
// (already-visible) modal's content in place. The await above made
// this race unlikely to lose in practice, but not guaranteed to.
app.modal.open({title: 'OAuth Secret', bodyHtml: 'Save this client secret, it will not be shown again: <br><br><code>' + res.results._raw_secret + '</code>'});
} else {
app.modal.close();
}
} catch (err) {
console.error(err);