Update rights in inner
This commit is contained in:
@@ -544,7 +544,8 @@ define([
|
|||||||
Object.keys(folders).forEach(function (id) {
|
Object.keys(folders).forEach(function (id) {
|
||||||
var f = folders[id];
|
var f = folders[id];
|
||||||
var sfData = files.sharedFolders[id] || {};
|
var sfData = files.sharedFolders[id] || {};
|
||||||
var parsed = Hash.parsePadUrl(sfData.href || sfData.roHref);
|
var href = manager.user.userObject.getHref(sfData);
|
||||||
|
var parsed = Hash.parsePadUrl(href);
|
||||||
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
||||||
manager.addProxy(id, {proxy: f}, null, secret.keys.secondaryKey);
|
manager.addProxy(id, {proxy: f}, null, secret.keys.secondaryKey);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ define([
|
|||||||
var team;
|
var team;
|
||||||
Object.keys(myTeams).some(function (k) {
|
Object.keys(myTeams).some(function (k) {
|
||||||
var _team = myTeams[k];
|
var _team = myTeams[k];
|
||||||
if (_team.channel === content.teamChannel) {
|
if (_team.channel === content.teamData.channel) {
|
||||||
teamId = k;
|
teamId = k;
|
||||||
team = _team;
|
team = _team;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -990,6 +990,7 @@ define([
|
|||||||
uo.setReadOnly(!secret.keys.secondaryKey, secret.keys.secondaryKey);
|
uo.setReadOnly(!secret.keys.secondaryKey, secret.keys.secondaryKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ctx.updateMetadata();
|
||||||
ctx.emit('ROSTER_CHANGE_RIGHTS', teamId, team.clients);
|
ctx.emit('ROSTER_CHANGE_RIGHTS', teamId, team.clients);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1006,10 +1007,14 @@ define([
|
|||||||
teamData.hash = data.hash;
|
teamData.hash = data.hash;
|
||||||
teamData.keys.drive.edPrivate = data.keys.drive.edPrivate;
|
teamData.keys.drive.edPrivate = data.keys.drive.edPrivate;
|
||||||
teamData.keys.chat.edit = data.keys.chat.edit;
|
teamData.keys.chat.edit = data.keys.chat.edit;
|
||||||
|
|
||||||
|
var secret = Hash.getSecrets('team', data.hash, teamData.password);
|
||||||
|
team.secondaryKey = secret && secret.keys.secondaryKey;
|
||||||
} else {
|
} else {
|
||||||
delete teamData.hash;
|
delete teamData.hash;
|
||||||
delete teamData.keys.drive.edPrivate;
|
delete teamData.keys.drive.edPrivate;
|
||||||
delete teamData.keys.chat.edit;
|
delete teamData.keys.chat.edit;
|
||||||
|
delete team.secondaryKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMyRights(ctx, teamId, data.hash);
|
updateMyRights(ctx, teamId, data.hash);
|
||||||
@@ -1055,14 +1060,14 @@ define([
|
|||||||
|
|
||||||
// Viewer to editor
|
// Viewer to editor
|
||||||
if (user.role === "VIEWER" && data.data.role !== "VIEWER") {
|
if (user.role === "VIEWER" && data.data.role !== "VIEWER") {
|
||||||
return void changeEditRights(ctx, teamId, user, true, function (err) {
|
changeEditRights(ctx, teamId, user, true, function (err) {
|
||||||
return void cb({error: err});
|
return void cb({error: err});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editor to viewer
|
// Editor to viewer
|
||||||
if (user.role !== "VIEWER" && data.data.role === "VIEWER") {
|
if (user.role !== "VIEWER" && data.data.role === "VIEWER") {
|
||||||
return void changeEditRights(ctx, teamId, user, false, function (err) {
|
changeEditRights(ctx, teamId, user, false, function (err) {
|
||||||
return void cb({error: err});
|
return void cb({error: err});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,22 @@ define([
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var getSharedFolderData = function (Env, id) {
|
||||||
|
if (!Env.folders[id]) { return {}; }
|
||||||
|
var obj = Env.folders[id].proxy.metadata || {};
|
||||||
|
for (var k in Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {}) {
|
||||||
|
var data = JSON.parse(JSON.stringify(Env.user.proxy[UserObject.SHARED_FOLDERS][id][k]));
|
||||||
|
if (data.href && data.href.indexOf('#') === -1) {
|
||||||
|
try {
|
||||||
|
data.href = Env.user.userObject.cryptor.decrypt(data.href);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
obj[k] = data;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Transform an absolute path into a path relative to the correct shared folder
|
// Transform an absolute path into a path relative to the correct shared folder
|
||||||
var _resolvePath = function (Env, path) {
|
var _resolvePath = function (Env, path) {
|
||||||
var res = {
|
var res = {
|
||||||
@@ -979,6 +995,7 @@ define([
|
|||||||
setPadAttribute: callWithEnv(setPadAttribute),
|
setPadAttribute: callWithEnv(setPadAttribute),
|
||||||
getTagsList: callWithEnv(getTagsList),
|
getTagsList: callWithEnv(getTagsList),
|
||||||
getSecureFilesList: callWithEnv(getSecureFilesList),
|
getSecureFilesList: callWithEnv(getSecureFilesList),
|
||||||
|
getSharedFolderData: callWithEnv(getSharedFolderData),
|
||||||
// Store
|
// Store
|
||||||
getChannelsList: callWithEnv(getChannelsList),
|
getChannelsList: callWithEnv(getChannelsList),
|
||||||
addPad: callWithEnv(addPad),
|
addPad: callWithEnv(addPad),
|
||||||
@@ -1149,21 +1166,6 @@ define([
|
|||||||
return Env.user.userObject.getOwnedPads(Env.edPublic);
|
return Env.user.userObject.getOwnedPads(Env.edPublic);
|
||||||
};
|
};
|
||||||
|
|
||||||
var getSharedFolderData = function (Env, id) {
|
|
||||||
if (!Env.folders[id]) { return {}; }
|
|
||||||
var obj = Env.folders[id].proxy.metadata || {};
|
|
||||||
for (var k in Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {}) {
|
|
||||||
var data = JSON.parse(JSON.stringify(Env.user.proxy[UserObject.SHARED_FOLDERS][id][k]));
|
|
||||||
if (data.href && data.href.indexOf('#') === -1) {
|
|
||||||
try {
|
|
||||||
data.href = Env.user.userObject.cryptor.decrypt(data.href);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
obj[k] = data;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
var getFolderData = function (Env, path) {
|
var getFolderData = function (Env, path) {
|
||||||
var resolved = _resolvePath(Env, path);
|
var resolved = _resolvePath(Env, path);
|
||||||
if (!resolved || !resolved.userObject) { return {}; }
|
if (!resolved || !resolved.userObject) { return {}; }
|
||||||
|
|||||||
@@ -433,6 +433,10 @@ define([
|
|||||||
Cryptpad.mailbox.execCommand(data, cb);
|
Cryptpad.mailbox.execCommand(data, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sframeChan.on('Q_STORE_IN_TEAM', function (data, cb) {
|
||||||
|
Cryptpad.storeInTeam(data, cb);
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
addCommonRpc(sframeChan);
|
addCommonRpc(sframeChan);
|
||||||
|
|
||||||
@@ -465,10 +469,6 @@ define([
|
|||||||
setDocumentTitle();
|
setDocumentTitle();
|
||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_STORE_IN_TEAM', function (data, cb) {
|
|
||||||
Cryptpad.storeInTeam(data, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
sframeChan.on('EV_SET_HASH', function (hash) {
|
sframeChan.on('EV_SET_HASH', function (hash) {
|
||||||
window.location.hash = hash;
|
window.location.hash = hash;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,29 +29,46 @@ define([
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var createCryptor = module.createCryptor = function (key) {
|
||||||
|
var cryptor = {};
|
||||||
|
if (!key) {
|
||||||
|
cryptor.encrypt = function (x) { return x; };
|
||||||
|
cryptor.decrypt = function (x) { return x; };
|
||||||
|
return cryptor;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var c = Crypto.createEncryptor(key);
|
||||||
|
cryptor.encrypt = function (href) {
|
||||||
|
// Never encrypt blob href, they are always read-only
|
||||||
|
if (href.slice(0,7) === '/file/#') { return href; }
|
||||||
|
return c.encrypt(href);
|
||||||
|
};
|
||||||
|
cryptor.decrypt = c.decrypt;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
return cryptor;
|
||||||
|
};
|
||||||
|
module.getHref = function (pad, cryptor) {
|
||||||
|
if (pad.href && pad.href.indexOf('#') !== -1) {
|
||||||
|
// Href exists and is not encrypted: return href
|
||||||
|
return pad.href;
|
||||||
|
}
|
||||||
|
if (pad.href) {
|
||||||
|
// Href exists and is encrypted
|
||||||
|
var d = cryptor.decrypt(pad.href);
|
||||||
|
// If we can decrypt, return the decrypted value, otherwise continue and return roHref
|
||||||
|
if (d.indexOf('#') !== -1) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pad.roHref;
|
||||||
|
};
|
||||||
|
|
||||||
module.init = function (files, config) {
|
module.init = function (files, config) {
|
||||||
var exp = {};
|
var exp = {};
|
||||||
|
|
||||||
exp.cryptor = {};
|
exp.cryptor = createCryptor(config.editKey);
|
||||||
var createCryptor = function (key) {
|
|
||||||
if (!key) {
|
|
||||||
exp.cryptor.encrypt = function (x) { return x; };
|
|
||||||
exp.cryptor.decrypt = function (x) { return x; };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
var c = Crypto.createEncryptor(key);
|
|
||||||
exp.cryptor.encrypt = function (href) {
|
|
||||||
// Never encrypt blob href, they are always read-only
|
|
||||||
if (href.slice(0,7) === '/file/#') { return href; }
|
|
||||||
return c.encrypt(href);
|
|
||||||
};
|
|
||||||
exp.cryptor.decrypt = c.decrypt;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
createCryptor(config.editKey);
|
|
||||||
|
|
||||||
exp.setReadOnly = function (state, key) {
|
exp.setReadOnly = function (state, key) {
|
||||||
config.editKey = key;
|
config.editKey = key;
|
||||||
@@ -124,19 +141,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var getHref = exp.getHref = function (pad) {
|
var getHref = exp.getHref = function (pad) {
|
||||||
if (pad.href && pad.href.indexOf('#') !== -1) {
|
return module.getHref(pad, exp.cryptor);
|
||||||
// Href exists and is not encrypted: return href
|
|
||||||
return pad.href;
|
|
||||||
}
|
|
||||||
if (pad.href) {
|
|
||||||
// Href exists and is encrypted
|
|
||||||
var d = exp.cryptor.decrypt(pad.href);
|
|
||||||
// If we can decrypt, return the decrypted value, otherwise continue and return roHref
|
|
||||||
if (d.indexOf('#') !== -1) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pad.roHref;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var type = function (dat) {
|
var type = function (dat) {
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ define([
|
|||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
||||||
var sfData = drive.sharedFolders[fId] || {};
|
var sfData = drive.sharedFolders[fId] || {};
|
||||||
var parsed = Hash.parsePadUrl(sfData.href || sfData.roHref);
|
var href = (sfData.href && sfData.href.indexOf('#') !== -1) ? sfData.href : sfData.roHref;
|
||||||
|
var parsed = Hash.parsePadUrl(href);
|
||||||
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
||||||
sframeChan.query('Q_DRIVE_GETOBJECT', {
|
sframeChan.query('Q_DRIVE_GETOBJECT', {
|
||||||
sharedFolder: fId
|
sharedFolder: fId
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ define([
|
|||||||
'/bower_components/nthen/index.js',
|
'/bower_components/nthen/index.js',
|
||||||
'/common/sframe-common.js',
|
'/common/sframe-common.js',
|
||||||
'/common/proxy-manager.js',
|
'/common/proxy-manager.js',
|
||||||
|
'/common/userObject.js',
|
||||||
'/common/hyperscript.js',
|
'/common/hyperscript.js',
|
||||||
'/customize/application_config.js',
|
'/customize/application_config.js',
|
||||||
'/common/messenger-ui.js',
|
'/common/messenger-ui.js',
|
||||||
@@ -32,6 +33,7 @@ define([
|
|||||||
nThen,
|
nThen,
|
||||||
SFCommon,
|
SFCommon,
|
||||||
ProxyManager,
|
ProxyManager,
|
||||||
|
UserObject,
|
||||||
h,
|
h,
|
||||||
AppConfig,
|
AppConfig,
|
||||||
MessengerUI,
|
MessengerUI,
|
||||||
@@ -53,7 +55,8 @@ define([
|
|||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
||||||
var sfData = drive.sharedFolders[fId] || {};
|
var sfData = drive.sharedFolders[fId] || {};
|
||||||
var parsed = Hash.parsePadUrl(sfData.href || sfData.roHref);
|
var href = UserObject.getHref(sfData, APP.cryptor);
|
||||||
|
var parsed = Hash.parsePadUrl(href);
|
||||||
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
||||||
sframeChan.query('Q_DRIVE_GETOBJECT', {
|
sframeChan.query('Q_DRIVE_GETOBJECT', {
|
||||||
sharedFolder: fId
|
sharedFolder: fId
|
||||||
@@ -78,6 +81,30 @@ define([
|
|||||||
|
|
||||||
var setEditable = DriveUI.setEditable;
|
var setEditable = DriveUI.setEditable;
|
||||||
|
|
||||||
|
var closeTeam = function (common, cb) {
|
||||||
|
var sframeChan = common.getSframeChannel();
|
||||||
|
APP.module.execCommand('SUBSCRIBE', null, function () {
|
||||||
|
sframeChan.query('Q_SET_TEAM', null, function (err) {
|
||||||
|
if (err) { return void console.error(err); }
|
||||||
|
if (APP.drive && APP.drive.close) { APP.drive.close(); }
|
||||||
|
$('.cp-toolbar-title-value').text(Messages.type.teams);
|
||||||
|
sframeChan.event('EV_SET_TAB_TITLE', Messages.type.teams);
|
||||||
|
APP.team = null;
|
||||||
|
APP.teamEdPublic = null;
|
||||||
|
APP.drive = null;
|
||||||
|
APP.cryptor = null;
|
||||||
|
APP.buildUI(common);
|
||||||
|
if (APP.usageBar) {
|
||||||
|
APP.usageBar.stop();
|
||||||
|
APP.usageBar = null;
|
||||||
|
}
|
||||||
|
if (cb) {
|
||||||
|
cb(common);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var mainCategories = {
|
var mainCategories = {
|
||||||
'list': [
|
'list': [
|
||||||
'cp-team-list',
|
'cp-team-list',
|
||||||
@@ -92,23 +119,7 @@ define([
|
|||||||
var teamCategories = {
|
var teamCategories = {
|
||||||
'back': {
|
'back': {
|
||||||
onClick: function (common) {
|
onClick: function (common) {
|
||||||
var sframeChan = common.getSframeChannel();
|
closeTeam(common);
|
||||||
APP.module.execCommand('SUBSCRIBE', null, function () {
|
|
||||||
sframeChan.query('Q_SET_TEAM', null, function (err) {
|
|
||||||
if (err) { return void console.error(err); }
|
|
||||||
if (APP.drive && APP.drive.close) { APP.drive.close(); }
|
|
||||||
$('.cp-toolbar-title-value').text(Messages.type.teams);
|
|
||||||
sframeChan.event('EV_SET_TAB_TITLE', Messages.type.teams);
|
|
||||||
APP.team = null;
|
|
||||||
APP.teamEdPublic = null;
|
|
||||||
APP.drive = null;
|
|
||||||
APP.buildUI(common);
|
|
||||||
if (APP.usageBar) {
|
|
||||||
APP.usageBar.stop();
|
|
||||||
APP.usageBar = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'drive': [
|
'drive': [
|
||||||
@@ -311,8 +322,26 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
var MAX_TEAMS_SLOTS = Constants.MAX_TEAMS_SLOTS;
|
var MAX_TEAMS_SLOTS = Constants.MAX_TEAMS_SLOTS;
|
||||||
var refreshList = function (common, cb) {
|
var openTeam = function (common, id, team) {
|
||||||
var sframeChan = common.getSframeChannel();
|
var sframeChan = common.getSframeChannel();
|
||||||
|
APP.module.execCommand('SUBSCRIBE', id, function () {
|
||||||
|
var t = Messages._getKey('team_title', [Util.fixHTML(team.metadata.name)]);
|
||||||
|
sframeChan.query('Q_SET_TEAM', id, function (err) {
|
||||||
|
if (err) { return void console.error(err); }
|
||||||
|
// Change title
|
||||||
|
$('.cp-toolbar-title-value').text(t);
|
||||||
|
sframeChan.event('EV_SET_TAB_TITLE', t);
|
||||||
|
// Get secondary key
|
||||||
|
var secret = Hash.getSecrets('team', team.hash || team.roHash, team.password);
|
||||||
|
APP.cryptor = UserObject.createCryptor(secret.keys.secondaryKey);
|
||||||
|
// Load data
|
||||||
|
APP.team = id;
|
||||||
|
APP.teamEdPublic = Util.find(team, ['keys', 'drive', 'edPublic']);
|
||||||
|
buildUI(common, true, team.owner);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var refreshList = function (common, cb) {
|
||||||
var content = [];
|
var content = [];
|
||||||
APP.module.execCommand('LIST_TEAMS', null, function (obj) {
|
APP.module.execCommand('LIST_TEAMS', null, function (obj) {
|
||||||
if (!obj) { return; }
|
if (!obj) { return; }
|
||||||
@@ -348,19 +377,7 @@ define([
|
|||||||
]));
|
]));
|
||||||
common.displayAvatar($(avatar), team.metadata.avatar, team.metadata.name);
|
common.displayAvatar($(avatar), team.metadata.avatar, team.metadata.name);
|
||||||
$(btn).click(function () {
|
$(btn).click(function () {
|
||||||
APP.module.execCommand('SUBSCRIBE', id, function () {
|
openTeam(common, id, team);
|
||||||
var t = Messages._getKey('team_title', [Util.fixHTML(team.metadata.name)]);
|
|
||||||
sframeChan.query('Q_SET_TEAM', id, function (err) {
|
|
||||||
if (err) { return void console.error(err); }
|
|
||||||
// Change title
|
|
||||||
$('.cp-toolbar-title-value').text(t);
|
|
||||||
sframeChan.event('EV_SET_TAB_TITLE', t);
|
|
||||||
// Load data
|
|
||||||
APP.team = id;
|
|
||||||
APP.teamEdPublic = Util.find(team, ['keys', 'drive', 'edPublic']);
|
|
||||||
buildUI(common, true, team.owner);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
content.push(h('div.cp-team-list-container', list));
|
content.push(h('div.cp-team-list-container', list));
|
||||||
@@ -506,7 +523,7 @@ define([
|
|||||||
var $actions = $(actions);
|
var $actions = $(actions);
|
||||||
var isMe = me && me.curvePublic === data.curvePublic;
|
var isMe = me && me.curvePublic === data.curvePublic;
|
||||||
var myRole = me ? (ROLES.indexOf(me.role) || 1) : -1;
|
var myRole = me ? (ROLES.indexOf(me.role) || 1) : -1;
|
||||||
var theirRole = ROLES.indexOf(data.role) || 1;
|
var theirRole = ROLES.indexOf(data.role);
|
||||||
var ADMIN = ROLES.indexOf('ADMIN');
|
var ADMIN = ROLES.indexOf('ADMIN');
|
||||||
// If they're an admin and I am an owner, I can promote them to owner
|
// If they're an admin and I am an owner, I can promote them to owner
|
||||||
if (!isMe && myRole > theirRole && theirRole === ADMIN && !data.pending) {
|
if (!isMe && myRole > theirRole && theirRole === ADMIN && !data.pending) {
|
||||||
@@ -895,6 +912,22 @@ define([
|
|||||||
]);
|
]);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
var redrawTeam = function (common) {
|
||||||
|
if (!APP.team) { return; }
|
||||||
|
var teamId = APP.team;
|
||||||
|
var name = $('.cp-toolbar-title-value').text();
|
||||||
|
APP.module.execCommand('LIST_TEAMS', null, function (obj) {
|
||||||
|
if (!obj) { return; }
|
||||||
|
if (obj.error) { return void console.error(obj.error); }
|
||||||
|
var team = obj[teamId];
|
||||||
|
if (!team) { return; }
|
||||||
|
closeTeam(common, function () {
|
||||||
|
openTeam(common, teamId, team);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var main = function () {
|
var main = function () {
|
||||||
var common;
|
var common;
|
||||||
var readOnly;
|
var readOnly;
|
||||||
@@ -961,6 +994,10 @@ define([
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ev === 'ROSTER_CHANGE_RIGHTS') {
|
||||||
|
redrawTeam(common);
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
APP.module = common.makeUniversal('team', {
|
APP.module = common.makeUniversal('team', {
|
||||||
|
|||||||
Reference in New Issue
Block a user