aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/transport.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/transport.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport.js27
1 files changed, 27 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
index 853ae75..a0509a0 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
@@ -103,6 +103,7 @@ class MeshBayTransport {
set onStreamEnd(fn) { this._onStreamEnd = fn; }
set onStreamError(fn) { this._onStreamError = fn; }
set onIndexSync(fn) { this._onIndexSync = fn; }
+ set onUploadPolicy(fn) { this._onUploadPolicy = fn; }
get sessionKeys() { return this._sessionKeys; }
@@ -592,6 +593,24 @@ class MeshBayTransport {
* Only the node can do this: its roster decides who it serves. Removing them
* on the hub is the other half, and neither implies the other.
*/
+ /**
+ * Turn uploading by ordinary members on or off.
+ *
+ * Signed by the operator like any other privileged operation — the node
+ * refuses an unsigned one, which is what stops a member turning it back on.
+ */
+ async setMemberUpload(allowed, signFn) {
+ const msg = await this._sendAndWait({
+ type: 'member_upload', v: '0.1', allowed: Boolean(allowed),
+ });
+ if (msg.type === 'error') throw new Error(msg.detail);
+ if (msg.type === 'admin_challenge') {
+ return this._authorizeAdminOp(
+ msg, 'member_upload', allowed ? 'on' : 'off', signFn);
+ }
+ return msg;
+ }
+
async revokeMember(userId, signFn) {
const msg = await this._sendAndWait({
type: 'member_revoke', v: '0.1', user_id: userId,
@@ -1079,6 +1098,14 @@ class MeshBayTransport {
return;
}
+ // The operator changed who may upload. Unsolicited: it arrives at everyone
+ // connected, not only at whoever asked. It still has to reach a pending
+ // caller — the operator's own request resolves on this reply — so it falls
+ // through to the matching below rather than returning here.
+ if (msg.type === 'member_upload_ack' && this._onUploadPolicy) {
+ this._onUploadPolicy(Boolean(msg.allowed));
+ }
+
if (msg.type === 'index_sync' && msg.entries) {
if (this._onIndexSync) this._onIndexSync(msg);
const oldest = this._pending.entries().next();