From db3a4651a2617cc44fe3af092b48ddbe1f8255cf Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Fri, 16 Nov 2012 16:59:47 +0000 Subject: [PATCH] Improved crypto and password prompting mechanism Now encrypted tiddlywikis prompt for their password with an html form, instead of a horrible javascript prompt. --- core/boot.js | 278 +++++++++++++----- core/styles/tiddlywiki.css | 31 ++ .../tiddlywiki5.encrypted.template.html.tid | 7 +- cssbuild/tiddlywiki.less | 30 ++ 4 files changed, 266 insertions(+), 80 deletions(-) diff --git a/core/boot.js b/core/boot.js index 9b3ee6e02..6a7d7a59b 100644 --- a/core/boot.js +++ b/core/boot.js @@ -39,43 +39,6 @@ if(!$tw.browser) { require("./bootprefix.js"); } -// Crypto helper object - -// Setup crypto -var Crypto = function() { - var password = null, - callSjcl = function(method,inputText) { - var outputText; - if(!password) { - getPassword(); - } - try { - outputText = $tw.crypto.sjcl[method](password,inputText); - } catch(ex) { - console.log("Crypto error:" + ex); - outputText = null; - } - return outputText; - }, - getPassword = function() { - if($tw.browser) { - password = window.prompt("Enter password to decrypt TiddlyWiki"); - } - }; - this.setPassword = function(newPassword) { - password = newPassword; - }; - this.encrypt = function(text) { - return callSjcl("encrypt",text); - }; - this.decrypt = function(text) { - return callSjcl("decrypt",text); - }; -}; -$tw.crypto = new Crypto(); - -$tw.crypto.sjcl = $tw.browser ? window.sjcl : require("./sjcl.js"); - // Boot information $tw.boot = {}; @@ -275,6 +238,106 @@ $tw.utils.checkVersions = function(required,actual) { (diff[0] === 0 && diff[1] === 0 && diff[2] > 0); }; +/* +Creates a PasswordPrompt object +*/ +$tw.utils.PasswordPrompt = function() { + // Store of pending password prompts + this.passwordPrompts = []; + // Create the wrapper + this.promptWrapper = document.createElement("div"); + this.promptWrapper.className = "tw-password-wrapper"; + document.body.appendChild(this.promptWrapper); + // Hide the empty wrapper + this.setWrapperDisplay(); +}; + +/* +Hides or shows the wrapper depending on whether there are any outstanding prompts +*/ +$tw.utils.PasswordPrompt.prototype.setWrapperDisplay = function() { + if(this.passwordPrompts.length) { + this.promptWrapper.style.display = "block"; + } else { + this.promptWrapper.style.display = "none"; + } +}; + +/* +Adds a new password prompt +*/ +$tw.utils.PasswordPrompt.prototype.createPrompt = function(options) { + // Create and add the prompt to the DOM + var form = document.createElement("form"), + html = ["

" + options.serviceName + "

"]; + if(!options.noUserName) { + html.push(""); + } + html.push("", + ""); + form.className = "form-inline"; + form.innerHTML = html.join("\n"); + this.promptWrapper.appendChild(form); + // Add a submit event handler + var self = this; + form.addEventListener("submit",function(event) { + // Collect the form data + var data = {}; + for(var t=0; t=0; t--) { + var decrypted = $tw.crypto.decrypt(encryptedTiddlers[t]); + if(decrypted) { + var json = JSON.parse(decrypted); + for(var title in json) { + if($tw.utils.hop(json,title)) { + $tw.preloadTiddler(json[title]); + } + } + encryptedTiddlers.splice(t,1); + } + } + // Check if we're all done + if(encryptedTiddlers.length === 0) { + // Continue startup + $tw.boot.startup(); + // Exit and remove the password prompt + return true; + } else { + // We didn't decrypt everything, so continue to prompt for password + return false; + } + } + }); +} else { + $tw.boot.startup(); +} })(); diff --git a/core/styles/tiddlywiki.css b/core/styles/tiddlywiki.css index cf32d2a89..655d60133 100644 --- a/core/styles/tiddlywiki.css +++ b/core/styles/tiddlywiki.css @@ -5918,6 +5918,37 @@ body { padding-top: 40px; } +/* +Password prompts +*/ + +.tw-password-wrapper { + position: fixed; + top: 1em; + left: 50%; + z-index: 20000; + width: 480px; + padding: 16px 16px 16px 16px; + margin-left: -264px; + color: #000; + text-align: center; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #c5ebb7; + border: 8px solid #a4c598; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + border-radius: 8px; +} + +.tw-password-wrapper form { + text-align: left; +} + +.tw-password-wrapper h1 { + font-size: 16px; + line-height: 20px; +} + /* Tweaks for full screen mode */ diff --git a/core/templates/tiddlywiki5.encrypted.template.html.tid b/core/templates/tiddlywiki5.encrypted.template.html.tid index c28bcae5b..899e4ad91 100644 --- a/core/templates/tiddlywiki5.encrypted.template.html.tid +++ b/core/templates/tiddlywiki5.encrypted.template.html.tid @@ -31,12 +31,9 @@ type: text/x-tiddlywiki-html <> - -