Add exact-image compatibility policy, experimental admission, paginated build history and shared reauthentication checks. Preserve uncertain Docker creation records, bound frontend resource waits and renew runtime sessions proactively. Lazy-load and split Monaco, add regression and opt-in live Docker fault tests, and record full race and real-browser acceptance results.
61 lines
2.4 KiB
Go
61 lines
2.4 KiB
Go
package api
|
|
|
|
import "net/http"
|
|
|
|
func runtimeSessionScript(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
fail(w, 405, "method not allowed")
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
w.Write([]byte(runtimeSessionJS))
|
|
}
|
|
|
|
const runtimeSessionJS = `(function () {
|
|
const prefix = location.pathname.match(/^\/dsh\/[^/]+(?=\/|$)/);
|
|
if (prefix) {
|
|
const originalFetch = window.fetch;
|
|
const bridge = /^\/api\/dsh-free-search-settings\/(describe|mutate|credentials-status|credentials-set|credentials-unset|check-update|update|raw-search)$/;
|
|
window.fetch = async function (input, init) {
|
|
let url;
|
|
try { url = new URL(input instanceof Request ? input.url : input, document.baseURI); } catch (_) {}
|
|
if (url && url.origin === location.origin && bridge.test(url.pathname)) {
|
|
url.pathname = prefix[0] + url.pathname;
|
|
if (input instanceof Request) {
|
|
const request = new Request(input, init);
|
|
return originalFetch.call(this, new Request(url, request));
|
|
}
|
|
input = url;
|
|
}
|
|
return originalFetch.call(this, input, init);
|
|
};
|
|
}
|
|
let pending;
|
|
async function renew() {
|
|
if (pending) return pending;
|
|
const run = async function () {
|
|
// Renew proactively: a successful /me does not extend the five-minute
|
|
// access lifetime. Web Locks serialize cookie rotation across pages.
|
|
const csrf = document.cookie.split("; ").find(c => c.startsWith("dsh_csrf="));
|
|
if (!csrf) return;
|
|
const response = await fetch("/api/refresh", {method:"POST", credentials:"same-origin", headers:{"X-CSRF-Token":csrf.slice(9)}});
|
|
if (response.status === 401 || response.status === 403 || response.status === 409) {
|
|
for (const delay of [0, 100, 250, 500]) {
|
|
if (delay) await new Promise(resolve => setTimeout(resolve, delay));
|
|
const check = await fetch("/api/me", {credentials:"same-origin"});
|
|
if (check.status !== 401) return;
|
|
}
|
|
if (response.status === 401 || response.status === 403) location.reload();
|
|
}
|
|
};
|
|
pending = (navigator.locks ? navigator.locks.request("dsh-session-refresh", run) : run())
|
|
.catch(function () {}).finally(function () { pending = undefined; });
|
|
return pending;
|
|
}
|
|
setInterval(renew, 240000);
|
|
window.addEventListener("pageshow", renew);
|
|
window.addEventListener("online", renew);
|
|
document.addEventListener("visibilitychange", function () { if (!document.hidden) renew(); });
|
|
})();`
|