summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/connection-pool.js14
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/de.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/en.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/es.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/it.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js1
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/search-page.js24
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport.js16
13 files changed, 60 insertions, 4 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/connection-pool.js b/packages/meshbay-hub/src/meshbay_hub/static/connection-pool.js
index 15d352a7..8a616c2a 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/connection-pool.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/connection-pool.js
@@ -58,6 +58,12 @@ const SEARCH_MAX_MS = 30000;
* opened fine from the sidebar. A refusal naming a state of this browser (a
* code, a passphrase, a device) is the same from every node and stops the
* walk; `not_hosted`, a timeout or a failed connection moves on.
+ *
+ * So does a node this device refuses to reach on the local network (Android
+ * 17, Chrome 155: transport.js localNetworkRefused): another node of the group
+ * may be elsewhere. Search gives up long before connect() would name it, so it
+ * is read from the connection when giving up, and it is what is thrown when
+ * no node answered: the page says what to change rather than "unreachable".
*/
async function connectToGroup(hubBase, groupId, token, bundleKey, username, userId) {
const nodesData = await hubFetch(`/v1/groups/${groupId}/nodes`, { token });
@@ -65,6 +71,7 @@ async function connectToGroup(hubBase, groupId, token, bundleKey, username, user
const live = (await ensureFreshToken()) || token;
let lastErr = null;
+ let lanErr = null;
for (const n of nodesData.nodes) {
const transport = new window.MeshBayTransport(hubBase, live);
transport.onNeedToken = async () => (await ensureFreshToken()) || token;
@@ -96,11 +103,16 @@ async function connectToGroup(hubBase, groupId, token, bundleKey, username, user
} catch (e) {
stopTimers();
lastErr = e;
+ if (!e.reason && await transport.localNetworkRefused()) {
+ lastErr = new Error('This device refused to reach the local network');
+ lastErr.reason = 'local_network_blocked';
+ }
try { transport.close(); } catch {}
+ if (lastErr.reason === 'local_network_blocked') { lanErr = lastErr; continue; }
if (e.reason && e.reason !== 'not_hosted') throw e;
}
}
- throw (lastErr || new Error('no node served this group'));
+ throw (lanErr || lastErr || new Error('no node served this group'));
}
// -- Connection pool ----------------------------------------------------------
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
index ae2dcfbf..228402c9 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/de.js
@@ -859,6 +859,7 @@ export default {
'search.hint': 'Tippen Sie einen Begriff ein, um in allen Ihren Gruppen zu suchen.',
'search.indexing': 'Indexierung von {done} / {total} Gruppen …',
'search.unreachable': { one: '{n} Gruppe nicht erreichbar', other: '{n} Gruppen nicht erreichbar' },
+ 'search.lan_blocked': { one: "Dieses Gerät verweigert den Zugriff auf das lokale Netzwerk, in dem der Node dieser Gruppe ist. Öffnen Sie sie, um zu sehen, wie Sie ihn erlauben:", other: "Dieses Gerät verweigert den Zugriff auf das lokale Netzwerk, in dem die Nodes dieser {n} Gruppen sind. Öffnen Sie eine, um zu sehen, wie Sie ihn erlauben:" },
'search.n_sources': { one: '{n} Quelle', other: '{n} Quellen' },
'search.view_files': 'Dateien',
'search.view_videos': 'Videos',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
index e5ed9cb3..40c20244 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/en.js
@@ -976,6 +976,7 @@ export default {
'search.hint': 'Type to search file names across all your groups.',
'search.indexing': 'Indexing {done} / {total} groups...',
'search.unreachable': { one: '{n} group unreachable', other: '{n} groups unreachable' },
+ 'search.lan_blocked': { one: "This device refuses to reach the local network, where this group's node is. Open it to see how to allow it:", other: "This device refuses to reach the local network, where the nodes of these {n} groups are. Open one to see how to allow it:" },
'search.n_sources': { one: '{n} source', other: '{n} sources' },
'search.view_files': 'Files',
'search.view_videos': 'Videos',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
index 9801f741..643fdeab 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/es.js
@@ -854,6 +854,7 @@ export default {
'search.hint': 'Escriba un término para buscar en todos sus grupos.',
'search.indexing': 'Indexando {done} / {total} grupos…',
'search.unreachable': { one: '{n} grupo inalcanzable', other: '{n} grupos inalcanzables' },
+ 'search.lan_blocked': { one: "Este dispositivo se niega a acceder a la red local, donde está el node de este grupo. Ábralo para ver cómo permitirlo:", other: "Este dispositivo se niega a acceder a la red local, donde están los nodes de estos {n} grupos. Abra uno para ver cómo permitirlo:" },
'search.n_sources': { one: '{n} fuente', other: '{n} fuentes' },
'search.view_files': 'Archivos',
'search.view_videos': 'Vídeos',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
index b0dfd37b..8df543e4 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
@@ -857,6 +857,7 @@ export default {
'search.hint': 'Saisissez un terme pour rechercher dans tous vos groupes.',
'search.indexing': 'Indexation de {done} / {total} groupes…',
'search.unreachable': { one: '{n} groupe injoignable', other: '{n} groupes injoignables' },
+ 'search.lan_blocked': { one: "Cet appareil refuse de joindre le réseau local, où se trouve le node de ce groupe. Ouvrez-le pour savoir comment l’autoriser :", other: "Cet appareil refuse de joindre le réseau local, où se trouvent les nodes de ces {n} groupes. Ouvrez-en un pour savoir comment l’autoriser :" },
'search.n_sources': { one: '{n} source', other: '{n} sources' },
'search.view_files': 'Fichiers',
'search.view_videos': 'Vidéos',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
index 22e09deb..8912af69 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/it.js
@@ -856,6 +856,7 @@ export default {
'search.hint': 'Digita un termine per cercare in tutti i tuoi gruppi.',
'search.indexing': 'Indicizzazione di {done} / {total} gruppi…',
'search.unreachable': { one: '{n} gruppo non raggiungibile', other: '{n} gruppi non raggiungibili' },
+ 'search.lan_blocked': { one: "Questo dispositivo rifiuta di raggiungere la rete locale, dove si trova il node di questo gruppo. Aprilo per vedere come consentirlo:", other: "Questo dispositivo rifiuta di raggiungere la rete locale, dove si trovano i node di questi {n} gruppi. Aprine uno per vedere come consentirlo:" },
'search.n_sources': { one: '{n} fonte', other: '{n} fonti' },
'search.view_files': 'File',
'search.view_videos': 'Video',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
index a4645ac3..01a84dc9 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/ja.js
@@ -844,6 +844,7 @@ export default {
'search.hint': '入力してすべてのグループを検索します。',
'search.indexing': '{done} / {total} グループをインデックス中…',
'search.unreachable': { other: '{n} グループに接続できません' },
+ 'search.lan_blocked': { other: "このデバイスはローカルネットワークへの接続を拒否しています。このネットワークに {n} 件のグループの node があります。グループを開くと、許可する方法が表示されます:" },
'search.n_sources': { other: '{n} 個のソース' },
'search.view_files': 'ファイル',
'search.view_videos': '動画',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
index 0f31f6cb..dec9e9f5 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/nl.js
@@ -858,6 +858,7 @@ export default {
'search.hint': 'Typ een zoekterm om in al uw groepen te zoeken.',
'search.indexing': '{done} / {total} groepen indexeren…',
'search.unreachable': { one: '{n} groep onbereikbaar', other: '{n} groepen onbereikbaar' },
+ 'search.lan_blocked': { one: "Dit apparaat weigert het lokale netwerk te bereiken, waar de node van deze groep staat. Open hem om te zien hoe je het toestaat:", other: "Dit apparaat weigert het lokale netwerk te bereiken, waar de nodes van deze {n} groepen staan. Open er een om te zien hoe je het toestaat:" },
'search.n_sources': { one: '{n} bron', other: '{n} bronnen' },
'search.view_files': 'Bestanden',
'search.view_videos': 'Video\'s',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
index c89a60d3..0de71416 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pl.js
@@ -878,6 +878,7 @@ export default {
'search.hint': 'Wpisz frazę, aby wyszukać we wszystkich grupach.',
'search.indexing': 'Indeksowanie {done} / {total} grup…',
'search.unreachable': { one: '{n} grupa nieosiągalna', few: '{n} grupy nieosiągalne', many: '{n} grup nieosiągalnych', other: '{n} grupy nieosiągalnej' },
+ 'search.lan_blocked': { one: "To urządzenie odmawia połączenia z siecią lokalną, w której jest node tej grupy. Otwórz ją, aby zobaczyć, jak na to zezwolić:", few: "To urządzenie odmawia połączenia z siecią lokalną, w której są node’y tych {n} grup. Otwórz jedną, aby zobaczyć, jak na to zezwolić:", many: "To urządzenie odmawia połączenia z siecią lokalną, w której są node’y tych {n} grup. Otwórz jedną, aby zobaczyć, jak na to zezwolić:", other: "To urządzenie odmawia połączenia z siecią lokalną, w której są node’y tych {n} grup. Otwórz jedną, aby zobaczyć, jak na to zezwolić:" },
'search.n_sources': { one: '{n} źródło', few: '{n} źródła', many: '{n} źródeł', other: '{n} źródła' },
'search.view_files': 'Pliki',
'search.view_videos': 'Filmy',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
index aa33e177..89e854c1 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/pt-BR.js
@@ -855,6 +855,7 @@ export default {
'search.hint': 'Digite um termo para pesquisar em todos os seus grupos.',
'search.indexing': 'Indexando {done} / {total} grupos…',
'search.unreachable': { one: '{n} grupo inacessível', other: '{n} grupos inacessíveis' },
+ 'search.lan_blocked': { one: "Este dispositivo se recusa a acessar a rede local, onde está o node deste grupo. Abra-o para ver como permitir:", other: "Este dispositivo se recusa a acessar a rede local, onde estão os nodes destes {n} grupos. Abra um para ver como permitir:" },
'search.n_sources': { one: '{n} fonte', other: '{n} fontes' },
'search.view_files': 'Arquivos',
'search.view_videos': 'Vídeos',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
index 27f20dc7..08bf5593 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/zh-CN.js
@@ -832,6 +832,7 @@ export default {
'search.hint': '输入关键词搜索所有群组。',
'search.indexing': '正在索引 {done} / {total} 个群组…',
'search.unreachable': { other: '{n} 个群组无法连接' },
+ 'search.lan_blocked': { other: "此设备拒绝访问本地网络,而 {n} 个群组的 node 就在该网络中。打开群组即可查看如何允许:" },
'search.n_sources': { other: '{n} 个来源' },
'search.view_files': '文件',
'search.view_videos': '视频',
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/search-page.js b/packages/meshbay-hub/src/meshbay_hub/static/search-page.js
index ae8eac75..d0150a8e 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/search-page.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/search-page.js
@@ -15,6 +15,7 @@ import { VideoPlayer } from './video-player.js';
import { transfers } from './transfers.js';
import { copyLink, entryPath, groupItemLink } from './copy-link.js';
import { say } from './note.js';
+import { groupLinkRoute } from './group-link.js';
import { mergeUnitEntries } from './source-merge.js';
import { useStickyBand } from './sticky.js';
import { ConnectionPool, MAX_IN_FLIGHT, MAX_POOL_SIZE } from './connection-pool.js';
@@ -139,6 +140,9 @@ async function fetchAllIndexes(pool, groups, token, username, userId, onProgress
const total = groups.length;
let done = 0;
const unreachable = [];
+ // Groups whose node this device refused to reach on the local network: a
+ // setting to change, said apart from the groups that did not answer.
+ const lanBlocked = [];
const downNow = new Set();
const results = new Map();
@@ -168,7 +172,8 @@ async function fetchAllIndexes(pool, groups, token, username, userId, onProgress
downNow.add(g.id);
}
} catch (e) {
- unreachable.push(g.name || g.id);
+ if (e && e.reason === 'local_network_blocked') lanBlocked.push(g);
+ else unreachable.push(g.name || g.id);
// Still refused after transport.js's retries: the hub was busy, which
// says nothing about this group's node, so it keeps its place next time.
if (!(e && e.status === 429)) downNow.add(g.id);
@@ -179,7 +184,7 @@ async function fetchAllIndexes(pool, groups, token, username, userId, onProgress
// A sweep cut short by the page closing saw nothing about any node: every
// group left was refused by this page, not by its node.
if (!(pool && pool.closed)) rememberDown(downNow);
- return { results, unreachable };
+ return { results, unreachable, lanBlocked };
}
// -- SearchPage ---------------------------------------------------------------
@@ -263,6 +268,7 @@ function SearchPage({ token, username, userId, groups, onPlayQueue, userPrefs })
const [indexedGroups, setIndexedGroups] = useState(new Map());
const [progress, setProgress] = useState({ done: 0, total: 0, unreachable: [] });
const [fetching, setFetching] = useState(false);
+ const [lanBlocked, setLanBlocked] = useState([]);
// Bumped by the Files breadcrumb refresh button — re-runs the all-groups
// index fetch below, the only "cache" this page has.
const [refreshTick, setRefreshTick] = useState(0);
@@ -314,9 +320,10 @@ function SearchPage({ token, username, userId, groups, onPlayQueue, userPrefs })
(async () => {
setFetching(true);
setProgress({ done: 0, total: groups.length, unreachable: [] });
+ setLanBlocked([]);
if (!poolRef.current) return;
- const { unreachable } = await fetchAllIndexes(
+ const { unreachable, lanBlocked: refused } = await fetchAllIndexes(
poolRef.current, groups, token, username, userId,
(p) => { if (!cancelled) setProgress(p); },
(results) => { if (!cancelled) setIndexedGroups(new Map(results)); },
@@ -324,6 +331,9 @@ function SearchPage({ token, username, userId, groups, onPlayQueue, userPrefs })
if (cancelled) return;
setFetching(false);
+ // Left up, unlike the line below: there is something to do about it,
+ // and the group page says what (group-page.js explainLanRefusal).
+ setLanBlocked(refused);
// Said once the pass is over, for a few seconds, rather than left above
// the results: by then nothing more can be done about it here, and a
// line that stays is one more thing between the reader and the results.
@@ -714,6 +724,14 @@ function SearchPage({ token, username, userId, groups, onPlayQueue, userPrefs })
`}
</div>
+ ${lanBlocked.length > 0 && html`
+ <p class="settings-hint">
+ ${t('search.lan_blocked', { n: lanBlocked.length })}${' '}
+ ${lanBlocked.map((g, i) => html`${i ? ', ' : ''}<a
+ href=${'#' + groupLinkRoute(g)}>${g.name || g.id}</a>`)}
+ </p>
+ `}
+
${fetching && html`
<div class="search-progress">
<span class="spinner"></span>
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
index 11088adc..98a6ecfa 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
@@ -844,6 +844,21 @@ class MeshBayTransport {
this._wakeReconnect();
}
+ /**
+ * Whether the connection being made is refused the local network, read from
+ * what is paired so far: the signature is there as soon as ICE checks
+ * begin, where connect() names it only once ICE gives up, half a minute.
+ * For a caller that stops waiting before that (connection-pool.js).
+ */
+ async localNetworkRefused() {
+ const pc = this._pc;
+ if (!pc || !this._rawAnswerSdp || !pc.localDescription) return false;
+ if (pc.iceConnectionState === 'connected' || pc.iceConnectionState === 'completed') {
+ return false;
+ }
+ return _localNetworkRefusedBy(pc, pc.localDescription.sdp, this._rawAnswerSdp);
+ }
+
get connected() { return this._connected; }
/** True while _reconnectLoop is running, backoff included. */
get reconnecting() { return !!this._reconnectPromise; }
@@ -1015,6 +1030,7 @@ class MeshBayTransport {
// the composer, exactly like one that had.
this._setDevicePk('', 'new connection');
this._sessionUp = false;
+ this._rawAnswerSdp = null;
this._pc = new RTCPeerConnection({ iceServers: await iceServers() });
this._channel = this._pc.createDataChannel('mnp', { ordered: true });