fix: embed token in HTML for WebSocket auth
The WebSocket connection at /ws was not including the token parameter, relying solely on the session cookie from the initial redirect. When scanning the QR code on a phone, the token (longest part of URL) was being truncated, so no cookie was ever set and all requests got 403. Fix: embed the token directly into the page as a JS variable, and append it to the WebSocket connection URL as a fallback. Now both the HTTP page and the WebSocket upgrade work even if the cookie isn't available.
This commit is contained in:
parent
a0713e8a02
commit
84e0caa1d3
|
|
@ -5,7 +5,7 @@
|
||||||
* Everything is self-contained — no external dependencies.
|
* Everything is self-contained — no external dependencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function buildHTML(nonce: string): string {
|
export function buildHTML(nonce: string, token?: string): string {
|
||||||
return /* html */ `<!DOCTYPE html>
|
return /* html */ `<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
|
@ -398,6 +398,7 @@ return /* html */ `<!DOCTYPE html>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script nonce="${nonce}">
|
<script nonce="${nonce}">
|
||||||
|
(function(){var _rcToken="${token || ''}";})();
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
@ -605,7 +606,11 @@ return /* html */ `<!DOCTYPE html>
|
||||||
var ws, timer;
|
var ws, timer;
|
||||||
function connect() {
|
function connect() {
|
||||||
var wsProtocol = location.protocol === "https:" ? "wss:" : "ws:";
|
var wsProtocol = location.protocol === "https:" ? "wss:" : "ws:";
|
||||||
ws = new WebSocket(wsProtocol + "//" + location.host + "/ws");
|
var wsUrl = wsProtocol + "//" + location.host + "/ws";
|
||||||
|
if (typeof _rcToken !== "undefined" && _rcToken) {
|
||||||
|
wsUrl += "?token=" + encodeURIComponent(_rcToken);
|
||||||
|
}
|
||||||
|
ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
ws.onopen = function () {
|
ws.onopen = function () {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ export function startServer(pi: ExtensionAPI, ctx: ExtensionContext): Promise<Re
|
||||||
"Content-Security-Policy":
|
"Content-Security-Policy":
|
||||||
`default-src 'none'; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}'; connect-src 'self'; base-uri 'none'`,
|
`default-src 'none'; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}'; connect-src 'self'; base-uri 'none'`,
|
||||||
});
|
});
|
||||||
res.end(buildHTML(nonce));
|
res.end(buildHTML(nonce, token));
|
||||||
} else {
|
} else {
|
||||||
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
||||||
res.end("Not found");
|
res.end("Not found");
|
||||||
|
|
@ -350,7 +350,7 @@ export function startServerTailscale(pi: ExtensionAPI, ctx: ExtensionContext): P
|
||||||
"Content-Security-Policy":
|
"Content-Security-Policy":
|
||||||
`default-src 'none'; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}'; connect-src 'self'; base-uri 'none'`,
|
`default-src 'none'; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}'; connect-src 'self'; base-uri 'none'`,
|
||||||
});
|
});
|
||||||
res.end(buildHTML(nonce));
|
res.end(buildHTML(nonce, token));
|
||||||
} else {
|
} else {
|
||||||
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
||||||
res.end("Not found");
|
res.end("Not found");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue