Remove util and hash from common
parent
c9e1de042c
commit
30c8c253dd
|
@ -3,12 +3,12 @@ define([
|
|||
'/bower_components/hyperjson/hyperjson.js',
|
||||
'/bower_components/textpatcher/TextPatcher.amd.js',
|
||||
'json.sortify',
|
||||
'/common/cryptpad-common.js',
|
||||
'/drive/tests.js',
|
||||
'/common/test.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-thumbnail.js',
|
||||
'/common/flat-dom.js',
|
||||
], function ($, Hyperjson, TextPatcher, Sortify, Cryptpad, Drive, Test, Thumb, Flat) {
|
||||
], function ($, Hyperjson, TextPatcher, Sortify, Drive, Test, Hash, Thumb, Flat) {
|
||||
window.Hyperjson = Hyperjson;
|
||||
window.TextPatcher = TextPatcher;
|
||||
window.Sortify = Sortify;
|
||||
|
@ -158,7 +158,7 @@ define([
|
|||
|
||||
// check that old hashes parse correctly
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy');
|
||||
var secret = Hash.parsePadUrl('/pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy');
|
||||
return cb(secret.hashData.channel === "67b8385b07352be53e40746d2be6ccd7" &&
|
||||
secret.hashData.key === "XAYSuJYYqa9NfmInyHci7LNy" &&
|
||||
secret.hashData.version === 0);
|
||||
|
@ -166,7 +166,7 @@ define([
|
|||
|
||||
// make sure version 1 hashes parse correctly
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI');
|
||||
return cb(secret.hashData.version === 1 &&
|
||||
secret.hashData.mode === "edit" &&
|
||||
secret.hashData.channel === "3Ujt4F2Sjnjbis6CoYWpoQ" &&
|
||||
|
@ -176,7 +176,7 @@ define([
|
|||
|
||||
// test support for present mode in hashes
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit/CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G/present');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit/CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G/present');
|
||||
return cb(secret.hashData.version === 1
|
||||
&& secret.hashData.mode === "edit"
|
||||
&& secret.hashData.channel === "CmN5+YJkrHFS3NSBg-P7Sg"
|
||||
|
@ -186,7 +186,7 @@ define([
|
|||
|
||||
// test support for present mode in hashes
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G//present');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G//present');
|
||||
return cb(secret.hashData.version === 1
|
||||
&& secret.hashData.mode === "edit"
|
||||
&& secret.hashData.channel === "CmN5+YJkrHFS3NSBg-P7Sg"
|
||||
|
@ -196,7 +196,7 @@ define([
|
|||
|
||||
// test support for present & embed mode in hashes
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G/embed/present/');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G/embed/present/');
|
||||
return cb(secret.hashData.version === 1
|
||||
&& secret.hashData.mode === "edit"
|
||||
&& secret.hashData.channel === "CmN5+YJkrHFS3NSBg-P7Sg"
|
||||
|
@ -207,7 +207,7 @@ define([
|
|||
|
||||
// test support for present & embed mode in hashes
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G/present/embed');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G/present/embed');
|
||||
return cb(secret.hashData.version === 1
|
||||
&& secret.hashData.mode === "edit"
|
||||
&& secret.hashData.channel === "CmN5+YJkrHFS3NSBg-P7Sg"
|
||||
|
@ -218,7 +218,7 @@ define([
|
|||
|
||||
// test support for embed mode in hashes
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G///embed//');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit//CmN5+YJkrHFS3NSBg-P7Sg/DNZ2wcG683GscU4fyOyqA87G///embed//');
|
||||
return cb(secret.hashData.version === 1
|
||||
&& secret.hashData.mode === "edit"
|
||||
&& secret.hashData.channel === "CmN5+YJkrHFS3NSBg-P7Sg"
|
||||
|
@ -229,7 +229,7 @@ define([
|
|||
|
||||
// test support for trailing slash
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/pad/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI/');
|
||||
var secret = Hash.parsePadUrl('/pad/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI/');
|
||||
return cb(secret.hashData.version === 1 &&
|
||||
secret.hashData.mode === "edit" &&
|
||||
secret.hashData.channel === "3Ujt4F2Sjnjbis6CoYWpoQ" &&
|
||||
|
@ -238,7 +238,7 @@ define([
|
|||
}, "test support for trailing slashes in version 1 hash failed to parse");
|
||||
|
||||
assert(function (cb) {
|
||||
var secret = Cryptpad.parsePadUrl('/invite/#/1/ilrOtygzDVoUSRpOOJrUuQ/e8jvf36S3chzkkcaMrLSW7PPrz7VDp85lIFNI26dTmr=/');
|
||||
var secret = Hash.parsePadUrl('/invite/#/1/ilrOtygzDVoUSRpOOJrUuQ/e8jvf36S3chzkkcaMrLSW7PPrz7VDp85lIFNI26dTmr=/');
|
||||
var hd = secret.hashData;
|
||||
cb(hd.channel === "ilrOtygzDVoUSRpOOJrUuQ" &&
|
||||
hd.pubkey === "e8jvf36S3chzkkcaMrLSW7PPrz7VDp85lIFNI26dTmr=" &&
|
||||
|
|
|
@ -7,6 +7,7 @@ define([
|
|||
'/common/sframe-common.js',
|
||||
'/common/sframe-app-framework.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/modes.js',
|
||||
'cm/lib/codemirror',
|
||||
|
||||
|
@ -45,6 +46,7 @@ define([
|
|||
SFCommon,
|
||||
Framework,
|
||||
Util,
|
||||
Hash,
|
||||
Modes,
|
||||
CMeditor)
|
||||
{
|
||||
|
@ -293,8 +295,8 @@ define([
|
|||
//var cursor = editor.getCursor();
|
||||
//var cleanName = data.name.replace(/[\[\]]/g, '');
|
||||
//var text = '';
|
||||
var parsed = Cryptpad.parsePadUrl(data.url);
|
||||
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
|
||||
var parsed = Hash.parsePadUrl(data.url);
|
||||
var hexFileName = Util.base64ToHex(parsed.hashData.channel);
|
||||
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
|
||||
var mt = '<media-tag src="' + src + '" data-crypto-key="cryptpad:' + parsed.hashData.key + '"></media-tag>';
|
||||
editor.replaceSelection(mt);
|
||||
|
|
|
@ -3,7 +3,9 @@ define([
|
|||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/common/curve.js',
|
||||
'/common/common-hash.js',
|
||||
], function ($, Crypto, Curve, Hash) {
|
||||
'/common/common-util.js',
|
||||
'/common/common-realtime.js',
|
||||
], function ($, Crypto, Curve, Hash, Util, Realtime) {
|
||||
'use strict';
|
||||
var Msg = {
|
||||
inputs: [],
|
||||
|
@ -149,7 +151,7 @@ define([
|
|||
return;
|
||||
}
|
||||
|
||||
var txid = common.uid();
|
||||
var txid = Util.uid();
|
||||
initRangeRequest(txid, curvePublic, hash, cb);
|
||||
var msg = [ 'GET_HISTORY_RANGE', chan.id, {
|
||||
from: hash,
|
||||
|
@ -245,7 +247,7 @@ define([
|
|||
if (!proxy.friends) { return; }
|
||||
var friends = proxy.friends;
|
||||
delete friends[curvePublic];
|
||||
common.whenRealtimeSyncs(realtime, cb);
|
||||
Realtime.whenRealtimeSyncs(realtime, cb);
|
||||
};
|
||||
|
||||
var pushMsg = function (channel, cryptMsg) {
|
||||
|
@ -352,7 +354,7 @@ define([
|
|||
return cb();
|
||||
};
|
||||
|
||||
var onDirectMessage = function (common, msg, sender) {
|
||||
var onDirectMessage = function (msg, sender) {
|
||||
if (sender !== Msg.hk) { return void onIdMessage(msg, sender); }
|
||||
var parsed = JSON.parse(msg);
|
||||
|
||||
|
@ -443,7 +445,7 @@ define([
|
|||
|
||||
// listen for messages...
|
||||
network.on('message', function(msg, sender) {
|
||||
onDirectMessage(common, msg, sender);
|
||||
onDirectMessage(msg, sender);
|
||||
});
|
||||
|
||||
messenger.removeFriend = function (curvePublic, cb) {
|
||||
|
@ -476,7 +478,7 @@ define([
|
|||
channel.wc.bcast(cryptMsg).then(function () {
|
||||
delete friends[curvePublic];
|
||||
delete channels[curvePublic];
|
||||
common.whenRealtimeSyncs(realtime, function () {
|
||||
Realtime.whenRealtimeSyncs(realtime, function () {
|
||||
cb();
|
||||
});
|
||||
}, function (err) {
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
define(function () {
|
||||
var module = {};
|
||||
|
||||
module.create = function (UserList, Title, cfg, Cryptpad) {
|
||||
var exp = {};
|
||||
|
||||
exp.update = function (shjson) {
|
||||
// Extract the user list (metadata) from the hyperjson
|
||||
var json = (!shjson || typeof shjson !== "string") ? "" : JSON.parse(shjson);
|
||||
var titleUpdated = false;
|
||||
var metadata;
|
||||
if (Array.isArray(json)) {
|
||||
metadata = json[3] && json[3].metadata;
|
||||
} else {
|
||||
metadata = json.metadata;
|
||||
}
|
||||
if (typeof metadata === "object") {
|
||||
if (Cryptpad) {
|
||||
if (typeof(metadata.type) === 'undefined') {
|
||||
// initialize pad type by location.pathname
|
||||
metadata.type = Cryptpad.getAppType();
|
||||
}
|
||||
} else {
|
||||
console.log("Cryptpad should exist but it does not");
|
||||
}
|
||||
if (metadata.users) {
|
||||
var userData = metadata.users;
|
||||
// Update the local user data
|
||||
UserList.addToUserData(userData);
|
||||
}
|
||||
if (metadata.defaultTitle) {
|
||||
Title.updateDefaultTitle(metadata.defaultTitle);
|
||||
}
|
||||
if (typeof metadata.title !== "undefined") {
|
||||
Title.updateTitle(metadata.title || Title.defaultTitle);
|
||||
titleUpdated = true;
|
||||
}
|
||||
if (metadata.slideOptions && cfg.slideOptions) {
|
||||
cfg.slideOptions(metadata.slideOptions);
|
||||
}
|
||||
if (metadata.color && cfg.slideColors) {
|
||||
cfg.slideColors(metadata.color, metadata.backColor);
|
||||
}
|
||||
if (typeof(metadata.palette) !== 'undefined' && cfg.updatePalette) {
|
||||
cfg.updatePalette(metadata.palette);
|
||||
}
|
||||
}
|
||||
if (!titleUpdated) {
|
||||
Title.updateTitle(Title.defaultTitle);
|
||||
}
|
||||
};
|
||||
|
||||
return exp;
|
||||
};
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
|
|
@ -3,28 +3,16 @@ define([
|
|||
'/api/config',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-language.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/media-tag.js',
|
||||
|
||||
'css!/common/tippy.css',
|
||||
], function ($, Config, Cryptpad, Util, Language, UI, MediaTag) {
|
||||
], function ($, Config, Cryptpad, Util, Hash, Language, UI, MediaTag) {
|
||||
var UIElements = {};
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
||||
/**
|
||||
* Requirements from cryptpad-common.js
|
||||
* getFileSize
|
||||
* - hrefToHexChannelId
|
||||
* displayAvatar
|
||||
* - getFirstEmojiOrCharacter
|
||||
* - parsePadUrl
|
||||
* - getSecrets
|
||||
* - base64ToHex
|
||||
* - getBlobPathFromHex
|
||||
* - bytesToMegabytes
|
||||
*/
|
||||
|
||||
UIElements.updateTags = function (common, href) {
|
||||
var sframeChan = common.getSframeChannel();
|
||||
sframeChan.query('Q_TAGS_GET', href || null, function (err, res) {
|
||||
|
@ -308,19 +296,19 @@ define([
|
|||
if (cb) { cb(); }
|
||||
};
|
||||
if (!href) { return void displayDefault(); }
|
||||
var parsed = Cryptpad.parsePadUrl(href);
|
||||
var secret = Cryptpad.getSecrets('file', parsed.hash);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
var secret = Hash.getSecrets('file', parsed.hash);
|
||||
if (secret.keys && secret.channel) {
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var hexFileName = Cryptpad.base64ToHex(secret.channel);
|
||||
var src = Cryptpad.getBlobPathFromHex(hexFileName);
|
||||
var hexFileName = Util.base64ToHex(secret.channel);
|
||||
var src = Hash.getBlobPathFromHex(hexFileName);
|
||||
Common.getFileSize(href, function (e, data) {
|
||||
if (e) {
|
||||
displayDefault();
|
||||
return void console.error(e);
|
||||
}
|
||||
if (typeof data !== "number") { return void displayDefault(); }
|
||||
if (Cryptpad.bytesToMegabytes(data) > 0.5) { return void displayDefault(); }
|
||||
if (Util.bytesToMegabytes(data) > 0.5) { return void displayDefault(); }
|
||||
var $img = $('<media-tag>').appendTo($container);
|
||||
$img.attr('src', src);
|
||||
$img.attr('data-crypto-key', 'cryptpad:' + cryptKey);
|
||||
|
@ -356,7 +344,7 @@ define([
|
|||
// so we can just use those and only check for errors
|
||||
var $container = $('<span>', {'class':'cp-limit-container'});
|
||||
var todo;
|
||||
var updateUsage = Cryptpad.notAgainForAnother(function () {
|
||||
var updateUsage = Util.notAgainForAnother(function () {
|
||||
common.getPinUsage(todo);
|
||||
}, LIMIT_REFRESH_RATE);
|
||||
|
||||
|
|
|
@ -89,22 +89,6 @@ define([], function () {
|
|||
return a;
|
||||
};
|
||||
|
||||
Util.getHash = function () {
|
||||
return window.location.hash.slice(1);
|
||||
};
|
||||
|
||||
Util.replaceHash = function (hash) {
|
||||
if (window.history && window.history.replaceState) {
|
||||
if (!/^#/.test(hash)) { hash = '#' + hash; }
|
||||
void window.history.replaceState({}, window.document.title, hash);
|
||||
if (typeof(window.onhashchange) === 'function') {
|
||||
window.onhashchange();
|
||||
}
|
||||
return;
|
||||
}
|
||||
window.location.hash = hash;
|
||||
};
|
||||
|
||||
/*
|
||||
* Saving files
|
||||
*/
|
||||
|
@ -186,13 +170,6 @@ define([], function () {
|
|||
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
||||
};
|
||||
|
||||
Util.getAppType = function () {
|
||||
var parts = window.location.pathname.split('/')
|
||||
.filter(function (x) { return x; });
|
||||
if (!parts[0]) { return ''; }
|
||||
return parts[0];
|
||||
};
|
||||
|
||||
/* for wrapping async functions such that they can only be called once */
|
||||
Util.once = function (f) {
|
||||
var called;
|
||||
|
|
|
@ -3,8 +3,11 @@ define([
|
|||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/bower_components/chainpad-netflux/chainpad-netflux.js',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-realtime.js',
|
||||
'/bower_components/textpatcher/TextPatcher.js'
|
||||
], function ($, Crypto, Realtime, Cryptpad, TextPatcher) {
|
||||
], function ($, Crypto, CPNetflux, Cryptpad, Util, Hash, Realtime, TextPatcher) {
|
||||
//var Messages = Cryptpad.Messages;
|
||||
//var noop = function () {};
|
||||
var finish = function (S, err, doc) {
|
||||
|
@ -12,9 +15,9 @@ define([
|
|||
S.cb(err, doc);
|
||||
S.done = true;
|
||||
|
||||
var disconnect = Cryptpad.find(S, ['network', 'disconnect']);
|
||||
var disconnect = Util.find(S, ['network', 'disconnect']);
|
||||
if (typeof(disconnect) === 'function') { disconnect(); }
|
||||
var abort = Cryptpad.find(S, ['realtime', 'realtime', 'abort']);
|
||||
var abort = Util.find(S, ['realtime', 'realtime', 'abort']);
|
||||
if (typeof(abort) === 'function') {
|
||||
S.realtime.realtime.sync();
|
||||
abort();
|
||||
|
@ -23,7 +26,7 @@ define([
|
|||
|
||||
var makeConfig = function (hash) {
|
||||
// We can't use cryptget with a file or a user so we can use 'pad' as hash type
|
||||
var secret = Cryptpad.getSecrets('pad', hash);
|
||||
var secret = Hash.getSecrets('pad', hash);
|
||||
if (!secret.keys) { secret.keys = secret.key; } // support old hashses
|
||||
var config = {
|
||||
websocketURL: Cryptpad.getWebsocketURL(),
|
||||
|
@ -58,7 +61,7 @@ define([
|
|||
};
|
||||
overwrite(config, opt);
|
||||
|
||||
Session.realtime = Realtime.start(config);
|
||||
Session.realtime = CPNetflux.start(config);
|
||||
};
|
||||
|
||||
var put = function (hash, doc, cb, opt) {
|
||||
|
@ -80,7 +83,7 @@ define([
|
|||
cb(new Error("Timeout"));
|
||||
}, 5000);
|
||||
|
||||
Cryptpad.whenRealtimeSyncs(realtime, function () {
|
||||
Realtime.whenRealtimeSyncs(realtime, function () {
|
||||
window.clearTimeout(to);
|
||||
realtime.abort();
|
||||
finish(Session, void 0);
|
||||
|
@ -88,7 +91,7 @@ define([
|
|||
};
|
||||
overwrite(config, opt);
|
||||
|
||||
Session.session = Realtime.start(config);
|
||||
Session.session = CPNetflux.start(config);
|
||||
};
|
||||
|
||||
return {
|
||||
|
|
|
@ -58,44 +58,44 @@ define([
|
|||
var anon_rpc;
|
||||
|
||||
// import common utilities for export
|
||||
common.find = Util.find;
|
||||
common.hexToBase64 = Util.hexToBase64;
|
||||
common.base64ToHex = Util.base64ToHex;
|
||||
var deduplicateString = common.deduplicateString = Util.deduplicateString;
|
||||
common.uint8ArrayToHex = Util.uint8ArrayToHex;
|
||||
common.replaceHash = Util.replaceHash;
|
||||
common.getHash = Util.getHash;
|
||||
common.fixFileName = Util.fixFileName;
|
||||
common.bytesToMegabytes = Util.bytesToMegabytes;
|
||||
common.bytesToKilobytes = Util.bytesToKilobytes;
|
||||
common.fetch = Util.fetch;
|
||||
common.throttle = Util.throttle;
|
||||
common.createRandomInteger = Util.createRandomInteger;
|
||||
common.getAppType = Util.getAppType;
|
||||
common.notAgainForAnother = Util.notAgainForAnother;
|
||||
common.uid = Util.uid;
|
||||
common.slice = Util.slice;
|
||||
//common.find = Util.find;
|
||||
//common.hexToBase64 = Util.hexToBase64;
|
||||
//common.base64ToHex = Util.base64ToHex;
|
||||
//var deduplicateString = common.deduplicateString = Util.deduplicateString;
|
||||
//common.uint8ArrayToHex = Util.uint8ArrayToHex;
|
||||
//common.replaceHash = Util.replaceHash;
|
||||
//common.getHash = Util.getHash;
|
||||
//common.fixFileName = Util.fixFileName;
|
||||
//common.bytesToMegabytes = Util.bytesToMegabytes;
|
||||
//common.bytesToKilobytes = Util.bytesToKilobytes;
|
||||
//common.fetch = Util.fetch;
|
||||
//common.throttle = Util.throttle;
|
||||
//common.createRandomInteger = Util.createRandomInteger;
|
||||
//common.getAppType = Util.getAppType;
|
||||
//common.notAgainForAnother = Util.notAgainForAnother;
|
||||
//common.uid = Util.uid;
|
||||
//common.slice = Util.slice;
|
||||
|
||||
// import hash utilities for export
|
||||
var createRandomHash = common.createRandomHash = Hash.createRandomHash;
|
||||
common.parseTypeHash = Hash.parseTypeHash;
|
||||
var parsePadUrl = common.parsePadUrl = Hash.parsePadUrl;
|
||||
common.isNotStrongestStored = Hash.isNotStrongestStored;
|
||||
var hrefToHexChannelId = common.hrefToHexChannelId = Hash.hrefToHexChannelId;
|
||||
var getRelativeHref = common.getRelativeHref = Hash.getRelativeHref;
|
||||
common.getBlobPathFromHex = Hash.getBlobPathFromHex;
|
||||
//var createRandomHash = common.createRandomHash = Hash.createRandomHash;
|
||||
//common.parseTypeHash = Hash.parseTypeHash;
|
||||
//var parsePadUrl = common.parsePadUrl = Hash.parsePadUrl;
|
||||
//common.isNotStrongestStored = Hash.isNotStrongestStored;
|
||||
//var hrefToHexChannelId = common.hrefToHexChannelId = Hash.hrefToHexChannelId;
|
||||
//var getRelativeHref = common.getRelativeHref = Hash.getRelativeHref;
|
||||
//common.getBlobPathFromHex = Hash.getBlobPathFromHex;
|
||||
|
||||
common.getEditHashFromKeys = Hash.getEditHashFromKeys;
|
||||
common.getViewHashFromKeys = Hash.getViewHashFromKeys;
|
||||
common.getFileHashFromKeys = Hash.getFileHashFromKeys;
|
||||
common.getUserHrefFromKeys = Hash.getUserHrefFromKeys;
|
||||
common.getSecrets = Hash.getSecrets;
|
||||
common.getHashes = Hash.getHashes;
|
||||
common.createChannelId = Hash.createChannelId;
|
||||
common.findWeaker = Hash.findWeaker;
|
||||
common.findStronger = Hash.findStronger;
|
||||
common.serializeHash = Hash.serializeHash;
|
||||
common.createInviteUrl = Hash.createInviteUrl;
|
||||
//common.getEditHashFromKeys = Hash.getEditHashFromKeys;
|
||||
//common.getViewHashFromKeys = Hash.getViewHashFromKeys;
|
||||
//common.getFileHashFromKeys = Hash.getFileHashFromKeys;
|
||||
//common.getUserHrefFromKeys = Hash.getUserHrefFromKeys;
|
||||
//common.getSecrets = Hash.getSecrets;
|
||||
//common.getHashes = Hash.getHashes;
|
||||
//common.createChannelId = Hash.createChannelId;
|
||||
//common.findWeaker = Hash.findWeaker;
|
||||
//common.findStronger = Hash.findStronger;
|
||||
//common.serializeHash = Hash.serializeHash;
|
||||
//common.createInviteUrl = Hash.createInviteUrl;
|
||||
|
||||
// Messaging
|
||||
common.addDirectMessageHandler = Messaging.addDirectMessageHandler;
|
||||
|
@ -107,10 +107,10 @@ define([
|
|||
common.getLatestMessages = Messaging.getLatestMessages;
|
||||
|
||||
// Realtime
|
||||
// REFACTOR: common is not needed anymore so we should just pull common-reealtime directly
|
||||
var whenRealtimeSyncs = common.whenRealtimeSyncs = function (realtime, cb) {
|
||||
Realtime.whenRealtimeSyncs(common, realtime, cb);
|
||||
};
|
||||
|
||||
common.beginDetectingInfiniteSpinner = function (realtime) {
|
||||
Realtime.beginDetectingInfiniteSpinner(common, realtime);
|
||||
};
|
||||
|
@ -137,12 +137,16 @@ define([
|
|||
}
|
||||
return;
|
||||
};
|
||||
|
||||
// REFACTOR pull language directly
|
||||
common.getLanguage = function () {
|
||||
return Messages._languageUsed;
|
||||
};
|
||||
common.setLanguage = function (l, cb) {
|
||||
Language.setLanguage(l, null, cb);
|
||||
};
|
||||
|
||||
// REAFCTOR store.getProfile should be store.get(['profile'])
|
||||
common.getProfileUrl = function () {
|
||||
if (store && store.getProfile()) {
|
||||
return store.getProfile().view;
|
||||
|
@ -166,13 +170,14 @@ define([
|
|||
return localStorage[common.userNameKey];
|
||||
};
|
||||
|
||||
// REFACTOR: move to util?
|
||||
var randomToken = function () {
|
||||
return Math.random().toString(16).replace(/0./, '');
|
||||
};
|
||||
|
||||
common.isFeedbackAllowed = function () {
|
||||
try {
|
||||
var entry = common.find(getProxy(), [
|
||||
var entry = Util.find(getProxy(), [
|
||||
'settings',
|
||||
'general',
|
||||
'allowUserFeedback'
|
||||
|
@ -246,7 +251,7 @@ define([
|
|||
common.login = function (hash, name, cb) {
|
||||
if (!hash) { throw new Error('expected a user hash'); }
|
||||
if (!name) { throw new Error('expected a user name'); }
|
||||
hash = common.serializeHash(hash);
|
||||
hash = Hash.serializeHash(hash);
|
||||
localStorage.setItem(userHashKey, hash);
|
||||
localStorage.setItem(userNameKey, name);
|
||||
if (cb) { cb(); }
|
||||
|
@ -283,7 +288,7 @@ define([
|
|||
// Make sure we have an FS_hash in localStorage before reloading all the tabs
|
||||
// so that we don't end up with tabs using different anon hashes
|
||||
if (!localStorage[fileHashKey]) {
|
||||
localStorage[fileHashKey] = common.createRandomHash();
|
||||
localStorage[fileHashKey] = Hash.createRandomHash();
|
||||
}
|
||||
eraseTempSessionValues();
|
||||
|
||||
|
@ -308,7 +313,7 @@ define([
|
|||
}
|
||||
|
||||
if (hash) {
|
||||
var sHash = common.serializeHash(hash);
|
||||
var sHash = Hash.serializeHash(hash);
|
||||
if (sHash !== hash) { localStorage[userHashKey] = sHash; }
|
||||
}
|
||||
|
||||
|
@ -357,9 +362,9 @@ define([
|
|||
var checkObjectData = function (pad, cb) {
|
||||
if (!pad.ctime) { pad.ctime = pad.atime; }
|
||||
if (/^https*:\/\//.test(pad.href)) {
|
||||
pad.href = common.getRelativeHref(pad.href);
|
||||
pad.href = Hash.getRelativeHref(pad.href);
|
||||
}
|
||||
var parsed = common.parsePadUrl(pad.href);
|
||||
var parsed = Hash.parsePadUrl(pad.href);
|
||||
if (!parsed || !parsed.hash) { return; }
|
||||
if (typeof(cb) === 'function') {
|
||||
cb(parsed);
|
||||
|
@ -369,28 +374,6 @@ define([
|
|||
}
|
||||
return parsed.hashData;
|
||||
};
|
||||
// Migrate from legacy store (localStorage)
|
||||
common.migrateRecentPads = function (pads) {
|
||||
return pads.map(function (pad) {
|
||||
var parsedHash;
|
||||
if (Array.isArray(pad)) { // TODO DEPRECATE_F
|
||||
return {
|
||||
href: pad[0],
|
||||
atime: pad[1],
|
||||
title: pad[2] || '',
|
||||
ctime: pad[1],
|
||||
};
|
||||
} else if (pad && typeof(pad) === 'object') {
|
||||
parsedHash = checkObjectData(pad);
|
||||
if (!parsedHash || !parsedHash.type) { return; }
|
||||
return pad;
|
||||
} else {
|
||||
console.error("[Cryptpad.migrateRecentPads] pad had unexpected value");
|
||||
console.log(pad);
|
||||
return;
|
||||
}
|
||||
}).filter(function (x) { return x; });
|
||||
};
|
||||
// Remove everything from RecentPads that is not an object and check the objects
|
||||
var checkRecentPads = common.checkRecentPads = function (pads) {
|
||||
Object.keys(pads).forEach(function (id, i) {
|
||||
|
@ -410,7 +393,7 @@ define([
|
|||
};
|
||||
|
||||
// Create untitled documents when no name is given
|
||||
var getLocaleDate = common.getLocaleDate = function () {
|
||||
var getLocaleDate = function () {
|
||||
if (window.Intl && window.Intl.DateTimeFormat) {
|
||||
var options = {weekday: "short", year: "numeric", month: "long", day: "numeric"};
|
||||
return new window.Intl.DateTimeFormat(undefined, options).format(new Date());
|
||||
|
@ -433,18 +416,13 @@ define([
|
|||
href: href,
|
||||
atime: now,
|
||||
ctime: now,
|
||||
title: title || getDefaultName(parsePadUrl(href)),
|
||||
title: title || getDefaultName(Hash.parsePadUrl(href)),
|
||||
};
|
||||
};
|
||||
|
||||
/* Sort pads according to how recently they were accessed */
|
||||
common.mostRecent = function (a, b) {
|
||||
return new Date(b.atime).getTime() - new Date(a.atime).getTime();
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
common.setPadAttribute = function (attr, value, cb, href) {
|
||||
href = getRelativeHref(href || window.location.href);
|
||||
href = Hash.getRelativeHref(href || window.location.href);
|
||||
getStore().setPadAttribute(href, attr, value, cb);
|
||||
};
|
||||
common.setDisplayName = function (value, cb) {
|
||||
|
@ -464,7 +442,7 @@ define([
|
|||
|
||||
// STORAGE
|
||||
common.getPadAttribute = function (attr, cb) {
|
||||
var href = getRelativeHref(window.location.href);
|
||||
var href = Hash.getRelativeHref(window.location.href);
|
||||
getStore().getPadAttribute(href, attr, cb);
|
||||
};
|
||||
common.getAttribute = function (attr, cb) {
|
||||
|
@ -492,7 +470,7 @@ define([
|
|||
href = href || (window.location.pathname + window.location.hash);
|
||||
var id = store.getIdFromHref(href);
|
||||
if (!id) { return void cb('NO_ID'); }
|
||||
var entry = common.find(getProxy(), [
|
||||
var entry = Util.find(getProxy(), [
|
||||
'drive',
|
||||
'filesData',
|
||||
id
|
||||
|
@ -558,7 +536,7 @@ define([
|
|||
common.listAllTags = function (cb) {
|
||||
var all = [];
|
||||
var proxy = getProxy();
|
||||
var files = common.find(proxy, ['drive', 'filesData']);
|
||||
var files = Util.find(proxy, ['drive', 'filesData']);
|
||||
|
||||
if (typeof(files) !== 'object') { return cb('invalid_drive'); }
|
||||
Object.keys(files).forEach(function (k) {
|
||||
|
@ -583,7 +561,7 @@ define([
|
|||
if (!type) { return allTemplates; }
|
||||
|
||||
var templates = allTemplates.filter(function (f) {
|
||||
var parsed = parsePadUrl(f.href);
|
||||
var parsed = Hash.parsePadUrl(f.href);
|
||||
return parsed.type === type;
|
||||
});
|
||||
return templates;
|
||||
|
@ -596,7 +574,7 @@ define([
|
|||
};
|
||||
|
||||
common.isTemplate = function (href) {
|
||||
var rhref = getRelativeHref(href);
|
||||
var rhref = Hash.getRelativeHref(href);
|
||||
var templates = listTemplates();
|
||||
return templates.some(function (t) {
|
||||
return t.href === rhref;
|
||||
|
@ -605,11 +583,11 @@ define([
|
|||
|
||||
// Secure iframes
|
||||
common.useTemplate = function (href, Crypt, cb) {
|
||||
var parsed = parsePadUrl(href);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
if(!parsed) { throw new Error("Cannot get template hash"); }
|
||||
Crypt.get(parsed.hash, function (err, val) {
|
||||
if (err) { throw new Error(err); }
|
||||
var p = parsePadUrl(window.location.href);
|
||||
var p = Hash.parsePadUrl(window.location.href);
|
||||
Crypt.put(p.hash, val, cb);
|
||||
});
|
||||
};
|
||||
|
@ -649,7 +627,7 @@ define([
|
|||
// STORAGE
|
||||
common.forgetPad = function (href, cb) {
|
||||
if (typeof(getStore().forgetPad) === "function") {
|
||||
getStore().forgetPad(common.getRelativeHref(href), cb);
|
||||
getStore().forgetPad(Hash.getRelativeHref(href), cb);
|
||||
return;
|
||||
}
|
||||
cb ("store.forgetPad is not a function");
|
||||
|
@ -657,10 +635,10 @@ define([
|
|||
|
||||
common.setPadTitle = function (name, padHref, cb) {
|
||||
var href = typeof padHref === "string" ? padHref : window.location.href;
|
||||
var parsed = parsePadUrl(href);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
if (!parsed.hash) { return; }
|
||||
href = parsed.getUrl({present: parsed.present});
|
||||
//href = getRelativeHref(href);
|
||||
//href = Hash.getRelativeHref(href);
|
||||
// getRecentPads return the array from the drive, not a copy
|
||||
// We don't have to call "set..." at the end, everything is stored with listmap
|
||||
getRecentPads(function (err, recent) {
|
||||
|
@ -673,7 +651,7 @@ define([
|
|||
var contains;
|
||||
Object.keys(recent).forEach(function (id) {
|
||||
var pad = recent[id];
|
||||
var p = parsePadUrl(pad.href);
|
||||
var p = Hash.parsePadUrl(pad.href);
|
||||
|
||||
if (p.type !== parsed.type) { return pad; }
|
||||
|
||||
|
@ -759,7 +737,7 @@ define([
|
|||
if (title === null) { return; }
|
||||
|
||||
if (title.trim() === "") {
|
||||
var parsed = parsePadUrl(href || window.location.href);
|
||||
var parsed = Hash.parsePadUrl(href || window.location.href);
|
||||
title = getDefaultName(parsed);
|
||||
}
|
||||
|
||||
|
@ -773,22 +751,6 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
common.getUserFilesList = function () {
|
||||
var store = common.getStore();
|
||||
var proxy = store.getProxy();
|
||||
var fo = proxy.fo;
|
||||
var hashes = [];
|
||||
var list = fo.getFiles([fo.ROOT]).filter(function (id) {
|
||||
var href = fo.getFileData(id).href;
|
||||
var parsed = parsePadUrl(href);
|
||||
if ((parsed.type === 'file' || parsed.type === 'media')
|
||||
&& hashes.indexOf(parsed.hash) === -1) {
|
||||
hashes.push(parsed.hash);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return list;
|
||||
};
|
||||
// Needed for the secure filepicker app
|
||||
common.getSecureFilesList = function (query, cb) {
|
||||
var store = common.getStore();
|
||||
|
@ -813,7 +775,7 @@ define([
|
|||
};
|
||||
fo.getFiles(where).forEach(function (id) {
|
||||
var data = fo.getFileData(id);
|
||||
var parsed = parsePadUrl(data.href);
|
||||
var parsed = Hash.parsePadUrl(data.href);
|
||||
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1)
|
||||
&& hashes.indexOf(parsed.hash) === -1) {
|
||||
if (isFiltered(parsed.type, data)) { return; }
|
||||
|
@ -833,21 +795,21 @@ define([
|
|||
var userHash = localStorage && localStorage.User_hash;
|
||||
if (!userHash) { return null; }
|
||||
|
||||
var userParsedHash = common.parseTypeHash('drive', userHash);
|
||||
var userParsedHash = Hash.parseTypeHash('drive', userHash);
|
||||
var userChannel = userParsedHash && userParsedHash.channel;
|
||||
if (!userChannel) { return null; }
|
||||
|
||||
var list = fo.getFiles([fo.FILES_DATA]).map(function (id) {
|
||||
return hrefToHexChannelId(fo.getFileData(id).href);
|
||||
return Hash.hrefToHexChannelId(fo.getFileData(id).href);
|
||||
})
|
||||
.filter(function (x) { return x; });
|
||||
|
||||
// Get the avatar
|
||||
var profile = store.getProfile();
|
||||
if (profile) {
|
||||
var profileChan = profile.edit ? hrefToHexChannelId('/profile/#' + profile.edit) : null;
|
||||
var profileChan = profile.edit ? Hash.hrefToHexChannelId('/profile/#' + profile.edit) : null;
|
||||
if (profileChan) { list.push(profileChan); }
|
||||
var avatarChan = profile.avatar ? hrefToHexChannelId(profile.avatar) : null;
|
||||
var avatarChan = profile.avatar ? Hash.hrefToHexChannelId(profile.avatar) : null;
|
||||
if (avatarChan) { list.push(avatarChan); }
|
||||
}
|
||||
|
||||
|
@ -856,14 +818,14 @@ define([
|
|||
list = list.concat(fList);
|
||||
}
|
||||
|
||||
list.push(common.base64ToHex(userChannel));
|
||||
list.push(Util.base64ToHex(userChannel));
|
||||
list.sort();
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
var getCanonicalChannelList = common.getCanonicalChannelList = function () {
|
||||
return deduplicateString(getUserChannelList()).sort();
|
||||
return Util.deduplicateString(getUserChannelList()).sort();
|
||||
};
|
||||
|
||||
var pinsReady = common.pinsReady = function () {
|
||||
|
@ -1042,100 +1004,6 @@ define([
|
|||
rpc.uploadCancel(cb);
|
||||
};
|
||||
|
||||
/* Create a usage bar which keeps track of how much storage space is used
|
||||
by your CryptDrive. The getPinnedUsage RPC is one of the heavier calls,
|
||||
so we throttle its usage. Clients will not update more than once per
|
||||
LIMIT_REFRESH_RATE. It will be update at least once every three such intervals
|
||||
If changes are made to your drive in the interim, they will trigger an
|
||||
update.
|
||||
*/
|
||||
var LIMIT_REFRESH_RATE = 30000; // milliseconds
|
||||
common.createUsageBar = function (cb) {
|
||||
if (!isLoggedIn()) { return cb("NOT_LOGGED_IN"); }
|
||||
// getPinnedUsage updates common.account.usage, and other values
|
||||
// so we can just use those and only check for errors
|
||||
var $container = $('<span>', {'class':'limit-container'});
|
||||
var todo;
|
||||
var updateUsage = window.updateUsage = common.notAgainForAnother(function () {
|
||||
common.getPinnedUsage(todo);
|
||||
}, LIMIT_REFRESH_RATE);
|
||||
|
||||
todo = function (err) {
|
||||
if (err) { return void console.error(err); }
|
||||
|
||||
$container.html('');
|
||||
var unit = Util.magnitudeOfBytes(common.account.limit);
|
||||
|
||||
var usage = unit === 'GB'? Util.bytesToGigabytes(common.account.usage):
|
||||
Util.bytesToMegabytes(common.account.usage);
|
||||
var limit = unit === 'GB'? Util.bytesToGigabytes(common.account.limit):
|
||||
Util.bytesToMegabytes(common.account.limit);
|
||||
|
||||
var $limit = $('<span>', {'class': 'cryptpad-limit-bar'}).appendTo($container);
|
||||
var quota = usage/limit;
|
||||
var $usage = $('<span>', {'class': 'usage'}).css('width', quota*100+'%');
|
||||
|
||||
var makeDonateButton = function () {
|
||||
$('<a>', {
|
||||
'class': 'upgrade btn btn-success',
|
||||
href: common.donateURL,
|
||||
rel: "noreferrer noopener",
|
||||
target: "_blank",
|
||||
}).text(Messages.supportCryptpad).appendTo($container);
|
||||
};
|
||||
|
||||
var makeUpgradeButton = function () {
|
||||
$('<a>', {
|
||||
'class': 'upgrade btn btn-success',
|
||||
href: common.upgradeURL,
|
||||
rel: "noreferrer noopener",
|
||||
target: "_blank",
|
||||
}).text(Messages.upgradeAccount).appendTo($container);
|
||||
};
|
||||
|
||||
if (!Config.removeDonateButton) {
|
||||
if (!common.isLoggedIn() || !Config.allowSubscriptions) {
|
||||
// user is not logged in, or subscriptions are disallowed
|
||||
makeDonateButton();
|
||||
} else if (!common.account.plan) {
|
||||
// user is logged in and subscriptions are allowed
|
||||
// and they don't have one. show upgrades
|
||||
makeUpgradeButton();
|
||||
} else {
|
||||
// they have a plan. show nothing
|
||||
}
|
||||
}
|
||||
|
||||
var prettyUsage;
|
||||
var prettyLimit;
|
||||
|
||||
if (unit === 'GB') {
|
||||
prettyUsage = Messages._getKey('formattedGB', [usage]);
|
||||
prettyLimit = Messages._getKey('formattedGB', [limit]);
|
||||
} else {
|
||||
prettyUsage = Messages._getKey('formattedMB', [usage]);
|
||||
prettyLimit = Messages._getKey('formattedMB', [limit]);
|
||||
}
|
||||
|
||||
if (quota < 0.8) { $usage.addClass('normal'); }
|
||||
else if (quota < 1) { $usage.addClass('warning'); }
|
||||
else { $usage.addClass('above'); }
|
||||
var $text = $('<span>', {'class': 'usageText'});
|
||||
$text.text(usage + ' / ' + prettyLimit);
|
||||
$limit.append($usage).append($text);
|
||||
};
|
||||
|
||||
setInterval(function () {
|
||||
updateUsage();
|
||||
}, LIMIT_REFRESH_RATE * 3);
|
||||
|
||||
updateUsage();
|
||||
getProxy().on('change', ['drive'], function () {
|
||||
updateUsage();
|
||||
});
|
||||
cb(null, $container);
|
||||
};
|
||||
|
||||
// Forget button
|
||||
// TODO REFACTOR only used in sframe-common-outer
|
||||
common.moveToTrash = function (cb, href) {
|
||||
|
@ -1159,11 +1027,12 @@ define([
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
// TODO REFACTOR only used in sframe-common-outer
|
||||
common.saveAsTemplate = function (Cryptput, data, cb) {
|
||||
var p = parsePadUrl(window.location.href);
|
||||
var p = Hash.parsePadUrl(window.location.href);
|
||||
if (!p.type) { return; }
|
||||
var hash = createRandomHash();
|
||||
var hash = Hash.createRandomHash();
|
||||
var href = '/' + p.type + '/#' + hash;
|
||||
Cryptput(hash, data.toSave, function (e) {
|
||||
if (e) { throw new Error(e); }
|
||||
|
@ -1175,23 +1044,6 @@ define([
|
|||
};
|
||||
|
||||
|
||||
common.getMediatagScript = function () {
|
||||
var origin = window.location.origin;
|
||||
return '<script src="' + origin + '/common/media-tag-nacl.min.js"></script>';
|
||||
};
|
||||
common.getMediatagFromHref = function (href) {
|
||||
var parsed = common.parsePadUrl(href);
|
||||
var secret = common.getSecrets('file', parsed.hash);
|
||||
if (secret.keys && secret.channel) {
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var hexFileName = common.base64ToHex(secret.channel);
|
||||
var origin = Config.fileHost || window.location.origin;
|
||||
var src = origin + common.getBlobPathFromHex(hexFileName);
|
||||
return '<media-tag src="' + src + '" data-crypto-key="cryptpad:' + cryptKey + '">' +
|
||||
'</media-tag>';
|
||||
}
|
||||
return;
|
||||
};
|
||||
$(window.document).on('decryption', function (e) {
|
||||
var decrypted = e.originalEvent;
|
||||
if (decrypted.callback) {
|
||||
|
@ -1218,7 +1070,7 @@ define([
|
|||
size = decrypted.blob.size;
|
||||
}
|
||||
|
||||
var sizeMb = common.bytesToMegabytes(size);
|
||||
var sizeMb = Util.bytesToMegabytes(size);
|
||||
|
||||
var $btn = $(root).find('button');
|
||||
$btn.addClass('btn btn-success')
|
||||
|
@ -1236,23 +1088,17 @@ define([
|
|||
});
|
||||
}
|
||||
});
|
||||
common.avatarAllowedTypes = [
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
];
|
||||
|
||||
common.getShareHashes = function (secret, cb) {
|
||||
if (!window.location.hash) {
|
||||
var hashes = common.getHashes(secret.channel, secret);
|
||||
var hashes = Hash.getHashes(secret.channel, secret);
|
||||
return void cb(null, hashes);
|
||||
}
|
||||
common.getRecentPads(function (err, recent) {
|
||||
var parsed = parsePadUrl(window.location.href);
|
||||
var parsed = Hash.parsePadUrl(window.location.href);
|
||||
if (!parsed.type || !parsed.hashData) { return void cb('E_INVALID_HREF'); }
|
||||
if (parsed.type === 'file') { secret.channel = Util.base64ToHex(secret.channel); }
|
||||
var hashes = common.getHashes(secret.channel, secret);
|
||||
var hashes = Hash.getHashes(secret.channel, secret);
|
||||
|
||||
if (!hashes.editHash && !hashes.viewHash && parsed.hashData && !parsed.hashData.mode) {
|
||||
// It means we're using an old hash
|
||||
|
@ -1260,9 +1106,9 @@ define([
|
|||
}
|
||||
|
||||
// If we have a stronger version in drive, add it and add a redirect button
|
||||
var stronger = recent && common.findStronger(null, recent);
|
||||
var stronger = recent && Hash.findStronger(null, recent);
|
||||
if (stronger) {
|
||||
var parsed2 = parsePadUrl(stronger);
|
||||
var parsed2 = Hash.parsePadUrl(stronger);
|
||||
hashes.editHash = parsed2.hash;
|
||||
}
|
||||
|
||||
|
@ -1357,8 +1203,8 @@ define([
|
|||
var oldHref = document.location.href;
|
||||
window.onhashchange = function () {
|
||||
var newHref = document.location.href;
|
||||
var parsedOld = parsePadUrl(oldHref).hashData;
|
||||
var parsedNew = parsePadUrl(newHref).hashData;
|
||||
var parsedOld = Hash.parsePadUrl(oldHref).hashData;
|
||||
var parsedNew = Hash.parsePadUrl(newHref).hashData;
|
||||
if (parsedOld && parsedNew && (
|
||||
parsedOld.type !== parsedNew.type
|
||||
|| parsedOld.channel !== parsedNew.channel
|
||||
|
@ -1438,7 +1284,7 @@ define([
|
|||
if (sessionStorage.createReadme) {
|
||||
var w = waitFor();
|
||||
require(['/common/cryptget.js'], function (Crypt) {
|
||||
var hash = common.createRandomHash();
|
||||
var hash = Hash.createRandomHash();
|
||||
Crypt.put(hash, Messages.driveReadme, function (e) {
|
||||
if (e) {
|
||||
console.error("Error while creating the default pad:", e);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
define([
|
||||
'jquery',
|
||||
'/bower_components/marked/marked.min.js',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-util.js',
|
||||
'/common/media-tag.js',
|
||||
'/bower_components/diff-dom/diffDOM.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
],function ($, Marked, Cryptpad, MediaTag) {
|
||||
],function ($, Marked, Hash, Util, MediaTag) {
|
||||
var DiffMd = {};
|
||||
|
||||
var DiffDOM = window.diffDOM;
|
||||
|
@ -40,8 +41,8 @@ define([
|
|||
};
|
||||
renderer.image = function (href, title, text) {
|
||||
if (href.slice(0,6) === '/file/') {
|
||||
var parsed = Cryptpad.parsePadUrl(href);
|
||||
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
var hexFileName = Util.base64ToHex(parsed.hashData.channel);
|
||||
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
|
||||
var mt = '<media-tag src="' + src + '" data-crypto-key="cryptpad:' + parsed.hashData.key + '">';
|
||||
if (mediaMap[src]) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,8 +5,9 @@ define([
|
|||
'/bower_components/textpatcher/TextPatcher.amd.js',
|
||||
'/common/userObject.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/migrate-user-object.js',
|
||||
], function ($, Listmap, Crypto, TextPatcher, FO, UI, Migrate) {
|
||||
], function ($, Listmap, Crypto, TextPatcher, FO, UI, Hash, Migrate) {
|
||||
/*
|
||||
This module uses localStorage, which is synchronous, but exposes an
|
||||
asyncronous API. This is so that we can substitute other storage
|
||||
|
@ -248,7 +249,7 @@ define([
|
|||
if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) {
|
||||
// even anonymous users should have a persistent, unique-ish id
|
||||
console.log('generating a persistent identifier');
|
||||
proxy.uid = Cryptpad.createChannelId();
|
||||
proxy.uid = Hash.createChannelId();
|
||||
}
|
||||
|
||||
// if the user is logged in, but does not have signing keys...
|
||||
|
@ -285,11 +286,11 @@ define([
|
|||
if (!Cryptpad || initialized) { return; }
|
||||
initialized = true;
|
||||
|
||||
var hash = Cryptpad.getUserHash() || localStorage.FS_hash || Cryptpad.createRandomHash();
|
||||
var hash = Cryptpad.getUserHash() || localStorage.FS_hash || Hash.createRandomHash();
|
||||
if (!hash) {
|
||||
throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...');
|
||||
}
|
||||
var secret = Cryptpad.getSecrets('drive', hash);
|
||||
var secret = Hash.getSecrets('drive', hash);
|
||||
var listmapConfig = {
|
||||
data: {},
|
||||
websocketURL: Cryptpad.getWebsocketURL(),
|
||||
|
@ -332,7 +333,7 @@ define([
|
|||
rt.proxy.on('create', function (info) {
|
||||
exp.info = info;
|
||||
if (!Cryptpad.getUserHash()) {
|
||||
localStorage.FS_hash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
||||
localStorage.FS_hash = Hash.getEditHashFromKeys(info.channel, secret.keys);
|
||||
}
|
||||
}).on('ready', function () {
|
||||
if (store) { return; } // the store is already ready, it is a reconnection
|
||||
|
|
|
@ -3,10 +3,11 @@ define([
|
|||
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-util.js',
|
||||
'/common/credential.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
'/bower_components/scrypt-async/scrypt-async.min.js', // better load speed
|
||||
], function ($, Listmap, Crypto, Cryptpad, Cred) {
|
||||
], function ($, Listmap, Crypto, Cryptpad, Util, Cred) {
|
||||
var Exports = {
|
||||
Cred: Cred,
|
||||
};
|
||||
|
@ -43,12 +44,12 @@ define([
|
|||
keys.editKeyStr = keys.editKeyStr.replace(/\//g, '-');
|
||||
|
||||
// 32 bytes of hex
|
||||
var channelHex = opt.channelHex = Cryptpad.uint8ArrayToHex(channelSeed);
|
||||
var channelHex = opt.channelHex = Util.uint8ArrayToHex(channelSeed);
|
||||
|
||||
// should never happen
|
||||
if (channelHex.length !== 32) { throw new Error('invalid channel id'); }
|
||||
|
||||
opt.channel64 = Cryptpad.hexToBase64(channelHex);
|
||||
opt.channel64 = Util.hexToBase64(channelHex);
|
||||
|
||||
opt.userHash = '/1/edit/' + [opt.channel64, opt.keys.editKeyStr].join('/');
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ define([
|
|||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/userObject.js',
|
||||
], function (Cryptpad, Crypt, FO) {
|
||||
'/common/common-hash.js',
|
||||
], function (Cryptpad, Crypt, FO, Hash) {
|
||||
var exp = {};
|
||||
|
||||
var getType = function (el) {
|
||||
|
@ -41,7 +42,7 @@ define([
|
|||
if (typeof(p) === "string") {
|
||||
if (getType(root) !== "object") { root = undefined; error(); return; }
|
||||
if (i === path.length - 1) {
|
||||
root[Cryptpad.createChannelId()] = id;
|
||||
root[Hash.createChannelId()] = id;
|
||||
return;
|
||||
}
|
||||
next = getType(path[i+1]);
|
||||
|
@ -120,10 +121,10 @@ define([
|
|||
// Do not migrate a pad if we already have it, it would create a duplicate in the drive
|
||||
if (newHrefs.indexOf(href) !== -1) { return; }
|
||||
// If we have a stronger version, do not add the current href
|
||||
if (Cryptpad.findStronger(href, newRecentPads)) { return; }
|
||||
if (Hash.findStronger(href, newRecentPads)) { return; }
|
||||
// If we have a weaker version, replace the href by the new one
|
||||
// NOTE: if that weaker version is in the trash, the strong one will be put in unsorted
|
||||
var weaker = Cryptpad.findWeaker(href, newRecentPads);
|
||||
var weaker = Hash.findWeaker(href, newRecentPads);
|
||||
if (weaker) {
|
||||
// Update RECENTPADS
|
||||
newRecentPads.some(function (pad) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
define([
|
||||
'/file/file-crypto.js',
|
||||
'/common/common-hash.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
], function (FileCrypto) {
|
||||
], function (FileCrypto, Hash) {
|
||||
var Nacl = window.nacl;
|
||||
var module = {};
|
||||
|
||||
|
@ -50,7 +51,7 @@ define([
|
|||
|
||||
var b64Key = Nacl.util.encodeBase64(key);
|
||||
|
||||
var hash = common.getFileHashFromKeys(id, b64Key);
|
||||
var hash = Hash.getFileHashFromKeys(id, b64Key);
|
||||
var href = '/file/#' + hash;
|
||||
|
||||
var title = metadata.name;
|
||||
|
|
|
@ -300,7 +300,7 @@ define([
|
|||
var ext = (typeof(extension) === 'function') ? extension() : extension;
|
||||
var suggestion = title.suggestTitle('cryptpad-document');
|
||||
UI.prompt(Messages.exportPrompt,
|
||||
Cryptpad.fixFileName(suggestion) + '.' + ext, function (filename)
|
||||
Util.fixFileName(suggestion) + '.' + ext, function (filename)
|
||||
{
|
||||
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||
if (async) {
|
||||
|
|
|
@ -3,9 +3,11 @@ define([
|
|||
'/file/file-crypto.js',
|
||||
'/common/common-thumbnail.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-util.js',
|
||||
'/customize/messages.js',
|
||||
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
], function ($, FileCrypto, Thumb, UI) {
|
||||
], function ($, FileCrypto, Thumb, UI, Util, Messages) {
|
||||
var Nacl = window.nacl;
|
||||
var module = {};
|
||||
|
||||
|
@ -33,9 +35,6 @@ define([
|
|||
|
||||
module.create = function (common, config) {
|
||||
var File = {};
|
||||
var Cryptpad = common.getCryptpadCommon();
|
||||
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
||||
var queue = File.queue = {
|
||||
queue: [],
|
||||
|
@ -168,9 +167,9 @@ define([
|
|||
};
|
||||
|
||||
var prettySize = function (bytes) {
|
||||
var kB = Cryptpad.bytesToKilobytes(bytes);
|
||||
var kB = Util.bytesToKilobytes(bytes);
|
||||
if (kB < 1024) { return kB + Messages.KB; }
|
||||
var mB = Cryptpad.bytesToMegabytes(bytes);
|
||||
var mB = Util.bytesToMegabytes(bytes);
|
||||
return mB + Messages.MB;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ define([
|
|||
var FilePicker;
|
||||
var Messenger;
|
||||
var Notifier;
|
||||
var Utils = {};
|
||||
|
||||
nThen(function (waitFor) {
|
||||
// Load #2, the loading screen is up so grab whatever you need...
|
||||
|
@ -31,8 +32,11 @@ define([
|
|||
'/filepicker/main.js',
|
||||
'/common/common-messenger.js',
|
||||
'/common/common-notifier.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-realtime.js',
|
||||
], waitFor(function (_CpNfOuter, _Cryptpad, _Crypto, _Cryptget, SFrameChannel,
|
||||
_FilePicker, _Messenger, _Notifier) {
|
||||
_FilePicker, _Messenger, _Notifier, _Hash, _Util, _Realtime) {
|
||||
CpNfOuter = _CpNfOuter;
|
||||
Cryptpad = _Cryptpad;
|
||||
Crypto = _Crypto;
|
||||
|
@ -40,6 +44,9 @@ define([
|
|||
FilePicker = _FilePicker;
|
||||
Messenger = _Messenger;
|
||||
Notifier = _Notifier;
|
||||
Utils.Hash = _Hash;
|
||||
Utils.Util = _Util;
|
||||
Utils.Realtime = _Realtime;
|
||||
|
||||
if (localStorage.CRYPTPAD_URLARGS !== ApiConfig.requireConf.urlArgs) {
|
||||
console.log("New version, flushing cache");
|
||||
|
@ -85,16 +92,16 @@ define([
|
|||
});
|
||||
});
|
||||
|
||||
secret = cfg.getSecrets ? cfg.getSecrets(Cryptpad) : Cryptpad.getSecrets();
|
||||
secret = cfg.getSecrets ? cfg.getSecrets(Cryptpad, Utils) : Utils.Hash.getSecrets();
|
||||
if (!secret.channel) {
|
||||
// New pad: create a new random channel id
|
||||
secret.channel = Cryptpad.createChannelId();
|
||||
secret.channel = Utils.Hash.createChannelId();
|
||||
}
|
||||
Cryptpad.getShareHashes(secret, waitFor(function (err, h) { hashes = h; }));
|
||||
}).nThen(function () {
|
||||
var readOnly = secret.keys && !secret.keys.editKeyStr;
|
||||
if (!secret.keys) { secret.keys = secret.key; }
|
||||
var parsed = Cryptpad.parsePadUrl(window.location.href);
|
||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
||||
if (!parsed.type) { throw new Error(); }
|
||||
var defaultTitle = Cryptpad.getDefaultName(parsed);
|
||||
var proxy = Cryptpad.getProxy();
|
||||
|
@ -335,11 +342,11 @@ define([
|
|||
|
||||
// Present mode URL
|
||||
sframeChan.on('Q_PRESENT_URL_GET_VALUE', function (data, cb) {
|
||||
var parsed = Cryptpad.parsePadUrl(window.location.href);
|
||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
||||
cb(parsed.hashData && parsed.hashData.present);
|
||||
});
|
||||
sframeChan.on('EV_PRESENT_URL_SET_VALUE', function (data) {
|
||||
var parsed = Cryptpad.parsePadUrl(window.location.href);
|
||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
||||
window.location.href = parsed.getUrl({
|
||||
embed: parsed.hashData.embed,
|
||||
present: data
|
||||
|
@ -463,7 +470,7 @@ define([
|
|||
});
|
||||
|
||||
if (cfg.addRpc) {
|
||||
cfg.addRpc(sframeChan, Cryptpad);
|
||||
cfg.addRpc(sframeChan, Cryptpad, Utils);
|
||||
}
|
||||
|
||||
if (cfg.messaging) {
|
||||
|
@ -580,6 +587,18 @@ define([
|
|||
|
||||
if (!realtime) { return; }
|
||||
|
||||
var replaceHash = function (hash) {
|
||||
if (window.history && window.history.replaceState) {
|
||||
if (!/^#/.test(hash)) { hash = '#' + hash; }
|
||||
void window.history.replaceState({}, window.document.title, hash);
|
||||
if (typeof(window.onhashchange) === 'function') {
|
||||
window.onhashchange();
|
||||
}
|
||||
return;
|
||||
}
|
||||
window.location.hash = hash;
|
||||
};
|
||||
|
||||
CpNfOuter.start({
|
||||
sframeChan: sframeChan,
|
||||
channel: secret.channel,
|
||||
|
@ -596,7 +615,7 @@ define([
|
|||
return;
|
||||
}
|
||||
if (readOnly || cfg.noHash) { return; }
|
||||
Cryptpad.replaceHash(Cryptpad.getEditHashFromKeys(wc.id, secret.keys));
|
||||
replaceHash(Utils.Hash.getEditHashFromKeys(wc.id, secret.keys));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,9 +12,9 @@ define([
|
|||
'/common/metadata-manager.js',
|
||||
|
||||
'/customize/application_config.js',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-realtime.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-thumbnail.js',
|
||||
'/common/common-interface.js',
|
||||
'/bower_components/localforage/dist/localforage.min.js'
|
||||
|
@ -31,9 +31,9 @@ define([
|
|||
CodeMirror,
|
||||
MetadataMgr,
|
||||
AppConfig,
|
||||
Cryptpad,
|
||||
CommonRealtime,
|
||||
Util,
|
||||
Hash,
|
||||
Thumb,
|
||||
UI,
|
||||
localForage
|
||||
|
@ -57,7 +57,6 @@ define([
|
|||
};
|
||||
|
||||
funcs.getMetadataMgr = function () { return ctx.metadataMgr; };
|
||||
funcs.getCryptpadCommon = function () { return Cryptpad; };
|
||||
funcs.getSframeChannel = function () { return ctx.sframeChan; };
|
||||
funcs.getAppConfig = function () { return AppConfig; };
|
||||
|
||||
|
@ -104,21 +103,21 @@ define([
|
|||
return '<script src="' + origin + '/common/media-tag-nacl.min.js"></script>';
|
||||
};
|
||||
funcs.getMediatagFromHref = function (href) {
|
||||
var parsed = Cryptpad.parsePadUrl(href);
|
||||
var secret = Cryptpad.getSecrets('file', parsed.hash);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
var secret = Hash.getSecrets('file', parsed.hash);
|
||||
var data = ctx.metadataMgr.getPrivateData();
|
||||
if (secret.keys && secret.channel) {
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var hexFileName = Cryptpad.base64ToHex(secret.channel);
|
||||
var hexFileName = Util.base64ToHex(secret.channel);
|
||||
var origin = data.fileHost || data.origin;
|
||||
var src = origin + Cryptpad.getBlobPathFromHex(hexFileName);
|
||||
var src = origin + Hash.getBlobPathFromHex(hexFileName);
|
||||
return '<media-tag src="' + src + '" data-crypto-key="cryptpad:' + cryptKey + '">' +
|
||||
'</media-tag>';
|
||||
}
|
||||
return;
|
||||
};
|
||||
funcs.getFileSize = function (href, cb) {
|
||||
var channelId = Cryptpad.hrefToHexChannelId(href);
|
||||
var channelId = Hash.hrefToHexChannelId(href);
|
||||
funcs.sendAnonRpcMsg("GET_FILE_SIZE", channelId, function (data) {
|
||||
if (!data) { return void cb("No response"); }
|
||||
if (data.error) { return void cb(data.error); }
|
||||
|
|
|
@ -1,677 +0,0 @@
|
|||
define([
|
||||
'jquery',
|
||||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/common/curve.js',
|
||||
'/common/common-hash.js',
|
||||
], function ($, Crypto, Curve, Hash) {
|
||||
'use strict';
|
||||
var Msg = {
|
||||
inputs: [],
|
||||
};
|
||||
|
||||
var Types = {
|
||||
message: 'MSG',
|
||||
update: 'UPDATE',
|
||||
unfriend: 'UNFRIEND',
|
||||
mapId: 'MAP_ID',
|
||||
mapIdAck: 'MAP_ID_ACK'
|
||||
};
|
||||
|
||||
var clone = function (o) {
|
||||
return JSON.parse(JSON.stringify(o));
|
||||
};
|
||||
|
||||
// TODO
|
||||
// - mute a channel (hide notifications or don't open it?)
|
||||
var createData = Msg.createData = function (proxy, hash) {
|
||||
return {
|
||||
channel: hash || Hash.createChannelId(),
|
||||
displayName: proxy['cryptpad.username'],
|
||||
profile: proxy.profile && proxy.profile.view,
|
||||
edPublic: proxy.edPublic,
|
||||
curvePublic: proxy.curvePublic,
|
||||
avatar: proxy.profile && proxy.profile.avatar
|
||||
};
|
||||
};
|
||||
|
||||
var getFriend = function (proxy, pubkey) {
|
||||
if (pubkey === proxy.curvePublic) {
|
||||
var data = createData(proxy);
|
||||
delete data.channel;
|
||||
return data;
|
||||
}
|
||||
return proxy.friends ? proxy.friends[pubkey] : undefined;
|
||||
};
|
||||
|
||||
var getFriendList = Msg.getFriendList = function (proxy) {
|
||||
if (!proxy.friends) { proxy.friends = {}; }
|
||||
return proxy.friends;
|
||||
};
|
||||
|
||||
var eachFriend = function (friends, cb) {
|
||||
Object.keys(friends).forEach(function (id) {
|
||||
if (id === 'me') { return; }
|
||||
cb(friends[id], id, friends);
|
||||
});
|
||||
};
|
||||
|
||||
Msg.getFriendChannelsList = function (proxy) {
|
||||
var list = [];
|
||||
eachFriend(proxy, function (friend) {
|
||||
list.push(friend.channel);
|
||||
});
|
||||
return list;
|
||||
};
|
||||
|
||||
var msgAlreadyKnown = function (channel, sig) {
|
||||
return channel.messages.some(function (message) {
|
||||
return message[0] === sig;
|
||||
});
|
||||
};
|
||||
|
||||
Msg.messenger = function (common) {
|
||||
var messenger = {
|
||||
handlers: {
|
||||
message: [],
|
||||
join: [],
|
||||
leave: [],
|
||||
update: [],
|
||||
friend: [],
|
||||
unfriend: [],
|
||||
},
|
||||
range_requests: {},
|
||||
};
|
||||
|
||||
var eachHandler = function (type, g) {
|
||||
messenger.handlers[type].forEach(g);
|
||||
};
|
||||
|
||||
messenger.on = function (type, f) {
|
||||
var stack = messenger.handlers[type];
|
||||
if (!Array.isArray(stack)) {
|
||||
return void console.error('unsupported message type');
|
||||
}
|
||||
if (typeof(f) !== 'function') {
|
||||
return void console.error('expected function');
|
||||
}
|
||||
stack.push(f);
|
||||
};
|
||||
|
||||
var channels = messenger.channels = {};
|
||||
|
||||
var joining = {};
|
||||
|
||||
// declare common variables
|
||||
var network = common.getNetwork();
|
||||
var proxy = common.getProxy();
|
||||
var realtime = common.getRealtime();
|
||||
Msg.hk = network.historyKeeper;
|
||||
var friends = getFriendList(proxy);
|
||||
|
||||
var getChannel = function (curvePublic) {
|
||||
var friend = friends[curvePublic];
|
||||
if (!friend) { return; }
|
||||
var chanId = friend.channel;
|
||||
if (!chanId) { return; }
|
||||
return channels[chanId];
|
||||
};
|
||||
|
||||
var initRangeRequest = function (txid, curvePublic, sig, cb) {
|
||||
messenger.range_requests[txid] = {
|
||||
messages: [],
|
||||
cb: cb,
|
||||
curvePublic: curvePublic,
|
||||
sig: sig,
|
||||
};
|
||||
};
|
||||
|
||||
var getRangeRequest = function (txid) {
|
||||
return messenger.range_requests[txid];
|
||||
};
|
||||
|
||||
var deleteRangeRequest = function (txid) {
|
||||
delete messenger.range_requests[txid];
|
||||
};
|
||||
|
||||
messenger.getMoreHistory = function (curvePublic, hash, count, cb) {
|
||||
if (typeof(cb) !== 'function') { return; }
|
||||
|
||||
if (typeof(hash) !== 'string') {
|
||||
// FIXME hash is not necessarily defined.
|
||||
// What does this mean?
|
||||
console.error("not sure what to do here");
|
||||
return;
|
||||
}
|
||||
|
||||
var chan = getChannel(curvePublic);
|
||||
if (typeof(chan) === 'undefined') {
|
||||
console.error("chan is undefined. we're going to have a problem here");
|
||||
return;
|
||||
}
|
||||
|
||||
var txid = common.uid();
|
||||
initRangeRequest(txid, curvePublic, hash, cb);
|
||||
var msg = [ 'GET_HISTORY_RANGE', chan.id, {
|
||||
from: hash,
|
||||
count: count,
|
||||
txid: txid,
|
||||
}
|
||||
];
|
||||
|
||||
network.sendto(network.historyKeeper, JSON.stringify(msg)).then(function () {
|
||||
}, function (err) {
|
||||
throw new Error(err);
|
||||
});
|
||||
};
|
||||
|
||||
var getCurveForChannel = function (id) {
|
||||
var channel = channels[id];
|
||||
if (!channel) { return; }
|
||||
return channel.curve;
|
||||
};
|
||||
|
||||
messenger.getChannelHead = function (curvePublic, cb) {
|
||||
var friend = friends[curvePublic];
|
||||
if (!friend) { return void cb('NO_SUCH_FRIEND'); }
|
||||
cb(void 0, friend.lastKnownHash);
|
||||
};
|
||||
|
||||
messenger.setChannelHead = function (curvePublic, hash, cb) {
|
||||
var friend = friends[curvePublic];
|
||||
if (!friend) { return void cb('NO_SUCH_FRIEND'); }
|
||||
friend.lastKnownHash = hash;
|
||||
cb();
|
||||
};
|
||||
|
||||
// Id message allows us to map a netfluxId with a public curve key
|
||||
var onIdMessage = function (msg, sender) {
|
||||
var channel;
|
||||
var isId = Object.keys(channels).some(function (chanId) {
|
||||
if (channels[chanId].userList.indexOf(sender) !== -1) {
|
||||
channel = channels[chanId];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!isId) { return; }
|
||||
|
||||
var decryptedMsg = channel.encryptor.decrypt(msg);
|
||||
|
||||
if (decryptedMsg === null) {
|
||||
return void console.error("Failed to decrypt message");
|
||||
}
|
||||
|
||||
if (!decryptedMsg) {
|
||||
console.error('decrypted message was falsey but not null');
|
||||
return;
|
||||
}
|
||||
|
||||
var parsed;
|
||||
try {
|
||||
parsed = JSON.parse(decryptedMsg);
|
||||
} catch (e) {
|
||||
console.error(decryptedMsg);
|
||||
return;
|
||||
}
|
||||
if (parsed[0] !== Types.mapId && parsed[0] !== Types.mapIdAck) { return; }
|
||||
|
||||
// check that the responding peer's encrypted netflux id matches
|
||||
// the sender field. This is to prevent replay attacks.
|
||||
if (parsed[2] !== sender || !parsed[1]) { return; }
|
||||
channel.mapId[sender] = parsed[1];
|
||||
eachHandler('join', function (f) {
|
||||
f(parsed[1], channel.id);
|
||||
});
|
||||
|
||||
if (parsed[0] !== Types.mapId) { return; } // Don't send your key if it's already an ACK
|
||||
// Answer with your own key
|
||||
var rMsg = [Types.mapIdAck, proxy.curvePublic, channel.wc.myID];
|
||||
var rMsgStr = JSON.stringify(rMsg);
|
||||
var cryptMsg = channel.encryptor.encrypt(rMsgStr);
|
||||
network.sendto(sender, cryptMsg);
|
||||
};
|
||||
|
||||
var orderMessages = function (curvePublic, new_messages /*, sig */) {
|
||||
var channel = getChannel(curvePublic);
|
||||
var messages = channel.messages;
|
||||
|
||||
// TODO improve performance, guarantee correct ordering
|
||||
new_messages.reverse().forEach(function (msg) {
|
||||
messages.unshift(msg);
|
||||
});
|
||||
};
|
||||
|
||||
var removeFromFriendList = function (curvePublic, cb) {
|
||||
if (!proxy.friends) { return; }
|
||||
var friends = proxy.friends;
|
||||
delete friends[curvePublic];
|
||||
common.whenRealtimeSyncs(realtime, cb);
|
||||
};
|
||||
|
||||
var pushMsg = function (channel, cryptMsg) {
|
||||
var msg = channel.encryptor.decrypt(cryptMsg);
|
||||
var sig = cryptMsg.slice(0, 64);
|
||||
if (msgAlreadyKnown(channel, sig)) { return; }
|
||||
|
||||
var parsedMsg = JSON.parse(msg);
|
||||
var curvePublic;
|
||||
if (parsedMsg[0] === Types.message) {
|
||||
// TODO validate messages here
|
||||
var res = {
|
||||
type: parsedMsg[0],
|
||||
sig: sig,
|
||||
author: parsedMsg[1],
|
||||
time: parsedMsg[2],
|
||||
text: parsedMsg[3],
|
||||
// this makes debugging a whole lot easier
|
||||
curve: getCurveForChannel(channel.id),
|
||||
};
|
||||
|
||||
channel.messages.push(res);
|
||||
eachHandler('message', function (f) {
|
||||
f(res);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
if (parsedMsg[0] === Types.update) {
|
||||
if (parsedMsg[1] === proxy.curvePublic) { return; }
|
||||
curvePublic = parsedMsg[1];
|
||||
var newdata = parsedMsg[3];
|
||||
var data = getFriend(proxy, parsedMsg[1]);
|
||||
var types = [];
|
||||
Object.keys(newdata).forEach(function (k) {
|
||||
if (data[k] !== newdata[k]) {
|
||||
types.push(k);
|
||||
data[k] = newdata[k];
|
||||
}
|
||||
});
|
||||
|
||||
eachHandler('update', function (f) {
|
||||
f(clone(newdata), curvePublic);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (parsedMsg[0] === Types.unfriend) {
|
||||
curvePublic = parsedMsg[1];
|
||||
delete friends[curvePublic];
|
||||
|
||||
removeFromFriendList(parsedMsg[1], function () {
|
||||
channel.wc.leave(Types.unfriend);
|
||||
eachHandler('unfriend', function (f) {
|
||||
f(curvePublic);
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/* Broadcast a display name, profile, or avatar change to all contacts
|
||||
*/
|
||||
|
||||
// TODO send event...
|
||||
messenger.updateMyData = function () {
|
||||
var friends = getFriendList(proxy);
|
||||
var mySyncData = friends.me;
|
||||
var myData = createData(proxy);
|
||||
if (!mySyncData || mySyncData.displayName !== myData.displayName
|
||||
|| mySyncData.profile !== myData.profile
|
||||
|| mySyncData.avatar !== myData.avatar) {
|
||||
delete myData.channel;
|
||||
Object.keys(channels).forEach(function (chan) {
|
||||
var channel = channels[chan];
|
||||
|
||||
if (!channel) {
|
||||
return void console.error('NO_SUCH_CHANNEL');
|
||||
}
|
||||
|
||||
|
||||
var msg = [Types.update, myData.curvePublic, +new Date(), myData];
|
||||
var msgStr = JSON.stringify(msg);
|
||||
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
||||
channel.wc.bcast(cryptMsg).then(function () {
|
||||
// TODO send event
|
||||
//channel.refresh();
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
eachHandler('update', function (f) {
|
||||
f(myData, myData.curvePublic);
|
||||
});
|
||||
friends.me = myData;
|
||||
}
|
||||
};
|
||||
|
||||
var onChannelReady = function (chanId) {
|
||||
var cb = joining[chanId];
|
||||
if (typeof(cb) !== 'function') {
|
||||
return void console.error('channel ready without callback');
|
||||
}
|
||||
delete joining[chanId];
|
||||
return cb();
|
||||
};
|
||||
|
||||
var onDirectMessage = function (common, msg, sender) {
|
||||
if (sender !== Msg.hk) { return void onIdMessage(msg, sender); }
|
||||
var parsed = JSON.parse(msg);
|
||||
|
||||
if (/HISTORY_RANGE/.test(parsed[0])) {
|
||||
//console.log(parsed);
|
||||
var txid = parsed[1];
|
||||
var req = getRangeRequest(txid);
|
||||
var type = parsed[0];
|
||||
if (!req) {
|
||||
return void console.error("received response to unknown request");
|
||||
}
|
||||
|
||||
if (type === 'HISTORY_RANGE') {
|
||||
req.messages.push(parsed[2]);
|
||||
} else if (type === 'HISTORY_RANGE_END') {
|
||||
// process all the messages (decrypt)
|
||||
var curvePublic = req.curvePublic;
|
||||
var channel = getChannel(curvePublic);
|
||||
|
||||
var decrypted = req.messages.map(function (msg) {
|
||||
if (msg[2] !== 'MSG') { return; }
|
||||
try {
|
||||
return {
|
||||
d: JSON.parse(channel.encryptor.decrypt(msg[4])),
|
||||
sig: msg[4].slice(0, 64),
|
||||
};
|
||||
} catch (e) {
|
||||
console.log('failed to decrypt');
|
||||
return null;
|
||||
}
|
||||
}).filter(function (decrypted) {
|
||||
return decrypted;
|
||||
}).map(function (O) {
|
||||
return {
|
||||
type: O.d[0],
|
||||
sig: O.sig,
|
||||
author: O.d[1],
|
||||
time: O.d[2],
|
||||
text: O.d[3],
|
||||
curve: curvePublic,
|
||||
};
|
||||
});
|
||||
|
||||
orderMessages(curvePublic, decrypted, req.sig);
|
||||
req.cb(void 0, decrypted);
|
||||
return deleteRangeRequest(txid);
|
||||
} else {
|
||||
console.log(parsed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((parsed.validateKey || parsed.owners) && parsed.channel) {
|
||||
return;
|
||||
}
|
||||
if (parsed.state && parsed.state === 1 && parsed.channel) {
|
||||
if (channels[parsed.channel]) {
|
||||
// parsed.channel is Ready
|
||||
// channel[parsed.channel].ready();
|
||||
channels[parsed.channel].ready = true;
|
||||
onChannelReady(parsed.channel);
|
||||
var updateTypes = channels[parsed.channel].updateOnReady;
|
||||
if (updateTypes) {
|
||||
|
||||
//channels[parsed.channel].updateUI(updateTypes);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
var chan = parsed[3];
|
||||
if (!chan || !channels[chan]) { return; }
|
||||
pushMsg(channels[chan], parsed[4]);
|
||||
};
|
||||
|
||||
var onMessage = function (msg, sender, chan) {
|
||||
if (!channels[chan.id]) { return; }
|
||||
|
||||
var isMessage = pushMsg(channels[chan.id], msg);
|
||||
if (isMessage) {
|
||||
if (channels[chan.id].wc.myID !== sender) {
|
||||
// Don't notify for your own messages
|
||||
//channels[chan.id].notify();
|
||||
}
|
||||
//channels[chan.id].refresh();
|
||||
// TODO emit message event
|
||||
}
|
||||
};
|
||||
|
||||
// listen for messages...
|
||||
network.on('message', function(msg, sender) {
|
||||
onDirectMessage(common, msg, sender);
|
||||
});
|
||||
|
||||
messenger.removeFriend = function (curvePublic, cb) {
|
||||
if (typeof(cb) !== 'function') { throw new Error('NO_CALLBACK'); }
|
||||
var data = getFriend(proxy, curvePublic);
|
||||
|
||||
if (!data) {
|
||||
// friend is not valid
|
||||
console.error('friend is not valid');
|
||||
return;
|
||||
}
|
||||
|
||||
var channel = channels[data.channel];
|
||||
if (!channel) {
|
||||
return void cb("NO_SUCH_CHANNEL");
|
||||
}
|
||||
|
||||
if (!network.webChannels.some(function (wc) {
|
||||
return wc.id === channel.id;
|
||||
})) {
|
||||
console.error('bad channel: ', curvePublic);
|
||||
}
|
||||
|
||||
var msg = [Types.unfriend, proxy.curvePublic, +new Date()];
|
||||
var msgStr = JSON.stringify(msg);
|
||||
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
||||
|
||||
// TODO emit remove_friend event?
|
||||
try {
|
||||
channel.wc.bcast(cryptMsg).then(function () {
|
||||
delete friends[curvePublic];
|
||||
delete channels[curvePublic];
|
||||
common.whenRealtimeSyncs(realtime, function () {
|
||||
cb();
|
||||
});
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
cb(err);
|
||||
});
|
||||
} catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
};
|
||||
|
||||
var getChannelMessagesSince = function (chan, data, keys) {
|
||||
console.log('Fetching [%s] messages since [%s]', data.curvePublic, data.lastKnownHash || '');
|
||||
var cfg = {
|
||||
validateKey: keys.validateKey,
|
||||
owners: [proxy.edPublic, data.edPublic],
|
||||
lastKnownHash: data.lastKnownHash
|
||||
};
|
||||
var msg = ['GET_HISTORY', chan.id, cfg];
|
||||
network.sendto(network.historyKeeper, JSON.stringify(msg))
|
||||
.then($.noop, function (err) {
|
||||
throw new Error(err);
|
||||
});
|
||||
};
|
||||
|
||||
var openFriendChannel = function (data, f) {
|
||||
var keys = Curve.deriveKeys(data.curvePublic, proxy.curvePrivate);
|
||||
var encryptor = Curve.createEncryptor(keys);
|
||||
network.join(data.channel).then(function (chan) {
|
||||
var channel = channels[data.channel] = {
|
||||
id: data.channel,
|
||||
sending: false,
|
||||
friendEd: f,
|
||||
keys: keys,
|
||||
curve: data.curvePublic,
|
||||
encryptor: encryptor,
|
||||
messages: [],
|
||||
wc: chan,
|
||||
userList: [],
|
||||
mapId: {},
|
||||
send: function (payload, cb) {
|
||||
if (!network.webChannels.some(function (wc) {
|
||||
if (wc.id === channel.wc.id) { return true; }
|
||||
})) {
|
||||
return void cb('NO_SUCH_CHANNEL');
|
||||
}
|
||||
|
||||
var msg = [Types.message, proxy.curvePublic, +new Date(), payload];
|
||||
var msgStr = JSON.stringify(msg);
|
||||
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
||||
|
||||
channel.wc.bcast(cryptMsg).then(function () {
|
||||
pushMsg(channel, cryptMsg);
|
||||
cb();
|
||||
}, function (err) {
|
||||
cb(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
chan.on('message', function (msg, sender) {
|
||||
onMessage(msg, sender, chan);
|
||||
});
|
||||
|
||||
var onJoining = function (peer) {
|
||||
if (peer === Msg.hk) { return; }
|
||||
if (channel.userList.indexOf(peer) !== -1) { return; }
|
||||
|
||||
channel.userList.push(peer);
|
||||
var msg = [Types.mapId, proxy.curvePublic, chan.myID];
|
||||
var msgStr = JSON.stringify(msg);
|
||||
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
||||
network.sendto(peer, cryptMsg);
|
||||
};
|
||||
chan.members.forEach(function (peer) {
|
||||
if (peer === Msg.hk) { return; }
|
||||
if (channel.userList.indexOf(peer) !== -1) { return; }
|
||||
channel.userList.push(peer);
|
||||
});
|
||||
chan.on('join', onJoining);
|
||||
chan.on('leave', function (peer) {
|
||||
var curvePublic = channel.mapId[peer];
|
||||
var i = channel.userList.indexOf(peer);
|
||||
while (i !== -1) {
|
||||
channel.userList.splice(i, 1);
|
||||
i = channel.userList.indexOf(peer);
|
||||
}
|
||||
// update status
|
||||
if (!curvePublic) { return; }
|
||||
eachHandler('leave', function (f) {
|
||||
f(curvePublic, channel.id);
|
||||
});
|
||||
});
|
||||
|
||||
// FIXME don't subscribe to the channel implicitly
|
||||
getChannelMessagesSince(chan, data, keys);
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
messenger.getFriendList = function (cb) {
|
||||
var friends = proxy.friends;
|
||||
if (!friends) { return void cb(void 0, []); }
|
||||
|
||||
cb(void 0, Object.keys(proxy.friends).filter(function (k) {
|
||||
return k !== 'me';
|
||||
}));
|
||||
};
|
||||
|
||||
messenger.openFriendChannel = function (curvePublic, cb) {
|
||||
if (typeof(curvePublic) !== 'string') { return void cb('INVALID_ID'); }
|
||||
if (typeof(cb) !== 'function') { throw new Error('expected callback'); }
|
||||
|
||||
var friend = clone(friends[curvePublic]);
|
||||
if (typeof(friend) !== 'object') {
|
||||
return void cb('NO_FRIEND_DATA');
|
||||
}
|
||||
var channel = friend.channel;
|
||||
if (!channel) { return void cb('E_NO_CHANNEL'); }
|
||||
joining[channel] = cb;
|
||||
openFriendChannel(friend, curvePublic);
|
||||
};
|
||||
|
||||
messenger.sendMessage = function (curvePublic, payload, cb) {
|
||||
var channel = getChannel(curvePublic);
|
||||
if (!channel) { return void cb('NO_CHANNEL'); }
|
||||
if (!network.webChannels.some(function (wc) {
|
||||
if (wc.id === channel.wc.id) { return true; }
|
||||
})) {
|
||||
return void cb('NO_SUCH_CHANNEL');
|
||||
}
|
||||
|
||||
var msg = [Types.message, proxy.curvePublic, +new Date(), payload];
|
||||
var msgStr = JSON.stringify(msg);
|
||||
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
||||
|
||||
channel.wc.bcast(cryptMsg).then(function () {
|
||||
pushMsg(channel, cryptMsg);
|
||||
cb();
|
||||
}, function (err) {
|
||||
cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
messenger.getStatus = function (curvePublic, cb) {
|
||||
var channel = getChannel(curvePublic);
|
||||
if (!channel) { return void cb('NO_SUCH_CHANNEL'); }
|
||||
var online = channel.userList.some(function (nId) {
|
||||
return channel.mapId[nId] === curvePublic;
|
||||
});
|
||||
cb(void 0, online);
|
||||
};
|
||||
|
||||
messenger.getFriendInfo = function (curvePublic, cb) {
|
||||
setTimeout(function () {
|
||||
var friend = friends[curvePublic];
|
||||
if (!friend) { return void cb('NO_SUCH_FRIEND'); }
|
||||
// this clone will be redundant when ui uses postmessage
|
||||
cb(void 0, clone(friend));
|
||||
});
|
||||
};
|
||||
|
||||
messenger.getMyInfo = function (cb) {
|
||||
cb(void 0, {
|
||||
curvePublic: proxy.curvePublic,
|
||||
displayName: common.getDisplayName(),
|
||||
});
|
||||
};
|
||||
|
||||
// TODO listen for changes to your friend list
|
||||
// emit 'update' events for clients
|
||||
|
||||
//var update = function (curvePublic
|
||||
proxy.on('change', ['friends'], function (o, n, p) {
|
||||
var curvePublic;
|
||||
if (o === undefined) {
|
||||
// new friend added
|
||||
curvePublic = p.slice(-1)[0];
|
||||
eachHandler('friend', function (f) {
|
||||
f(curvePublic, clone(n));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(o, n, p);
|
||||
}).on('remove', ['friends'], function (o, p) {
|
||||
eachHandler('unfriend', function (f) {
|
||||
f(p[1]); // TODO
|
||||
});
|
||||
});
|
||||
|
||||
Object.freeze(messenger);
|
||||
|
||||
return messenger;
|
||||
};
|
||||
|
||||
return Msg;
|
||||
});
|
|
@ -3,10 +3,11 @@ define([
|
|||
'/customize/application_config.js',
|
||||
'/api/config',
|
||||
'/common/common-ui-elements.js',
|
||||
'/common/common-interface.js'
|
||||
], function ($, Config, ApiConfig, UIElements, UI) {
|
||||
var Messages = {};
|
||||
var Cryptpad;
|
||||
'/common/common-interface.js',
|
||||
'/common/common-hash.js',
|
||||
'/customize/messages.js',
|
||||
'/common/clipboard.js',
|
||||
], function ($, Config, ApiConfig, UIElements, UI, Hash, Messages, Clipboard) {
|
||||
var Common;
|
||||
|
||||
var Bar = {
|
||||
|
@ -439,7 +440,7 @@ define([
|
|||
if (!err) { UI.log(Messages.shareSuccess); }
|
||||
});*/
|
||||
var url = origin + pathname + '#' + hashes.editHash;
|
||||
var success = Cryptpad.Clipboard.copy(url);
|
||||
var success = Clipboard.copy(url);
|
||||
if (success) { UI.log(Messages.shareSuccess); }
|
||||
});
|
||||
}
|
||||
|
@ -449,12 +450,12 @@ define([
|
|||
if (!err) { UI.log(Messages.shareSuccess); }
|
||||
});*/
|
||||
var url = origin + pathname + '#' + hashes.viewHash;
|
||||
var success = Cryptpad.Clipboard.copy(url);
|
||||
var success = Clipboard.copy(url);
|
||||
if (success) { UI.log(Messages.shareSuccess); }
|
||||
});
|
||||
$shareBlock.find('a.cp-toolbar-share-view-embed').click(function () {
|
||||
var url = origin + pathname + '#' + hashes.viewHash;
|
||||
var parsed = Cryptpad.parsePadUrl(url);
|
||||
var parsed = Hash.parsePadUrl(url);
|
||||
url = origin + parsed.getUrl({embed: true, present: true});
|
||||
// Alertify content
|
||||
var $content = $('<div>');
|
||||
|
@ -474,7 +475,7 @@ define([
|
|||
$('#'+iframeId).click(function () {
|
||||
this.select();
|
||||
});
|
||||
//var success = Cryptpad.Clipboard.copy(url);
|
||||
//var success = Clipboard.copy(url);
|
||||
//if (success) { UI.log(Messages.shareSuccess); }
|
||||
});
|
||||
}
|
||||
|
@ -520,7 +521,7 @@ define([
|
|||
|
||||
// Add handlers
|
||||
$shareBlock.find('a.cp-toolbar-share-file-copy').click(function () {
|
||||
var success = Cryptpad.Clipboard.copy(url);
|
||||
var success = Clipboard.copy(url);
|
||||
if (success) { UI.log(Messages.shareSuccess); }
|
||||
});
|
||||
$shareBlock.find('a.cp-toolbar-share-file-embed').click(function () {
|
||||
|
@ -570,8 +571,8 @@ define([
|
|||
if (config.readOnly === 1) {
|
||||
$titleContainer.append($('<span>', {'class': 'cp-toolbar-title-readonly'})
|
||||
.text('('+Messages.readonly+')'));
|
||||
return $titleContainer;
|
||||
}
|
||||
if (config.readOnly === 1 || typeof(Cryptpad) === "undefined") { return $titleContainer; }
|
||||
var $input = $('<input>', {
|
||||
type: 'text',
|
||||
placeholder: placeholder
|
||||
|
@ -842,7 +843,6 @@ define([
|
|||
console.error(err);
|
||||
return;
|
||||
}
|
||||
//Cryptpad.changeDisplayName(newName, true); Already done?
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -894,90 +894,88 @@ define([
|
|||
if (!config.metadataMgr) { return; }
|
||||
var metadataMgr = config.metadataMgr;
|
||||
var userNetfluxId = metadataMgr.getNetfluxId();
|
||||
if (typeof Cryptpad !== "undefined") {
|
||||
var notify = function(type, name, oldname) {
|
||||
// type : 1 (+1 user), 0 (rename existing user), -1 (-1 user)
|
||||
if (typeof name === "undefined") { return; }
|
||||
name = name || Messages.anonymous;
|
||||
if (Config.disableUserlistNotifications) { return; }
|
||||
switch(type) {
|
||||
case 1:
|
||||
UI.log(Messages._getKey("notifyJoined", [name]));
|
||||
break;
|
||||
case 0:
|
||||
oldname = (!oldname) ? Messages.anonymous : oldname;
|
||||
UI.log(Messages._getKey("notifyRenamed", [oldname, name]));
|
||||
break;
|
||||
case -1:
|
||||
UI.log(Messages._getKey("notifyLeft", [name]));
|
||||
break;
|
||||
default:
|
||||
console.log("Invalid type of notification");
|
||||
break;
|
||||
}
|
||||
};
|
||||
var notify = function(type, name, oldname) {
|
||||
// type : 1 (+1 user), 0 (rename existing user), -1 (-1 user)
|
||||
if (typeof name === "undefined") { return; }
|
||||
name = name || Messages.anonymous;
|
||||
if (Config.disableUserlistNotifications) { return; }
|
||||
switch(type) {
|
||||
case 1:
|
||||
UI.log(Messages._getKey("notifyJoined", [name]));
|
||||
break;
|
||||
case 0:
|
||||
oldname = (!oldname) ? Messages.anonymous : oldname;
|
||||
UI.log(Messages._getKey("notifyRenamed", [oldname, name]));
|
||||
break;
|
||||
case -1:
|
||||
UI.log(Messages._getKey("notifyLeft", [name]));
|
||||
break;
|
||||
default:
|
||||
console.log("Invalid type of notification");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var userPresent = function (id, user, data) {
|
||||
if (!(user && user.uid)) {
|
||||
console.log('no uid');
|
||||
return 0;
|
||||
}
|
||||
if (!data) {
|
||||
console.log('no data');
|
||||
return 0;
|
||||
}
|
||||
var userPresent = function (id, user, data) {
|
||||
if (!(user && user.uid)) {
|
||||
console.log('no uid');
|
||||
return 0;
|
||||
}
|
||||
if (!data) {
|
||||
console.log('no data');
|
||||
return 0;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
Object.keys(data).forEach(function (k) {
|
||||
if (data[k] && data[k].uid === user.uid) { count++; }
|
||||
});
|
||||
return count;
|
||||
};
|
||||
|
||||
var joined = false;
|
||||
metadataMgr.onChange(function () {
|
||||
var newdata = metadataMgr.getMetadata().users;
|
||||
var netfluxIds = Object.keys(newdata);
|
||||
// Notify for disconnected users
|
||||
if (typeof oldUserData !== "undefined") {
|
||||
for (var u in oldUserData) {
|
||||
// if a user's uid is still present after having left, don't notify
|
||||
if (netfluxIds.indexOf(u) === -1) {
|
||||
var temp = JSON.parse(JSON.stringify(oldUserData[u]));
|
||||
delete oldUserData[u];
|
||||
if (temp && newdata[userNetfluxId] && temp.uid === newdata[userNetfluxId].uid) { return; }
|
||||
if (userPresent(u, temp, newdata || oldUserData) < 1) {
|
||||
notify(-1, temp.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update the "oldUserData" object and notify for new users and names changed
|
||||
if (typeof newdata === "undefined") { return; }
|
||||
if (typeof oldUserData === "undefined") {
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
return;
|
||||
}
|
||||
if (config.readOnly === 0 && !oldUserData[userNetfluxId]) {
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
return;
|
||||
}
|
||||
for (var k in newdata) {
|
||||
if (joined && k !== userNetfluxId && netfluxIds.indexOf(k) !== -1) {
|
||||
if (typeof oldUserData[k] === "undefined") {
|
||||
// if the same uid is already present in the userdata, don't notify
|
||||
if (!userPresent(k, newdata[k], oldUserData)) {
|
||||
notify(1, newdata[k].name);
|
||||
}
|
||||
} else if (oldUserData[k].name !== newdata[k].name) {
|
||||
notify(0, newdata[k].name, oldUserData[k].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
joined = true;
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
var count = 0;
|
||||
Object.keys(data).forEach(function (k) {
|
||||
if (data[k] && data[k].uid === user.uid) { count++; }
|
||||
});
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
var joined = false;
|
||||
metadataMgr.onChange(function () {
|
||||
var newdata = metadataMgr.getMetadata().users;
|
||||
var netfluxIds = Object.keys(newdata);
|
||||
// Notify for disconnected users
|
||||
if (typeof oldUserData !== "undefined") {
|
||||
for (var u in oldUserData) {
|
||||
// if a user's uid is still present after having left, don't notify
|
||||
if (netfluxIds.indexOf(u) === -1) {
|
||||
var temp = JSON.parse(JSON.stringify(oldUserData[u]));
|
||||
delete oldUserData[u];
|
||||
if (temp && newdata[userNetfluxId] && temp.uid === newdata[userNetfluxId].uid) { return; }
|
||||
if (userPresent(u, temp, newdata || oldUserData) < 1) {
|
||||
notify(-1, temp.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update the "oldUserData" object and notify for new users and names changed
|
||||
if (typeof newdata === "undefined") { return; }
|
||||
if (typeof oldUserData === "undefined") {
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
return;
|
||||
}
|
||||
if (config.readOnly === 0 && !oldUserData[userNetfluxId]) {
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
return;
|
||||
}
|
||||
for (var k in newdata) {
|
||||
if (joined && k !== userNetfluxId && netfluxIds.indexOf(k) !== -1) {
|
||||
if (typeof oldUserData[k] === "undefined") {
|
||||
// if the same uid is already present in the userdata, don't notify
|
||||
if (!userPresent(k, newdata[k], oldUserData)) {
|
||||
notify(1, newdata[k].name);
|
||||
}
|
||||
} else if (oldUserData[k].name !== newdata[k].name) {
|
||||
notify(0, newdata[k].name, oldUserData[k].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
joined = true;
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
@ -986,9 +984,7 @@ define([
|
|||
|
||||
Bar.create = function (cfg) {
|
||||
var config = cfg || {};
|
||||
Cryptpad = config.common;
|
||||
Common = config.sfCommon;
|
||||
Messages = Cryptpad.Messages;
|
||||
config.readOnly = (typeof config.readOnly !== "undefined") ? (config.readOnly ? 1 : 0) : -1;
|
||||
config.displayed = config.displayed || [];
|
||||
|
||||
|
@ -1042,7 +1038,7 @@ define([
|
|||
initClickEvents(toolbar, config);
|
||||
initNotifications(toolbar, config);
|
||||
|
||||
var failed = toolbar.failed = function () {
|
||||
toolbar.failed = function () {
|
||||
toolbar.connected = false;
|
||||
|
||||
if (toolbar.spinner) {
|
||||
|
@ -1083,11 +1079,12 @@ define([
|
|||
};
|
||||
|
||||
// On log out, remove permanently the realtime elements of the toolbar
|
||||
Cryptpad.onLogout(function () {
|
||||
// TODO
|
||||
/*Common.onLogout(function () {
|
||||
failed();
|
||||
if (toolbar.useradmin) { toolbar.useradmin.hide(); }
|
||||
if (toolbar.userlist) { toolbar.userlist.hide(); }
|
||||
});
|
||||
});*/
|
||||
|
||||
return toolbar;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
define([
|
||||
'jquery',
|
||||
'/customize/application_config.js'
|
||||
], function ($, AppConfig) {
|
||||
'/customize/application_config.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-realtime.js'
|
||||
], function ($, AppConfig, Util, Hash, Realtime) {
|
||||
var module = {};
|
||||
|
||||
var ROOT = module.ROOT = "root";
|
||||
|
@ -74,7 +77,7 @@ define([
|
|||
exp.isReadOnlyFile = function (element) {
|
||||
if (!isFile(element)) { return false; }
|
||||
var data = exp.getFileData(element);
|
||||
var parsed = Cryptpad.parsePadUrl(data.href);
|
||||
var parsed = Hash.parsePadUrl(data.href);
|
||||
if (!parsed) { return false; }
|
||||
var pHash = parsed.hashData;
|
||||
if (!pHash || pHash.type !== "pad") { return; }
|
||||
|
@ -243,7 +246,7 @@ define([
|
|||
getHrefArray().forEach(function (c) {
|
||||
ret = ret.concat(_getFiles[c]());
|
||||
});
|
||||
return Cryptpad.deduplicateString(ret);
|
||||
return Util.deduplicateString(ret);
|
||||
};
|
||||
_getFiles[ROOT] = function () {
|
||||
var ret = [];
|
||||
|
@ -294,7 +297,7 @@ define([
|
|||
ret = ret.concat(_getFiles[c]());
|
||||
}
|
||||
});
|
||||
return Cryptpad.deduplicateString(ret);
|
||||
return Util.deduplicateString(ret);
|
||||
};
|
||||
|
||||
var getIdFromHref = exp.getIdFromHref = function (href) {
|
||||
|
@ -437,13 +440,13 @@ define([
|
|||
});
|
||||
|
||||
// Search Href
|
||||
var href = Cryptpad.getRelativeHref(value);
|
||||
var href = Hash.getRelativeHref(value);
|
||||
if (href) {
|
||||
var id = getIdFromHref(href);
|
||||
if (id) { res.push(id); }
|
||||
}
|
||||
|
||||
res = Cryptpad.deduplicateString(res);
|
||||
res = Util.deduplicateString(res);
|
||||
|
||||
var ret = [];
|
||||
res.forEach(function (l) {
|
||||
|
@ -486,14 +489,14 @@ define([
|
|||
// TODO: can only be called from outside atm
|
||||
if (typeof cb !== "function") { cb = function () {}; }
|
||||
var todo = function () {
|
||||
var id = Cryptpad.createRandomInteger();
|
||||
var id = Util.createRandomInteger();
|
||||
files[FILES_DATA][id] = data;
|
||||
cb(null, id);
|
||||
};
|
||||
if (!loggedIn || !AppConfig.enablePinning || config.testMode) {
|
||||
return void todo();
|
||||
}
|
||||
Cryptpad.pinPads([Cryptpad.hrefToHexChannelId(data.href)], function (e) {
|
||||
Cryptpad.pinPads([Hash.hrefToHexChannelId(data.href)], function (e) {
|
||||
if (e) { return void cb(e); }
|
||||
todo();
|
||||
});
|
||||
|
@ -547,7 +550,7 @@ define([
|
|||
}
|
||||
// Move to root
|
||||
var newName = isFile(element) ?
|
||||
getAvailableName(newParent, Cryptpad.createChannelId()) :
|
||||
getAvailableName(newParent, Hash.createChannelId()) :
|
||||
isInTrashRoot(elementPath) ?
|
||||
elementPath[1] : elementPath.pop();
|
||||
|
||||
|
@ -605,7 +608,7 @@ define([
|
|||
if (path && isPathIn(newPath, [ROOT]) || filesList.indexOf(id) === -1) {
|
||||
parentEl = find(newPath || [ROOT]);
|
||||
if (parentEl) {
|
||||
var newName = getAvailableName(parentEl, Cryptpad.createChannelId());
|
||||
var newName = getAvailableName(parentEl, Hash.createChannelId());
|
||||
parentEl[newName] = id;
|
||||
return;
|
||||
}
|
||||
|
@ -865,10 +868,10 @@ define([
|
|||
oldData.forEach(function (obj) {
|
||||
if (!obj || !obj.href) { return; }
|
||||
var href = obj.href;
|
||||
var id = Cryptpad.createRandomInteger();
|
||||
var id = Util.createRandomInteger();
|
||||
var paths = findFile(href);
|
||||
var data = obj;
|
||||
var key = Cryptpad.createChannelId();
|
||||
var key = Hash.createChannelId();
|
||||
if (data) {
|
||||
newData[id] = data;
|
||||
} else {
|
||||
|
@ -901,7 +904,7 @@ define([
|
|||
if (exp.rt) {
|
||||
exp.rt.sync();
|
||||
// TODO
|
||||
Cryptpad.whenRealtimeSyncs(exp.rt, next);
|
||||
Realtime.whenRealtimeSyncs(exp.rt, next);
|
||||
} else {
|
||||
window.setTimeout(next, 1000);
|
||||
}
|
||||
|
@ -943,8 +946,8 @@ define([
|
|||
}
|
||||
if (typeof element[el] === "string") {
|
||||
// We have an old file (href) which is not in filesData: add it
|
||||
var id = Cryptpad.createRandomInteger();
|
||||
var key = Cryptpad.createChannelId();
|
||||
var id = Util.createRandomInteger();
|
||||
var key = Hash.createChannelId();
|
||||
files[FILES_DATA][id] = {href: element[el], filename: el};
|
||||
element[key] = id;
|
||||
delete element[el];
|
||||
|
@ -968,7 +971,7 @@ define([
|
|||
if (!$.isArray(obj.path)) { toClean.push(idx); return; }
|
||||
if (typeof obj.element === "string") {
|
||||
// We have an old file (href) which is not in filesData: add it
|
||||
var id = Cryptpad.createRandomInteger();
|
||||
var id = Util.createRandomInteger();
|
||||
files[FILES_DATA][id] = {href: obj.element, filename: el};
|
||||
obj.element = id;
|
||||
}
|
||||
|
@ -1002,7 +1005,7 @@ define([
|
|||
};
|
||||
var fixTemplate = function () {
|
||||
if (!Array.isArray(files[TEMPLATE])) { debug("TEMPLATE was not an array"); files[TEMPLATE] = []; }
|
||||
files[TEMPLATE] = Cryptpad.deduplicateString(files[TEMPLATE].slice());
|
||||
files[TEMPLATE] = Util.deduplicateString(files[TEMPLATE].slice());
|
||||
var us = files[TEMPLATE];
|
||||
var rootFiles = getFiles([ROOT]).slice();
|
||||
var toClean = [];
|
||||
|
@ -1012,7 +1015,7 @@ define([
|
|||
}
|
||||
if (typeof el === "string") {
|
||||
// We have an old file (href) which is not in filesData: add it
|
||||
var id = Cryptpad.createRandomInteger();
|
||||
var id = Util.createRandomInteger();
|
||||
files[FILES_DATA][id] = {href: el};
|
||||
us[idx] = id;
|
||||
}
|
||||
|
@ -1050,7 +1053,7 @@ define([
|
|||
toClean.push(id);
|
||||
continue;
|
||||
}
|
||||
var parsed = Cryptpad.parsePadUrl(el.href);
|
||||
var parsed = Hash.parsePadUrl(el.href);
|
||||
if (!parsed.hash) {
|
||||
debug("Removing an element in filesData with a invalid href.", el);
|
||||
toClean.push(id);
|
||||
|
@ -1059,7 +1062,7 @@ define([
|
|||
|
||||
if ((loggedIn || config.testMode) && rootFiles.indexOf(id) === -1) {
|
||||
debug("An element in filesData was not in ROOT, TEMPLATE or TRASH.", id, el);
|
||||
var newName = Cryptpad.createChannelId();
|
||||
var newName = Hash.createChannelId();
|
||||
root[newName] = id;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ define([
|
|||
'json.sortify',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-ui-elements.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/cryptget.js',
|
||||
|
@ -25,6 +26,7 @@ define([
|
|||
JSONSortify,
|
||||
Cryptpad,
|
||||
Util,
|
||||
Hash,
|
||||
UIElements,
|
||||
UI,
|
||||
Cryptget,
|
||||
|
@ -1148,7 +1150,7 @@ define([
|
|||
var data = filesOp.getFileData(element);
|
||||
if (!data) { return void logError("No data for the file", element); }
|
||||
|
||||
var hrefData = Cryptpad.parsePadUrl(data.href);
|
||||
var hrefData = Hash.parsePadUrl(data.href);
|
||||
if (hrefData.type) {
|
||||
$span.addClass('cp-border-color-'+hrefData.type);
|
||||
}
|
||||
|
@ -1707,7 +1709,7 @@ define([
|
|||
var data = filesOp.getFileData(id);
|
||||
if (!data) { return ''; }
|
||||
if (prop === 'type') {
|
||||
var hrefData = Cryptpad.parsePadUrl(data.href);
|
||||
var hrefData = Hash.parsePadUrl(data.href);
|
||||
return hrefData.type;
|
||||
}
|
||||
if (prop === 'atime' || prop === 'ctime') {
|
||||
|
@ -1742,7 +1744,7 @@ define([
|
|||
};
|
||||
}
|
||||
if (prop === 'type') {
|
||||
var hrefData = Cryptpad.parsePadUrl(e.href);
|
||||
var hrefData = Hash.parsePadUrl(e.href);
|
||||
return hrefData.type;
|
||||
}
|
||||
if (prop === 'atime' || prop === 'ctime') {
|
||||
|
@ -1957,7 +1959,7 @@ define([
|
|||
filesList.forEach(function (r) {
|
||||
r.paths.forEach(function (path) {
|
||||
var href = r.data.href;
|
||||
var parsed = Cryptpad.parsePadUrl(href);
|
||||
var parsed = Hash.parsePadUrl(href);
|
||||
var $table = $('<table>');
|
||||
var $icon = $('<td>', {'rowspan': '3', 'class': 'cp-app-drive-search-icon'})
|
||||
.append(getFileIcon(href));
|
||||
|
@ -2447,13 +2449,13 @@ define([
|
|||
if (!filesOp.isFile(id)) { return; }
|
||||
var data = filesOp.getFileData(id);
|
||||
if (!data) { return; }
|
||||
var parsed = Cryptpad.parsePadUrl(data.href);
|
||||
var parsed = Hash.parsePadUrl(data.href);
|
||||
if (parsed.hashData.type !== "pad") { return; }
|
||||
var i = data.href.indexOf('#') + 1;
|
||||
var base = data.href.slice(0, i);
|
||||
var hrefsecret = Cryptpad.getSecrets(parsed.type, parsed.hash);
|
||||
var hrefsecret = Hash.getSecrets(parsed.type, parsed.hash);
|
||||
if (!hrefsecret.keys) { return; }
|
||||
var viewHash = Cryptpad.getViewHashFromKeys(hrefsecret.channel, hrefsecret.keys);
|
||||
var viewHash = Hash.getViewHashFromKeys(hrefsecret.channel, hrefsecret.keys);
|
||||
return base + viewHash;
|
||||
};
|
||||
|
||||
|
@ -2486,7 +2488,7 @@ define([
|
|||
}));
|
||||
}
|
||||
|
||||
var parsed = Cryptpad.parsePadUrl(data.href);
|
||||
var parsed = Hash.parsePadUrl(data.href);
|
||||
if (parsed.hashData && parsed.hashData.type === 'pad') {
|
||||
var roLink = ro ? base + data.href : base + getReadOnlyUrl(el);
|
||||
if (roLink) {
|
||||
|
@ -2528,7 +2530,7 @@ define([
|
|||
|
||||
return void cb(void 0, $d);
|
||||
}
|
||||
var KB = Cryptpad.bytesToKilobytes(bytes);
|
||||
var KB = Util.bytesToKilobytes(bytes);
|
||||
|
||||
var formatted = Messages._getKey('formattedKB', [KB]);
|
||||
$('<br>').appendTo($d);
|
||||
|
|
|
@ -38,9 +38,9 @@ define([
|
|||
};
|
||||
window.addEventListener('message', onMsg);
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
var getSecrets = function (Cryptpad) {
|
||||
var getSecrets = function (Cryptpad, Utils) {
|
||||
var hash = window.location.hash.slice(1) || Cryptpad.getUserHash() || localStorage.FS_hash;
|
||||
return Cryptpad.getSecrets('drive', hash);
|
||||
return Utils.Hash.getSecrets('drive', hash);
|
||||
};
|
||||
Netflux.connect(Cryptpad.getWebsocketURL()).then(function (network) {
|
||||
SFCommonO.start({
|
||||
|
|
|
@ -2,12 +2,13 @@ define([
|
|||
'jquery',
|
||||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/common/toolbar3.js',
|
||||
'/common/cryptpad-common.js',
|
||||
'/bower_components/nthen/index.js',
|
||||
'/common/sframe-common.js',
|
||||
'/common/common-realtime.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-interface.js',
|
||||
'/customize/messages.js',
|
||||
|
||||
'/file/file-crypto.js',
|
||||
'/common/media-tag.js',
|
||||
|
@ -22,22 +23,20 @@ define([
|
|||
$,
|
||||
Crypto,
|
||||
Toolbar,
|
||||
Cryptpad,
|
||||
nThen,
|
||||
SFCommon,
|
||||
CommonRealtime,
|
||||
Util,
|
||||
Hash,
|
||||
UI,
|
||||
Messages,
|
||||
FileCrypto,
|
||||
MediaTag)
|
||||
{
|
||||
var Messages = Cryptpad.Messages;
|
||||
var saveAs = window.saveAs;
|
||||
var Nacl = window.nacl;
|
||||
|
||||
var APP = window.APP = {
|
||||
Cryptpad: Cryptpad,
|
||||
};
|
||||
var APP = window.APP = {};
|
||||
|
||||
var andThen = function (common) {
|
||||
var $appContainer = $('#cp-app-file-content');
|
||||
|
@ -62,9 +61,9 @@ define([
|
|||
if (!priv.filehash) {
|
||||
uploadMode = true;
|
||||
} else {
|
||||
secret = Cryptpad.getSecrets('file', priv.filehash);
|
||||
secret = Hash.getSecrets('file', priv.filehash);
|
||||
if (!secret.keys) { throw new Error("You need a hash"); }
|
||||
hexFileName = Cryptpad.base64ToHex(secret.channel);
|
||||
hexFileName = Util.base64ToHex(secret.channel);
|
||||
}
|
||||
|
||||
var Title = common.createTitle({});
|
||||
|
@ -74,7 +73,6 @@ define([
|
|||
}
|
||||
var configTb = {
|
||||
displayed: displayed,
|
||||
common: Cryptpad,
|
||||
//hideDisplayName: true,
|
||||
$container: $bar,
|
||||
metadataMgr: metadataMgr,
|
||||
|
@ -88,7 +86,7 @@ define([
|
|||
toolbar.$rightside.html('');
|
||||
|
||||
if (!uploadMode) {
|
||||
var src = Cryptpad.getBlobPathFromHex(hexFileName);
|
||||
var src = Hash.getBlobPathFromHex(hexFileName);
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var key = Nacl.util.decodeBase64(cryptKey);
|
||||
|
||||
|
@ -110,7 +108,7 @@ define([
|
|||
|
||||
var $mt = $dlview.find('media-tag');
|
||||
var cryptKey = secret.keys && secret.keys.fileKeyStr;
|
||||
var hexFileName = Cryptpad.base64ToHex(secret.channel);
|
||||
var hexFileName = Util.base64ToHex(secret.channel);
|
||||
$mt.attr('src', '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName);
|
||||
$mt.attr('data-crypto-key', 'cryptpad:'+cryptKey);
|
||||
|
||||
|
@ -232,7 +230,7 @@ define([
|
|||
if (e) {
|
||||
return void UI.errorLoadingScreen(e);
|
||||
}
|
||||
var size = Cryptpad.bytesToMegabytes(data);
|
||||
var size = Util.bytesToMegabytes(data);
|
||||
return void todoBigFile(size);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,6 +8,8 @@ define([
|
|||
'/common/sframe-common.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-ui-elements.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'json.sortify',
|
||||
|
||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||
|
@ -23,6 +25,8 @@ define([
|
|||
SFCommon,
|
||||
UI,
|
||||
UIElements,
|
||||
Util,
|
||||
Hash,
|
||||
Sortify)
|
||||
{
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
@ -45,10 +49,10 @@ define([
|
|||
sframeChan.event('EV_FILE_PICKER_CLOSE');
|
||||
};
|
||||
var onFilePicked = function (data) {
|
||||
var parsed = Cryptpad.parsePadUrl(data.url);
|
||||
var parsed = Hash.parsePadUrl(data.url);
|
||||
hideFileDialog();
|
||||
if (parsed.type === 'file') {
|
||||
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
|
||||
var hexFileName = Util.base64ToHex(parsed.hashData.channel);
|
||||
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
|
||||
sframeChan.event("EV_FILE_PICKED", {
|
||||
type: parsed.type,
|
||||
|
|
|
@ -2,10 +2,11 @@ define([
|
|||
'jquery',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/common-interface.js',
|
||||
//'/common/common-hash.js',
|
||||
//'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||
//'/common/curve.js',
|
||||
'less!/invite/main.less',
|
||||
], function ($, Cryptpad, UI /*, Listmap, Curve*/) {
|
||||
], function ($, Cryptpad, UI/*, Hash , Listmap, Curve*/) {
|
||||
var Messages = Cryptpad.Messages;
|
||||
var comingSoon = function () {
|
||||
return $('<div>', {
|
||||
|
@ -34,7 +35,7 @@ define([
|
|||
var andThen = function () {
|
||||
var hash = window.location.hash.slice(1);
|
||||
|
||||
var info = Cryptpad.parseTypeHash('invite', hash);
|
||||
var info = Hash.parseTypeHash('invite', hash);
|
||||
console.log(info);
|
||||
|
||||
if (!info.pubkey) {
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="cp">
|
||||
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
|
||||
<head>
|
||||
<title data-localization="main_title">CryptPad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
|
||||
</head>
|
||||
<body class="html">
|
||||
<noscript>
|
||||
<p><strong>OOPS</strong> In order to do encryption in your browser, Javascript is really <strong>really</strong> required.</p>
|
||||
<p><strong>OUPS</strong> Afin de pouvoir réaliser le chiffrement dans votre navigateur, Javascript est <strong>vraiment</strong> nécessaire.</p>
|
||||
</noscript>
|
||||
</html>
|
|
@ -1,569 +0,0 @@
|
|||
define([
|
||||
'jquery',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/mergeDrive.js',
|
||||
'/common/toolbar2.js',
|
||||
'/bower_components/file-saver/FileSaver.min.js',
|
||||
|
||||
'less!/customize/src/less/cryptpad.less',
|
||||
'less!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||
'less!/customize/src/less/toolbar.less',
|
||||
'less!/settings/main.less',
|
||||
], function ($, Cryptpad, Crypt, Merge, Toolbar) {
|
||||
var saveAs = window.saveAs;
|
||||
|
||||
var USERNAME_KEY = 'cryptpad.username';
|
||||
|
||||
var APP = window.APP = {
|
||||
Cryptpad: Cryptpad,
|
||||
_onRefresh: []
|
||||
};
|
||||
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
||||
// Manage changes in the realtime object made from another page
|
||||
var onRefresh = function (h) {
|
||||
if (typeof(h) !== "function") { return; }
|
||||
if (APP._onRefresh.indexOf(h) !== -1) { return; }
|
||||
APP._onRefresh.push(h);
|
||||
};
|
||||
var refresh = APP.refresh = function () {
|
||||
APP._onRefresh.forEach(function (h) {
|
||||
h();
|
||||
});
|
||||
};
|
||||
|
||||
var categories = {
|
||||
'account': [
|
||||
'infoBlock',
|
||||
'displayName',
|
||||
'languageSelector',
|
||||
'logoutEverywhere',
|
||||
'resetTips',
|
||||
'thumbnails',
|
||||
'userFeedback'
|
||||
],
|
||||
'drive': [
|
||||
'backupDrive',
|
||||
'importLocalPads',
|
||||
'resetDrive'
|
||||
],
|
||||
'code': [
|
||||
'indentUnit',
|
||||
'indentType'
|
||||
]
|
||||
};
|
||||
|
||||
var createInfoBlock = function (store) {
|
||||
var obj = store.proxy;
|
||||
var $div = $('<div>', {'class': 'infoBlock'});
|
||||
|
||||
var $account = $('<div>', {'class': 'element'}).appendTo($div);
|
||||
var accountName = obj.login_name || localStorage[Cryptpad.userNameKey];
|
||||
var $label = $('<span>', {'class': 'label'}).text(Messages.user_accountName);
|
||||
var $name = $('<span>').text(accountName || '');
|
||||
if (!accountName) {
|
||||
$label.text('');
|
||||
$name.text(Messages.settings_anonymous);
|
||||
}
|
||||
$account.append($label).append($name);
|
||||
|
||||
var publicKey = obj.edPublic;
|
||||
if (publicKey) {
|
||||
var $key = $('<div>', {'class': 'element'}).appendTo($div);
|
||||
var userHref = Cryptpad.getUserHrefFromKeys(accountName, publicKey);
|
||||
var $pubLabel = $('<span>', {'class': 'label'})
|
||||
.text(Messages.settings_publicSigningKey);
|
||||
$key.append($pubLabel).append(Cryptpad.dialog.selectable(userHref));
|
||||
}
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
// Create the block containing the display name field
|
||||
var createDisplayNameInput = function (store) {
|
||||
var obj = store.proxy;
|
||||
var $div = $('<div>', {'class': 'displayName element'});
|
||||
$('<label>', {'for' : 'displayName'}).text(Messages.user_displayName).appendTo($div);
|
||||
var $inputBlock = $('<div>', {'class': 'inputBlock'}).appendTo($div);
|
||||
var $input = $('<input>', {
|
||||
'type': 'text',
|
||||
'id': 'displayName',
|
||||
'placeholder': Messages.anonymous}).appendTo($inputBlock);
|
||||
var $save = $('<button>', {'class': 'btn btn-primary'}).text(Messages.settings_save).appendTo($inputBlock);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide().appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
|
||||
|
||||
var displayName = obj[USERNAME_KEY] || '';
|
||||
$input.val(displayName);
|
||||
|
||||
// When the display name is changed (enter or button clicked)
|
||||
var todo = function () {
|
||||
displayName = $input.val();
|
||||
if (displayName === obj[USERNAME_KEY]) { return; }
|
||||
obj[USERNAME_KEY] = displayName;
|
||||
Cryptpad.changeDisplayName(displayName);
|
||||
$spinner.show();
|
||||
Cryptpad.whenRealtimeSyncs(store.info.realtime, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
});
|
||||
};
|
||||
$input.on('keyup', function (e) {
|
||||
if ($input.val() !== displayName) { $ok.hide(); }
|
||||
if (e.which === 13) { todo(); }
|
||||
});
|
||||
$save.click(todo);
|
||||
|
||||
// On remote change
|
||||
var onChange = function () {
|
||||
if (obj[USERNAME_KEY] !== $input.val()) {
|
||||
$input.val(obj[USERNAME_KEY]);
|
||||
$input.focusout();
|
||||
}
|
||||
};
|
||||
onRefresh(onChange);
|
||||
|
||||
return $div;
|
||||
};
|
||||
var createIndentUnitSelector = function (obj) {
|
||||
var proxy = obj.proxy;
|
||||
proxy.settings = proxy.settings || {};
|
||||
|
||||
var $div = $('<div>', {
|
||||
'class': 'indentUnit element'
|
||||
});
|
||||
$('<label>').text(Messages.settings_codeIndentation).appendTo($div);
|
||||
|
||||
var $inputBlock = $('<div>', {
|
||||
'class': 'inputBlock',
|
||||
}).appendTo($div);
|
||||
|
||||
var $input = $('<input>', {
|
||||
'min': 1,
|
||||
'max': 8,
|
||||
type: 'number',
|
||||
}).on('change', function () {
|
||||
var val = parseInt($input.val());
|
||||
if (typeof(val) !== 'number') { return; }
|
||||
Cryptpad.setAttribute(['codemirror', 'indentUnit'], val);
|
||||
}).appendTo($inputBlock);
|
||||
|
||||
proxy.on('change', [ 'settings', 'codemirror', 'indentUnit', ], function (o, n) {
|
||||
$input.val(n);
|
||||
});
|
||||
|
||||
Cryptpad.getAttribute(['codemirror', 'indentUnit'], function (e, val) {
|
||||
if (e) { return void console.error(e); }
|
||||
if (typeof(val) !== 'number') {
|
||||
$input.val(2);
|
||||
} else {
|
||||
$input.val(val);
|
||||
}
|
||||
});
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createIndentTypeSelector = function (obj) {
|
||||
var proxy = obj.proxy;
|
||||
proxy.settings = proxy.settings || {};
|
||||
|
||||
var key = 'indentWithTabs';
|
||||
|
||||
var $div = $('<div>', {
|
||||
'class': 'indentType element'
|
||||
});
|
||||
$('<label>').text(Messages.settings_codeUseTabs).appendTo($div);
|
||||
|
||||
var $inputBlock = $('<div>', {
|
||||
'class': 'inputBlock',
|
||||
}).css('flex-flow', 'column')
|
||||
.appendTo($div);
|
||||
|
||||
var $input = $('<input>', {
|
||||
type: 'checkbox',
|
||||
}).on('change', function () {
|
||||
var val = $input.is(':checked');
|
||||
if (typeof(val) !== 'boolean') { return; }
|
||||
Cryptpad.setAttribute(['codemirror', key], val);
|
||||
}).appendTo($inputBlock);
|
||||
|
||||
$input[0].checked = !!proxy.settings[key];
|
||||
proxy.on('change', ['settings', 'codemirror', key], function (o, n) {
|
||||
$input[0].checked = !!n;
|
||||
});
|
||||
|
||||
Cryptpad.getAttribute(['codemirror', key], function (e, val) {
|
||||
if (e) { return void console.error(e); }
|
||||
$input[0].checked = !!val;
|
||||
});
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createResetTips = function () {
|
||||
var $div = $('<div>', {'class': 'resetTips element'});
|
||||
$('<label>', {'for' : 'resetTips'}).text(Messages.settings_resetTips).appendTo($div);
|
||||
$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_resetTipsButton).appendTo($div);
|
||||
var $button = $('<button>', {'id': 'resetTips', 'class': 'btn btn-primary'})
|
||||
.text(Messages.settings_resetTipsAction).appendTo($div);
|
||||
|
||||
$button.click(function () {
|
||||
Object.keys(localStorage).forEach(function (k) {
|
||||
if(k.slice(0, 9) === "hide-info") {
|
||||
delete localStorage[k];
|
||||
}
|
||||
});
|
||||
Cryptpad.alert(Messages.settings_resetTipsDone);
|
||||
});
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createThumbnails = function (obj) {
|
||||
var $div = $('<div>', {'class': 'thumbnails element'});
|
||||
$('<label>').text(Messages.settings_thumbnails).appendTo($div);
|
||||
|
||||
// Disable
|
||||
$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_disableThumbnailsDescription).appendTo($div);
|
||||
var $label = $('<label>', { 'for': 'disableThumbnails', 'class': 'noTitle' })
|
||||
.text(Messages.settings_disableThumbnailsAction);
|
||||
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved});
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'});
|
||||
|
||||
var $checkbox = $('<input>', {
|
||||
'type': 'checkbox',
|
||||
id: 'disableThumbnails'
|
||||
}).on('change', function () {
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
if (!obj.proxy.settings) { obj.proxy.settings = {}; }
|
||||
if (!obj.proxy.settings.general) { obj.proxy.settings.general = {}; }
|
||||
obj.proxy.settings.general.disableThumbnails = $checkbox.is(':checked') || false;
|
||||
Cryptpad.whenRealtimeSyncs(obj.info.realtime, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
});
|
||||
});
|
||||
|
||||
$checkbox.appendTo($div);
|
||||
$label.appendTo($div);
|
||||
|
||||
$ok.hide().appendTo($div);
|
||||
$spinner.hide().appendTo($div);
|
||||
|
||||
if (obj.proxy.settings && obj.proxy.settings.general
|
||||
&& obj.proxy.settings.general.disableThumbnails) {
|
||||
$checkbox[0].checked = true;
|
||||
}
|
||||
|
||||
// Reset
|
||||
/*$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_resetThumbnailsDescription).appendTo($div);
|
||||
var $button = $('<button>', {'id': 'resetThumbnails', 'class': 'btn btn-primary'})
|
||||
.text(Messages.settings_resetThumbnailsAction).appendTo($div);
|
||||
|
||||
$button.click(function () {
|
||||
// TODO we need to have access to the sandbox localforage first...
|
||||
Cryptpad.alert(Messages.settings_resetThumbnailsDone);
|
||||
});*/
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createBackupDrive = function (store) {
|
||||
var obj = store.proxy;
|
||||
var $div = $('<div>', {'class': 'backupDrive element'});
|
||||
|
||||
var exportFile = function () {
|
||||
var sjson = JSON.stringify(obj);
|
||||
var name = obj.login_name || obj[USERNAME_KEY] || Messages.anonymous;
|
||||
var suggestion = name + '-' + new Date().toDateString();
|
||||
Cryptpad.prompt(Cryptpad.Messages.exportPrompt,
|
||||
Cryptpad.fixFileName(suggestion) + '.json', function (filename) {
|
||||
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||
var blob = new Blob([sjson], {type: "application/json;charset=utf-8"});
|
||||
saveAs(blob, filename);
|
||||
});
|
||||
};
|
||||
var importFile = function (content) {
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).appendTo($div);
|
||||
Crypt.put(Cryptpad.getUserHash() || localStorage[Cryptpad.fileHashKey], content, function (e) {
|
||||
if (e) { console.error(e); }
|
||||
$spinner.remove();
|
||||
});
|
||||
};
|
||||
|
||||
$('<label>', {'for' : 'exportDrive'}).text(Messages.settings_backupCategory).appendTo($div);
|
||||
$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_backupTitle).appendTo($div);
|
||||
/* add an export button */
|
||||
var $export = Cryptpad.createButton('export', true, {}, exportFile);
|
||||
$export.attr('class', 'btn btn-success').text(Messages.settings_backup);
|
||||
$div.append($export);
|
||||
|
||||
/* add an import button */
|
||||
var $import = Cryptpad.createButton('import', true, {}, importFile);
|
||||
$import.attr('class', 'btn btn-success').text(Messages.settings_restore);
|
||||
$div.append($import);
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createResetDrive = function (obj) {
|
||||
var $div = $('<div>', {'class': 'resetDrive element'});
|
||||
$('<label>', {'for' : 'resetDrive'}).text(Messages.settings_resetNewTitle).appendTo($div);
|
||||
$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_reset).appendTo($div);
|
||||
var $button = $('<button>', {'id': 'resetDrive', 'class': 'btn btn-danger'})
|
||||
.text(Messages.settings_resetButton).appendTo($div);
|
||||
|
||||
$button.click(function () {
|
||||
Cryptpad.prompt(Messages.settings_resetPrompt, "", function (val) {
|
||||
if (val !== "I love CryptPad") {
|
||||
Cryptpad.alert(Messages.settings_resetError);
|
||||
return;
|
||||
}
|
||||
obj.proxy.drive = Cryptpad.getStore().getEmptyObject();
|
||||
Cryptpad.alert(Messages.settings_resetDone);
|
||||
}, undefined, true);
|
||||
});
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createUserFeedbackToggle = function (obj) {
|
||||
var $div = $('<div>', { 'class': 'userFeedback element'});
|
||||
|
||||
$('<span>', {'class': 'label'}).text(Messages.settings_userFeedbackTitle).appendTo($div);
|
||||
|
||||
var $label = $('<label>', { 'for': 'userFeedback', 'class': 'noTitle' })
|
||||
.text(Messages.settings_userFeedback);
|
||||
|
||||
$('<span>', {'class': 'description'})
|
||||
.append(Messages.settings_userFeedbackHint1)
|
||||
.append(Messages.settings_userFeedbackHint2).appendTo($div);
|
||||
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved});
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'});
|
||||
|
||||
var $checkbox = $('<input>', {
|
||||
'type': 'checkbox',
|
||||
}).on('change', function () {
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
obj.proxy.allowUserFeedback = $checkbox.is(':checked') || false;
|
||||
Cryptpad.whenRealtimeSyncs(obj.info.realtime, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
});
|
||||
});
|
||||
|
||||
$checkbox.appendTo($div);
|
||||
$label.appendTo($div);
|
||||
|
||||
$ok.hide().appendTo($div);
|
||||
$spinner.hide().appendTo($div);
|
||||
|
||||
if (obj.proxy.allowUserFeedback) {
|
||||
$checkbox[0].checked = true;
|
||||
}
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createUsageButton = function () {
|
||||
Cryptpad.createUsageBar(function (err, $bar) {
|
||||
if (err) { return void console.error(err); }
|
||||
APP.$usage.html('').append($bar);
|
||||
}, true);
|
||||
};
|
||||
|
||||
var createLogoutEverywhere = function (obj) {
|
||||
var proxy = obj.proxy;
|
||||
var $div = $('<div>', { 'class': 'logoutEverywhere element'});
|
||||
$('<label>', { 'for': 'logoutEverywhere'})
|
||||
.text(Messages.settings_logoutEverywhereTitle).appendTo($div);
|
||||
$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_logoutEverywhere).appendTo($div);
|
||||
var $button = $('<button>', { id: 'logoutEverywhere', 'class': 'btn btn-primary' })
|
||||
.text(Messages.settings_logoutEverywhereButton)
|
||||
.appendTo($div);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide().appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
|
||||
|
||||
$button.click(function () {
|
||||
var realtime = obj.info.realtime;
|
||||
console.log(realtime);
|
||||
|
||||
Cryptpad.confirm(Messages.settings_logoutEverywhereConfirm, function (yes) {
|
||||
if (!yes) { return; }
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
|
||||
var token = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER);
|
||||
localStorage.setItem('loginToken', token);
|
||||
proxy.loginToken = token;
|
||||
|
||||
Cryptpad.whenRealtimeSyncs(realtime, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
window.setTimeout(function () {
|
||||
$ok.fadeOut(1500);
|
||||
}, 2500);
|
||||
});
|
||||
});
|
||||
});
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createImportLocalPads = function (obj) {
|
||||
if (!Cryptpad.isLoggedIn()) { return; }
|
||||
var $div = $('<div>', {'class': 'importLocalPads element'});
|
||||
$('<label>', {'for' : 'importLocalPads'}).text(Messages.settings_import).appendTo($div);
|
||||
$('<span>', {'class': 'description'})
|
||||
.text(Messages.settings_importTitle).appendTo($div);
|
||||
var $button = $('<button>', {'id': 'importLocalPads', 'class': 'btn btn-primary'})
|
||||
.text(Messages.settings_import).appendTo($div);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide().appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
|
||||
|
||||
$button.click(function () {
|
||||
Cryptpad.confirm(Messages.settings_importConfirm, function (yes) {
|
||||
if (!yes) { return; }
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
Merge.anonDriveIntoUser(obj, localStorage.FS_hash, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
Cryptpad.alert(Messages.settings_importDone);
|
||||
});
|
||||
}, undefined, true);
|
||||
});
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createLanguageSelector = function () {
|
||||
var $div = $('<div>', {'class': 'languageSelector element'});
|
||||
$('<label>').text(Messages.language).appendTo($div);
|
||||
var $b = Cryptpad.createLanguageSelector().appendTo($div);
|
||||
$b.find('button').addClass('btn btn-secondary');
|
||||
return $div;
|
||||
};
|
||||
|
||||
|
||||
var hideCategories = function () {
|
||||
APP.$rightside.find('> div').hide();
|
||||
};
|
||||
var showCategories = function (cat) {
|
||||
hideCategories();
|
||||
cat.forEach(function (c) {
|
||||
APP.$rightside.find('.'+c).show();
|
||||
});
|
||||
};
|
||||
|
||||
var createLeftside = function () {
|
||||
var $categories = $('<div>', {'class': 'categories'}).appendTo(APP.$leftside);
|
||||
APP.$usage = $('<div>', {'class': 'usage'}).appendTo(APP.$leftside);
|
||||
var active = 'account';
|
||||
Object.keys(categories).forEach(function (key) {
|
||||
var $category = $('<div>', {'class': 'category'}).appendTo($categories);
|
||||
if (key === 'account') { $category.append($('<span>', {'class': 'fa fa-user-o'})); }
|
||||
if (key === 'drive') { $category.append($('<span>', {'class': 'fa fa-hdd-o'})); }
|
||||
if (key === 'code') { $category.append($('<span>', {'class': 'fa fa-file-code-o' })); }
|
||||
|
||||
if (key === active) {
|
||||
$category.addClass('active');
|
||||
}
|
||||
|
||||
$category.click(function () {
|
||||
active = key;
|
||||
$categories.find('.active').removeClass('active');
|
||||
$category.addClass('active');
|
||||
showCategories(categories[key]);
|
||||
});
|
||||
|
||||
$category.append(Messages['settings_cat_'+key]);
|
||||
});
|
||||
showCategories(categories[active]);
|
||||
};
|
||||
|
||||
var createToolbar = function () {
|
||||
var displayed = ['useradmin', 'newpad', 'limit', 'upgrade', 'pageTitle'];
|
||||
var configTb = {
|
||||
displayed: displayed,
|
||||
ifrw: window,
|
||||
common: Cryptpad,
|
||||
$container: APP.$toolbar,
|
||||
pageTitle: Messages.settings_title
|
||||
};
|
||||
var toolbar = APP.toolbar = Toolbar.create(configTb);
|
||||
toolbar.$rightside.html(''); // Remove the drawer if we don't use it to hide the toolbar
|
||||
};
|
||||
|
||||
var andThen = function (obj) {
|
||||
APP.$leftside = $('<div>', {id: 'leftSide'}).appendTo(APP.$container);
|
||||
var $rightside = APP.$rightside = $('<div>', {id: 'rightSide'}).appendTo(APP.$container);
|
||||
|
||||
createToolbar();
|
||||
|
||||
//$rightside.append(createTitle());
|
||||
$rightside.append(createInfoBlock(obj));
|
||||
$rightside.append(createDisplayNameInput(obj));
|
||||
$rightside.append(createLanguageSelector());
|
||||
$rightside.append(createIndentUnitSelector(obj));
|
||||
$rightside.append(createIndentTypeSelector(obj));
|
||||
|
||||
if (Cryptpad.isLoggedIn()) {
|
||||
$rightside.append(createLogoutEverywhere(obj));
|
||||
}
|
||||
$rightside.append(createResetTips());
|
||||
$rightside.append(createThumbnails(obj));
|
||||
$rightside.append(createBackupDrive(obj));
|
||||
$rightside.append(createImportLocalPads(obj));
|
||||
$rightside.append(createResetDrive(obj));
|
||||
$rightside.append(createUserFeedbackToggle(obj));
|
||||
|
||||
obj.proxy.on('change', [], refresh);
|
||||
obj.proxy.on('remove', [], refresh);
|
||||
Cryptpad.onDisplayNameChanged(refresh);
|
||||
|
||||
createLeftside();
|
||||
createUsageButton();
|
||||
|
||||
Cryptpad.removeLoadingScreen();
|
||||
};
|
||||
|
||||
$(function () {
|
||||
$(window).click(function () {
|
||||
$('.cp-dropdown-content').hide();
|
||||
});
|
||||
|
||||
APP.$container = $('#container');
|
||||
APP.$toolbar = $('#toolbar');
|
||||
|
||||
Cryptpad.ready(function () {
|
||||
//if (!Cryptpad.getUserHash()) { return redirectToMain(); }
|
||||
|
||||
var storeObj = Cryptpad.getStore().getProxy && Cryptpad.getStore().getProxy().proxy
|
||||
? Cryptpad.getStore().getProxy() : undefined;
|
||||
|
||||
andThen(storeObj);
|
||||
Cryptpad.reportAppUsage();
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('storage', function (e) {
|
||||
if (e.key !== Cryptpad.userHashKey) { return; }
|
||||
var o = e.oldValue;
|
||||
var n = e.newValue;
|
||||
window.location.reload();
|
||||
if (o && !n) { // disconnect
|
||||
//redirectToMain();
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,54 +0,0 @@
|
|||
@import '/customize/src/less/variables.less';
|
||||
@import '/customize/src/less/mixins.less';
|
||||
@import '/customize/src/less/sidebar-layout.less';
|
||||
|
||||
.cp {
|
||||
#container {
|
||||
#rightSide {
|
||||
.userFeedback, .thumbnails {
|
||||
input[type="checkbox"] {
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.languageSelector {
|
||||
button.btn {
|
||||
width: @button-width;
|
||||
background-color: @button-alt-bg;
|
||||
border-color: #adadad;
|
||||
color: black;
|
||||
&:hover {
|
||||
background-color: darken(@button-alt-bg, 15%);
|
||||
}
|
||||
}
|
||||
}
|
||||
.inputBlock {
|
||||
input {
|
||||
border-top-right-radius: 0.25em;
|
||||
border-bottom-right-radius: 0.25em;
|
||||
padding: 5px;
|
||||
padding-left: 15px;
|
||||
&[type="number"] {
|
||||
border-right: 1px solid #adadad;
|
||||
}
|
||||
&[type="checkbox"] {
|
||||
margin-right: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.infoBlock {
|
||||
[type="text"] {
|
||||
width: @button-width;
|
||||
}
|
||||
}
|
||||
.backupDrive {
|
||||
button {
|
||||
span.fa {
|
||||
margin-right: 5px;
|
||||
}
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ define([
|
|||
Cryptpad: Cryptpad,
|
||||
mobile: function () { return $('body').width() <= 600; } // Menu and content area are not inline-block anymore for mobiles
|
||||
};
|
||||
var Render = Renderer(Cryptpad, APP);
|
||||
var Render = Renderer(APP);
|
||||
|
||||
var debug = $.noop; //console.log;
|
||||
|
||||
|
@ -119,7 +119,7 @@ define([
|
|||
var csv = getCSV();
|
||||
var suggestion = Title.suggestTitle(Title.defaultTitle);
|
||||
UI.prompt(Messages.exportPrompt,
|
||||
Cryptpad.fixFileName(suggestion) + '.csv', function (filename) {
|
||||
Util.fixFileName(suggestion) + '.csv', function (filename) {
|
||||
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||
var blob = new Blob([csv], {type: "application/csv;charset=utf-8"});
|
||||
saveAs(blob, filename);
|
||||
|
|
|
@ -3,8 +3,10 @@ define([
|
|||
'jquery',
|
||||
'/bower_components/hyperjson/hyperjson.js',
|
||||
'/bower_components/textpatcher/TextPatcher.js',
|
||||
'/common/common-util.js',
|
||||
'/customize/messages.js',
|
||||
'/bower_components/diff-dom/diffDOM.js',
|
||||
], function ($, Hyperjson, TextPatcher) {
|
||||
], function ($, Hyperjson, TextPatcher, Util, Messages) {
|
||||
var DiffDOM = window.diffDOM;
|
||||
|
||||
var Example = {
|
||||
|
@ -31,7 +33,7 @@ by maintaining indexes in rowsOrder and colsOrder
|
|||
}
|
||||
};
|
||||
|
||||
var Renderer = function (Cryptpad, APP) {
|
||||
var Renderer = function (APP) {
|
||||
|
||||
var Render = {
|
||||
Example: Example
|
||||
|
@ -64,15 +66,15 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
var getColumnValue = Render.getColumnValue = function (obj, colId) {
|
||||
return Cryptpad.find(obj, ['content', 'cols'].concat([colId]));
|
||||
return Util.find(obj, ['content', 'cols'].concat([colId]));
|
||||
};
|
||||
|
||||
var getRowValue = Render.getRowValue = function (obj, rowId) {
|
||||
return Cryptpad.find(obj, ['content', 'rows'].concat([rowId]));
|
||||
return Util.find(obj, ['content', 'rows'].concat([rowId]));
|
||||
};
|
||||
|
||||
var getCellValue = Render.getCellValue = function (obj, cellId) {
|
||||
var value = Cryptpad.find(obj, ['content', 'cells'].concat([cellId]));
|
||||
var value = Util.find(obj, ['content', 'cells'].concat([cellId]));
|
||||
if (typeof value === 'boolean') {
|
||||
return (value === true ? 1 : 0);
|
||||
} else {
|
||||
|
@ -81,25 +83,25 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
var setRowValue = Render.setRowValue = function (obj, rowId, value) {
|
||||
var parent = Cryptpad.find(obj, ['content', 'rows']);
|
||||
var parent = Util.find(obj, ['content', 'rows']);
|
||||
if (typeof(parent) === 'object') { return (parent[rowId] = value); }
|
||||
return null;
|
||||
};
|
||||
|
||||
var setColumnValue = Render.setColumnValue = function (obj, colId, value) {
|
||||
var parent = Cryptpad.find(obj, ['content', 'cols']);
|
||||
var parent = Util.find(obj, ['content', 'cols']);
|
||||
if (typeof(parent) === 'object') { return (parent[colId] = value); }
|
||||
return null;
|
||||
};
|
||||
|
||||
var setCellValue = Render.setCellValue = function (obj, cellId, value) {
|
||||
var parent = Cryptpad.find(obj, ['content', 'cells']);
|
||||
var parent = Util.find(obj, ['content', 'cells']);
|
||||
if (typeof(parent) === 'object') { return (parent[cellId] = value); }
|
||||
return null;
|
||||
};
|
||||
|
||||
Render.createColumn = function (obj, cb, id, value) {
|
||||
var order = Cryptpad.find(obj, ['content', 'colsOrder']);
|
||||
var order = Util.find(obj, ['content', 'colsOrder']);
|
||||
if (!order) { throw new Error("Uninitialized realtime object!"); }
|
||||
id = id || coluid();
|
||||
value = value || "";
|
||||
|
@ -109,8 +111,8 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
Render.removeColumn = function (obj, id, cb) {
|
||||
var order = Cryptpad.find(obj, ['content', 'colsOrder']);
|
||||
var parent = Cryptpad.find(obj, ['content', 'cols']);
|
||||
var order = Util.find(obj, ['content', 'colsOrder']);
|
||||
var parent = Util.find(obj, ['content', 'cols']);
|
||||
|
||||
if (!(order && parent)) { throw new Error("Uninitialized realtime object!"); }
|
||||
|
||||
|
@ -134,7 +136,7 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
Render.createRow = function (obj, cb, id, value) {
|
||||
var order = Cryptpad.find(obj, ['content', 'rowsOrder']);
|
||||
var order = Util.find(obj, ['content', 'rowsOrder']);
|
||||
if (!order) { throw new Error("Uninitialized realtime object!"); }
|
||||
id = id || rowuid();
|
||||
value = value || "";
|
||||
|
@ -144,8 +146,8 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
Render.removeRow = function (obj, id, cb) {
|
||||
var order = Cryptpad.find(obj, ['content', 'rowsOrder']);
|
||||
var parent = Cryptpad.find(obj, ['content', 'rows']);
|
||||
var order = Util.find(obj, ['content', 'rowsOrder']);
|
||||
var parent = Util.find(obj, ['content', 'rows']);
|
||||
|
||||
if (!(order && parent)) { throw new Error("Uninitialized realtime object!"); }
|
||||
|
||||
|
@ -185,15 +187,15 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
var getRowIds = Render.getRowIds = function (obj) {
|
||||
return Cryptpad.find(obj, ['content', 'rowsOrder']);
|
||||
return Util.find(obj, ['content', 'rowsOrder']);
|
||||
};
|
||||
|
||||
var getColIds = Render.getColIds = function (obj) {
|
||||
return Cryptpad.find(obj, ['content', 'colsOrder']);
|
||||
return Util.find(obj, ['content', 'colsOrder']);
|
||||
};
|
||||
|
||||
var getCells = Render.getCells = function (obj) {
|
||||
return Cryptpad.find(obj, ['content', 'cells']);
|
||||
return Util.find(obj, ['content', 'cells']);
|
||||
};
|
||||
|
||||
/* cellMatrix takes a proxy object, and optionally an alternate ordering
|
||||
|
@ -219,13 +221,13 @@ var Renderer = function (Cryptpad, APP) {
|
|||
'data-rt-id': col,
|
||||
type: 'text',
|
||||
value: getColumnValue(obj, col) || "",
|
||||
title: getColumnValue(obj, col) || Cryptpad.Messages.anonymous,
|
||||
placeholder: Cryptpad.Messages.anonymous,
|
||||
title: getColumnValue(obj, col) || Messages.anonymous,
|
||||
placeholder: Messages.anonymous,
|
||||
disabled: 'disabled'
|
||||
};
|
||||
return result;
|
||||
})).concat([{
|
||||
content: Cryptpad.Messages.poll_total
|
||||
content: Messages.poll_total
|
||||
}]);
|
||||
}
|
||||
if (i === rows.length) {
|
||||
|
@ -239,9 +241,9 @@ var Renderer = function (Cryptpad, APP) {
|
|||
return [{
|
||||
'data-rt-id': row,
|
||||
value: getRowValue(obj, row) || '',
|
||||
title: getRowValue(obj, row) || Cryptpad.Messages.poll_optionPlaceholder,
|
||||
title: getRowValue(obj, row) || Messages.poll_optionPlaceholder,
|
||||
type: 'text',
|
||||
placeholder: Cryptpad.Messages.poll_optionPlaceholder,
|
||||
placeholder: Messages.poll_optionPlaceholder,
|
||||
disabled: 'disabled',
|
||||
}].concat(cols.map(function (col) {
|
||||
var id = [col, rows[i-1]].join('_');
|
||||
|
@ -269,7 +271,7 @@ var Renderer = function (Cryptpad, APP) {
|
|||
var makeRemoveElement = Render.makeRemoveElement = function (id) {
|
||||
return ['SPAN', {
|
||||
'data-rt-id': id,
|
||||
'title': Cryptpad.Messages.poll_remove,
|
||||
'title': Messages.poll_remove,
|
||||
class: 'cp-app-poll-table-remove',
|
||||
}, ['✖']];
|
||||
};
|
||||
|
@ -277,7 +279,7 @@ var Renderer = function (Cryptpad, APP) {
|
|||
var makeEditElement = Render.makeEditElement = function (id) {
|
||||
return ['SPAN', {
|
||||
'data-rt-id': id,
|
||||
'title': Cryptpad.Messages.poll_edit,
|
||||
'title': Messages.poll_edit,
|
||||
class: 'cp-app-poll-table-edit',
|
||||
}, ['✐']];
|
||||
};
|
||||
|
@ -285,7 +287,7 @@ var Renderer = function (Cryptpad, APP) {
|
|||
var makeLockElement = Render.makeLockElement = function (id) {
|
||||
return ['SPAN', {
|
||||
'data-rt-id': id,
|
||||
'title': Cryptpad.Messages.poll_locked,
|
||||
'title': Messages.poll_locked,
|
||||
class: 'cp-app-poll-table-lock fa fa-lock',
|
||||
}, []];
|
||||
};
|
||||
|
@ -293,7 +295,7 @@ var Renderer = function (Cryptpad, APP) {
|
|||
var makeBookmarkElement = Render.makeBookmarkElement = function (id) {
|
||||
return ['SPAN', {
|
||||
'data-rt-id': id,
|
||||
'title': Cryptpad.Messages.poll_bookmark_col,
|
||||
'title': Messages.poll_bookmark_col,
|
||||
'style': 'visibility: hidden;',
|
||||
class: 'cp-app-poll-table-bookmark fa fa-thumb-tack',
|
||||
}, []];
|
||||
|
@ -383,13 +385,13 @@ var Renderer = function (Cryptpad, APP) {
|
|||
};
|
||||
|
||||
var diffIsInput = Render.diffIsInput = function (info) {
|
||||
var nodeName = Cryptpad.find(info, ['node', 'nodeName']);
|
||||
var nodeName = Util.find(info, ['node', 'nodeName']);
|
||||
if (nodeName !== 'INPUT') { return; }
|
||||
return true;
|
||||
};
|
||||
|
||||
var getInputType = Render.getInputType = function (info) {
|
||||
return Cryptpad.find(info, ['node', 'type']);
|
||||
return Util.find(info, ['node', 'type']);
|
||||
};
|
||||
|
||||
var preserveCursor = Render.preserveCursor = function (info) {
|
||||
|
@ -457,14 +459,14 @@ var Renderer = function (Cryptpad, APP) {
|
|||
// Enable input for the userid column
|
||||
APP.enableColumn(userid, table);
|
||||
$(table).find('input[disabled="disabled"][data-rt-id^="' + userid + '"]')
|
||||
.attr('placeholder', Cryptpad.Messages.poll_userPlaceholder);
|
||||
.attr('placeholder', Messages.poll_userPlaceholder);
|
||||
$(table).find('.cp-app-poll-table-lock[data-rt-id="' + userid + '"]').remove();
|
||||
$(table).find('[data-rt-id^="' + userid + '"]').closest('td')
|
||||
.addClass("cp-app-poll-table-own");
|
||||
$(table).find('.cp-app-poll-table-bookmark[data-rt-id="' + userid + '"]')
|
||||
.css('visibility', '')
|
||||
.addClass('cp-app-poll-table-bookmark-full')
|
||||
.attr('title', Cryptpad.Messages.poll_bookmarked_col);
|
||||
.attr('title', Messages.poll_bookmarked_col);
|
||||
};
|
||||
var styleUncommittedColumn = function (table) {
|
||||
APP.uncommitted.content.colsOrder.forEach(function(id) {
|
||||
|
|
|
@ -139,7 +139,7 @@ define([
|
|||
|
||||
/* jshint ignore:start */
|
||||
var isFriend = function (proxy, edKey) {
|
||||
var friends = Cryptpad.find(proxy, ['friends']);
|
||||
var friends = Util.find(proxy, ['friends']);
|
||||
return typeof(edKey) === 'string' && friends && (edKey in friends);
|
||||
};
|
||||
|
||||
|
@ -148,7 +148,7 @@ define([
|
|||
var obj = APP.lm.proxy;
|
||||
|
||||
var proxy = Cryptpad.getProxy();
|
||||
var userViewHash = Cryptpad.find(proxy, ['profile', 'view']);
|
||||
var userViewHash = Util.find(proxy, ['profile', 'view']);
|
||||
|
||||
var edKey = obj.edKey;
|
||||
var curveKey = obj.curveKey;
|
||||
|
@ -257,10 +257,15 @@ define([
|
|||
createEditableInput($block, LINK_ID, placeholder, getValue, setValue);
|
||||
};
|
||||
|
||||
var allowedMediaTypes = [
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/gif',
|
||||
];
|
||||
var addAvatar = function ($container) {
|
||||
var $block = $('<div>', {id: AVATAR_ID}).appendTo($container);
|
||||
var $span = $('<span>').appendTo($block);
|
||||
var allowedMediaTypes = Cryptpad.avatarAllowedTypes;
|
||||
var sframeChan = common.getSframeChannel();
|
||||
var displayAvatar = function () {
|
||||
$span.html('');
|
||||
|
@ -320,7 +325,7 @@ define([
|
|||
var data = {
|
||||
FM: APP.FM,
|
||||
filter: function (file) {
|
||||
var sizeMB = Cryptpad.bytesToMegabytes(file.size);
|
||||
var sizeMB = Util.bytesToMegabytes(file.size);
|
||||
var type = file.type;
|
||||
return sizeMB <= 0.5 && allowedMediaTypes.indexOf(type) !== -1;
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ define([
|
|||
'/api/config',
|
||||
'jquery',
|
||||
'/common/requireconfig.js',
|
||||
'/common/sframe-common-outer.js'
|
||||
'/common/sframe-common-outer.js',
|
||||
], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) {
|
||||
var requireConfig = RequireConfig();
|
||||
|
||||
|
@ -36,20 +36,21 @@ define([
|
|||
};
|
||||
window.addEventListener('message', onMsg);
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
var getSecrets = function (Cryptpad) {
|
||||
var getSecrets = function (Cryptpad, Utils) {
|
||||
var Hash = Utils.Hash;
|
||||
// 1st case: visiting someone else's profile with hash in the URL
|
||||
if (window.location.hash) {
|
||||
return Cryptpad.getSecrets('profile', window.location.hash.slice(1));
|
||||
return Hash.getSecrets('profile', window.location.hash.slice(1));
|
||||
}
|
||||
// 2nd case: visiting our own existing profile
|
||||
var obj = Cryptpad.getProxy();
|
||||
if (obj.profile && obj.profile.view && obj.profile.edit) {
|
||||
return Cryptpad.getSecrets('profile', obj.profile.edit);
|
||||
return Hash.getSecrets('profile', obj.profile.edit);
|
||||
}
|
||||
// 3rd case: profile creation (create a new random hash, store it later if needed)
|
||||
if (!Cryptpad.isLoggedIn()) { return; }
|
||||
var hash = Cryptpad.createRandomHash();
|
||||
var secret = Cryptpad.getSecrets('profile', hash);
|
||||
var hash = Hash.createRandomHash();
|
||||
var secret = Hash.getSecrets('profile', hash);
|
||||
Cryptpad.pinPads([secret.channel], function (e) {
|
||||
if (e) {
|
||||
if (e === 'E_OVER_LIMIT') {
|
||||
|
@ -59,26 +60,26 @@ define([
|
|||
//return void UI.log(Messages._getKey('profile_error', [e])) // TODO
|
||||
}
|
||||
obj.profile = {};
|
||||
obj.profile.edit = Cryptpad.getEditHashFromKeys(secret.channel, secret.keys);
|
||||
obj.profile.view = Cryptpad.getViewHashFromKeys(secret.channel, secret.keys);
|
||||
obj.profile.edit = Utils.Hash.getEditHashFromKeys(secret.channel, secret.keys);
|
||||
obj.profile.view = Utils.Hash.getViewHashFromKeys(secret.channel, secret.keys);
|
||||
});
|
||||
return secret;
|
||||
};
|
||||
var addRpc = function (sframeChan, Cryptpad) {
|
||||
var addRpc = function (sframeChan, Cryptpad, Utils) {
|
||||
// Adding a new avatar from the profile: pin it and store it in the object
|
||||
sframeChan.on('Q_PROFILE_AVATAR_ADD', function (data, cb) {
|
||||
var chanId = Cryptpad.hrefToHexChannelId(data);
|
||||
var chanId = Utils.Hash.hrefToHexChannelId(data);
|
||||
Cryptpad.pinPads([chanId], function (e) {
|
||||
if (e) { return void cb(e); }
|
||||
Cryptpad.getProxy().profile.avatar = data;
|
||||
Cryptpad.whenRealtimeSyncs(Cryptpad.getRealtime(), function () {
|
||||
Utils.Realtime.whenRealtimeSyncs(Cryptpad.getRealtime(), function () {
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
// Removing the avatar from the profile: unpin it
|
||||
sframeChan.on('Q_PROFILE_AVATAR_REMOVE', function (data, cb) {
|
||||
var chanId = Cryptpad.hrefToHexChannelId(data);
|
||||
var chanId = Utils.Hash.hrefToHexChannelId(data);
|
||||
Cryptpad.unpinPads([chanId], function (e) {
|
||||
delete Cryptpad.getProxy().profile.avatar;
|
||||
cb(e);
|
||||
|
|
|
@ -5,9 +5,10 @@ define([
|
|||
'/common/test.js',
|
||||
'/common/credential.js', // preloaded for login.js
|
||||
'/common/common-interface.js',
|
||||
'/common/common-util.js',
|
||||
|
||||
'less!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||
], function ($, Login, Cryptpad, Test, Cred, UI) {
|
||||
], function ($, Login, Cryptpad, Test, Cred, UI, Util) {
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
||||
$(function () {
|
||||
|
@ -215,7 +216,7 @@ define([
|
|||
}, 150);
|
||||
});
|
||||
|
||||
var clickRegister = Cryptpad.notAgainForAnother(function () {
|
||||
var clickRegister = Util.notAgainForAnother(function () {
|
||||
$register.click();
|
||||
}, 500);
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ define([
|
|||
'/bower_components/nthen/index.js',
|
||||
'/common/sframe-common.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/customize/messages.js',
|
||||
|
||||
'/bower_components/file-saver/FileSaver.min.js',
|
||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||
|
@ -16,17 +19,16 @@ define([
|
|||
Cryptpad,
|
||||
nThen,
|
||||
SFCommon,
|
||||
UI
|
||||
UI,
|
||||
Util,
|
||||
Hash,
|
||||
Messages
|
||||
)
|
||||
{
|
||||
var saveAs = window.saveAs;
|
||||
var Messages = Cryptpad.Messages;
|
||||
var APP = window.APP = {
|
||||
Cryptpad: Cryptpad,
|
||||
};
|
||||
var onConnectError = function () {
|
||||
UI.errorLoadingScreen(Messages.websocketError);
|
||||
};
|
||||
|
||||
var common;
|
||||
var metadataMgr;
|
||||
|
@ -70,7 +72,7 @@ define([
|
|||
var publicKey = privateData.edPublic;
|
||||
if (publicKey) {
|
||||
var $key = $('<div>', {'class': 'cp-sidebarlayout-element'}).appendTo($div);
|
||||
var userHref = Cryptpad.getUserHrefFromKeys(accountName, publicKey);
|
||||
var userHref = Hash.getUserHrefFromKeys(accountName, publicKey);
|
||||
var $pubLabel = $('<span>', {'class': 'label'})
|
||||
.text(Messages.settings_publicSigningKey);
|
||||
$key.append($pubLabel).append(UI.dialog.selectable(userHref));
|
||||
|
@ -270,8 +272,8 @@ define([
|
|||
var sjson = JSON.stringify(data);
|
||||
var name = displayName || accountName || Messages.anonymous;
|
||||
var suggestion = name + '-' + new Date().toDateString();
|
||||
UI.prompt(Cryptpad.Messages.exportPrompt,
|
||||
Cryptpad.fixFileName(suggestion) + '.json', function (filename) {
|
||||
UI.prompt(Messages.exportPrompt,
|
||||
Util.fixFileName(suggestion) + '.json', function (filename) {
|
||||
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||
var blob = new Blob([sjson], {type: "application/json;charset=utf-8"});
|
||||
saveAs(blob, filename);
|
||||
|
@ -500,12 +502,6 @@ define([
|
|||
sframeChan = common.getSframeChannel();
|
||||
sframeChan.onReady(waitFor());
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
Cryptpad.onError(function (info) {
|
||||
if (info && info.type === "store") {
|
||||
onConnectError();
|
||||
}
|
||||
});
|
||||
|
||||
metadataMgr = common.getMetadataMgr();
|
||||
privateData = metadataMgr.getPrivateData();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ define([
|
|||
'/slide/slide.js',
|
||||
'/common/sframe-app-framework.js',
|
||||
'/common/common-util.js',
|
||||
'/common/common-hash.js',
|
||||
'/common/common-interface.js',
|
||||
'cm/lib/codemirror',
|
||||
|
||||
|
@ -49,6 +50,7 @@ define([
|
|||
Slide,
|
||||
Framework,
|
||||
Util,
|
||||
Hash,
|
||||
UI,
|
||||
CMeditor)
|
||||
{
|
||||
|
@ -438,8 +440,8 @@ define([
|
|||
//var cursor = editor.getCursor();
|
||||
//var cleanName = data.name.replace(/[\[\]]/g, '');
|
||||
//var text = '';
|
||||
var parsed = Cryptpad.parsePadUrl(data.url);
|
||||
var hexFileName = Cryptpad.base64ToHex(parsed.hashData.channel);
|
||||
var parsed = Hash.parsePadUrl(data.url);
|
||||
var hexFileName = Util.base64ToHex(parsed.hashData.channel);
|
||||
var src = '/blob/' + hexFileName.slice(0,2) + '/' + hexFileName;
|
||||
var mt = '<media-tag src="' + src + '" data-crypto-key="cryptpad:' + parsed.hashData.key + '"></media-tag>';
|
||||
editor.replaceSelection(mt);
|
||||
|
|
|
@ -7,6 +7,7 @@ define([
|
|||
'/bower_components/nthen/index.js',
|
||||
'/common/sframe-common.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-hash.js',
|
||||
'/todo/todo.js',
|
||||
|
||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||
|
@ -20,6 +21,7 @@ define([
|
|||
Cryptpad,
|
||||
nThen,
|
||||
SFCommon,
|
||||
Hash,
|
||||
UI,
|
||||
Todo
|
||||
)
|
||||
|
@ -165,7 +167,7 @@ define([
|
|||
"mtime": +new Date()
|
||||
};
|
||||
|
||||
var id = Cryptpad.createChannelId();
|
||||
var id = Hash.createChannelId();
|
||||
todo.add(id, obj);
|
||||
|
||||
$input.val("");
|
||||
|
|
|
@ -36,10 +36,10 @@ define([
|
|||
};
|
||||
window.addEventListener('message', onMsg);
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
var getSecrets = function (Cryptpad) {
|
||||
var getSecrets = function (Cryptpad, Utils) {
|
||||
var proxy = Cryptpad.getProxy();
|
||||
var hash = proxy.todo || Cryptpad.createRandomHash();
|
||||
return Cryptpad.getSecrets('todo', hash);
|
||||
var hash = proxy.todo || Utils.Hash.createRandomHash();
|
||||
return Utils.Hash.getSecrets('todo', hash);
|
||||
};
|
||||
SFCommonO.start({
|
||||
getSecrets: getSecrets,
|
||||
|
|
Loading…
Reference in New Issue