Import calendars from URL and upgrade if needed

pull/1/head
yflory 4 years ago
parent 67fae22156
commit 63581e2cf3

@ -65,6 +65,7 @@ Messages.calendar_deleteOwned = " It will still be visible for the users it has
Messages.calendar_errorNoCalendar = "No editable calendar selected!";
Messages.calendar_myCalendars = "My calendars";
Messages.calendar_tempCalendar = "Temp calendar";
Messages.calendar_import = "Import to my calendars";
var onCalendarsUpdate = Util.mkEvent();
@ -86,6 +87,12 @@ Messages.calendar_tempCalendar = "Temp calendar";
cb(null, obj);
});
};
var importCalendar = function (data, cb) {
APP.module.execCommand('IMPORT', data, function (obj) {
if (obj && obj.error) { return void cb(obj.error); }
cb(null, obj);
});
};
var newEvent = function (data, cb) {
var start = data.start;
var end = data.end;
@ -307,50 +314,83 @@ Messages.calendar_tempCalendar = "Temp calendar";
UI.openCustomModal(m);
};
var isReadOnly = function (id, teamId) {
var data = APP.calendars[id];
return data.readOnly || (data.roTeams && data.roTeams.indexOf(teamId) !== -1);
};
var makeEditDropdown = function (id, teamId) {
var options = [{
tag: 'a',
attributes: {
'class': 'fa fa-pencil',
},
content: h('span', Messages.tag_edit),
action: function (e) {
e.stopPropagation();
editCalendar(id);
return true;
}
}, {
tag: 'a',
attributes: {
'class': 'fa fa-shhare-alt',
},
content: h('span', Messages.shareButton),
action: function (e) {
e.stopPropagation();
var friends = common.getFriends();
var cal = APP.calendars[id];
var title = Util.find(cal, ['content', 'metadata', 'title']);
var color = Util.find(cal, ['content', 'metadata', 'color']);
Share.getShareModal(common, {
teamId: teamId === 1 ? undefined : teamId,
origin: APP.origin,
pathname: "/calendar/",
friends: friends,
title: title,
password: cal.password, // XXX support passwords
calendar: {
title: title,
color: color,
channel: id,
},
common: common,
hashes: cal.hashes
});
return true;
}
}];
var options = [];
var privateData = metadataMgr.getPrivateData();
var cantRemove = teamId === 0 || (teamId !== 1 && privateData.teams[teamId].viewer);
var data = APP.calendars[id];
if (!data.readOnly) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-pencil',
},
content: h('span', Messages.tag_edit),
action: function (e) {
e.stopPropagation();
editCalendar(id);
return true;
}
});
}
if (data.teams.indexOf(1) === -1 || teamId === 0) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-clone',
},
content: h('span', Messages.calendar_import),
action: function (e) {
e.stopPropagation();
importCalendar({
id: id,
teamId: teamId
}, function (obj) {
if (obj && obj.error) {
console.error(obj.error);
return void UI.warn(obj.error);
}
});
return true;
}
});
}
if (!data.restricted) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-shhare-alt',
},
content: h('span', Messages.shareButton),
action: function (e) {
e.stopPropagation();
var friends = common.getFriends();
var cal = APP.calendars[id];
var title = Util.find(cal, ['content', 'metadata', 'title']);
var color = Util.find(cal, ['content', 'metadata', 'color']);
Share.getShareModal(common, {
teamId: teamId === 1 ? undefined : teamId,
origin: APP.origin,
pathname: "/calendar/",
friends: friends,
title: title,
password: cal.password, // XXX support passwords
calendar: {
title: title,
color: color,
channel: id,
},
common: common,
hashes: cal.hashes
});
return true;
}
});
}
if (!cantRemove) {
options.push({
tag: 'a',
@ -397,7 +437,7 @@ Messages.calendar_tempCalendar = "Temp calendar";
var edit;
if (data.loading) {
edit = h('i.fa.fa-spinner.fa-spin');
} else if (!data.readOnly) {
} else {
edit = makeEditDropdown(id, teamId);
}
var md = Util.find(data, ['content', 'metadata']);
@ -410,6 +450,7 @@ Messages.calendar_tempCalendar = "Temp calendar";
style: 'background-color: '+md.color+';'
}),
h('span.cp-calendar-title', md.title),
isReadOnly(id, teamId) ? h('i.fa.fa-eye', {title: Messages.readonly}) : undefined,
edit
]);
$(calendar).click(function () {

@ -96,6 +96,7 @@ ctx.calendars[channel] = {
var sendUpdate = function (ctx, c) {
ctx.emit('UPDATE', {
teams: c.stores,
roTeams: c.roStores,
id: c.channel,
loading: !c.ready && !c.cacheready,
readOnly: c.readOnly || (!c.ready && c.cacheready),
@ -135,12 +136,38 @@ ctx.calendars[channel] = {
if (c) {
if (c.readOnly && data.href) {
// XXX UPGRADE
// c.hashes.editHash =
// XXX different cases if already ready or not?
// Upgrade readOnly calendar to editable
var upgradeParsed = Hash.parsePadUrl(data.href);
var upgradeSecret = Hash.getSecrets('calendar', upgradeParsed.hash, data.password);
var upgradeCrypto = Crypto.createEncryptor(upgradeSecret.keys);
c.hashes.editHash = Hash.getEditHashFromKeys(upgradeSecret);
c.lm.setReadOnly(false, upgradeCrypto);
c.readOnly = false;
} else if (teamId === 0) {
// Existing calendars can't be "temp calendars" (unless they are an upgrade)
return void cb();
}
// Remove from roStores when upgrading this store
if (c.roStores.indexOf(teamId) !== -1 && data.href) {
c.roStores.splice(c.roStores.indexOf(teamId), 1);
// If we've upgraded a stored calendar, remove the temp calendar
if (c.stores.indexOf(0) !== -1) {
c.stores.splice(c.stores.indexOf(0), 1);
}
update();
}
// Don't store duplicates
if (c.stores && c.stores.indexOf(teamId) !== -1) { return void cb(); }
// If we store a temp calendar to our account or team, remove this "temp calendar"
if (c.stores.indexOf(0) !== -1) { c.stores.splice(c.stores.indexOf(0), 1); }
c.stores.push(teamId);
if (!data.href) {
c.roStores.push(teamId);
}
update();
return void cb();
}
@ -152,6 +179,7 @@ ctx.calendars[channel] = {
channel: channel,
readOnly: !data.href,
stores: [teamId],
roStores: data.href ? [] : [teamId],
hashes: {}
};
@ -343,6 +371,38 @@ ctx.calendars[channel] = {
isNew: true
}, cb);
};
var importCalendar = function (ctx, data, cId, cb) {
var id = data.id;
var c = ctx.calendars[id];
if (!c) { return void cb({error: "ENOENT"}); }
if (!Array.isArray(c.stores) || c.stores.indexOf(data.teamId) === -1) {
return void cb({error: 'EINVAL'});
}
// Add to my calendars
var store = ctx.store;
var calendars = store.proxy.calendars = store.proxy.calendars || {};
var hash = c.hashes.editHash;
var roHash = c.hashes.viewHash;
calendars[id] = {
href: hash && Hash.hashToHref(hash, 'calendar'),
roHref: roHash && Hash.hashToHref(roHash, 'calendar'),
channel: id,
color: Util.find(c,['proxy', 'metadata', 'color']) || Util.getRandomColor(),
title: Util.find(c,['proxy', 'metadata', 'title']) || '...'
};
ctx.Store.onSync(null, cb);
// Make the change in memory
openChannel(ctx, {
storeId: 1,
data: {
href: calendars[id].href,
toHref: calendars[id].roHref,
channel: id
}
});
};
var addCalendar = function (ctx, data, cId, cb) {
var store = getStore(ctx, data.teamId);
if (!store) { return void cb({error: "NO_STORE"}); }
@ -353,13 +413,21 @@ ctx.calendars[channel] = {
var parsed = Hash.parsePadUrl(data.href);
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
if (secret.channel !== data.channel) { return void cb({error: 'EINVAL'}); }
var hash = Hash.getEditHashFromKeys(secret);
var roHash = Hash.getViewHashFromKeys(secret);
var cal = {
href: Hash.getEditHashFromKeys(secret),
roHref: Hash.getViewHashFromKeys(secret),
href: hash && Hash.hashToHref(hash, 'calendar'),
roHref: roHash && Hash.hashToHref(roHash, 'calendar'),
color: data.color,
title: data.title,
channel: data.channel
};
// If it already existed and it's not an upgrade, nothing to do
if (c[data.channel] && (c[data.channel].href || !cal.href)) { return void cb(); }
cal.color = data.color;
cal.title = data.title;
openChannel(ctx, {
@ -373,6 +441,7 @@ ctx.calendars[channel] = {
return void cb({error: err.error})
}
// Add the calendar and call back
// If it already existed it means this is an upgrade
c[cal.channel] = cal;
var pin = store.pin || ctx.pinPads;
pin([cal.channel], function (res) {
@ -539,6 +608,10 @@ ctx.calendars[channel] = {
});
return;
}
if (cmd === 'IMPORT') {
if (ctx.store.offline) { return void cb({error: 'OFFLINE'}); }
return void importCalendar(ctx, data, clientId, cb);
}
if (cmd === 'ADD') {
if (ctx.store.offline) { return void cb({error: 'OFFLINE'}); }
return void addCalendar(ctx, data, clientId, cb);

Loading…
Cancel
Save