Fix SVG dataset crash and 403 on intent API
- Remove `dataset = {}` assignment on SVG circle element (read-only
property on SVGElement, causes TypeError crash on every render)
- Add authHeaders() helper using encryptid-token from localStorage
- Include Authorization header on all mutating intent API calls
(create, solver/run, accept, reject)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2907935c50
commit
1dcc3ff0a1
|
|
@ -323,6 +323,12 @@ class FolkTimebankApp extends HTMLElement {
|
||||||
return match ? match[0] : '/rtime';
|
return match ? match[0] : '/rtime';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Auth headers from encryptid session token. */
|
||||||
|
private authHeaders(): Record<string, string> {
|
||||||
|
const token = localStorage.getItem('encryptid-token');
|
||||||
|
return token ? { Authorization: `Bearer ${token}` } : {};
|
||||||
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
if (this.animFrame) cancelAnimationFrame(this.animFrame);
|
if (this.animFrame) cancelAnimationFrame(this.animFrame);
|
||||||
}
|
}
|
||||||
|
|
@ -968,7 +974,7 @@ class FolkTimebankApp extends HTMLElement {
|
||||||
portHit.setAttribute('cx', String(pts[1][0])); portHit.setAttribute('cy', String(pts[1][1]));
|
portHit.setAttribute('cx', String(pts[1][0])); portHit.setAttribute('cy', String(pts[1][1]));
|
||||||
portHit.setAttribute('r', '18'); portHit.setAttribute('fill', 'transparent');
|
portHit.setAttribute('r', '18'); portHit.setAttribute('fill', 'transparent');
|
||||||
portHit.setAttribute('class', 'port');
|
portHit.setAttribute('class', 'port');
|
||||||
(portHit as any).dataset = {}; portHit.setAttribute('data-node', node.id); portHit.setAttribute('data-port', 'output');
|
portHit.setAttribute('data-node', node.id); portHit.setAttribute('data-port', 'output');
|
||||||
g.appendChild(portHit);
|
g.appendChild(portHit);
|
||||||
const port = ns('circle');
|
const port = ns('circle');
|
||||||
port.setAttribute('cx', String(pts[1][0])); port.setAttribute('cy', String(pts[1][1]));
|
port.setAttribute('cx', String(pts[1][0])); port.setAttribute('cy', String(pts[1][1]));
|
||||||
|
|
@ -1458,7 +1464,7 @@ class FolkTimebankApp extends HTMLElement {
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`${this.getApiBase()}/api/intent`, {
|
const resp = await fetch(`${this.getApiBase()}/api/intent`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json', ...this.authHeaders() },
|
||||||
body: JSON.stringify({ type, skill, hours, description }),
|
body: JSON.stringify({ type, skill, hours, description }),
|
||||||
});
|
});
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
|
|
@ -1475,7 +1481,7 @@ class FolkTimebankApp extends HTMLElement {
|
||||||
|
|
||||||
private async triggerSolver() {
|
private async triggerSolver() {
|
||||||
try {
|
try {
|
||||||
await fetch(`${this.getApiBase()}/api/solver/run`, { method: 'POST' });
|
await fetch(`${this.getApiBase()}/api/solver/run`, { method: 'POST', headers: this.authHeaders() });
|
||||||
this.refreshCollaborate();
|
this.refreshCollaborate();
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
|
|
@ -1607,7 +1613,7 @@ class FolkTimebankApp extends HTMLElement {
|
||||||
btn.addEventListener('click', async () => {
|
btn.addEventListener('click', async () => {
|
||||||
const resultId = (btn as HTMLElement).dataset.resultId;
|
const resultId = (btn as HTMLElement).dataset.resultId;
|
||||||
try {
|
try {
|
||||||
await fetch(`${this.getApiBase()}/api/solver-results/${resultId}/accept`, { method: 'POST' });
|
await fetch(`${this.getApiBase()}/api/solver-results/${resultId}/accept`, { method: 'POST', headers: this.authHeaders() });
|
||||||
this.refreshCollaborate();
|
this.refreshCollaborate();
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
});
|
});
|
||||||
|
|
@ -1617,7 +1623,7 @@ class FolkTimebankApp extends HTMLElement {
|
||||||
btn.addEventListener('click', async () => {
|
btn.addEventListener('click', async () => {
|
||||||
const resultId = (btn as HTMLElement).dataset.resultId;
|
const resultId = (btn as HTMLElement).dataset.resultId;
|
||||||
try {
|
try {
|
||||||
await fetch(`${this.getApiBase()}/api/solver-results/${resultId}/reject`, { method: 'POST' });
|
await fetch(`${this.getApiBase()}/api/solver-results/${resultId}/reject`, { method: 'POST', headers: this.authHeaders() });
|
||||||
this.refreshCollaborate();
|
this.refreshCollaborate();
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue