← back to Dw Marketing Reels
chore: harden /api/youtube (escapeAttr href, strict video-id regex), v0.9.1 (session close)
69537a313ef297247dde2c02bec9b5abeeb69fce · 2026-08-25 10:55:58 -0700 · steve
Files touched
M package-lock.jsonM package.jsonM public/index.htmlM server.js
Diff
commit 69537a313ef297247dde2c02bec9b5abeeb69fce
Author: steve <steve@designerwallcoverings.com>
Date: Tue Aug 25 10:55:58 2026 -0700
chore: harden /api/youtube (escapeAttr href, strict video-id regex), v0.9.1 (session close)
---
package-lock.json | 4 ++--
package.json | 2 +-
public/index.html | 2 +-
server.js | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6c141e5..4aefc16 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "dw-marketing-reels",
- "version": "0.9.0",
+ "version": "0.9.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "dw-marketing-reels",
- "version": "0.9.0"
+ "version": "0.9.1"
}
}
}
diff --git a/package.json b/package.json
index 2489f36..6aa016b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "dw-marketing-reels",
- "version": "0.9.0",
+ "version": "0.9.1",
"private": true,
"type": "module",
"description": "DW Marketing — auto-generated New Arrivals reels (HyperFrames) + auth-gated console",
diff --git a/public/index.html b/public/index.html
index b5e1027..6b9d986 100644
--- a/public/index.html
+++ b/public/index.html
@@ -417,7 +417,7 @@ $('#videos').addEventListener('click', async e => {
body: JSON.stringify({ path: b.dataset.path }) })).json();
if (j.ok) {
b.textContent = '✓ On YouTube';
- if (out) out.innerHTML = `✓ Uploaded <b>unlisted</b> · <a href="${j.watch}" target="_blank" rel="noopener">${escapeHtml(j.watch)}</a> — flip to Public in YouTube Studio.`;
+ if (out) out.innerHTML = `✓ Uploaded <b>unlisted</b> · <a href="${escapeAttr(j.watch)}" target="_blank" rel="noopener">${escapeHtml(j.watch)}</a> — flip to Public in YouTube Studio.`;
} else {
b.disabled = false; b.textContent = label;
if (out) out.textContent = '✗ ' + (j.error || 'upload failed');
diff --git a/server.js b/server.js
index d1abec0..5573b08 100644
--- a/server.js
+++ b/server.js
@@ -322,7 +322,7 @@ const server = http.createServer(async (req, res) => {
ch.on('close', code => resolve({ code, out }));
});
building = false; lastLog += `\n[youtube exit ${result.code}]`;
- const m = /UPLOAD_OK\s+(\S+)/.exec(result.out);
+ const m = /UPLOAD_OK\s+([A-Za-z0-9_-]{6,32})/.exec(result.out);
if (result.code === 0 && m) return res.writeHead(200, { 'content-type': 'application/json' })
.end(JSON.stringify({ ok: true, id: m[1], watch: 'https://youtu.be/' + m[1], privacy: 'unlisted' }));
return res.writeHead(502, { 'content-type': 'application/json' })
← b778dff publish-ig.mjs: resolve per-account ig_user_id (--account /
·
back to Dw Marketing Reels
·
5x: verify accounts console clean twice (35 ready/5 pending) 1e97884 →