openvibers/openvibe.live Commits

A follow Network took is notified by Network, not pushed from Live (roadmap WS-E task 3, D08; Network 8188c26). Both follow routes pushed a FOLLOW notification over Network's internal route for every follow. Network now sends one itself when a follow starts in its graph, so the routes push only when writeThrough says Network did not take the follow (w.network false: FOLLOWS_AUTHORITY unset, or a side with no Network subject), which keeps the rollback path notifying. The PowerChat follow alert and the OpenCoins award stay here. test/network-follows.test.js checks that each route pushes FOLLOW only under !w.network. npm test 150/150.

OP OpenVibers committed 28 Sept 2026 · a70f562c26 · 2 files, +9 −4


Changes

ddiff --git a/server/streaming/routes.js b/server/streaming/routes.js
iindex 10db1697..72fb1927 100644
---- a/server/streaming/routes.js
++++ b/server/streaming/routes.js
@@@ -2377,8 +2377,9 @@ router.post('/:id/follow', requireAuth, async (req, res) => {
externalId: 'u' + req.user.id,
});
} catch { /* non-critical */ }
-- // Notify the followed user
-- try {
++ // Notify the followed user. A follow Network took notifies there (its follow graph sends FOLLOW);
++ // only a Live-only follow (FOLLOWS_AUTHORITY unset, or a side with no subject) is pushed from here.
++ if (!w.network) try {
const { pushNotification, actorInfo } = require('../utils/notify');
const follower = db.getUserById(req.user.id);
pushNotification({
@@@ -2425,8 +2426,8 @@ router.post('/channel/:username/follow', requireAuth, async (req, res) => {
externalId: 'u' + req.user.id,
});
} catch { /* non-critical */ }
-- // Notify the followed user
-- try {
++ // Notify the followed user, unless Network took the follow and notifies (see the route above).
++ if (!w.network) try {
const { pushNotification, actorInfo } = require('../utils/notify');
const follower = db.getUserById(req.user.id);
pushNotification({
ddiff --git a/test/network-follows.test.js b/test/network-follows.test.js
iindex 3b400d2d..ef121e54 100644
---- a/test/network-follows.test.js
++++ b/test/network-follows.test.js
@@@ -69,6 +69,10 @@ link.run(1, '101', ANN); link.run(2, '102', BOB); link.run(3, '103', CAT);
const body = routes.slice(routes.indexOf(route), routes.indexOf(route) + 1200);
assert.ok(body.indexOf('writeThrough(') > 0 && body.indexOf('writeThrough(') < body.indexOf('db.followUser('), `${route} writes Network first`);
assert.match(body, /if \(!w\.ok\) return res\.status\(503\)/);
++ // A follow Network took is notified by Network (FOLLOW from its follow graph); Live pushes only a Live-only one.
++ const whole = routes.slice(routes.indexOf(route), routes.indexOf('\nrouter.', routes.indexOf(route) + 1));
++ assert.match(whole, /if \(!w\.network\) try \{\s*const \{ pushNotification/, `${route} leaves a Network follow's notification to Network`);
++ assert.strictEqual((whole.match(/type: 'FOLLOW'/g) || []).length, 1);
}
// Live subscribes to the follow events.
assert.match(fs.readFileSync(path.join(__dirname, '..', 'scripts', 'subscribe-media-events.js'), 'utf8'), /'network\.follow\.created', 'network\.follow\.deleted'/);