From 905b339492ee6e4007726cf4ddaa6483de8559d4 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 8 Apr 2021 12:02:36 +0200 Subject: [PATCH] Encrypt calendars edit URL in teams --- www/calendar/inner.js | 1 + www/common/outer/calendar.js | 71 +++++++++++++++++++++++++++++++----- www/common/outer/team.js | 7 ++++ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index c1eff9665..92eb886fe 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -859,6 +859,7 @@ Messages.calendar_import = "Import to my calendars"; // No calendar yet, create one newCalendar({ teamId: 1, + initialCalendar: true, color: user.color, title: Messages.calendar_default }, function (err, obj) { diff --git a/www/common/outer/calendar.js b/www/common/outer/calendar.js index 82bb6339e..0ef17cd6b 100644 --- a/www/common/outer/calendar.js +++ b/www/common/outer/calendar.js @@ -324,6 +324,24 @@ ctx.calendars[channel] = { }); }); }; + var decryptTeamCalendarHref = function (store, calData) { + if (!calData.href) { return; } + + // Already decrypted? nothing to do + if (calData.href.indexOf('#') !== -1) { return; } + + // href exists and is encrypted: decrypt if we can or ignore the href + if (store.secondaryKey) { + try { + calData.href = store.userObject.cryptor.decrypt(calData.href); + } catch (e) { + console.error(e); + delete calData.href; + } + } else { + delete calData.href; + } + }; var initializeStore = function (ctx, store) { var c = store.proxy.calendars; var storeId = store.id || 1; @@ -358,11 +376,13 @@ ctx.calendars[channel] = { if (!o && n) { (function () { var id = p[1]; - var cal = store.proxy.calendars[id]; - if (!cal) { return; } + var _cal = store.proxy.calendars[id]; + if (!_cal) { return; } + var cal = Util.clone(_cal); + decryptTeamCalendarHref(store, cal); openChannel(ctx, { storeId: storeId, - data: Util.clone(cal) + data: cal }); })(); } @@ -378,9 +398,11 @@ ctx.calendars[channel] = { // If this store contains existing calendars, open them Object.keys(c || {}).forEach(function (channel) { + var cal = Util.clone(c[channel]); + decryptTeamCalendarHref(store, cal); openChannel(ctx, { storeId: storeId, - data: c[channel] + data: cal }); }); }; @@ -426,9 +448,7 @@ ctx.calendars[channel] = { }; openChannel(ctx, { storeId: 0, - data: cal, - noStore: true, - isNew: true + data: cal }, cb); }; var importCalendar = function (ctx, data, cId, cb) { @@ -477,8 +497,9 @@ ctx.calendars[channel] = { var hash = Hash.getEditHashFromKeys(secret); var roHash = Hash.getViewHashFromKeys(secret); + var href = hash && Hash.hashToHref(hash, 'calendar'); var cal = { - href: hash && Hash.hashToHref(hash, 'calendar'), + href: href, roHref: roHash && Hash.hashToHref(roHash, 'calendar'), color: data.color, title: data.title, @@ -492,13 +513,22 @@ ctx.calendars[channel] = { cal.title = data.title; openChannel(ctx, { storeId: store.id || 1, - data: cal + data: Util.clone(cal) }, function (err) { if (err) { // Can't open this channel, don't store it console.error(err); return void cb({error: err.error}) } + + if (href && store.id && store.secondaryKey) { + try { + cal.href = store.userObject.cryptor.encrypt(href); + } catch (e) { + console.error(e); + } + } + // Add the calendar and call back // If it already existed it means this is an upgrade c[cal.channel] = cal; @@ -682,6 +712,24 @@ ctx.calendars[channel] = { if (!store) { return; } initializeStore(ctx, store); }; + calendar.upgradeTeam = function (teamId) { + if (!teamId) { return; } + var store = getStore(ctx, teamId); + if (!store) { return; } + Object.keys(ctx.calendars).forEach(function (id) { + var ctxCal = ctx.calendars[id]; + var idx = ctxCal.stores.indexOf(teamId); + if (idx === -1) { return; } + var _cal = store.proxy.calendars[id]; + var cal = Util.clone(_cal); + decryptTeamCalendarHref(store, cal); + openChannel(ctx, { + storeId: teamId, + data: cal + }); + sendUpdate(ctx, ctxCal); + }); + }; calendar.removeClient = function (clientId) { removeClient(ctx, clientId); @@ -707,6 +755,11 @@ ctx.calendars[channel] = { return void addCalendar(ctx, data, clientId, cb); } if (cmd === 'CREATE') { + if (data.initialCalendar) { + return void ctx.Store.onReadyEvt.reg(function () { + createCalendar(ctx, data, clientId, cb); + }); + } if (ctx.store.offline) { return void cb({error: 'OFFLINE'}); } return void createCalendar(ctx, data, clientId, cb); } diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 146b6d879..db6326115 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -1260,6 +1260,13 @@ define([ team.userObject.setReadOnly(!secret.keys.secondaryKey, secret.keys.secondaryKey); } + // Upgrade? update calendar rights + if (secret.keys.secondaryKey) { + try { + ctx.store.modules.calendar.upgradeTeam(teamId); + } catch (e) { console.error(e); } + } + if (!secret.keys.secondaryKey && team.rpc) { team.rpc.destroy(); }