roster changes:
* validate that a user can add a role before adding them * support deletion of non-required metadata attributes via null
This commit is contained in:
parent
8761e2071a
commit
2a809cf120
@ -525,6 +525,26 @@ nThen(function (w) {
|
|||||||
}
|
}
|
||||||
console.log("Promoted Alice to ADMIN");
|
console.log("Promoted Alice to ADMIN");
|
||||||
}));
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
var data = {};
|
||||||
|
data[bob.curveKeys.curvePublic] = {
|
||||||
|
notifications: Hash.createChannelId(),
|
||||||
|
displayName: "BORB",
|
||||||
|
};
|
||||||
|
|
||||||
|
alice.roster.add(data, w(function (err) {
|
||||||
|
if (err === 'ALREADY_PRESENT' || err === 'NO_CHANGE') {
|
||||||
|
return void console.log("Duplicate add command failed as expected");
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
console.error("Unexpected error", err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (!err) {
|
||||||
|
console.log("Duplicate add succeeded unexpectedly");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
}).nThen(function (w) {
|
}).nThen(function (w) {
|
||||||
alice.roster.checkpoint(w(function (err) {
|
alice.roster.checkpoint(w(function (err) {
|
||||||
if (!err) { return; }
|
if (!err) { return; }
|
||||||
@ -539,6 +559,16 @@ nThen(function (w) {
|
|||||||
console.error(err);
|
console.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}));
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
alice.roster.remove([
|
||||||
|
oscar.curveKeys.curvePublic,
|
||||||
|
], w(function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.error("Removal of owner by admin succeeded unexpectedly");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.log("Removal of owner by admin failed as expected");
|
||||||
|
}));
|
||||||
}).nThen(function (w) {
|
}).nThen(function (w) {
|
||||||
// bob finally connects, this time with the lastKnownHash provided by oscar
|
// bob finally connects, this time with the lastKnownHash provided by oscar
|
||||||
var rosterKeys = Crypto.Team.deriveMemberKeys(sharedConfig.rosterSeed, bob.curveKeys);
|
var rosterKeys = Crypto.Team.deriveMemberKeys(sharedConfig.rosterSeed, bob.curveKeys);
|
||||||
@ -581,16 +611,109 @@ nThen(function (w) {
|
|||||||
}
|
}
|
||||||
console.log("'add' by member failed as expected");
|
console.log("'add' by member failed as expected");
|
||||||
}));
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
bob.roster.remove([
|
||||||
|
alice.curveKeys.curvePublic,
|
||||||
|
], w(function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.error("Removal of admin by member succeeded unexpectedly");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.log("Removal of admin by member failed as expected");
|
||||||
|
}));
|
||||||
}).nThen(function (w) {
|
}).nThen(function (w) {
|
||||||
bob.roster.remove([
|
bob.roster.remove([
|
||||||
oscar.curveKeys.curvePublic,
|
oscar.curveKeys.curvePublic,
|
||||||
alice.curveKeys.curvePublic
|
//alice.curveKeys.curvePublic
|
||||||
], w(function (err) {
|
], w(function (err) {
|
||||||
if (err) { return void console.log("command failed as expected"); }
|
if (err) { return void console.log("command failed as expected"); }
|
||||||
w.abort();
|
w.abort();
|
||||||
console.log("Expected command to fail!");
|
console.log("Expected command to fail!");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}));
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
var data = {};
|
||||||
|
data[bob.curveKeys.curvePublic] = {
|
||||||
|
displayName: 'BORB',
|
||||||
|
};
|
||||||
|
|
||||||
|
bob.roster.describe(data, w(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error("self-description by a member failed unexpectedly");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
var data = {};
|
||||||
|
data[oscar.curveKeys.curvePublic] = {
|
||||||
|
displayName: 'NULL',
|
||||||
|
};
|
||||||
|
|
||||||
|
bob.roster.describe(data, w(function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.error("description of an owner by a member succeeded unexpectedly");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.log("description of an owner by a member failed as expected");
|
||||||
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
var data = {};
|
||||||
|
data[alice.curveKeys.curvePublic] = {
|
||||||
|
displayName: 'NULL',
|
||||||
|
};
|
||||||
|
|
||||||
|
bob.roster.describe(data, w(function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.error("description of an admin by a member succeeded unexpectedly");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.log("description of an admin by a member failed as expected");
|
||||||
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
var data = {};
|
||||||
|
data[bob.curveKeys.curvePublic] = {
|
||||||
|
displayName: "NULL",
|
||||||
|
};
|
||||||
|
|
||||||
|
alice.roster.describe(data, w(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error("Description of member by admin failed unexpectedly");
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
alice.roster.metadata({
|
||||||
|
name: "BEST TEAM",
|
||||||
|
topic: "Champions de monde!",
|
||||||
|
cheese: "Camembert",
|
||||||
|
}, w(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error("Metadata change by admin failed unexpectedly");
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
bob.roster.metadata({
|
||||||
|
name: "WORST TEAM",
|
||||||
|
topic: "not a good team",
|
||||||
|
}, w(function (err) {
|
||||||
|
if (!err) {
|
||||||
|
console.error("Metadata change by member should have failed");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}).nThen(function (w) {
|
||||||
|
oscar.roster.metadata({
|
||||||
|
cheese: null, // delete a field that you don't want presenet
|
||||||
|
}, w(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
}).nThen(function (w) {
|
}).nThen(function (w) {
|
||||||
alice.roster.remove([bob.curveKeys.curvePublic], w(function (err) {
|
alice.roster.remove([bob.curveKeys.curvePublic], w(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@ -171,6 +171,10 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||||||
// if no role was provided, assume MEMBER
|
// if no role was provided, assume MEMBER
|
||||||
if (typeof(data.role) !== 'string') { data.role = 'MEMBER'; }
|
if (typeof(data.role) !== 'string') { data.role = 'MEMBER'; }
|
||||||
|
|
||||||
|
if (!canAddRole(author, data.role, members)) {
|
||||||
|
throw new Error("INSUFFICIENT_PERMISSIONS");
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof(data.displayName) !== 'string') { throw new Error("DISPLAYNAME_REQUIRED"); }
|
if (typeof(data.displayName) !== 'string') { throw new Error("DISPLAYNAME_REQUIRED"); }
|
||||||
if (typeof(data.notifications) !== 'string') { throw new Error("NOTIFICATIONS_REQUIRED"); }
|
if (typeof(data.notifications) !== 'string') { throw new Error("NOTIFICATIONS_REQUIRED"); }
|
||||||
});
|
});
|
||||||
@ -178,12 +182,9 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||||||
var changed = false;
|
var changed = false;
|
||||||
// then iterate again and apply it
|
// then iterate again and apply it
|
||||||
Object.keys(args).forEach(function (curve) {
|
Object.keys(args).forEach(function (curve) {
|
||||||
var data = args[curve];
|
|
||||||
if (!canAddRole(author, data.role, members)) { return; }
|
|
||||||
|
|
||||||
// this will result in a change
|
// this will result in a change
|
||||||
changed = true;
|
changed = true;
|
||||||
members[curve] = data;
|
members[curve] = args[curve];
|
||||||
});
|
});
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
@ -322,6 +323,12 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var MANDATORY_METADATA_FIELDS = [
|
||||||
|
'avatar',
|
||||||
|
'name',
|
||||||
|
'topic',
|
||||||
|
];
|
||||||
|
|
||||||
// only admin/owner can change group metadata
|
// only admin/owner can change group metadata
|
||||||
commands.METADATA = function (args, author, roster) {
|
commands.METADATA = function (args, author, roster) {
|
||||||
if (!isMap(args)) { throw new Error("INVALID_ARGS"); }
|
if (!isMap(args)) { throw new Error("INVALID_ARGS"); }
|
||||||
@ -330,6 +337,11 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||||||
|
|
||||||
// validate inputs
|
// validate inputs
|
||||||
Object.keys(args).forEach(function (k) {
|
Object.keys(args).forEach(function (k) {
|
||||||
|
if (args[k] === null) {
|
||||||
|
if (MANDATORY_METADATA_FIELDS.indexOf(k) === -1) { return; }
|
||||||
|
throw new Error('CANNOT_REMOVE_MANDATORY_METADATA');
|
||||||
|
}
|
||||||
|
|
||||||
// can't set metadata to anything other than strings
|
// can't set metadata to anything other than strings
|
||||||
// use empty string to unset a value if you must
|
// use empty string to unset a value if you must
|
||||||
if (typeof(args[k]) !== 'string') { throw new Error("INVALID_ARGUMENTS"); }
|
if (typeof(args[k]) !== 'string') { throw new Error("INVALID_ARGUMENTS"); }
|
||||||
@ -338,6 +350,11 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto) {
|
|||||||
var changed = false;
|
var changed = false;
|
||||||
// {topic, name, avatar} are all strings...
|
// {topic, name, avatar} are all strings...
|
||||||
Object.keys(args).forEach(function (k) {
|
Object.keys(args).forEach(function (k) {
|
||||||
|
if (typeof(roster.state.metadata[k]) !== 'undefined' && args[k] === null) {
|
||||||
|
changed = true;
|
||||||
|
delete roster.state.metadata[k];
|
||||||
|
}
|
||||||
|
|
||||||
// ignore things that won't cause changes
|
// ignore things that won't cause changes
|
||||||
if (args[k] === roster.state.metadata[k]) { return; }
|
if (args[k] === roster.state.metadata[k]) { return; }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user