diff --git a/muxplex/frontend/app.js b/muxplex/frontend/app.js
index 35f750a..5b7fc2b 100644
--- a/muxplex/frontend/app.js
+++ b/muxplex/frontend/app.js
@@ -463,6 +463,11 @@ function buildTileHTML(session, index, mobile) {
bellHtml = `${countStr}`;
}
+ // Device badge (shown when multiple sources configured and session has a device name)
+ const badgeHtml = _sources.length > 1 && session.deviceName
+ ? `${escapeHtml(session.deviceName)}`
+ : '';
+
// Last 20 lines of snapshot
const snapshot = session.snapshot || '';
const lastLines = snapshot.split('\n').slice(-20).join('\n');
@@ -470,7 +475,7 @@ function buildTileHTML(session, index, mobile) {
return (
`` +
`` +
`` +
diff --git a/muxplex/frontend/tests/test_app.mjs b/muxplex/frontend/tests/test_app.mjs
index be83e7a..c29ad4c 100644
--- a/muxplex/frontend/tests/test_app.mjs
+++ b/muxplex/frontend/tests/test_app.mjs
@@ -2371,8 +2371,20 @@ test('buildTileHTML includes data-session-key and data-source-url attributes on
snapshot: '',
};
const html = app.buildTileHTML(session, 0, false);
- assert.ok(html.includes('data-session-key='), 'article should have data-session-key attribute');
- assert.ok(html.includes('data-source-url='), 'article should have data-source-url attribute');
+ assert.ok(html.includes('data-session-key="https://remote.example.com::work"'), 'article should have data-session-key with correct value');
+ assert.ok(html.includes('data-source-url="https://remote.example.com"'), 'article should have data-source-url with correct value');
+});
+
+test('buildTileHTML escapes HTML in deviceName within device-badge', () => {
+ app._setSources([
+ { url: '', name: 'This device', type: 'local', status: 'authenticated', backoffMs: 2000 },
+ { url: 'https://remote.example.com', name: 'Remote', type: 'remote', status: 'authenticated', backoffMs: 2000 },
+ ]);
+ const session = { name: 'work', deviceName: '', sourceUrl: '', sessionKey: '::work', snapshot: '' };
+ const html = app.buildTileHTML(session, 0, false);
+ assert.ok(!html.includes('