Fix e621 images and the setup screen in the desktop shell
e621's CDN answers cross-site image loads that carry no Referer with a 403 (Chromium sends none from a custom-scheme page, then blocks the response as ORB), so images never appeared in the desktop app. The main process now attaches an e621 referrer to requests for its hosts. The shell also answers /api, /admin, /static and /health with a 404 JSON instead of the SPA fallback — that fallback made the setup screen's empty-URL connection test report "Connected" against the shell itself. The setup screen is now desktop-aware (no same-origin option, no "Use this server", clearer copy), and the smoke test runs against a throwaway profile and covers both regressions.
This commit is contained in:
@@ -17,6 +17,16 @@ import { setToken } from "@/lib/api";
|
||||
type TestResult = { ok: boolean; text: string } | null;
|
||||
|
||||
async function testBackend(base: string): Promise<TestResult> {
|
||||
// The desktop shell has no server of its own: an empty URL is not a
|
||||
// same-origin backend, and /health on app://j621 is answered by the shell.
|
||||
if (!base && window.j621Desktop) {
|
||||
return {
|
||||
ok: false,
|
||||
text:
|
||||
"The desktop app has no backend of its own. Enter your J621 server's " +
|
||||
"URL, or continue without a backend.",
|
||||
};
|
||||
}
|
||||
const controller = new AbortController();
|
||||
const timeout = window.setTimeout(() => controller.abort(), 5_000);
|
||||
try {
|
||||
@@ -110,10 +120,15 @@ export function SetupPage() {
|
||||
</div>
|
||||
|
||||
<p className="mt-3 text-sm leading-relaxed text-ctp-subtext0">
|
||||
Enter the origin this app should call for its API. Leave it blank
|
||||
when the app and the API are served from the same domain. Without a
|
||||
backend the app runs in local mode: e621 browsing only, with
|
||||
credentials kept in this browser.
|
||||
{window.j621Desktop
|
||||
? "Enter the origin of your J621 server (for example " +
|
||||
"https://j621.example.com). Without a backend the app runs in " +
|
||||
"local mode: e621 browsing only, with credentials kept on this " +
|
||||
"device."
|
||||
: "Enter the origin this app should call for its API. Leave it " +
|
||||
"blank when the app and the API are served from the same " +
|
||||
"domain. Without a backend the app runs in local mode: e621 " +
|
||||
"browsing only, with credentials kept in this browser."}
|
||||
</p>
|
||||
|
||||
<label className="mt-5 flex flex-col gap-1.5">
|
||||
@@ -122,7 +137,11 @@ export function SetupPage() {
|
||||
</span>
|
||||
<input
|
||||
className={cn(inputClass, "font-mono")}
|
||||
placeholder="https://j621.example.com — blank for this server"
|
||||
placeholder={
|
||||
window.j621Desktop
|
||||
? "https://j621.example.com"
|
||||
: "https://j621.example.com — blank for this server"
|
||||
}
|
||||
value={value}
|
||||
onChange={(event) => {
|
||||
setValue(event.target.value);
|
||||
@@ -161,7 +180,7 @@ export function SetupPage() {
|
||||
{testing ? <Spinner className="h-3.5 w-3.5" /> : null}
|
||||
{testing ? "Testing…" : "Test connection"}
|
||||
</Button>
|
||||
{value.trim() ? (
|
||||
{value.trim() && !window.j621Desktop ? (
|
||||
<Button variant="ghost" onClick={() => save("")}>
|
||||
Use this server
|
||||
</Button>
|
||||
@@ -172,8 +191,10 @@ export function SetupPage() {
|
||||
</div>
|
||||
|
||||
<p className="mt-4 text-xs leading-relaxed text-ctp-overlay0">
|
||||
Stored in this browser only. Changing the backend signs you out of
|
||||
the previous one.
|
||||
{window.j621Desktop
|
||||
? "Stored in this app only."
|
||||
: "Stored in this browser only."}{" "}
|
||||
Changing the backend signs you out of the previous one.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user