mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-06-01 14:14:06 +00:00
Refactor importing of encrypted TiddlyWiki files so that it works on Node.js
This commit is contained in:
parent
98edbec46d
commit
ed5cf8b044
@ -100,7 +100,7 @@ exports["text/html"] = function(text,fields) {
|
|||||||
var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi,
|
var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi,
|
||||||
match = storeAreaMarkerRegExp.exec(text);
|
match = storeAreaMarkerRegExp.exec(text);
|
||||||
if(match) {
|
if(match) {
|
||||||
// If so, it's either a classic TiddlyWiki file or a TW5 file
|
// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file
|
||||||
// First read the normal tiddlers
|
// First read the normal tiddlers
|
||||||
var results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);
|
var results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);
|
||||||
// Then any system tiddlers
|
// Then any system tiddlers
|
||||||
@ -111,8 +111,15 @@ exports["text/html"] = function(text,fields) {
|
|||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
} else {
|
} else {
|
||||||
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
|
// Check whether we've got an encrypted file
|
||||||
return deserializeHtmlFile(text,fields);
|
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
|
||||||
|
if(encryptedStoreArea) {
|
||||||
|
// If so, attempt to decrypt it using the current password
|
||||||
|
return $tw.utils.decryptStoreArea(encryptedStoreArea);
|
||||||
|
} else {
|
||||||
|
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
|
||||||
|
return deserializeHtmlFile(text,fields);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
80
core/modules/utils/crypto.js
Normal file
80
core/modules/utils/crypto.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/utils/crypto.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: utils
|
||||||
|
|
||||||
|
Utility functions related to crypto.
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Look for an encrypted store area in the text of a TiddlyWiki file
|
||||||
|
*/
|
||||||
|
exports.extractEncryptedStoreArea = function(text) {
|
||||||
|
var encryptedStoreAreaStartMarker = "<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">",
|
||||||
|
encryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker);
|
||||||
|
if(encryptedStoreAreaStart !== -1) {
|
||||||
|
var encryptedStoreAreaEnd = text.indexOf("</pre>",encryptedStoreAreaStart);
|
||||||
|
if(encryptedStoreAreaEnd !== -1) {
|
||||||
|
return $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Attempt to extract the tiddlers from an encrypted store area using the current password
|
||||||
|
*/
|
||||||
|
exports.decryptStoreArea = function(encryptedStoreArea) {
|
||||||
|
var decryptedText = $tw.crypto.decrypt(encryptedStoreArea);
|
||||||
|
if(decryptedText) {
|
||||||
|
var json = JSON.parse(decryptedText),
|
||||||
|
tiddlers = [];
|
||||||
|
for(var title in json) {
|
||||||
|
tiddlers.push(json[title]);
|
||||||
|
}
|
||||||
|
return tiddlers;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback) {
|
||||||
|
// Try to decrypt with the current password
|
||||||
|
var tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);
|
||||||
|
if(tiddlers) {
|
||||||
|
callback(tiddlers);
|
||||||
|
} else {
|
||||||
|
// Prompt for a new password and keep trying
|
||||||
|
$tw.passwordPrompt.createPrompt({
|
||||||
|
serviceName: "Enter a password to decrypt the imported TiddlyWiki",
|
||||||
|
noUserName: true,
|
||||||
|
canCancel: true,
|
||||||
|
submitText: "Decrypt",
|
||||||
|
callback: function(data) {
|
||||||
|
// Exit if the user cancelled
|
||||||
|
if(!data) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Attempt to decrypt the tiddlers
|
||||||
|
$tw.crypto.setPassword(data.password);
|
||||||
|
var tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);
|
||||||
|
if(tiddlers) {
|
||||||
|
callback(tiddlers);
|
||||||
|
// Exit and remove the password prompt
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// We didn't decrypt everything, so continue to prompt for password
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
@ -1083,56 +1083,14 @@ exports.readFile = function(file,callback) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check whether this is an encrypted TiddlyWiki file
|
// Check whether this is an encrypted TiddlyWiki file
|
||||||
var encryptedStoreAreaStartMarker = "<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">",
|
var encryptedJson = $tw.utils.extractEncryptedStoreArea(text);
|
||||||
encryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker),
|
if(encryptedJson) {
|
||||||
encryptedStoreAreaEnd = encryptedStoreAreaStart !== -1 ? text.indexOf("</pre>",encryptedStoreAreaStart) : -1;
|
// If so, attempt to decrypt it with the current password
|
||||||
if(encryptedStoreAreaStart !== -1 && encryptedStoreAreaEnd !== -1) {
|
$tw.utils.decryptStoreAreaInteractive(encryptedJson,function(tiddlers) {
|
||||||
var encryptedJson = $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1)),
|
|
||||||
attemptDecryption = function() {
|
|
||||||
var decryptedText = $tw.crypto.decrypt(encryptedJson);
|
|
||||||
if(decryptedText) {
|
|
||||||
var json = JSON.parse(decryptedText),
|
|
||||||
tiddlers = [];
|
|
||||||
for(var title in json) {
|
|
||||||
tiddlers.push(json[title]);
|
|
||||||
}
|
|
||||||
return tiddlers;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Try to decrypt with the current password
|
|
||||||
var tiddlers = attemptDecryption();
|
|
||||||
if(tiddlers) {
|
|
||||||
callback(tiddlers);
|
callback(tiddlers);
|
||||||
} else {
|
});
|
||||||
// Prompt for a new password and keep trying
|
|
||||||
$tw.passwordPrompt.createPrompt({
|
|
||||||
serviceName: "Enter a password to decrypt the imported TiddlyWiki",
|
|
||||||
noUserName: true,
|
|
||||||
canCancel: true,
|
|
||||||
submitText: "Decrypt",
|
|
||||||
callback: function(data) {
|
|
||||||
// Exit if the user cancelled
|
|
||||||
if(!data) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Attempt to decrypt the tiddlers
|
|
||||||
$tw.crypto.setPassword(data.password);
|
|
||||||
var tiddlers = attemptDecryption();
|
|
||||||
if(tiddlers) {
|
|
||||||
callback(tiddlers);
|
|
||||||
// Exit and remove the password prompt
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// We didn't decrypt everything, so continue to prompt for password
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Try to deserialise any tiddlers in the file
|
// Otherwise, just try to deserialise any tiddlers in the file
|
||||||
callback(self.deserializeTiddlers(type,text,tiddlerFields));
|
callback(self.deserializeTiddlers(type,text,tiddlerFields));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user