openvibers/openvibe.network Commits

A go-live notice never links to a section of a live channel (#776)

OP OpenVibers committed 3 days ago · e163c710ef · 2 files, +18 −4

Changes

ddiff --git a/server/notifications/stream-live.js b/server/notifications/stream-live.js
iindex c16f0e3f..6cba9e99 100644
---- a/server/notifications/stream-live.js
++++ b/server/notifications/stream-live.js
@@@ -15,9 +15,20 @@ function channelUrl(username) {
return `${LIVE_ORIGIN}/@${encodeURIComponent(String(username || '').replace(/^@+/, ''))}`;
}
function canonicalChannelUrl(url, username) {
-- const m = /^https:\/\/openvibe\.live\/([A-Za-z0-9_]{3,24})\/?$/.exec(String(url || ''));
-- if (m) return channelUrl(m[1]);
-- return url || channelUrl(username);
++ const raw = String(url || '').trim();
++ if (!raw) return channelUrl(username);
++ // A section (or a query naming one) is not part of a channel: /@name#about, /@name?section=videos and the old
++ // /name#about all hand over /@name, so a go-live notice never lands on About (ask 285). Other Live pages keep
++ // their own address, including any fragment that means something there.
++ try {
++ const u = new URL(raw);
++ if (u.origin === LIVE_ORIGIN) {
++ const m = /^\/(?:@)?([A-Za-z0-9_]{3,24})\/?$/.exec(u.pathname);
++ if (m) return channelUrl(m[1]);
++ }
++ } catch { /* not an absolute URL: the old-style check below */ }
++ const m = /^https:\/\/openvibe\.live\/([A-Za-z0-9_]{3,24})\/?$/.exec(raw);
++ return m ? channelUrl(m[1]) : raw;
}
/** One fan-out per streamer per `stream_live_cooldown_min` (60) and at most `stream_live_daily_cap` (8) per 24h. */
ddiff --git a/test/events-consumer.test.js b/test/events-consumer.test.js
iindex b7d0b91d..6155d1d5 100644
---- a/test/events-consumer.test.js
++++ b/test/events-consumer.test.js
@@@ -257,7 +257,10 @@ const rows = async (userId) => await db.prepare('SELECT * FROM notifications WHE
assert.strictEqual(channelUrl('@carol'), 'https://openvibe.live/@carol');
assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol', 'carol'), 'https://openvibe.live/@carol', 'a channel link is kept');
assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/', 'carol'), 'https://openvibe.live/@carol');
-- assert.strictEqual(canonicalChannelUrl('https://openvibe.live/vod/5', 'carol'), 'https://openvibe.live/vod/5', 'other Live pages are kept');
++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol#about', 'carol'), 'https://openvibe.live/@carol', 'a section is not part of a channel link');
++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/@carol?section=videos', 'carol'), 'https://openvibe.live/@carol', 'a section query is not either');
++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/carol/#clips', 'carol'), 'https://openvibe.live/@carol', 'nor on the old channel shape');
++ assert.strictEqual(canonicalChannelUrl('https://openvibe.live/vod/5#t=10', 'carol'), 'https://openvibe.live/vod/5#t=10', 'other Live pages keep their own address');
assert.strictEqual(canonicalChannelUrl(null, 'carol'), 'https://openvibe.live/@carol', 'no link: the channel page');
}
assert.strictEqual(n1.sender_id, 20, 'sender is the streamer\'s Network account (dedupe key)');