Remove util and hash from common
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user