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

pull/1/head
Caleb James DeLisle 8 years ago
commit 9148aab636

@ -81,20 +81,20 @@
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li>CryptPad<li>
<li><a href="/about" data-localization="about"></a></li>
<li><a href="/terms" data-localization="terms"></a></li>
<li><a href="/privacy" data-localization="privacy"></a></li>
<li>CryptPad</li>
<li><a href="/about.html" data-localization="about"></a></li>
<li><a href="/terms.html" data-localization="terms"></a></li>
<li><a href="/privacy.html" data-localization="privacy"></a></li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li data-localization="footer_applications"><li>
<li><a href="/pad/" data-localization="main_richText"></a></li>
<li><a href="#" data-localization="main_code"></a></li>
<li><a href="#" data-localization="main_slide"></a></li>
<li><a href="#" data-localization="main_poll"></a></li>
<li><a href="#" data-localization="main_drive"></a></li>
<li><a href="/code/" data-localization="main_code"></a></li>
<li><a href="/slide/" data-localization="main_slide"></a></li>
<li><a href="/poll/" data-localization="main_poll"></a></li>
<li><a href="/drive/" data-localization="main_drive"></a></li>
</ul>
</div>
<div class="col">
@ -111,7 +111,7 @@
<li><a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" target="_blank" rel="noopener noreferrer">IRC</a></li>
<li><a href="https://twitter.com/cryptpad" target="_blank" rel="noopener noreferrer">Twitter</a></li>
<li><a href="https://github.com/xwiki-labs/cryptpad" target="_blank" rel="noopener noreferrer">GitHub</a></li>
<li><a href="/contact">Email</a></li>
<li><a href="/contact.html">Email</a></li>
</ul>
</div>
</div>

@ -12,8 +12,5 @@ define(function() {
*/
config.notificationTimeout = 5000;
config.USE_FS_STORE = true;
config.USE_HOMEPAGE_TABLE = false;
return config;
});

@ -78,20 +78,20 @@
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li>CryptPad<li>
<li><a href="/about" data-localization="about"></a></li>
<li><a href="/terms" data-localization="terms"></a></li>
<li><a href="/privacy" data-localization="privacy"></a></li>
<li>CryptPad</li>
<li><a href="/about.html" data-localization="about"></a></li>
<li><a href="/terms.html" data-localization="terms"></a></li>
<li><a href="/privacy.html" data-localization="privacy"></a></li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li data-localization="footer_applications"><li>
<li><a href="/pad/" data-localization="main_richText"></a></li>
<li><a href="#" data-localization="main_code"></a></li>
<li><a href="#" data-localization="main_slide"></a></li>
<li><a href="#" data-localization="main_poll"></a></li>
<li><a href="#" data-localization="main_drive"></a></li>
<li><a href="/code/" data-localization="main_code"></a></li>
<li><a href="/slide/" data-localization="main_slide"></a></li>
<li><a href="/poll/" data-localization="main_poll"></a></li>
<li><a href="/drive/" data-localization="main_drive"></a></li>
</ul>
</div>
<div class="col">
@ -108,7 +108,7 @@
<li><a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" target="_blank" rel="noopener noreferrer">IRC</a></li>
<li><a href="https://twitter.com/cryptpad" target="_blank" rel="noopener noreferrer">Twitter</a></li>
<li><a href="https://github.com/xwiki-labs/cryptpad" target="_blank" rel="noopener noreferrer">GitHub</a></li>
<li><a href="/contact">Email</a></li>
<li><a href="/contact.html">Email</a></li>
</ul>
</div>
</div>

@ -16,133 +16,116 @@ define([
*/
var Store = {};
var storeObj;
var ready = false;
var filesOp;
var exp = {};
var store;
var safeSet = function (key, val) {
storeObj[key] = val;
};
var initStore = function (filesOp, storeObj, exp) {
var ret = {};
// Store uses nodebacks...
Store.set = function (key, val, cb) {
safeSet(key, val);
cb();
};
var safeSet = function (key, val) {
storeObj[key] = val;
};
// implement in alternative store
Store.setBatch = function (map, cb) {
Object.keys(map).forEach(function (key) {
safeSet(key, map[key]);
});
cb(void 0, map);
};
// Store uses nodebacks...
ret.set = function (key, val, cb) {
safeSet(key, val);
cb();
};
Store.setDrive = function (key, val, cb) {
storeObj.drive[key] = val;
cb();
};
// implement in alternative store
ret.setBatch = function (map, cb) {
Object.keys(map).forEach(function (key) {
safeSet(key, map[key]);
});
cb(void 0, map);
};
var safeGet = window.safeGet = function (key) {
return storeObj[key];
};
ret.setDrive = function (key, val, cb) {
storeObj.drive[key] = val;
cb();
};
Store.get = function (key, cb) {
cb(void 0, safeGet(key));
};
var safeGet = function (key) {
return storeObj[key];
};
// implement in alternative store
Store.getBatch = function (keys, cb) {
var res = {};
keys.forEach(function (key) {
res[key] = safeGet(key);
});
cb(void 0, res);
};
ret.get = function (key, cb) {
cb(void 0, safeGet(key));
};
Store.getDrive = function (key, cb) {
cb(void 0, storeObj.drive[key]);
};
// implement in alternative store
ret.getBatch = function (keys, cb) {
var res = {};
keys.forEach(function (key) {
res[key] = safeGet(key);
});
cb(void 0, res);
};
var safeRemove = function (key) {
delete storeObj[key];
};
ret.getDrive = function (key, cb) {
cb(void 0, storeObj.drive[key]);
};
Store.remove = function (key, cb) {
safeRemove(key);
cb();
};
var safeRemove = function (key) {
delete storeObj[key];
};
// implement in alternative store
Store.removeBatch = function (keys, cb) {
keys.forEach(function (key) {
ret.remove = function (key, cb) {
safeRemove(key);
});
cb();
};
cb();
};
Store.keys = function (cb) {
cb(void 0, Object.keys(storeObj));
};
// implement in alternative store
ret.removeBatch = function (keys, cb) {
keys.forEach(function (key) {
safeRemove(key);
});
cb();
};
Store.addPad = function (href, path, name) {
filesOp.addPad(href, path, name);
};
ret.keys = function (cb) {
cb(void 0, Object.keys(storeObj));
};
Store.forgetPad = function (href, cb) {
filesOp.forgetPad(href);
cb();
};
ret.addPad = function (href, path, name) {
filesOp.addPad(href, path, name);
};
Store.addTemplate = function (href) {
filesOp.addTemplate(href);
};
ret.forgetPad = function (href, cb) {
filesOp.forgetPad(href);
cb();
};
Store.listTemplates = function () {
return filesOp.listTemplates();
};
ret.addTemplate = function (href) {
filesOp.addTemplate(href);
};
Store.getProxy = function () {
return exp;
};
ret.listTemplates = function () {
return filesOp.listTemplates();
};
Store.getLoginName = function () {
return storeObj.login_name;
};
ret.getProxy = function () {
return exp;
};
var changeHandlers = Store.changeHandlers = [];
ret.getLoginName = function () {
return storeObj.login_name;
};
Store.change = function (f) {
if (typeof(f) !== 'function') {
throw new Error('[Store.change] callback must be a function');
}
changeHandlers.push(f);
if (changeHandlers.length === 1) {
// start listening for changes
/* TODO: listen for changes in the proxy
window.addEventListener('storage', function (e) {
changeHandlers.forEach(function (f) {
f({
key: e.key,
oldValue: e.oldValue,
newValue: e.newValue,
});
});
});
*/
}
var changeHandlers = ret.changeHandlers = [];
ret.change = function (f) {};
return ret;
};
var onReady = function (f, proxy, storageKey) {
filesOp = FO.init(proxy.drive, {
var onReady = function (f, proxy, storageKey, exp) {
var fo = FO.init(proxy.drive, {
storageKey: storageKey
});
storeObj = proxy;
ready = true;
//storeObj = proxy;
store = initStore(fo, proxy, exp);
if (typeof(f) === 'function') {
f(void 0, Store);
f(void 0, store);
}
};
@ -167,6 +150,8 @@ define([
logLevel: 1,
};
var exp = {};
window.addEventListener('storage', function (e) {
var key = e.key;
if (e.key !== Cryptpad.userHashKey) { return; }
@ -175,8 +160,6 @@ define([
if (!o && n) {
window.location.reload();
} else if (o && !n) {
//window.location.reload();
//window.location.href = '/';
$(window).on('keyup', function (e) {
if (e.keyCode === 27) {
Cryptpad.removeLoadingScreen();
@ -192,6 +175,7 @@ define([
});
var rt = window.rt = Listmap.create(listmapConfig);
exp.proxy = rt.proxy;
rt.proxy.on('create', function (info) {
exp.info = info;
@ -199,44 +183,36 @@ define([
localStorage.FS_hash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
}
}).on('ready', function () {
if (ready) { return; }
if (store) { return; } // the store is already ready, it is a reconnection
if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; }
var drive = rt.proxy.drive;
// Creating a new anon drive: import anon pads from localStorage
if (!drive[Cryptpad.storageKey] || !Cryptpad.isArray(drive[Cryptpad.storageKey])) {
var oldStore = Cryptpad.getStore(true);
Cryptpad.getRecentPads(function (err, s) {
drive[Cryptpad.storageKey] = s;
onReady(f, rt.proxy, Cryptpad.storageKey);
}, true);
Cryptpad.getLegacyPads(function (err, data) {
drive[Cryptpad.storageKey] = data;
onReady(f, rt.proxy, Cryptpad.storageKey, exp);
});
return;
}
onReady(f, rt.proxy, Cryptpad.storageKey);
// Drive already exist: return the existing drive, don't load data from legacy store
onReady(f, rt.proxy, Cryptpad.storageKey, exp);
})
.on('disconnect', function (info) {
//setEditable(false);
// We only manage errors during the loading screen here. Other websocket errors are handled by the apps
if (info.error) {
//Cryptpad.alert(Messages.websocketError);
if (typeof Cryptpad.storeError === "function") {
Cryptpad.storeError();
}
return;
}
//Cryptpad.alert(Messages.common_connectionLost);
});
};
Store.ready = function (f, Cryptpad) {
/*if (Cryptpad.parsePadUrl(window.location.href).type === "file") {
if (typeof(f) === 'function') {
f(void 0, Cryptpad.getStore(true));
}
return;
}*/
if (ready) {
if (store) { // Store.ready probably called twice, store already ready
if (typeof(f) === 'function') {
f(void 0, Store);
f(void 0, store);
}
} else {
init(f, Cryptpad);

@ -69,25 +69,20 @@
<div id="main">
<div class="mainOverlay"></div>
<div id="align-container">
<div id="main-container">
<div id="data" class="hidden">
<p class="left" data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>
<div id="buttons" class="buttons"><button class="btn btn-secondary nologin" data-localization="login_nologin"></button></div>
<p class="left" data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>
</div>
<div id="userForm" class="form-group hidden">
<!--<center>
<h1 data-localization="form_title"></h1>
</center>-->
<!--<label for="name" data-localization="form_username"></label>-->
<input type="text" id="name" name="name" class="form-control" data-localization-placeholder="login_username" autofocus><br>
<!--<label for="password" data-localization="form_password"></label>-->
<input type="password" id="password" name="password" class="form-control" data-localization-placeholder="login_password"><br>
<input type="text" id="name" name="name" class="form-control" data-localization-placeholder="login_username" autofocus>
<input type="password" id="password" name="password" class="form-control" data-localization-placeholder="login_password">
<div style="display: none;"><span class="remember form-check"><label for="rememberme" class="form-check-label" data-localization-append="login_remember"><input type="checkbox" id="rememberme" class="form-check-input" checked="checked"></label></span><br></div>
<button class="btn btn-secondary login half first" data-localization="login_login"></button> <button class="btn btn-primary register half" data-localization="login_register"></button><br>
<button class="btn btn-secondary login half first" data-localization="login_login"></button> <button class="btn btn-success register half" data-localization="login_register"></button>
<p class="separator" data-localization="login_orNoLogin"></p>
<p id="buttons" class="buttons"></p>
<p class="driveLink"><a class="nologin" href="/drive/" data-localization="login_nologin"></a></p>
</div>
<div id="loggedIn" class="hidden">
<p id="loggedInHello"></p>
@ -95,6 +90,7 @@
<p><button id="loggedInLogOut" class="btn btn-secondary" data-localization="logoutButton"></button></p>
</div>
</div>
</div>
</div>
<div class="page category first" id="knowmore">
<center>
@ -204,20 +200,20 @@
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li>CryptPad<li>
<li><a href="/about" data-localization="about"></a></li>
<li><a href="/terms" data-localization="terms"></a></li>
<li><a href="/privacy" data-localization="privacy"></a></li>
<li>CryptPad</li>
<li><a href="/about.html" data-localization="about"></a></li>
<li><a href="/terms.html" data-localization="terms"></a></li>
<li><a href="/privacy.html" data-localization="privacy"></a></li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li data-localization="footer_applications"><li>
<li><a href="/pad/" data-localization="main_richText"></a></li>
<li><a href="#" data-localization="main_code"></a></li>
<li><a href="#" data-localization="main_slide"></a></li>
<li><a href="#" data-localization="main_poll"></a></li>
<li><a href="#" data-localization="main_drive"></a></li>
<li><a href="/code/" data-localization="main_code"></a></li>
<li><a href="/slide/" data-localization="main_slide"></a></li>
<li><a href="/poll/" data-localization="main_poll"></a></li>
<li><a href="/drive/" data-localization="main_drive"></a></li>
</ul>
</div>
<div class="col">
@ -234,7 +230,7 @@
<li><a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" target="_blank" rel="noopener noreferrer">IRC</a></li>
<li><a href="https://twitter.com/cryptpad" target="_blank" rel="noopener noreferrer">Twitter</a></li>
<li><a href="https://github.com/xwiki-labs/cryptpad" target="_blank" rel="noopener noreferrer">GitHub</a></li>
<li><a href="/contact">Email</a></li>
<li><a href="/contact.html">Email</a></li>
</ul>
</div>
</div>

@ -450,28 +450,33 @@
#cryptpadTopBar .right a {
font-weight: 500;
font-size: 0.75em;
color: #558;
color: #41b7d8;
}
#cryptpadTopBar .right a:hover {
color: #279ebf !important;
text-decoration: underline;
}
#cryptpadTopBar .right a:visited {
color: #41b7d8;
}
.cp footer {
background: #cccccc;
background: #f4f4f4;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
padding-top: 1em;
font-size: 1.2em;
}
.cp footer a {
color: #555;
color: #41b7d8;
}
.cp footer a:visited {
color: #777;
color: #41b7d8;
}
.cp footer a:hover {
color: #333;
color: #279ebf !important;
}
.cp footer li:first-child {
font-size: 1.2em;
font-weight: bold;
text-decoration: underline;
}
html.cp,
.cp body {
@ -560,10 +565,10 @@ html.cp,
text-decoration: none;
}
.cp a:hover {
color: #279ebf;
color: #279ebf !important;
}
.cp a:visited {
color: #558;
color: #41b7d8;
}
.cp img {
height: auto;
@ -600,7 +605,7 @@ html.cp,
}
.cp .page .info-container {
color: #121212;
width: 900px;
width: 800px;
max-width: 100%;
margin: 0 auto;
}
@ -630,7 +635,7 @@ html.cp,
@media screen and (max-width: 800px) {
}
.cp .page.category {
background: #f7f7f7;
background: #f4f4f4;
}
.cp .page .app {
display: inline-block;
@ -687,7 +692,6 @@ html.cp,
}
.cp .page p {
font-size: 18px;
text-align: justify;
}
.cp .btn-default:hover {
background-color: #d8d8d8;
@ -757,8 +761,8 @@ html.cp,
z-index: 1;
font-size: medium;
}
.cp #main #main-container,
.cp #main_other #main-container {
.cp #main #align-container,
.cp #main_other #align-container {
position: absolute;
top: 50%;
left: 50%;
@ -769,24 +773,29 @@ html.cp,
width: 1000px;
max-width: 90%;
}
.cp #main #main-container,
.cp #main_other #main-container {
position: absolute;
display: inline-block;
top: 50%;
left: 0;
transform: translateY(-50%);
width: 100%;
}
.cp #main #data,
.cp #main_other #data {
width: 600px;
max-width: 60%;
color: #fff;
padding: 15px;
padding: 0 15px;
box-sizing: border-box;
position: absolute;
display: inline-block;
top: 50%;
left: 0;
transform: translateY(-50%);
}
.cp #main #data p,
.cp #main_other #data p {
margin: 0;
padding: 0;
font-size: 20px;
font-size: 28px;
line-height: 1.5em;
}
.cp #main #data h1,
@ -797,6 +806,7 @@ html.cp,
font-size: 48px;
line-height: 1.2em;
color: #fff;
padding: 0;
}
.cp #main #data h5,
.cp #main_other #data h5 {
@ -810,15 +820,11 @@ html.cp,
}
.cp #main #loggedIn,
.cp #main_other #loggedIn {
float: right;
color: #fff;
display: inline-block;
position: absolute;
top: 50%;
right: 0;
margin-left: 50px;
width: 350px;
max-width: 35%;
transform: translateY(-50%);
text-align: center;
font-weight: bold;
}
@ -836,11 +842,7 @@ html.cp,
}
.cp #main #userForm,
.cp #main_other #userForm {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
margin-left: 50px;
float: right;
display: inline-block;
width: 350px;
max-width: 35%;
@ -848,47 +850,15 @@ html.cp,
box-sizing: border-box;
font-family: lato, Helvetica, sans-serif;
color: #fff;
/*.remember {
vertical-align: middle;
line-height: 28px;
height: 28px;
display: inline-block;
margin: 10px 0 20px 0;
}
[type="checkbox"] {
vertical-align: text-top;
margin: 0;
//margin-top: 10px;
margin-right: 5px;
}
*/
}
.cp #main #userForm h1,
.cp #main_other #userForm h1 {
color: #fff;
padding: 0;
}
.cp #main #userForm [type="text"],
.cp #main_other #userForm [type="text"],
.cp #main #userForm [type="password"],
.cp #main_other #userForm [type="password"] {
width: 100%;
}
.cp #main #userForm label,
.cp #main_other #userForm label {
margin-bottom: 0;
}
.cp #main #userForm [type="checkbox"],
.cp #main_other #userForm [type="checkbox"] {
margin-right: 5px;
}
.cp #main #userForm button,
.cp #main_other #userForm button {
font-weight: bold;
width: 100%;
margin: 2px 0px;
cursor: pointer;
}
.cp #main #userForm button.half,
@ -899,17 +869,80 @@ html.cp,
.cp #main_other #userForm button.half:not(.first) {
float: right;
}
.cp #main #userForm p,
.cp #main_other #userForm p {
margin: 0;
padding: 0;
}
.cp #main #userForm p.buttons,
.cp #main_other #userForm p.buttons {
margin-bottom: 10px;
}
.cp #main #userForm p.buttons .dropdown-bar,
.cp #main_other #userForm p.buttons .dropdown-bar {
display: block;
}
.cp #main #userForm p.buttons .dropdown-bar button,
.cp #main_other #userForm p.buttons .dropdown-bar button {
white-space: normal;
text-align: left;
}
.cp #main #userForm p.buttons .dropdown-bar button .fa,
.cp #main_other #userForm p.buttons .dropdown-bar button .fa {
float: right;
}
.cp #main #userForm p.separator,
.cp #main_other #userForm p.separator {
margin: 5px 0 15px 0;
text-align: center;
font-weight: bold;
font-size: 1.1em;
}
.cp #main #userForm p a,
.cp #main_other #userForm p a {
color: #fff;
font-weight: bold;
font-size: 14px;
}
.cp #main #userForm p a:hover,
.cp #main_other #userForm p a:hover,
.cp #main #userForm p a :visited,
.cp #main_other #userForm p a :visited {
color: #fff !important;
}
.cp #main #userForm .driveLink,
.cp #main_other #userForm .driveLink {
padding-left: 1rem;
font-size: 1em;
}
.cp #main #userForm > *,
.cp #main_other #userForm > * {
margin-bottom: 10px;
}
@media screen and (max-width: 800px) {
.cp #main #main-container,
.cp #main_other #main-container {
.cp #main,
.cp #main_other {
position: relative;
height: auto;
}
.cp #main #align-container,
.cp #main_other #align-container {
transform: initial;
position: relative;
display: block;
width: 90%;
left: 0;
}
}
@media screen and (max-width: 800px) {
.cp #main #main-container,
.cp #main_other #main-container {
position: relative;
transform: unset;
top: 0;
}
.cp #main #data,
.cp #main_other #data {
text-align: center;
}
.cp #main #userForm,
.cp #main_other #userForm,
.cp #main #loggedIn,
@ -923,42 +956,13 @@ html.cp,
max-width: 100%;
margin: 10px 0;
box-sizing: border-box;
}
}
@media screen and (max-width: 800px) {
.cp #main #userForm,
.cp #main_other #userForm,
.cp #main #loggedIn,
.cp #main_other #loggedIn {
border: 1px solid #888;
}
}
@media screen and (max-width: 800px) {
.cp #main,
.cp #main_other {
position: relative;
height: auto;
top: -10px;
float: none;
}
}
.cp #main .buttons,
.cp #main_other .buttons {
margin-top: 15px;
}
.cp p.buttons,
.cp div.buttons {
text-align: center;
}
.cp p.buttons button,
.cp div.buttons button {
font-weight: bold;
cursor: pointer;
margin-top: 10px;
}
.cp p.buttons .dropdown-bar,
.cp div.buttons .dropdown-bar {
margin-left: 4px;
}
.cp #fileManagerIframe {
width: 100%;
height: 500px;

@ -7,111 +7,114 @@ define([
'/bower_components/jquery/dist/jquery.min.js',
], function (Messages, Config, Cryptpad, LilUri, LS) {
var $ = window.$;
var $main = $('#mainBlock');
var APP = window.APP = {
Cryptpad: Cryptpad,
};
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
$(function () {
var $main = $('#mainBlock');
$(window).click(function () {
$('.cryptpad-dropdown').hide();
});
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
$(window).click(function () {
$('.cryptpad-dropdown').hide();
});
// main block is hidden in case javascript is disabled
$main.removeClass('hidden');
// main block is hidden in case javascript is disabled
$main.removeClass('hidden');
// Make sure we don't display non-translated content (empty button)
$main.find('#data').removeClass('hidden');
// Make sure we don't display non-translated content (empty button)
$main.find('#data').removeClass('hidden');
if (Cryptpad.isLoggedIn()) {
var name = localStorage[Cryptpad.userNameKey] || sessionStorage[Cryptpad.userNameKey];
var $loggedInBlock = $main.find('#loggedIn');
var $hello = $loggedInBlock.find('#loggedInHello');
var $logout = $loggedInBlock.find('#loggedInLogOut');
if (Cryptpad.isLoggedIn()) {
var name = localStorage[Cryptpad.userNameKey] || sessionStorage[Cryptpad.userNameKey];
var $loggedInBlock = $main.find('#loggedIn');
var $hello = $loggedInBlock.find('#loggedInHello');
var $logout = $loggedInBlock.find('#loggedInLogOut');
if (name) {
$hello.text(Messages._getKey('login_hello', [name]));
} else {
$hello.text(Messages.login_helloNoName);
}
$('#buttons').find('.nologin').hide();
if (name) {
$hello.text(Messages._getKey('login_hello', [name]));
$logout.click(function () {
Cryptpad.logout(function () {
window.location.reload();
});
});
$loggedInBlock.removeClass('hidden');
//return;
} else {
$hello.text(Messages.login_helloNoName);
$main.find('#userForm').removeClass('hidden');
}
$('#buttons').find('.nologin').hide();
$logout.click(function () {
Cryptpad.logout(function () {
window.location.reload();
var displayCreateButtons = function () {
var $parent = $('#buttons');
var options = [];
var $container = $('<div>', {'class': 'dropdown-bar'}).appendTo($parent);
Config.availablePadTypes.forEach(function (el) {
if (el === 'drive') { return; }
options.push({
tag: 'a',
attributes: {
'class': 'newdoc',
'href': '/' + el + '/',
'target': '_blank'
},
content: Messages['button_new' + el] // Pretty name of the language value
});
});
var dropdownConfig = {
text: Messages.login_makeAPad, // Button initial text
options: options, // Entries displayed in the menu
container: $container
};
var $block = Cryptpad.createDropdown(dropdownConfig);
$block.find('button').addClass('btn').addClass('btn-primary');
$block.appendTo($parent);
};
var addButtonHandlers = function () {
$('button.login').click(function (e) {
var username = $('#name').val();
var passwd = $('#password').val();
var remember = $('#rememberme').is(':checked');
sessionStorage.login_user = username;
sessionStorage.login_pass = passwd;
sessionStorage.login_rmb = remember;
sessionStorage.login = 1;
document.location.href = '/user/';
});
$('button.register').click(function (e) {
var username = $('#name').val();
var passwd = $('#password').val();
var remember = $('#rememberme').is(':checked');
sessionStorage.login_user = username;
sessionStorage.login_pass = passwd;
sessionStorage.login_rmb = remember;
sessionStorage.register = 1;
document.location.href = '/user/';
});
});
$loggedInBlock.removeClass('hidden');
//return;
} else {
$main.find('#userForm').removeClass('hidden');
}
var displayCreateButtons = function () {
var $parent = $('#buttons');
var options = [];
Config.availablePadTypes.forEach(function (el) {
if (el === 'drive') { return; }
options.push({
tag: 'a',
attributes: {
'class': 'newdoc',
'href': '/' + el + '/',
'target': '_blank'
},
content: Messages['button_new' + el] // Pretty name of the language value
var $passwd = $('#password');
$passwd.on('keyup', function (e) {
if (e.which !== 13) { return; } // enter
$('button.login').click();
});
});
var dropdownConfig = {
text: Messages.makeAPad, // Button initial text
options: options, // Entries displayed in the menu
};
var $block = Cryptpad.createDropdown(dropdownConfig);
$block.find('button').addClass('btn').addClass('btn-success');
$block.appendTo($parent);
};
var addButtonHandlers = function () {
$('button.login').click(function (e) {
var username = $('#name').val();
var passwd = $('#password').val();
var remember = $('#rememberme').is(':checked');
sessionStorage.login_user = username;
sessionStorage.login_pass = passwd;
sessionStorage.login_rmb = remember;
sessionStorage.login = 1;
document.location.href = '/user/';
});
$('button.register').click(function (e) {
var username = $('#name').val();
var passwd = $('#password').val();
var remember = $('#rememberme').is(':checked');
sessionStorage.login_user = username;
sessionStorage.login_pass = passwd;
sessionStorage.login_rmb = remember;
sessionStorage.register = 1;
document.location.href = '/user/';
});
$('button.nologin').click(function (e) {
document.location.href = '/drive/';
});
var $passwd = $('#password');
$passwd.on('keyup', function (e) {
if (e.which !== 13) { return; } // enter
$('button.login').click();
});
};
displayCreateButtons();
displayCreateButtons();
addButtonHandlers();
console.log("ready");
addButtonHandlers();
console.log("ready");
});
});

@ -100,20 +100,20 @@
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li>CryptPad<li>
<li><a href="/about" data-localization="about"></a></li>
<li><a href="/terms" data-localization="terms"></a></li>
<li><a href="/privacy" data-localization="privacy"></a></li>
<li>CryptPad</li>
<li><a href="/about.html" data-localization="about"></a></li>
<li><a href="/terms.html" data-localization="terms"></a></li>
<li><a href="/privacy.html" data-localization="privacy"></a></li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li data-localization="footer_applications"><li>
<li><a href="/pad/" data-localization="main_richText"></a></li>
<li><a href="#" data-localization="main_code"></a></li>
<li><a href="#" data-localization="main_slide"></a></li>
<li><a href="#" data-localization="main_poll"></a></li>
<li><a href="#" data-localization="main_drive"></a></li>
<li><a href="/code/" data-localization="main_code"></a></li>
<li><a href="/slide/" data-localization="main_slide"></a></li>
<li><a href="/poll/" data-localization="main_poll"></a></li>
<li><a href="/drive/" data-localization="main_drive"></a></li>
</ul>
</div>
<div class="col">
@ -130,7 +130,7 @@
<li><a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" target="_blank" rel="noopener noreferrer">IRC</a></li>
<li><a href="https://twitter.com/cryptpad" target="_blank" rel="noopener noreferrer">Twitter</a></li>
<li><a href="https://github.com/xwiki-labs/cryptpad" target="_blank" rel="noopener noreferrer">GitHub</a></li>
<li><a href="/contact">Email</a></li>
<li><a href="/contact.html">Email</a></li>
</ul>
</div>
</div>

@ -3,20 +3,20 @@
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li>CryptPad<li>
<li><a href="/about" data-localization="about"></a></li>
<li><a href="/terms" data-localization="terms"></a></li>
<li><a href="/privacy" data-localization="privacy"></a></li>
<li>CryptPad</li>
<li><a href="/about.html" data-localization="about"></a></li>
<li><a href="/terms.html" data-localization="terms"></a></li>
<li><a href="/privacy.html" data-localization="privacy"></a></li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li data-localization="footer_applications"><li>
<li><a href="/pad/" data-localization="main_richText"></a></li>
<li><a href="#" data-localization="main_code"></a></li>
<li><a href="#" data-localization="main_slide"></a></li>
<li><a href="#" data-localization="main_poll"></a></li>
<li><a href="#" data-localization="main_drive"></a></li>
<li><a href="/code/" data-localization="main_code"></a></li>
<li><a href="/slide/" data-localization="main_slide"></a></li>
<li><a href="/poll/" data-localization="main_poll"></a></li>
<li><a href="/drive/" data-localization="main_drive"></a></li>
</ul>
</div>
<div class="col">
@ -33,7 +33,7 @@
<li><a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" target="_blank" rel="noopener noreferrer">IRC</a></li>
<li><a href="https://twitter.com/cryptpad" target="_blank" rel="noopener noreferrer">Twitter</a></li>
<li><a href="https://github.com/xwiki-labs/cryptpad" target="_blank" rel="noopener noreferrer">GitHub</a></li>
<li><a href="/contact">Email</a></li>
<li><a href="/contact.html">Email</a></li>
</ul>
</div>
</div>

@ -2,25 +2,20 @@
<div id="main">
<div class="mainOverlay"></div>
<div id="align-container">
<div id="main-container">
<div id="data" class="hidden">
<p class="left" data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>
<div id="buttons" class="buttons"><button class="btn btn-secondary nologin" data-localization="login_nologin"></button></div>
<p class="left" data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>
</div>
<div id="userForm" class="form-group hidden">
<!--<center>
<h1 data-localization="form_title"></h1>
</center>-->
<!--<label for="name" data-localization="form_username"></label>-->
<input type="text" id="name" name="name" class="form-control" data-localization-placeholder="login_username" autofocus><br>
<!--<label for="password" data-localization="form_password"></label>-->
<input type="password" id="password" name="password" class="form-control" data-localization-placeholder="login_password"><br>
<input type="text" id="name" name="name" class="form-control" data-localization-placeholder="login_username" autofocus>
<input type="password" id="password" name="password" class="form-control" data-localization-placeholder="login_password">
<div style="display: none;"><span class="remember form-check"><label for="rememberme" class="form-check-label" data-localization-append="login_remember"><input type="checkbox" id="rememberme" class="form-check-input" checked="checked"></label></span><br></div>
<button class="btn btn-secondary login half first" data-localization="login_login"></button> <button class="btn btn-primary register half" data-localization="login_register"></button><br>
<button class="btn btn-secondary login half first" data-localization="login_login"></button> <button class="btn btn-success register half" data-localization="login_register"></button>
<p class="separator" data-localization="login_orNoLogin"></p>
<p id="buttons" class="buttons"></p>
<p class="driveLink"><a class="nologin" href="/drive/" data-localization="login_nologin"></a></p>
</div>
<div id="loggedIn" class="hidden">
<p id="loggedInHello"></p>
@ -28,6 +23,7 @@
<p><button id="loggedInLogOut" class="btn btn-secondary" data-localization="logoutButton"></button></p>
</div>
</div>
</div>
</div>
<div class="page category first" id="knowmore">
<center>

@ -96,16 +96,15 @@ h6 {
a {
cursor: pointer;
color: @cp-light-blue;
//#41b7d8; //@cp-darkblue;
color: @cp-link;
text-decoration: none;
&:hover {
color: darken(@cp-light-blue, 10%); //@cp-accent2;
color: @cp-link-hover;
}
&:visited {
color: @cp-purple;
color: @cp-link-visited;
}
}
@ -143,7 +142,7 @@ body.html {
.info-container {
color: #121212;
width: 900px;
width: 800px;
max-width: 100%;
margin: 0 auto;
&>div{
@ -179,7 +178,7 @@ body.html {
//background: darken(@base, 1%);
}
&.category {
background: darken(@base, 3%);
background: @category-bg;
}
.app {
@ -233,7 +232,7 @@ body.html {
p {
font-size: 18px;
text-align: justify;
//text-align: justify;
}
}
@ -313,7 +312,7 @@ body.html {
font-size: medium;
#main-container {
#align-container {
position: absolute;
top: 50%;
left: 50%;
@ -325,11 +324,20 @@ body.html {
max-width: 90%;
}
#main-container {
position: absolute;
display: inline-block;
top: 50%;
left: 0;
transform: translateY(-50%);
width: 100%;
}
#data {
p {
margin: 0;
padding: 0;
font-size: 20px;
font-size: 28px;
line-height: 1.5em;
}
h1, h2 {
@ -337,6 +345,7 @@ body.html {
font-size: 48px;
line-height: 1.2em;
color: @main-color;
padding: 0;
}
h5 {
@ -346,13 +355,9 @@ body.html {
width: 600px;
max-width: 60%;
color: @main-color;
padding: 15px;
padding: 0 15px;
box-sizing: border-box;
position: absolute;
display: inline-block;
top: 50%;
left: 0;
transform: translateY(-50%);
#tryit {
margin-top: 20px;
@ -361,15 +366,11 @@ body.html {
}
#loggedIn {
float: right;
color: @main-color;
display: inline-block;
position: absolute;
top: 50%;
right: 0;
margin-left: 50px;
width: 350px;
max-width: 35%;
transform: translateY(-50%);
text-align: center;
font-weight: bold;
button {
@ -386,11 +387,7 @@ body.html {
}
#userForm {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
margin-left: 50px;
float: right;
display: inline-block;
width: 350px;
max-width: 35%;
@ -399,42 +396,13 @@ body.html {
font-family: lato, Helvetica, sans-serif;
color: @main-color;
h1 {
color: @main-color;
padding: 0;
}
[type="text"], [type="password"] {
width: 100%;
}
label {
margin-bottom: 0;
}
/*.remember {
vertical-align: middle;
line-height: 28px;
height: 28px;
display: inline-block;
margin: 10px 0 20px 0;
}
[type="checkbox"] {
vertical-align: text-top;
margin: 0;
//margin-top: 10px;
margin-right: 5px;
}
*/
[type="checkbox"] {
margin-right: 5px;
}
button {
font-weight: bold;
width: 100%;
margin: 2px 0px;
cursor: pointer;
&.half {
width: ~"calc(50% - 2px)";
@ -443,18 +411,66 @@ body.html {
}
}
}
p {
margin: 0;
padding: 0;
&.buttons {
margin-bottom: 10px;
.dropdown-bar {
button {
white-space: normal;
text-align: left;
.fa {
float: right;
}
}
display: block;
}
}
&.separator {
margin: 5px 0 15px 0;
text-align: center;
font-weight: bold;
font-size: 1.1em;
}
a {
color: @main-color;
font-weight:bold;
font-size: 14px;
&:hover, :visited {
color: @main-color !important;
}
}
}
.driveLink {
padding-left: 1rem; //Bootstrap padding in buttons
font-size: 1em;
}
&> * {
margin-bottom: 10px;
}
}
#main-container {
@media screen and (max-width: @media-not-big) {
@media screen and (max-width: @media-not-big) {
#align-container {
transform: initial;
position: relative;
display: block;
width: 90%;
left: 0;
}
}
#userForm, #loggedIn, #data {
@media screen and (max-width: @media-not-big) {
#main-container {
position: relative;
transform: unset;
top:0;
}
#data {
text-align: center;
}
#userForm, #loggedIn, #data {
transform: initial;
position: relative;
display: block;
@ -462,34 +478,19 @@ body.html {
max-width: 100%;
margin: 10px 0;
box-sizing: border-box;
float: none;
}
}
#userForm, #loggedIn {
@media screen and (max-width: @media-not-big) {
border: 1px solid #888;
#userForm, #loggedIn {
//border: 1px solid #888;
}
}
@media screen and (max-width: @media-not-big) {
position: relative;
height: auto;
top: -10px;
}
.buttons {
margin-top: 15px;
}
}
p.buttons, div.buttons {
text-align: center;
button {
font-weight: bold;
cursor: pointer;
margin-top: 10px;
}
.dropdown-bar {
margin-left: 4px;
}
}
#fileManagerIframe {
width: 100%;

@ -1,20 +1,21 @@
@import "./variables.less";
.cp footer {
background: @dark-base;
background: @category-bg;
font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
padding-top: 1em;
font-size: 1.2em;
a {
color: #555;
color: @cp-link;
&:visited {
color: #777;
color: @cp-link-visited;
}
&:hover {
color: #333;
color: @cp-link-hover;
}
}
li:first-child {
font-size: 1.2em;
font-weight: bold;
text-decoration: underline;
}
}

@ -50,11 +50,15 @@
a {
font-weight: 500;
font-size: 0.75em;
color: @cp-purple;
color: @cp-link;
&:hover {
color: @cp-link-hover;
text-decoration: underline;
}
&:visited {
color: @cp-link-visited;
}
}
}
}

@ -24,6 +24,11 @@
@page-white: #fafafa;
// links
@cp-link: @cp-light-blue;
@cp-link-visited: @cp-light-blue;
@cp-link-hover: darken(@cp-light-blue, 10%) !important;
// alertify things
@box-shadow: 0 2px 5px 0 rgba(0,0,0,.2);
@ -88,3 +93,4 @@
@main-color: #fff;
@main-bg: url('/customize/bg3.jpg') no-repeat center center;
@category-bg: #f4f4f4;

@ -82,20 +82,20 @@
<div class="row">
<div class="col">
<ul class="list-unstyled">
<li>CryptPad<li>
<li><a href="/about" data-localization="about"></a></li>
<li><a href="/terms" data-localization="terms"></a></li>
<li><a href="/privacy" data-localization="privacy"></a></li>
<li>CryptPad</li>
<li><a href="/about.html" data-localization="about"></a></li>
<li><a href="/terms.html" data-localization="terms"></a></li>
<li><a href="/privacy.html" data-localization="privacy"></a></li>
</ul>
</div>
<div class="col">
<ul class="list-unstyled">
<li data-localization="footer_applications"><li>
<li><a href="/pad/" data-localization="main_richText"></a></li>
<li><a href="#" data-localization="main_code"></a></li>
<li><a href="#" data-localization="main_slide"></a></li>
<li><a href="#" data-localization="main_poll"></a></li>
<li><a href="#" data-localization="main_drive"></a></li>
<li><a href="/code/" data-localization="main_code"></a></li>
<li><a href="/slide/" data-localization="main_slide"></a></li>
<li><a href="/poll/" data-localization="main_poll"></a></li>
<li><a href="/drive/" data-localization="main_drive"></a></li>
</ul>
</div>
<div class="col">
@ -112,7 +112,7 @@
<li><a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" target="_blank" rel="noopener noreferrer">IRC</a></li>
<li><a href="https://twitter.com/cryptpad" target="_blank" rel="noopener noreferrer">Twitter</a></li>
<li><a href="https://github.com/xwiki-labs/cryptpad" target="_blank" rel="noopener noreferrer">GitHub</a></li>
<li><a href="/contact">Email</a></li>
<li><a href="/contact.html">Email</a></li>
</ul>
</div>
</div>

@ -103,8 +103,6 @@
out.notifyRenamed = "{0} heißt nun {1}";
out.notifyLeft = "{0} hat die gemeinsame Sitzung verlassen";
out.disconnectAlert = 'Netzwerkverbindung verloren!';
out.tryIt = 'Probier\'s aus!';
out.recentPads = 'Deine letzten Pads (diese Liste ist nur in deinem Browser gespeichert))';

@ -100,8 +100,6 @@ define(function () {
out.notifyRenamed = "{0} ahora se conoce como {1}";
out.notifyLeft = "{0} ha dejado la sesión de colaboración";
out.disconnectAlert = '¡Conexión a la red perdida!';
out.tryIt = '¡PROBARLO!';
out.recentPads = 'Tus documentos recientes (almacenadas solo en el navegador)';

@ -118,8 +118,6 @@ define(function () {
out.notifyRenamed = "{0} a changé son nom en {1}";
out.notifyLeft = "{0} a quitté la session collaborative";
out.disconnectAlert = 'Perte de la connexion au réseau !';
out.okButton = 'OK (Entrée)';
out.cancel = "Annuler";
@ -244,7 +242,8 @@ define(function () {
// login
out.login_login = "Connexion";
out.login_nologin = "Documents récents de ce navigateur";
out.login_makeAPad = 'Créer un document anonymement';
out.login_nologin = "Voir les documents récents";
out.login_register = "Inscription";
out.logoutButton = "Déconnexion";
@ -253,9 +252,9 @@ define(function () {
out.username_label = "Nom d'utilisateur : ";
out.displayname_label = "Nom affiché : ";
out.login_username = "votre nom d'utilisateur";
out.login_password = "votre mot de passe";
out.login_confirm = "confirmer votre mot de passe";
out.login_username = "Nom d'utilisateur";
out.login_password = "Mot de passe";
out.login_confirm = "Confirmer votre mot de passe";
out.login_remember = "Se souvenir de moi";
out.login_cancel_prompt = "...ou si vous avez entré le mauvais nom d'utilisateur ou mot de passe, annulez pour essayer à nouveau.";
@ -281,11 +280,12 @@ define(function () {
out.login_hello = 'Bonjour {0},'; // {0} is the username
out.login_helloNoName = 'Bonjour,';
out.login_accessDrive = 'Accédez à votre drive';
out.login_orNoLogin = 'ou';
// index.html
//out.main_p1 = 'CryptPad est l\'éditeur collaboratif en temps réel <strong>zero knowledge</strong>. Le chiffrement est effectué depuis votre navigateur, ce qui protège les données contre le serveur, le cloud, et la NSA. La clé de chiffrement est stockée dans l\'<a href="https://fr.wikipedia.org/wiki/Identificateur_de_fragment">identifieur de fragment</a> de l\'URL qui n\'est jamais envoyée au serveur mais est accessible depuis javascript, de sorte qu\'en partageant l\'URL, vous donnez l\'accès au pad à ceux qui souhaitent participer.';
out.main_p1 = "<h2>Collaborez en tout confiance</h2><br>Développez vos idées collaborativement grâce à des documents partagés en temps-réel, tout en gardant vos données personnelles invisibles, même pour nous, avec la technologie <strong>Zero Knowledge</strong>.";
out.main_p1 = "<h2>Collaborez avec confiance</h2><br>Développez vos idées en groupe avec des documents partagés; la technologie <strong>Zero Knowledge</strong> sécurise vos données.";
out.main_p2 = 'Ce projet utilise l\'éditeur visuel (WYSIWYG) <a href="http://ckeditor.com/">CKEditor</a>, l\'éditeur de code source <a href="https://codemirror.net/">CodeMirror</a>, et le moteur temps-réel <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks_p1 = 'CryptPad utilise une variante de l\'algorithme d\'<a href="https://en.wikipedia.org/wiki/Operational_transformation">Operational transformation</a> qui est capable de trouver un consensus distribué en utilisant <a href="https://bitcoin.org/bitcoin.pdf">une chaîne de bloc Nakamoto</a>, un outil popularisé par le <a href="https://fr.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. De cette manière, l\'algorithme évite la nécessité d\'utiliser un serveur central pour résoudre les conflits d\'édition de l\'Operational Transformation, et sans ce besoin de résolution des conflits le serveur peut rester ignorant du contenu qui est édité dans le pad.';
out.main_about = 'À propos';
@ -295,9 +295,9 @@ define(function () {
out.main_howitworks = 'Comment ça fonctionne';
out.main_zeroKnowledge = 'Zero Knowledge';
out.main_zeroKnowledge_p = "Vous n'avez pas besoin de croire que nous n'<em>allons</em> pas regarder vos documents. Avec la technologie Zero Knowledge de Cryptpad, nous ne <em>pouvons</em> pas le faire. Apprenez-en plus sur notre manière de protéger vos données.";
out.main_jotItDown = 'Prenez-en note';
out.main_jotItDown_p = "Les plus grands projets naissent des plus petites idées. Prenez note de vos moments d'inspiration et de vos idées inattendues car vous ne savez pas lesquels seront des découvertes capitales.";
out.main_zeroKnowledge_p = "Vous n'avez pas besoin de croire que nous n'<em>allons</em> pas regarder vos documents. Avec la technologie Zero Knowledge de Cryptpad, nous ne <em>pouvons</em> pas le faire. Apprenez-en plus sur notre manière de <a href=\"privacy.html\" title='Protection des données'>protéger vos données</a>.";
out.main_writeItDown = 'Prenez-en note';
out.main_writeItDown_p = "Les plus grands projets naissent des plus petites idées. Prenez note de vos moments d'inspiration et de vos idées inattendues car vous ne savez pas lesquels seront des découvertes capitales.";
out.main_share = 'Partager le lien, partager le document';
out.main_share_p = "Faites croître vos idées à plusieurs : réalisez des réunions efficaes, collaborez sur vos listes de tâches et réalisez des présentations rapide avec tous vos amis sur tous vos appareils.";
out.main_organize = 'Soyez organisés';
@ -322,7 +322,6 @@ define(function () {
out.table_created = 'Créé le';
out.table_last = 'Dernier accès';
out.makeAPad = 'Créer un document';
out.button_newpad = 'Nouveau document texte';
out.button_newcode = 'Nouvelle page de code';
out.button_newpoll = 'Nouveau sondage';

@ -122,8 +122,6 @@ define(function () {
out.notifyRenamed = "{0} is now known as {1}";
out.notifyLeft = "{0} has left the collaborative session";
out.disconnectAlert = 'Network connection lost!';
out.okButton = 'OK (enter)';
out.cancel = "Cancel";
@ -245,7 +243,8 @@ define(function () {
// login
out.login_login = "Log in";
out.login_nologin = "Your browser's recent pads";
out.login_makeAPad = 'Create a pad anonymously';
out.login_nologin = "Browse local pads";
out.login_register = "Sign up";
out.logoutButton = "Log out";
@ -254,9 +253,9 @@ define(function () {
out.username_label = "Username: ";
out.displayname_label = "Display name: ";
out.login_username = "your username";
out.login_password = "your password";
out.login_confirm = "confirm your password";
out.login_username = "Username";
out.login_password = "Password";
out.login_confirm = "Confirm your password";
out.login_remember = "Remember me";
out.login_cancel_prompt = "...or if you may have entered the wrong username or password, cancel to try again.";
@ -282,6 +281,7 @@ define(function () {
out.login_hello = 'Hello {0},'; // {0} is the username
out.login_helloNoName = 'Hello,';
out.login_accessDrive = 'Access your drive';
out.login_orNoLogin = 'or';
// index.html
@ -298,7 +298,7 @@ define(function () {
out.main_howitworks = 'How It Works';
out.main_zeroKnowledge = 'Zero Knowledge';
out.main_zeroKnowledge_p = "You don't have to trust that we <em>won't</em> look at your pads, with CryptPad's revolutionary Zero Knowledge Technology we <em>can't</em>. Learn more about how we protect your Privacy and Security.";
out.main_zeroKnowledge_p = "You don't have to trust that we <em>won't</em> look at your pads, with CryptPad's revolutionary Zero Knowledge Technology we <em>can't</em>. Learn more about how we protect your <a href=\"/privacy.html\" title='Privacy'>Privacy and Security</a>.";
out.main_writeItDown = 'Write it down';
out.main_writeItDown_p = "The greatest projects come from the smallest ideas. Take down the moments of inspiration and unexpected ideas because you never know which one might be a breakthrough.";
out.main_share = 'Share the link, share the pad';
@ -325,7 +325,6 @@ define(function () {
out.table_created = 'Created';
out.table_last = 'Last Accessed';
out.makeAPad = 'Make a pad right now';
out.button_newpad = 'New Rich Text pad';
out.button_newcode = 'New Code pad';
out.button_newpoll = 'New Poll';

@ -102,8 +102,6 @@ define(function () {
out.notifyRenamed = "{0} jest teraz znany jako {1}";
out.notifyLeft = "{0} opuścił sesję współpracy";
out.disconnectAlert = 'Utracono połączenie sieciowe!';
out.tryIt = 'Wypróbuj!';
out.recentPads = 'Ostatnio otwarte dokumenty (przechowywane jedynie w twojej przeglądarce)';

@ -110,8 +110,6 @@ define(function () {
out.notifyRenamed = "{0} agora é conhecido como {1}";
out.notifyLeft = "{0} deixou essa sessão colaborativa";
out.disconnectAlert = 'Conexão de rede perdida!';
out.tryIt = 'Experimente!';
out.recentPads = 'Seu bloco de nota recente (armazenado em seu navegador)';

@ -699,7 +699,7 @@ define([
// inform of network disconnect
setEditable(false);
toolbar.failed();
Cryptpad.alert(Messages.disconnectAlert);
Cryptpad.alert(Messages.common_connectionLost);
};
var onConnectionChange = config.onConnectionChange = function (info) {
@ -710,7 +710,7 @@ define([
toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click();
} else {
Cryptpad.alert(Messages.disconnectAlert);
Cryptpad.alert(Messages.common_connectionLost);
}
};

@ -1,7 +1,7 @@
define([
'/api/config?cb=' + Math.random().toString(16).slice(2),
'/customize/messages.js',
'/customize/store.js',
'/customize/fsStore.js',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/alertifyjs/dist/js/alertify.js',
'/bower_components/spin.js/spin.min.js',
@ -10,7 +10,7 @@ define([
'/customize/application_config.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Config, Messages, Store, Crypto, Alertify, Spinner, Clipboard, FS, AppConfig) {
], function (Config, Messages, Store, Crypto, Alertify, Spinner, Clipboard, AppConfig) {
/* This file exposes functionality which is specific to Cryptpad, but not to
any particular pad type. This includes functions for committing metadata
about pads to your local storage for future use and improved usability.
@ -19,18 +19,11 @@ define([
*/
var $ = window.jQuery;
// When set to true, USE_FS_STORE becomes the default store, but the localStorage store is
// still loaded for migration purpose. When false, the localStorage is used.
var USE_FS_STORE = AppConfig.USE_FS_STORE;
var storeToUse = USE_FS_STORE ? FS : Store;
var common = window.Cryptpad = {
Messages: Messages,
Alertify: Alertify,
};
var store;
var fsStore;
var find = common.find = function (map, path) {
return (map && path.reduce(function (p, n) {
@ -38,15 +31,14 @@ define([
}, map));
};
var getStore = common.getStore = function (legacy) {
if ((!USE_FS_STORE || legacy) && store) { return store; }
if (USE_FS_STORE && !legacy && fsStore) { return fsStore; }
var getStore = common.getStore = function () {
if (store) { return store; }
throw new Error("Store is not ready!");
};
var getNetwork = common.getNetwork = function () {
if (USE_FS_STORE && fsStore) {
if (fsStore.getProxy() && fsStore.getProxy().info) {
return fsStore.getProxy().info.network;
if (store) {
if (store.getProxy() && store.getProxy().info) {
return store.getProxy().info.network;
}
}
return;
@ -131,7 +123,6 @@ define([
};
var isLoggedIn = common.isLoggedIn = function () {
//return typeof getStore().getLoginName() === "string";
return typeof getUserHash() === "string";
};
@ -373,6 +364,23 @@ define([
});
};
// Get the pads from localStorage to migrate them to the object store
var getLegacyPads = common.getLegacyPads = function (cb) {
require(['/customize/store.js'], function(Legacy) {
Legacy.ready(function (err, legacy) {
if (err) { cb(err, null); return; }
Legacy.get(storageKey, function (err2, recentPads) {
if (err2) { cb(err2, null); return; }
if (isArray(recentPads)) {
cb(void 0, migrateRecentPads(recentPads));
return;
}
cb(void 0, []);
});
});
});
};
var getHash = common.getHash = function () {
return window.location.hash.slice(1);
};
@ -446,13 +454,13 @@ define([
};
// STORAGE
var setPadAttribute = common.setPadAttribute = function (attr, value, cb, legacy) {
getStore(legacy).setDrive([getHash(), attr].join('.'), value, function (err, data) {
var setPadAttribute = common.setPadAttribute = function (attr, value, cb) {
getStore().setDrive([getHash(), attr].join('.'), value, function (err, data) {
cb(err, data);
});
};
var setAttribute = common.setAttribute = function (attr, value, cb, legacy) {
getStore(legacy).set(["cryptpad", attr].join('.'), value, function (err, data) {
var setAttribute = common.setAttribute = function (attr, value, cb) {
getStore().set(["cryptpad", attr].join('.'), value, function (err, data) {
cb(err, data);
});
};
@ -461,13 +469,13 @@ define([
};
// STORAGE
var getPadAttribute = common.getPadAttribute = function (attr, cb, legacy) {
getStore(legacy).getDrive([getHash(), attr].join('.'), function (err, data) {
var getPadAttribute = common.getPadAttribute = function (attr, cb) {
getStore().getDrive([getHash(), attr].join('.'), function (err, data) {
cb(err, data);
});
};
var getAttribute = common.getAttribute = function (attr, cb, legacy) {
getStore(legacy).get(["cryptpad", attr].join('.'), function (err, data) {
var getAttribute = common.getAttribute = function (attr, cb) {
getStore().get(["cryptpad", attr].join('.'), function (err, data) {
cb(err, data);
});
};
@ -493,12 +501,8 @@ define([
// STORAGE
/* fetch and migrate your pad history from localStorage */
var getRecentPads = common.getRecentPads = function (cb, legacy) {
var sstore = getStore(legacy);
if (legacy) {
sstore.getDrive = sstore.get;
}
sstore.getDrive(storageKey, function (err, recentPads) {
var getRecentPads = common.getRecentPads = function (cb) {
getStore().getDrive(storageKey, function (err, recentPads) {
if (isArray(recentPads)) {
cb(void 0, migrateRecentPads(recentPads));
return;
@ -509,21 +513,14 @@ define([
// STORAGE
/* commit a list of pads to localStorage */
var setRecentPads = common.setRecentPads = function (pads, cb, legacy) {
var sstore = getStore(legacy);
if (legacy) {
sstore.setDrive = sstore.set;
}
sstore.setDrive(storageKey, pads, function (err, data) {
var setRecentPads = common.setRecentPads = function (pads, cb) {
getStore().setDrive(storageKey, pads, function (err, data) {
cb(err, data);
});
};
// STORAGE
var forgetFSPad = function (href, cb) {
getStore().forgetPad(href, cb);
};
var forgetPad = common.forgetPad = function (href, cb, legacy) {
var forgetPad = common.forgetPad = function (href, cb) {
var parsed = parsePadUrl(href);
var callback = function (err, data) {
@ -532,7 +529,7 @@ define([
return;
}
getStore(legacy).keys(function (err, keys) {
getStore().keys(function (err, keys) {
if (err) {
cb(err);
return;
@ -545,35 +542,14 @@ define([
cb();
return;
}
getStore(legacy).removeBatch(toRemove, function (err, data) {
getStore().removeBatch(toRemove, function (err, data) {
cb(err, data);
});
});
};
if (USE_FS_STORE && !legacy) {
// TODO implement forgetPad in store.js
forgetFSPad(href, callback);
return;
}
getRecentPads(function (err, recentPads) {
setRecentPads(recentPads.filter(function (pad) {
var p = parsePadUrl(pad.href);
// find duplicates
if (parsed.hash === p.hash && parsed.type === p.type) {
console.log("Found a duplicate");
return;
}
return true;
}), callback, legacy);
}, legacy);
if (typeof(getStore(legacy).forgetPad) === "function") {
// TODO implement forgetPad in store.js
getStore(legacy).forgetPad(href, callback);
if (typeof(getStore().forgetPad) === "function") {
getStore().forgetPad(href, callback);
}
};
@ -626,7 +602,7 @@ define([
if (!contains) {
var data = makePad(href, name);
renamed.push(data);
if (USE_FS_STORE && typeof(getStore().addPad) === "function") {
if (typeof(getStore().addPad) === "function") {
getStore().addPad(href, common.initialPath, common.initialName || name);
}
}
@ -701,58 +677,47 @@ define([
f(void 0, env);
};
var todo = function () {
storeToUse.ready(function (err, store) {
common.store = env.store = store;
if (USE_FS_STORE) {
fsStore = store;
}
Store.ready(function (err, storeObj) {
store = common.store = env.store = storeObj;
$(function() {
// Race condition : if document.body is undefined when alertify.js is loaded, Alertify
// won't work. We have to reset it now to make sure it uses a correct "body"
Alertify.reset();
// Load the new pad when the hash has changed
var oldHash = document.location.hash.slice(1);
window.onhashchange = function () {
var newHash = document.location.hash.slice(1);
var parsedOld = parseHash(oldHash);
var parsedNew = parseHash(newHash);
if (parsedOld && parsedNew && (
parsedOld.channel !== parsedNew.channel
|| parsedOld.mode !== parsedNew.mode
|| parsedOld.key !== parsedNew.key)) {
document.location.reload();
return;
}
if (parsedNew) {
oldHash = newHash;
}
};
$(function() {
// Race condition : if document.body is undefined when alertify.js is loaded, Alertify
// won't work. We have to reset it now to make sure it uses a correct "body"
Alertify.reset();
// Load the new pad when the hash has changed
var oldHash = document.location.hash.slice(1);
window.onhashchange = function () {
var newHash = document.location.hash.slice(1);
var parsedOld = parseHash(oldHash);
var parsedNew = parseHash(newHash);
if (parsedOld && parsedNew && (
parsedOld.channel !== parsedNew.channel
|| parsedOld.mode !== parsedNew.mode
|| parsedOld.key !== parsedNew.key)) {
document.location.reload();
return;
}
if (parsedNew) {
oldHash = newHash;
}
};
// Everything's ready, continue...
if($('#pad-iframe').length) {
var $iframe = $('#pad-iframe');
var iframe = $iframe[0];
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.readyState === 'complete') {
cb();
return;
}
$iframe.load(cb);
// Everything's ready, continue...
if($('#pad-iframe').length) {
var $iframe = $('#pad-iframe');
var iframe = $iframe[0];
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.readyState === 'complete') {
cb();
return;
}
cb();
});
}, common);
};
// If we use the fs store, make sure the localStorage or iframe store is ready
if (USE_FS_STORE) {
Store.ready(todo);
return;
}
todo();
$iframe.load(cb);
return;
}
cb();
});
}, common);
};
var errorHandlers = [];
@ -1263,15 +1228,6 @@ define([
};
};
// All code which is called implicitly is found below
Store.ready(function (err, Store) {
if (err) {
console.error(err);
return;
}
store = Store;
});
$(function () {
Messages._applyTranslation();
});

@ -0,0 +1,112 @@
define([
'/bower_components/chainpad-listmap/chainpad-listmap.js',
'/bower_components/chainpad-crypto/crypto.js',
'/common/cryptpad-common.js',
'/common/credential.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
'/bower_components/scrypt-async/scrypt-async.min.js', // better load speed
'/bower_components/jquery/dist/jquery.min.js',
], function (Listmap, Crypto, Cryptpad, Cred) {
var Exports = {
Cred: Cred,
};
var allocateBytes = function (bytes) {
var dispense = Cred.dispenser(bytes);
var opt = {};
// dispense 18 bytes of entropy for your encryption key
var encryptionSeed = dispense(18);
// 16 bytes for a deterministic channel key
var channelSeed = dispense(16);
// 32 bytes for a curve key
var curveSeed = opt.curveSeed = dispense(32);
// 32 more for a signing key
var edSeed = opt.edSeed = dispense(32);
var keys = opt.keys = Crypto.createEditCryptor(null, encryptionSeed);
// 24 bytes of base64
keys.editKeyStr = keys.editKeyStr.replace(/\//g, '-');
// 32 bytes of hex
var channelHex = opt.channelHex = Cryptpad.uint8ArrayToHex(channelSeed);
// should never happen
if (channelHex.length !== 32) { throw new Error('invalid channel id'); }
var channel64 = opt.channel64 = Cryptpad.hexToBase64(channelHex);
var userHash = opt.userHash = '/1/edit/' + [opt.channel64, opt.keys.editKeyStr].join('/');
return opt;
};
var loadUserObject = function (opt, cb) {
var config = {
websocketURL: Cryptpad.getWebsocketURL(),
channel: opt.channelHex,
data: {},
validateKey: opt.keys.validateKey, // derived validation key
crypto: Crypto.createEncryptor(opt.keys),
logLevel: 1,
};
var rt = opt.rt = Listmap.create(config);
rt.proxy
.on('ready', function (info) {
cb(void 0, rt);
})
.on('disconnect', function (info) {
cb('E_DISCONNECT', info);
});
};
var isProxyEmpty = function (proxy) {
return Object.keys(proxy).length === 0;
};
Exports.loginOrRegister = function (uname, passwd, isRegister, cb) {
if (typeof(cb) !== 'function') { return; }
// validate inputs
if (!Cred.isValidUsername(uname)) { return void cb('INVAL_USER'); }
if (!Cred.isValidPassword(passwd)) { return void cb('INVAL_PASS'); }
Cred.deriveFromPassphrase(uname, passwd, 128, function (bytes) {
// results...
var res = {
register: isRegister,
};
// run scrypt to derive the user's keys
var opt = res.opt = allocateBytes(bytes);
// use the derived key to generate an object
loadUserObject(opt, function (err, rt) {
if (err) { return void cb(err); }
res.proxy = rt.proxy;
res.realtime = rt.realtime;
res.network = rt.network;
// they tried to just log in but there's no such user
if (!isRegister && isProxyEmpty(rt.proxy)) {
rt.network.disconnect(); // clean up after yourself
return void cb('NO_SUCH_USER', res);
}
// they're registering...
res.userHash = opt.userHash;
res.userName = uname;
//res.displayName // TODO
cb(void 0, res);
});
});
};
return Exports;
});

@ -9,8 +9,9 @@ define([
'/common/cryptpad-common.js',
'/common/fileObject.js',
'/common/toolbar.js',
'/customize/application_config.js'
], function (Config, Listmap, Crypto, TextPatcher, Messages, JSONSortify, Cryptpad, FO, Toolbar, AppConfig) {
'/customize/application_config.js',
'/common/cryptget.js'
], function (Config, Listmap, Crypto, TextPatcher, Messages, JSONSortify, Cryptpad, FO, Toolbar, AppConfig, Get) {
var module = window.MODULE = {};
var $ = window.jQuery;
@ -1854,6 +1855,31 @@ define([
});
};
// TODO: move that function and use a more generic API
var migrateAnonDrive = function (proxy, cb) {
if (sessionStorage.migrateAnonDrive) {
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
if (!localStorage.FS_hash || !APP.loggedIn) {
delete sessionStorage.migrateAnonDrive;
if (typeof(cb) === "function") { cb(); }
}
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
var todo = function (err, doc) {
if (err) { logError("Cannot migrate recent pads", err); return; }
var parsed;
try { parsed = JSON.parse(doc); } catch (e) { logError("Cannot parsed recent pads", e); }
if (parsed) {
$.extend(true, proxy, parsed);
}
delete sessionStorage.migrateAnonDrive;
if (typeof(cb) === "function") { cb(); }
};
Get.get(localStorage.FS_hash, todo);
} else {
if (typeof(cb) === "function") { cb(); }
}
};
// don't initialize until the store is ready.
Cryptpad.ready(function () {
APP.$bar = $iframe.find('#toolbar');
@ -1950,23 +1976,13 @@ define([
};
var onReady = function () {
module.files = proxy;
if (JSON.stringify(proxy) === '{}') {
var store = Cryptpad.getStore(true);
var drive = proxy.drive = {};
store.get(Cryptpad.storageKey, function (err, s) {
drive[FILES_DATA] = s;
initLocalStorage();
init(proxy);
APP.userList.onChange();
Cryptpad.removeLoadingScreen();
});
return;
}
if (!proxy.drive || typeof(proxy.drive) !== 'object') { proxy.drive = {}; }
initLocalStorage();
init(proxy);
APP.userList.onChange();
Cryptpad.removeLoadingScreen();
migrateAnonDrive(proxy, function () {
initLocalStorage();
init(proxy);
APP.userList.onChange();
Cryptpad.removeLoadingScreen();
});
};
var onDisconnect = function (info) {
setEditable(false);

@ -739,7 +739,7 @@ define([
setEditable(false);
// TODO inform them that the session was torn down
toolbar.failed();
Cryptpad.alert(Messages.disconnectAlert);
Cryptpad.alert(Messages.common_connectionLost);
};
var onConnectionChange = realtimeOptions.onConnectionChange = function (info) {
@ -750,7 +750,7 @@ define([
toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click();
} else {
Cryptpad.alert(Messages.disconnectAlert);
Cryptpad.alert(Messages.common_connectionLost);
}
};

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html class="cp">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Cryptpad: login</title>
<script data-main="main" src="/bower_components/requirejs/require.js"></script>
<link rel="stylesheet" href="/customize/main.css" />
<style>
html, body{
padding: 0px;
margin: 0px;
height: 100% !important;
width: 100%;
box-sizing: border-box;
}
body {
padding: 45px;
}
div.panel{
width: 70%;
margin: auto;
border: 1px solid black;
padding: 15px;
display: none;
border-radius: 5px;
}
.register {
display: none;
}
@media (max-width: 1000px) {
div.panel { width: 90%; }
}
input[type="text"], input[type="password"] {
width: 80%;
}
hr.choice {
margin-top: 45px;
margin-bottom: 45px;
}
#notice-panel {
text-align: center;
font-size: 25px;
}
</style>
</head>
<body id="main">
<div id="login-panel" class="panel" style="display:block;">
<input id="username" type="text" autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false" data-localization-placeholder="login_username" autofocus/><br />
<input id="password" type="password" data-localization-placeholder="login_password"/><br />
<input id="password-confirm" type="password" data-localization-placeholder="login_confirm"/><br />
<!-- TODO translate labels -->
<input id="import-recent" type="checkbox" /><label for="import-recent">Import recent pads from your browser (Optional)</label><br />
<input id="accept-terms" type="checkbox" /><label for="accept-terms">Accept the terms and conditions</label><br />
<input id="promise" type="checkbox" /><label for="promise">I promise to remember my username and password</label><br />
<button id="register" class="btn btn-primary" data-localization="login_login">Sign up</button>
</div>

@ -0,0 +1,43 @@
define([
'/common/login.js',
'/common/credential.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Login) {
var $ = window.jQuery;
// text and password input fields
var $uname = $('#username');
var $passwd = $('#password');
var $confirm = $('#password-confirm');
// checkboxes
var $checkImport = $('#import-recent');
var $checkAcceptTerms = $('#accept-terms');
var $checkPromise = $('#promise');
var $register = $('button#register');
$register.click(function () {
var uname = $uname.val();
var passwd = $passwd.val();
var confirmPassword = $confirm.val();
var shouldImport = $checkImport[0].checked;
var doesAccept = $checkAcceptTerms[0].checked;
var doesPromise = $checkPromise[0].checked;
/* basic validation */
// do their passwords match?
if (passwd !== confirmPassword) {
alert('invalid password');
return;
}
Login.loginOrRegister(uname, passwd, true, function (err, out) {
if (err) { alert(err); }
console.log(out);
})
});
});

@ -782,7 +782,7 @@ define([
// inform of network disconnect
setEditable(false);
toolbar.failed();
Cryptpad.alert(Messages.disconnectAlert);
Cryptpad.alert(Messages.common_connectionLost);
};
var onConnectionChange = config.onConnectionChange = function (info) {
@ -793,7 +793,7 @@ define([
toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click();
} else {
Cryptpad.alert(Messages.disconnectAlert);
Cryptpad.alert(Messages.common_connectionLost);
}
};

@ -1,13 +1,13 @@
define([
'/api/config?cb=' + Math.random().toString(16).substring(2),
'/bower_components/chainpad-listmap/chainpad-listmap.js',
'/bower_components/chainpad-crypto/crypto.js',
'/common/cryptpad-common.js',
'credential.js',
'/common/credential.js',
'/common/login.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
'/bower_components/scrypt-async/scrypt-async.min.js', // better load speed
'/bower_components/jquery/dist/jquery.min.js',
], function (Config, Listmap, Crypto, Cryptpad, Cred) {
], function (Listmap, Crypto, Cryptpad, Cred, Login) {
var $ = window.jQuery;
var Nacl = window.nacl;
@ -16,6 +16,7 @@ define([
var APP = window.APP = {
Cryptpad: Cryptpad,
Crypto: Crypto,
Login: Login,
};
// login elements
@ -161,6 +162,9 @@ define([
});
};
addEnterListener($confirm, function () {
$register.click();
});
addEnterListener($password_register, function () {
$login.click();
});
@ -354,7 +358,9 @@ define([
APP.setNotice(Cryptpad.Messages.login_hashing);
// inform the user that we're hashing their password
revealNotice(true);
revealLogin(false, function () {
window.setTimeout(function () {
resetUI();

Loading…
Cancel
Save