Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging

pull/1/head
yflory 7 years ago
commit 3e064e6638

@ -7,7 +7,6 @@
"iterator": true, "iterator": true,
"latedef": true, "latedef": true,
"nocomma": true, "nocomma": true,
"notypeof": true,
"shadow": false, "shadow": false,
"undef": true, "undef": true,
"unused": true, "unused": true,

@ -159,6 +159,24 @@ module.exports = {
*/ */
defaultStorageLimit: 50 * 1024 * 1024, defaultStorageLimit: 50 * 1024 * 1024,
/*
* CryptPad allows administrators to give custom limits to their friends.
* add an entry for each friend, identified by their user id,
* which can be found on the settings page. Include a 'limit' (number of bytes),
* a 'plan' (string), and a 'note' (string).
*
* hint: 1GB is 1024 * 1024 * 1024 bytes
*/
customLimits: {
/*
"https://my.awesome.website/user/#/1/cryptpad-user/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=": {
limit: 20 * 1024 * 1024 * 1024,
plan: 'insider',
note: 'storage space donated by my.awesome.website'
}
*/
},
/* /*
* By default, CryptPad also contacts our accounts server once a day to check for changes in * By default, CryptPad also contacts our accounts server once a day to check for changes in
* the people who have accounts. This check-in will also send the version of your CryptPad * the people who have accounts. This check-in will also send the version of your CryptPad

@ -18,7 +18,7 @@ define([
var loggedIn = LocalStore.isLoggedIn(); var loggedIn = LocalStore.isLoggedIn();
var link = h('a#cp-link', { var link = h('a#cp-link', {
href: loggedIn? '/drive/': '/', href: loggedIn? '/drive/': '/',
}, loggedIn? Messages.four04_goToDrive: Messages.four04_goToHome); }, loggedIn? Messages.header_logoTitle: Messages.header_homeTitle);
var content = h('div#cp-main', [ var content = h('div#cp-main', [
img, img,
@ -68,10 +68,10 @@ define([
}; };
}; };
makeDecryptor(brand, 90, 4, function () { })(); makeDecryptor(brand, 70, 2, function () { })();
makeDecryptor(title, 50, 14, function () { })(); makeDecryptor(title, 50, 14, function () { })();
makeDecryptor(link, 20, 10, function () {})(); makeDecryptor(link, 20, 4, function () {})();
makeDecryptor(message, 12, 5, function () { makeDecryptor(message, 12, 3, function () {
console.log('done'); console.log('done');
})(); })();
}); });

@ -1,5 +1,5 @@
/* Bottom Bar */ /* Bottom Bar */
@import (once) "../less2/include/colortheme.less"; @import (once) "../less2/include/colortheme-all.less";
.top-bar, .bottom-bar { .top-bar, .bottom-bar {
position:fixed; position:fixed;

@ -2,7 +2,7 @@
@import "./mixins.less"; @import "./mixins.less";
@import "../less2/include/alertify.less"; @import "../less2/include/alertify.less";
@import "../less2/include/colortheme.less"; @import "../less2/include/colortheme-all.less";
@import "../less2/include/modal.less"; @import "../less2/include/modal.less";
@import "../less2/include/font.less"; @import "../less2/include/font.less";
@import "../less2/loading.less"; @import "../less2/loading.less";

@ -1,5 +1,5 @@
@import "./variables.less"; @import "./variables.less";
@import (once) "../less2/include/colortheme.less"; @import (once) "../less2/include/colortheme-all.less";
footer { footer {
background: @category-bg; background: @category-bg;

@ -1,6 +1,6 @@
@import '/customize/src/less/variables.less'; @import '/customize/src/less/variables.less';
@import '/customize/src/less/mixins.less'; @import '/customize/src/less/mixins.less';
@import (once) "/customize/src/less2/include/colortheme.less"; @import (once) "/customize/src/less2/include/colortheme-all.less";
@leftside-bg: @colortheme_sidebar-left-bg; @leftside-bg: @colortheme_sidebar-left-bg;
@leftside-color: @colortheme_sidebar-left-fg; @leftside-color: @colortheme_sidebar-left-fg;

@ -2,7 +2,7 @@
@import "./mixins.less"; @import "./mixins.less";
@import (once) "../less2/include/dropdown.less"; @import (once) "../less2/include/dropdown.less";
@import (once) "../less2/include/colortheme.less"; @import (once) "../less2/include/colortheme-all.less";
@import (once) "../less2/include/ckeditor-fix.less"; @import (once) "../less2/include/ckeditor-fix.less";
@import (once) "../less2/include/icon-colors.less"; @import (once) "../less2/include/icon-colors.less";

@ -1,5 +1,5 @@
@import "./variables.less"; @import "./variables.less";
@import (once) "../less2/include/colortheme.less"; @import (once) "../less2/include/colortheme-all.less";
#cryptpadTopBar { #cryptpadTopBar {
background: @topbar-back; background: @topbar-back;

@ -1,4 +1,4 @@
@import (once) '../less2/include/colortheme.less'; @import (once) '../less2/include/colortheme-all.less';
@import (once) '../less2/include/browser.less'; @import (once) '../less2/include/browser.less';
@base: @colortheme_base; @base: @colortheme_base;

@ -0,0 +1,6 @@
// Don't override/edit this file directly, you can create
// create a file: customize/src/less2/include/colortheme.less
// override whatever colors you want. When you update, the new colors will be
// added ok because the original file is pulled in first.
@import (once) "/customize.dist/src/less2/include/colortheme.less";
@import (once) "/customize/src/less2/include/colortheme.less";

@ -42,42 +42,54 @@
@colortheme_pad-bg: #1c4fa0; @colortheme_pad-bg: #1c4fa0;
@colortheme_pad-color: #fff; @colortheme_pad-color: #fff;
@colortheme_pad-toolbar-bg: #c1e7ff; @colortheme_pad-toolbar-bg: #c1e7ff;
@colortheme_pad-warn: #F83A3A;
@colortheme_slide-bg: #e57614; @colortheme_slide-bg: #e57614;
@colortheme_slide-color: #fff; @colortheme_slide-color: #fff;
@colortheme_slide-warn: #7bccd1;
@colortheme_code-bg: #ffae00; @colortheme_code-bg: #ffae00;
@colortheme_code-color: #000; @colortheme_code-color: #000;
@colortheme_code-warn: #005bef;
@colortheme_poll-bg: #006304; @colortheme_poll-bg: #006304;
@colortheme_poll-color: #fff; @colortheme_poll-color: #fff;
@colortheme_poll-help-bg: #bbffbb; @colortheme_poll-help-bg: #bbffbb;
@colortheme_poll-th-bg: #005bef; @colortheme_poll-th-bg: #005bef;
@colortheme_poll-th-fg: #fff; @colortheme_poll-th-fg: #fff;
@colortheme_poll-warn: #cd2532;
@colortheme_whiteboard-bg: #800080; @colortheme_whiteboard-bg: #800080;
@colortheme_whiteboard-color: #fff; @colortheme_whiteboard-color: #fff;
@colortheme_whiteboard-warn: #ffae00;
@colortheme_drive-bg: #0087ff; @colortheme_drive-bg: #0087ff;
@colortheme_drive-color: #fff; @colortheme_drive-color: #fff;
@colortheme_drive-warn: #cd2532;
@colortheme_file-bg: #cd2532; @colortheme_file-bg: #cd2532;
@colortheme_file-color: #fff; @colortheme_file-color: #fff;
@colortheme_file-warn: #ffae00;
@colortheme_friends-bg: #607b8d; @colortheme_friends-bg: #607b8d;
@colortheme_friends-color: #fff; @colortheme_friends-color: #fff;
@colortheme_friends-warn: #cd2532;
@colortheme_default-bg: #ddd; @colortheme_default-bg: #ddd;
@colortheme_default-color: #000; @colortheme_default-color: #000;
@colortheme_default-warn: #cd2532;
@colortheme_settings-bg: #0087ff; @colortheme_settings-bg: #0087ff;
@colortheme_settings-color: #fff; @colortheme_settings-color: #fff;
@colortheme_settings-warn: #cd2532;
@colortheme_profile-bg: #0087ff; @colortheme_profile-bg: #0087ff;
@colortheme_profile-color: #fff; @colortheme_profile-color: #fff;
@colortheme_profile-warn: #cd2532;
@colortheme_todo-bg: #7bccd1; @colortheme_todo-bg: #7bccd1;
@colortheme_todo-color: #000; @colortheme_todo-color: #000;
@colortheme_todo-warn: #cd2532;
// Sidebar layout (profile / settings) // Sidebar layout (profile / settings)
@colortheme_sidebar-active: #fff; @colortheme_sidebar-active: #fff;

@ -1,4 +1,4 @@
@import (once) "/customize/src/less2/include/colortheme.less"; @import (once) "/customize/src/less2/include/colortheme-all.less";
@import (once) "/customize/src/less2/include/leftside-menu.less"; @import (once) "/customize/src/less2/include/leftside-menu.less";
@leftside-bg: @colortheme_sidebar-left-bg; @leftside-bg: @colortheme_sidebar-left-bg;

@ -7,6 +7,7 @@
@import (once) "./icon-colors.less"; @import (once) "./icon-colors.less";
@import (once) "./tools.less"; @import (once) "./tools.less";
@_cp-toolbar-color-warn: black;
.toolbar_main () { .toolbar_main () {
@ -224,6 +225,7 @@
} }
.cp-toolbar-limit { .cp-toolbar-limit {
text-shadow: -1px 0 @color, 0 1px @color, 1px 0 @color, 0 -1px @color; text-shadow: -1px 0 @color, 0 1px @color, 1px 0 @color, 0 -1px @color;
color: @_cp-toolbar-color-warn;
} }
.cp-toolbar-leftside, .cp-toolbar-rightside { .cp-toolbar-leftside, .cp-toolbar-rightside {
background-color: lighten(@bgcolor, 8%); background-color: lighten(@bgcolor, 8%);
@ -238,6 +240,19 @@
width: 100%; width: 100%;
} }
} }
.cp-pad-not-pinned {
padding-left: 20px;
font-size: @colortheme_app-font-size;
color: @_cp-toolbar-color-warn;
a {
font-size: @colortheme_app-font-size;
font-weight: bold;
color: @_cp-toolbar-color-warn;
&:hover {
text-decoration: underline;
}
}
}
.cp-toolbar-title-hoverable:hover { .cp-toolbar-title-hoverable:hover {
.cp-toolbar-title-editable, .cp-toolbar-title-edit { .cp-toolbar-title-editable, .cp-toolbar-title-edit {
cursor: text; cursor: text;
@ -383,7 +398,6 @@
vertical-align: middle; vertical-align: middle;
line-height: @toolbar_top-height; line-height: @toolbar_top-height;
span { span {
color: red;
cursor: pointer; cursor: pointer;
margin: auto; margin: auto;
font-size: 20px; font-size: 20px;

@ -3,7 +3,7 @@ WARNING: THIS FILE DOES NOTHING
It exists only as a proposal of what CSS you should use in loading.js It exists only as a proposal of what CSS you should use in loading.js
The CSS inside of loading.js is precompiled in order to save 200ish milliseconds to the loading screen. The CSS inside of loading.js is precompiled in order to save 200ish milliseconds to the loading screen.
*/ */
@import (once) "./include/colortheme.less"; @import (once) "./include/colortheme-all.less";
@import (once) "./include/browser.less"; @import (once) "./include/browser.less";
#cp-loading { #cp-loading {

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
.infopages_main(); .infopages_main();
.infopages_topbar(); .infopages_topbar();

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
.infopages_main(); .infopages_main();
.infopages_topbar(); .infopages_topbar();

@ -1,7 +1,7 @@
//@import (once) "./variables.less"; //@import (once) "./variables.less";
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
.infopages_main(); .infopages_main();

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
@import (once) "../include/alertify.less"; @import (once) "../include/alertify.less";
@import (once) "../loading.less"; @import (once) "../loading.less";

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
.infopages_main(); .infopages_main();
.infopages_topbar(); .infopages_topbar();

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
@import (once) "../include/alertify.less"; @import (once) "../include/alertify.less";
@import (once) "../loading.less"; @import (once) "../loading.less";

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
.infopages_main(); .infopages_main();
.infopages_topbar(); .infopages_topbar();

@ -1,5 +1,5 @@
@import (once) "../include/infopages.less"; @import (once) "../include/infopages.less";
@import (once) "../include/colortheme.less"; @import (once) "../include/colortheme-all.less";
.infopages_main(); .infopages_main();
.infopages_topbar(); .infopages_topbar();

@ -683,10 +683,8 @@ define(function () {
out.tos_logs = "Les meta-données fournies par votre navigateur au serveur peuvent être enregistrées dans le but de maintenir le service."; out.tos_logs = "Les meta-données fournies par votre navigateur au serveur peuvent être enregistrées dans le but de maintenir le service.";
out.tos_3rdparties = "Nous ne fournissons aucune donnée individuelle à des tierces parties à moins d'y être contraints par la loi."; out.tos_3rdparties = "Nous ne fournissons aucune donnée individuelle à des tierces parties à moins d'y être contraints par la loi.";
// BottomBar.html // 404 page
out.four04_pageNotFound = "Nous n'avons pas trouvé la page que vous cherchez.";
out.bottom_france = '<a href="http://www.xwiki.com/fr" target="_blank" rel="noopener noreferrer">Fait avec <img class="bottom-bar-heart" src="/customize/heart.png" alt="amour" /> en <img class="bottom-bar-fr" src="/customize/fr.png" alt="France" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Un projet <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/> Labs</a> avec le soutien de <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html // Header.html

@ -31,6 +31,7 @@ define(function () {
out.typeError = "This pad is not compatible with the selected application"; out.typeError = "This pad is not compatible with the selected application";
out.onLogout = 'You are logged out, <a href="/" target="_blank">click here</a> to log in<br>or press <em>Escape</em> to access your pad in read-only mode.'; out.onLogout = 'You are logged out, <a href="/" target="_blank">click here</a> to log in<br>or press <em>Escape</em> to access your pad in read-only mode.';
out.wrongApp = "Unable to display the content of that realtime session in your browser. Please try to reload that page."; out.wrongApp = "Unable to display the content of that realtime session in your browser. Please try to reload that page.";
out.padNotPinned = 'This pad will expire in 3 months, <a href="{0}" target="blank">login</a> or <a href="{1}" target="blank">register</a> to preserve it.';
out.loading = "Loading..."; out.loading = "Loading...";
out.error = "Error"; out.error = "Error";
@ -690,9 +691,8 @@ define(function () {
out.tos_logs = "Metadata provided by your browser to the server may be logged for the purpose of maintaining the service."; out.tos_logs = "Metadata provided by your browser to the server may be logged for the purpose of maintaining the service.";
out.tos_3rdparties = "We do not provide individualized data to third parties unless required to by law."; out.tos_3rdparties = "We do not provide individualized data to third parties unless required to by law.";
// 404 page
out.four04_pageNotFound = "We couldn't find the page you were looking for."; out.four04_pageNotFound = "We couldn't find the page you were looking for.";
out.four04_goToHome = "Go to the home page.";
out.four04_goToDrive = "Go to my CryptDrive.";
// BottomBar.html // BottomBar.html

@ -0,0 +1,74 @@
/* jshint esversion: 6, node: true */
const Fs = require('fs');
const Semaphore = require('saferphore');
const nThen = require('nthen');
const sema = Semaphore.create(20);
let dirList;
const fileList = [];
const pinned = {};
const hashesFromPinFile = (pinFile, fileName) => {
var pins = {};
pinFile.split('\n').filter((x)=>(x)).map((l) => JSON.parse(l)).forEach((l) => {
switch (l[0]) {
case 'RESET': {
pins = {};
//jshint -W086
// fallthrough
}
case 'PIN': {
l[1].forEach((x) => { pins[x] = 1; });
break;
}
case 'UNPIN': {
l[1].forEach((x) => { delete pins[x]; });
break;
}
default: throw new Error(JSON.stringify(l) + ' ' + fileName);
}
});
return Object.keys(pins);
};
module.exports.load = function (cb) {
nThen((waitFor) => {
Fs.readdir('./pins', waitFor((err, list) => {
if (err) { throw err; }
dirList = list;
}));
}).nThen((waitFor) => {
fileList.splice(0, fileList.length);
dirList.forEach((f) => {
sema.take((returnAfter) => {
Fs.readdir('./pins/' + f, waitFor(returnAfter((err, list2) => {
if (err) { throw err; }
list2.forEach((ff) => { fileList.push('./pins/' + f + '/' + ff); });
})));
});
});
}).nThen((waitFor) => {
fileList.forEach((f) => {
sema.take((returnAfter) => {
Fs.readFile(f, waitFor(returnAfter((err, content) => {
if (err) { throw err; }
const hashes = hashesFromPinFile(content.toString('utf8'), f);
hashes.forEach((x) => {
(pinned[x] = pinned[x] || {})[f.replace(/.*\/([^/]*).ndjson$/, (x, y)=>y)] = 1;
});
})));
});
});
}).nThen(() => {
cb(pinned);
});
};
if (!module.parent) {
module.exports.load(function (data) {
Object.keys(data).forEach(function (x) {
console.log(x + ' ' + JSON.stringify(data[x]));
});
});
}

145
rpc.js

@ -10,6 +10,7 @@ var Fs = require("fs");
var Path = require("path"); var Path = require("path");
var Https = require("https"); var Https = require("https");
const Package = require('./package.json'); const Package = require('./package.json');
const Pinned = require('./pinned');
var RPC = module.exports; var RPC = module.exports;
@ -212,7 +213,6 @@ var checkSignature = function (signedMsg, signature, publicKey) {
}; };
var loadUserPins = function (Env, publicKey, cb) { var loadUserPins = function (Env, publicKey, cb) {
var pinStore = Env.pinStore;
var session = beginSession(Env.Sessions, publicKey); var session = beginSession(Env.Sessions, publicKey);
if (session.channels) { if (session.channels) {
@ -230,7 +230,7 @@ var loadUserPins = function (Env, publicKey, cb) {
pins[channel] = false; pins[channel] = false;
}; };
pinStore.getMessages(publicKey, function (msg) { Env.pinStore.getMessages(publicKey, function (msg) {
// handle messages... // handle messages...
var parsed; var parsed;
try { try {
@ -325,9 +325,8 @@ var getFileSize = function (Env, channel, cb) {
}; };
var getMultipleFileSize = function (Env, channels, cb) { var getMultipleFileSize = function (Env, channels, cb) {
var msgStore = Env.msgStore;
if (!Array.isArray(channels)) { return cb('INVALID_PIN_LIST'); } if (!Array.isArray(channels)) { return cb('INVALID_PIN_LIST'); }
if (typeof(msgStore.getChannelSize) !== 'function') { if (typeof(Env.msgStore.getChannelSize) !== 'function') {
return cb('GET_CHANNEL_SIZE_UNSUPPORTED'); return cb('GET_CHANNEL_SIZE_UNSUPPORTED');
} }
@ -428,6 +427,28 @@ var updateLimits = function (config, publicKey, cb /*:(?string, ?any[])=>void*/)
"Content-Length": Buffer.byteLength(body) "Content-Length": Buffer.byteLength(body)
} }
}; };
// read custom limits from the config
var customLimits = (function (custom) {
var limits = {};
Object.keys(custom).forEach(function (k) {
k.replace(/\/([^\/]+)$/, function (all, safeKey) {
var id = unescapeKeyCharacters(safeKey || '');
limits[id] = custom[k];
return '';
});
});
return limits;
}(config.customLimits || {}));
var isLimit = function (o) {
var valid = o && typeof(o) === 'object' &&
typeof(o.limit) === 'number' &&
typeof(o.plan) === 'string' &&
typeof(o.note) === 'string';
return valid;
};
var req = Https.request(options, function (response) { var req = Https.request(options, function (response) {
if (!('' + response.statusCode).match(/^2\d\d$/)) { if (!('' + response.statusCode).match(/^2\d\d$/)) {
return void cb('SERVER ERROR ' + response.statusCode); return void cb('SERVER ERROR ' + response.statusCode);
@ -442,6 +463,11 @@ var updateLimits = function (config, publicKey, cb /*:(?string, ?any[])=>void*/)
try { try {
var json = JSON.parse(str); var json = JSON.parse(str);
limits = json; limits = json;
Object.keys(customLimits).forEach(function (k) {
if (!isLimit(customLimits[k])) { return; }
limits[k] = customLimits[k];
});
var l; var l;
if (userId) { if (userId) {
var limit = limits[userId]; var limit = limits[userId];
@ -499,6 +525,54 @@ var sumChannelSizes = function (sizes) {
.reduce(function (a, b) { return a + b; }, 0); .reduce(function (a, b) { return a + b; }, 0);
}; };
// inform that the
var loadChannelPins = function (Env) {
Pinned.load(function (data) {
Env.pinnedPads = data;
Env.evPinnedPadsReady.fire();
});
};
var addPinned = function (
Env,
publicKey /*:string*/,
channelList /*Array<string>*/,
cb /*:()=>void*/)
{
Env.evPinnedPadsReady.reg(() => {
channelList.forEach((c) => {
const x = Env.pinnedPads[c];
if (!x) { return; }
delete x[publicKey];
});
cb();
});
};
var removePinned = function (
Env,
publicKey /*:string*/,
channelList /*Array<string>*/,
cb /*:()=>void*/)
{
Env.evPinnedPadsReady.reg(() => {
channelList.forEach((c) => {
const x = Env.pinnedPads[c];
if (!x) { return; }
delete x[publicKey];
});
cb();
});
};
var isChannelPinned = function (Env, channel, cb) {
Env.evPinnedPadsReady.reg(() => {
if (Env.pinnedPads[channel] && Object.keys(Env.pinnedPads[channel]).length) {
cb(true);
} else {
delete Env.pinnedPads[channel];
cb(false);
}
});
};
var pinChannel = function (Env, publicKey, channels, cb) { var pinChannel = function (Env, publicKey, channels, cb) {
if (!channels && channels.filter) { if (!channels && channels.filter) {
return void cb('INVALID_PIN_LIST'); return void cb('INVALID_PIN_LIST');
@ -534,6 +608,7 @@ var pinChannel = function (Env, publicKey, channels, cb) {
toStore.forEach(function (channel) { toStore.forEach(function (channel) {
session.channels[channel] = true; session.channels[channel] = true;
}); });
addPinned(Env, publicKey, toStore, () => {});
getHash(Env, publicKey, cb); getHash(Env, publicKey, cb);
}); });
}); });
@ -542,7 +617,6 @@ var pinChannel = function (Env, publicKey, channels, cb) {
}; };
var unpinChannel = function (Env, publicKey, channels, cb) { var unpinChannel = function (Env, publicKey, channels, cb) {
var pinStore = Env.pinStore;
if (!channels && channels.filter) { if (!channels && channels.filter) {
// expected array // expected array
return void cb('INVALID_PIN_LIST'); return void cb('INVALID_PIN_LIST');
@ -560,13 +634,13 @@ var unpinChannel = function (Env, publicKey, channels, cb) {
return void getHash(Env, publicKey, cb); return void getHash(Env, publicKey, cb);
} }
pinStore.message(publicKey, JSON.stringify(['UNPIN', toStore]), Env.pinStore.message(publicKey, JSON.stringify(['UNPIN', toStore]),
function (e) { function (e) {
if (e) { return void cb(e); } if (e) { return void cb(e); }
toStore.forEach(function (channel) { toStore.forEach(function (channel) {
delete session.channels[channel]; delete session.channels[channel];
}); });
removePinned(Env, publicKey, toStore, () => {});
getHash(Env, publicKey, cb); getHash(Env, publicKey, cb);
}); });
}); });
@ -574,7 +648,6 @@ var unpinChannel = function (Env, publicKey, channels, cb) {
var resetUserPins = function (Env, publicKey, channelList, cb) { var resetUserPins = function (Env, publicKey, channelList, cb) {
if (!Array.isArray(channelList)) { return void cb('INVALID_PIN_LIST'); } if (!Array.isArray(channelList)) { return void cb('INVALID_PIN_LIST'); }
var pinStore = Env.pinStore;
var session = beginSession(Env.Sessions, publicKey); var session = beginSession(Env.Sessions, publicKey);
if (!channelList.length) { if (!channelList.length) {
@ -605,13 +678,18 @@ var resetUserPins = function (Env, publicKey, channelList, cb) {
They will not be able to pin additional pads until they upgrade They will not be able to pin additional pads until they upgrade
or delete enough files to go back under their limit. */ or delete enough files to go back under their limit. */
if (pinSize > limit[0] && session.hasPinned) { return void(cb('E_OVER_LIMIT')); } if (pinSize > limit[0] && session.hasPinned) { return void(cb('E_OVER_LIMIT')); }
pinStore.message(publicKey, JSON.stringify(['RESET', channelList]), Env.pinStore.message(publicKey, JSON.stringify(['RESET', channelList]),
function (e) { function (e) {
if (e) { return void cb(e); } if (e) { return void cb(e); }
channelList.forEach(function (channel) { channelList.forEach(function (channel) {
pins[channel] = true; pins[channel] = true;
}); });
var oldChannels = Object.keys(session.channels);
removePinned(Env, publicKey, oldChannels, () => {
addPinned(Env, publicKey, channelList, ()=>{});
});
// update in-memory cache IFF the reset was allowed. // update in-memory cache IFF the reset was allowed.
session.channels = pins; session.channels = pins;
getHash(Env, publicKey, function (e, hash) { getHash(Env, publicKey, function (e, hash) {
@ -879,6 +957,7 @@ var isUnauthenticatedCall = function (call) {
return [ return [
'GET_FILE_SIZE', 'GET_FILE_SIZE',
'GET_MULTIPLE_FILE_SIZE', 'GET_MULTIPLE_FILE_SIZE',
'IS_CHANNEL_PINNED',
].indexOf(call) !== -1; ].indexOf(call) !== -1;
}; };
@ -894,10 +973,31 @@ var isAuthenticatedCall = function (call) {
'GET_LIMIT', 'GET_LIMIT',
'UPLOAD_COMPLETE', 'UPLOAD_COMPLETE',
'UPLOAD_CANCEL', 'UPLOAD_CANCEL',
'EXPIRE_SESSION', 'EXPIRE_SESSION'
].indexOf(call) !== -1; ].indexOf(call) !== -1;
}; };
const mkEvent = function (once) {
var handlers = [];
var fired = false;
return {
reg: function (cb) {
if (once && fired) { return void setTimeout(cb); }
handlers.push(cb);
},
unreg: function (cb) {
if (handlers.indexOf(cb) === -1) { throw new Error("Not registered"); }
handlers.splice(handlers.indexOf(cb), 1);
},
fire: function () {
if (once && fired) { return; }
fired = true;
var args = Array.prototype.slice.call(arguments);
handlers.forEach(function (h) { h.apply(null, args); });
}
};
};
/*::const ConfigType = require('./config.example.js');*/ /*::const ConfigType = require('./config.example.js');*/
RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)=>void*/) { RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)=>void*/) {
// load pin-store... // load pin-store...
@ -909,14 +1009,19 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
return typeof(config[key]) === 'string'? config[key]: def; return typeof(config[key]) === 'string'? config[key]: def;
}; };
var Env = {}; var Env = {
Env.defaultStorageLimit = config.defaultStorageLimit; defaultStorageLimit: config.defaultStorageLimit,
maxUploadSize: config.maxUploadSize || (20 * 1024 * 1024),
Env.maxUploadSize = config.maxUploadSize || (20 * 1024 * 1024); Sessions: {},
paths: {},
var Sessions = Env.Sessions = {}; msgStore: (undefined /*:any*/),
pinStore: (undefined /*:any*/),
pinnedPads: {},
evPinnedPadsReady: mkEvent(true)
};
var paths = Env.paths = {}; var Sessions = Env.Sessions;
var paths = Env.paths;
var pinPath = paths.pin = keyOrDefaultString('pinPath', './pins'); var pinPath = paths.pin = keyOrDefaultString('pinPath', './pins');
var blobPath = paths.blob = keyOrDefaultString('blobPath', './blob'); var blobPath = paths.blob = keyOrDefaultString('blobPath', './blob');
var blobStagingPath = paths.staging = keyOrDefaultString('blobStagingPath', './blobstage'); var blobStagingPath = paths.staging = keyOrDefaultString('blobStagingPath', './blobstage');
@ -943,6 +1048,10 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
} }
respond(e, [null, dict, null]); respond(e, [null, dict, null]);
}); });
case 'IS_CHANNEL_PINNED':
return void isChannelPinned(Env, msg[1], function (isPinned) {
respond(null, [null, isPinned, null]);
});
default: default:
console.error("unsupported!"); console.error("unsupported!");
return respond('UNSUPPORTED_RPC_CALL', msg); return respond('UNSUPPORTED_RPC_CALL', msg);
@ -1174,6 +1283,8 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)
updateLimitDaily(); updateLimitDaily();
setInterval(updateLimitDaily, 24*3600*1000); setInterval(updateLimitDaily, 24*3600*1000);
loadChannelPins(Env);
Store.create({ Store.create({
filePath: pinPath, filePath: pinPath,
}, function (s) { }, function (s) {

@ -102,6 +102,7 @@ app.use("/blob", Express.static(Path.join(__dirname, (config.blobPath || './blob
app.use("/customize", Express.static(__dirname + '/customize')); app.use("/customize", Express.static(__dirname + '/customize'));
app.use("/customize", Express.static(__dirname + '/customize.dist')); app.use("/customize", Express.static(__dirname + '/customize.dist'));
app.use("/customize.dist", Express.static(__dirname + '/customize.dist'));
app.use(/^\/[^\/]*$/, Express.static('customize')); app.use(/^\/[^\/]*$/, Express.static('customize'));
app.use(/^\/[^\/]*$/, Express.static('customize.dist')); app.use(/^\/[^\/]*$/, Express.static('customize.dist'));

@ -5,6 +5,8 @@
@import (once) '../../customize/src/less2/include/alertify.less'; @import (once) '../../customize/src/less2/include/alertify.less';
@import (once) '../../customize/src/less2/include/tokenfield.less'; @import (once) '../../customize/src/less2/include/tokenfield.less';
@_cp-toolbar-color-warn: @colortheme_code-warn;
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();
.alertify_main(); .alertify_main();

@ -605,6 +605,7 @@ define([
var initialized = false; var initialized = false;
return function (f, rdyCfg) { return function (f, rdyCfg) {
rdyCfg = rdyCfg || {};
if (initialized) { if (initialized) {
return void setTimeout(function () { f(void 0, env); }); return void setTimeout(function () { f(void 0, env); });
} }

@ -1,4 +1,4 @@
@import (once) '../customize/src/less2/include/colortheme.less'; @import (once) '../customize/src/less2/include/colortheme-all.less';
@import '../customize/src/less2/include/modal.less'; @import '../customize/src/less2/include/modal.less';
.fileDialog_main () { .fileDialog_main () {

@ -461,7 +461,16 @@ define([
getHeadingText: function () { return titleRecommender(); } getHeadingText: function () { return titleRecommender(); }
}, onLocal); }, onLocal);
var configTb = { var configTb = {
displayed: ['userlist', 'title', 'useradmin', 'spinner', 'newpad', 'share', 'limit'], displayed: [
'userlist',
'title',
'useradmin',
'spinner',
'newpad',
'share',
'limit',
'unpinnedWarning'
],
title: title.getTitleConfig(), title: title.getTitleConfig(),
metadataMgr: cpNfInner.metadataMgr, metadataMgr: cpNfInner.metadataMgr,
readOnly: readOnly, readOnly: readOnly,

@ -719,6 +719,26 @@ define([
return $titleContainer; return $titleContainer;
}; };
var createUnpinnedWarning = function (toolbar, config) {
if (Common.isLoggedIn()) { return; }
var pd = config.metadataMgr.getPrivateData();
var o = pd.origin;
var hashes = pd.availableHashes;
var url = pd.origin + pd.pathname + '#' + (hashes.editHash || hashes.viewHash);
var cid = Hash.hrefToHexChannelId(url);
Common.sendAnonRpcMsg('IS_CHANNEL_PINNED', cid, function (x) {
if (x.error || !Array.isArray(x.response)) { return void console.log(x); }
if (x.response[0] === true) { return; }
var msg = $('<span>', {
'class': 'cp-pad-not-pinned',
}).append(
Messages._getKey('padNotPinned', [o + '/login', o + '/register'])
);
$('.cp-toolbar-title').append(msg);
console.log("This pad is not pinned");
});
};
var createPageTitle = function (toolbar, config) { var createPageTitle = function (toolbar, config) {
if (config.title || !config.pageTitle) { return; } if (config.title || !config.pageTitle) { return; }
var $titleContainer = $('<span>', { var $titleContainer = $('<span>', {
@ -1087,6 +1107,7 @@ define([
tb['upgrade'] = $.noop; tb['upgrade'] = $.noop;
tb['newpad'] = createNewPad; tb['newpad'] = createNewPad;
tb['useradmin'] = createUserAdmin; tb['useradmin'] = createUserAdmin;
tb['unpinnedWarning'] = createUnpinnedWarning;
var addElement = toolbar.addElement = function (arr, additionnalCfg, init) { var addElement = toolbar.addElement = function (arr, additionnalCfg, init) {
if (typeof additionnalCfg === "object") { $.extend(true, config, additionnalCfg); } if (typeof additionnalCfg === "object") { $.extend(true, config, additionnalCfg); }

@ -8,6 +8,7 @@
@import (once) '../../customize/src/less2/include/avatar.less'; @import (once) '../../customize/src/less2/include/avatar.less';
@_cp-toolbar-color-warn: @colortheme_friends-warn;;
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();

@ -8,6 +8,8 @@
@import (once) "../../customize/src/less2/include/limit-bar.less"; @import (once) "../../customize/src/less2/include/limit-bar.less";
@import (once) "../../customize/src/less2/include/tokenfield.less"; @import (once) "../../customize/src/less2/include/tokenfield.less";
@_cp-toolbar-color-warn: @colortheme_drive-warn;
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();
.alertify_main(); .alertify_main();

@ -5,6 +5,8 @@
@import (once) '../../customize/src/less2/include/alertify.less'; @import (once) '../../customize/src/less2/include/alertify.less';
@import (once) '../../customize/src/less2/include/tokenfield.less'; @import (once) '../../customize/src/less2/include/tokenfield.less';
@_cp-toolbar-color-warn: @colortheme_file-warn;
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();
.alertify_main(); .alertify_main();

@ -1,4 +1,4 @@
@import (once) '../../customize/src/less2/include/colortheme.less'; @import (once) '../../customize/src/less2/include/colortheme-all.less';
@import (once) '../../customize/src/less2/include/modal.less'; @import (once) '../../customize/src/less2/include/modal.less';
@import (once) '../../customize/src/less2/include/icon-colors.less'; @import (once) '../../customize/src/less2/include/icon-colors.less';
@import (once) '../../customize/src/less2/include/fileupload.less'; @import (once) '../../customize/src/less2/include/fileupload.less';

@ -6,6 +6,8 @@
@import (once) '../../customize/src/less2/include/alertify.less'; @import (once) '../../customize/src/less2/include/alertify.less';
@import (once) '../../customize/src/less2/include/tokenfield.less'; @import (once) '../../customize/src/less2/include/tokenfield.less';
@_cp-toolbar-color-warn: @colortheme_pad-warn;
.toolbar_main(); .toolbar_main();
.alertify_main(); .alertify_main();

@ -13,6 +13,8 @@
@import (once) '../../customize/src/less2/include/tools.less'; @import (once) '../../customize/src/less2/include/tools.less';
@import (once) '../../customize/src/less2/include/avatar.less'; @import (once) '../../customize/src/less2/include/avatar.less';
@_cp-toolbar-color-warn: @colortheme_poll-warn;
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();
.alertify_main(); .alertify_main();

@ -1,10 +1,12 @@
@import (once) "../../customize/src/less2/include/colortheme.less"; @import (once) "../../customize/src/less2/include/colortheme-all.less";
@import (once) "../../customize/src/less2/include/browser.less"; @import (once) "../../customize/src/less2/include/browser.less";
@import (once) "../../customize/src/less2/include/toolbar.less"; @import (once) "../../customize/src/less2/include/toolbar.less";
@import (once) "../../customize/src/less2/include/markdown.less"; @import (once) "../../customize/src/less2/include/markdown.less";
@import (once) '../../customize/src/less2/include/alertify.less'; @import (once) '../../customize/src/less2/include/alertify.less';
@import (once) '../../customize/src/less2/include/sidebar-layout.less'; @import (once) '../../customize/src/less2/include/sidebar-layout.less';
@import (once) "../../customize/src/less2/include/limit-bar.less"; @import (once) "../../customize/src/less2/include/limit-bar.less";
@_cp-toolbar-color-warn: @colortheme_settings-warn;
.toolbar_main(); .toolbar_main();
.alertify_main(); .alertify_main();

@ -6,6 +6,8 @@
@import (once) "../../customize/src/less2/include/mediatag.less"; @import (once) "../../customize/src/less2/include/mediatag.less";
@import (once) '../../customize/src/less2/include/tokenfield.less'; @import (once) '../../customize/src/less2/include/tokenfield.less';
@_cp-toolbar-color-warn: @colortheme_slide-warn;
.mediatag_base(); .mediatag_base();
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();

@ -6,6 +6,8 @@
@import (once) '../../customize/src/less2/include/tools.less'; @import (once) '../../customize/src/less2/include/tools.less';
@import (once) '../../customize/src/less2/include/tokenfield.less'; @import (once) '../../customize/src/less2/include/tokenfield.less';
@_cp-toolbar-color-warn: @colortheme_whiteboard-warn;
.toolbar_main(); .toolbar_main();
.fileupload_main(); .fileupload_main();
.alertify_main(); .alertify_main();

@ -393,7 +393,16 @@ define([
Title = common.createTitle({}); Title = common.createTitle({});
var configTb = { var configTb = {
displayed: ['title', 'useradmin', 'spinner', 'share', 'userlist', 'newpad', 'limit'], displayed: [
'userlist',
'title',
'useradmin',
'spinner',
'newpad',
'share',
'limit',
'unpinnedWarning'
],
title: Title.getTitleConfig(), title: Title.getTitleConfig(),
metadataMgr: metadataMgr, metadataMgr: metadataMgr,
readOnly: readOnly, readOnly: readOnly,

Loading…
Cancel
Save