fix(auth): offer a Sign in button instead of the raw API 401
The style browser surfaced the REST 401 verbatim, which told people to send an `Authorization: Bearer` header and pointed at styleref.io/mcp — neither of which anyone can act on from inside ComfyUI. - A signed-out lane now renders one actionable row: a Sign in button running the same browser OAuth flow as the Login node, plus a link to the setup guide. Headless boxes still get the full instructions in the overlay, since they cannot just click. - /styleref/saved and /styleref/my-styles map an API 401 to `signedIn: false` rather than echoing the message. Expired or revoked stored credentials are the signed-out state, so the dialog should offer sign-in, not an error. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cec7f9f9cd
commit
8beb0e19a8
@@ -99,6 +99,13 @@ async def styleref_saved(request: web.Request) -> web.Response:
|
||||
offset=_int_param(request, "offset", 0),
|
||||
)
|
||||
except StyleRefError as err:
|
||||
# A 401 here means stored credentials that no longer work (expired, or
|
||||
# revoked on styleref.io). That is the signed-out state as far as the UI
|
||||
# is concerned, so report it as one and let the dialog offer Sign in —
|
||||
# echoing the server's raw 401 told people to set an Authorization header,
|
||||
# which is not something anyone can do from inside ComfyUI.
|
||||
if err.needs_login:
|
||||
return web.json_response({"styles": [], "signedIn": False})
|
||||
return web.json_response({"styles": [], "signedIn": True, "error": err.message})
|
||||
|
||||
return web.json_response(
|
||||
@@ -124,6 +131,13 @@ async def styleref_my_styles(request: web.Request) -> web.Response:
|
||||
limit=_int_param(request, "limit", 8), cursor=cursor, query=query
|
||||
)
|
||||
except StyleRefError as err:
|
||||
# A 401 here means stored credentials that no longer work (expired, or
|
||||
# revoked on styleref.io). That is the signed-out state as far as the UI
|
||||
# is concerned, so report it as one and let the dialog offer Sign in —
|
||||
# echoing the server's raw 401 told people to set an Authorization header,
|
||||
# which is not something anyone can do from inside ComfyUI.
|
||||
if err.needs_login:
|
||||
return web.json_response({"styles": [], "signedIn": False})
|
||||
return web.json_response({"styles": [], "signedIn": True, "error": err.message})
|
||||
|
||||
return web.json_response(
|
||||
|
||||
+54
-4
@@ -211,6 +211,58 @@ function openPicker(initialQuery) {
|
||||
const message = (text) =>
|
||||
el("div", "background:#26262a;border-radius:8px;padding:10px 12px;margin-bottom:6px;opacity:.75;font-size:13px;", text);
|
||||
|
||||
/**
|
||||
* Signed-out state, as one actionable row rather than a wall of text.
|
||||
* The old copy pasted the server's raw 401 — which told people to send an
|
||||
* `Authorization: Bearer` header and linked the MCP install page, neither
|
||||
* of which anyone can do from inside ComfyUI. Signing in is one click here.
|
||||
*/
|
||||
const signInPrompt = (out, what) => {
|
||||
const box = el(
|
||||
"div",
|
||||
"background:#26262a;border-radius:8px;padding:12px;margin-bottom:6px;font-size:13px;",
|
||||
);
|
||||
box.append(
|
||||
el("div", "opacity:.8;margin-bottom:8px;", `Sign in to StyleRef to see ${what}.`),
|
||||
);
|
||||
|
||||
const actions = el("div", "display:flex;gap:8px;align-items:center;");
|
||||
const signIn = el(
|
||||
"button",
|
||||
"background:#4f46e5;border:0;color:#fff;border-radius:6px;padding:6px 12px;cursor:pointer;font-size:13px;",
|
||||
"Sign in",
|
||||
);
|
||||
signIn.onclick = async () => {
|
||||
signIn.disabled = true;
|
||||
signIn.textContent = "Waiting for browser…";
|
||||
const res = await postJson("/styleref/auth/signin");
|
||||
if (res && res.ok === false && res.message) {
|
||||
// Headless boxes get the full instructions — they can't just click.
|
||||
showMessage(res.message);
|
||||
signIn.disabled = false;
|
||||
signIn.textContent = "Sign in";
|
||||
return;
|
||||
}
|
||||
// Both sections were rendered against the signed-out state.
|
||||
renderMine();
|
||||
renderGallery();
|
||||
};
|
||||
actions.append(signIn);
|
||||
|
||||
const help = el(
|
||||
"a",
|
||||
"color:#9b9bff;text-decoration:none;font-size:12px;opacity:.9;",
|
||||
"Setup guide",
|
||||
);
|
||||
help.href = "https://docs.styleref.io/connectors/comfyui/login-and-credits";
|
||||
help.target = "_blank";
|
||||
help.rel = "noopener";
|
||||
actions.append(help);
|
||||
|
||||
box.append(actions);
|
||||
out.append(box);
|
||||
};
|
||||
|
||||
function row(style) {
|
||||
const button = el(
|
||||
"button",
|
||||
@@ -350,7 +402,7 @@ function openPicker(initialQuery) {
|
||||
|
||||
section(mineBox, "My styles", (out) => {
|
||||
if (mine.signedIn === false) {
|
||||
out.append(message("Sign in (StyleRef Login node) to see your styles here."));
|
||||
signInPrompt(out, "your style library");
|
||||
return;
|
||||
}
|
||||
if (mine.error) {
|
||||
@@ -412,9 +464,7 @@ function openPicker(initialQuery) {
|
||||
|
||||
section(galleryBox, title, (out) => {
|
||||
if (gallery.signedIn === false) {
|
||||
out.append(
|
||||
message("Sign in (StyleRef Login node) to see the styles you saved."),
|
||||
);
|
||||
signInPrompt(out, "the styles you saved");
|
||||
return;
|
||||
}
|
||||
if (gallery.error) {
|
||||
|
||||
Reference in New Issue
Block a user