dev-util/idea-* minor fixes
[anomen-overlay.git] / www-apps / pmwiki / cookbook / AesCrypt / main.js
bloba4fb4801d53eba00c8ac825e673b64569fae6ad4
1 /**
2  * Aes encryption for PmWiki recipe AesCrypt
3  *
4  * Based on:
5  *   http://submodal.googlecode.com
6  *   http://www.pmwiki.org/wiki/Cookbook/DesCrypt
7  *   http://www.pmwiki.org/wiki/Cookbook/AesCrypt
8  *   http://the-stickman.com/web-development/javascript/finding-selection-cursor-position-in-a-textarea-in-internet-explorer/
9  *
10  *
11  */
13 var AesCrypt = {};
15 /**
16  * Mode of work. Either ['enc', before-selection, selection, after-selection] or ['dec',block_id];
17  */
18 AesCrypt.mode = null;
20 /**
21  * Title of dialog
22  */
23 AesCrypt.title = null;
25 /**
26  * is popup element created?
27  */
28 AesCrypt.popupDiv = false;
30 /**
31  * create hidden modal box for encryption
32  */
33 AesCrypt.createPopup = function ()
35     if (!AesCrypt.popupDiv) {
36         var popup =  '<div id=\'aescrypt_o\' class=\'aescrypt_overlay\'>' 
37                 + '<div>' 
38                 + '<img onclick=\'AesCrypt.hideDialog()\' width=\'24\' height=\'24\' title=\'close dialog\' alt=\'close dialog\' id=\'aescrypt_i\' src=\''+AesCrypt.PubDirUrl+'/close.png\' />'
39                 + '<p id=\'aescrypt_l\'>Enter password:</p>'
40                 + '<form id=\'aescrypt_f\' onsubmit=\'AesCrypt.overlaySubmit();return false;\'>'
41                 + '<span><input type=\'password\' name=\'aescrypt_p\' id=\'aescrypt_p\' onkeypress=\'AesCrypt.hidePass()\' />  '
42                 + '<img onmousedown=\'AesCrypt.showPass()\' style=\'vertical-align:bottom\' onmouseup=\'AesCrypt.hidePass()\' onmouseout=\'AesCrypt.hidePass()\' onmouseover=\'AesCrypt.hidePass()\'   width=\'24\' height=\'24\' alt=\'Show password\' title=\'Show password\' id=\'aescrypt_sp\' src=\''+AesCrypt.PubDirUrl+'/showpass.png\' />'
43                 + '</span><br />'
44                 + '<label title=\'All encrypted texts on this page will be decrypted.\' id=\'aescrypt_all\'><input type=\"checkbox\" name=\"aescrypt_allb\" id=\"aescrypt_allb\"  checked=\"checked\" value=\"true\" /> decrypt all</label>'
45                 + '<br />'
46                 + '<input type=\'submit\' />'
47                 + '</form>' + '</div>' + '</div>';
49             var theBody = document.getElementsByTagName('body')[0];
50             var popmask = document.createElement('div');
51             popmask.id = 'aescrypt_m';
52             var popcont = document.createElement('div');
53             popcont.id = 'aescrypt_x';
54             popcont.innerHTML = popup;
56             theBody.appendChild(popmask);
57             theBody.appendChild(popcont);
58         
59             AesCrypt.popupDiv = true;
60     }
63 /**
64  * Retrieve password and clear password box.
65  */
66 AesCrypt.getPassword = function ()
68     var pwel = document.getElementById('aescrypt_p');
69     var pw = pwel.value;
70     pwel.value = '';
71     return pw;
75 /**
76  * Display modal dialog.
77  */
78 AesCrypt.showDialog = function(label, decmode) 
80     document.getElementById('aescrypt_o').style.visibility = 'visible';
81     document.getElementById('aescrypt_m').style.visibility = 'visible';
82     document.getElementById('aescrypt_all').style.visibility = (decmode ? 'visible' : 'hidden');
83     document.getElementById('aescrypt_l').childNodes[0].nodeValue = label;
84     AesCrypt.title = label;
86     var pw = document.getElementById('aescrypt_p');
87     pw.focus();
88     pw.value = '';
89         
90     AesCrypt.addEvent(window, 'keyup', AesCrypt.onEscPress);
93 /**
94  * Hide modal dialog.
95  */
96 AesCrypt.hideDialog = function() 
98     document.getElementById('aescrypt_o').style.visibility = 'hidden';
99     document.getElementById('aescrypt_m').style.visibility = 'hidden';
100     document.getElementById('aescrypt_all').style.visibility = 'inherit';
101     document.getElementById('aescrypt_l').childNodes[0].nodeValue = 'Enter password:';
103     AesCrypt.removeEvent(window, 'keyup', AesCrypt.onEscPress, false);
107 AesCrypt.addEvent = function (obj, evType, fn)
109     if (obj.addEventListener){
110         obj.addEventListener(evType, fn, false);
111         return true;
112     } 
113     else if (obj.attachEvent) {
114         var r = obj.attachEvent('on'+evType, fn);
115         return r;
116     } else {
117         return false;
118     }
121 AesCrypt.removeEvent = function(obj, evType, fn, useCapture)
123     if (obj.removeEventListener){
124         obj.removeEventListener(evType, fn, useCapture);
125         return true;
126     } else if (obj.detachEvent){
127         var r = obj.detachEvent('on'+evType, fn);
128         return r;
129     } else {
130         alert('Handler could not be removed');
131     }
134 AesCrypt.onEscPress = function(e)
136     if (!e) e = event;
138     if (e.keyCode == 27) {
139         AesCrypt.hideDialog();
140     }
146  * display modal box for encryption
147  */
148 AesCrypt.encPopup = function()
150     AesCrypt.mode = AesCrypt.saveSelection();
152     //alert("selection: " + AesCrypt.mode);
153     
154     if (!AesCrypt.mode) {
155             alert('Please select text to encrypt');
156             return false;
157     }
159     AesCrypt.createPopup();
161     document.getElementById('aescrypt_p').value = '';
163     AesCrypt.showDialog("Encrypt selected text", false);
164     
168  * display modal box for decryption
169  */
170 AesCrypt.decPopup = function(id)
172     AesCrypt.mode = ['dec',id];
173     
174     AesCrypt.createPopup();
176     document.getElementById('aescrypt_p').value = '';
178     var c = document.getElementById('aescrypt_c_'+id).childNodes[0].nodeValue;
179     if (c.length > 20) {
180         c = c.substr(0,19) + "\u2026";
181     }
182     AesCrypt.showDialog("Decrypt " + c, true);
185 AesCrypt.showPass = function()
187     var pwel = document.getElementById('aescrypt_p');
188     var pw = pwel.value;
189     if (pw) {
190         document.getElementById('aescrypt_l').childNodes[0].nodeValue = "Password is: "+pw;
191     }
194 AesCrypt.hidePass = function()
196     if (AesCrypt.title) {
197         document.getElementById('aescrypt_l').childNodes[0].nodeValue = AesCrypt.title;
198     }
202 AesCrypt.overlaySubmit = function()
204     var pw = AesCrypt.getPassword();
206     AesCrypt.hideDialog();
208     if (!pw) {
209       alert("No password given!");
210       return;
211     }
212     
213     if (!AesCrypt.mode) {
214         alert('Nothing to do.');
215     } 
216     else if (AesCrypt.mode[0] == 'enc') {
217         AesCrypt.encSubmit(pw);
218     }
219     else if (AesCrypt.mode[0] == 'dec') {
220         AesCrypt.decSubmit(pw);
221     }
222     else {
223         alert('Unknown action: '+AesCrypt.mode[0]);
224     }
225     AesCrypt.mode = null;
229  * Function invoked on submit of password modal dialog.
230  * Performs decryption.
231  */
232 AesCrypt.decSubmit = function(password)
234     // decrypt all ?
235     var allEl = document.getElementById('aescrypt_allb');
237     var i = AesCrypt.mode[1];
238     var to = i;
239     if (allEl.checked) {
240         i = 1;
241         to = 10000; // just some big number
242     }
244     while (i <= to) {
245         var contentel = document.getElementById('aescrypt_c_'+i);
246         if (!contentel) {
247             break;
248         }
249         if (contentel.style.display == 'none') {
250             var cipher = contentel.childNodes[0].nodeValue;
251             var plain = AesCtr.decrypt(cipher,password,256);
252             if (plain.charAt(plain.length-1) != ' ') {
253                 alert ("Invalid password for cipher #"+i);
254             }
255             else {
256                 var plainTrim = plain.replace(/\s\s*$/, '');
257                 contentel.childNodes[0].nodeValue = plainTrim;
258                 contentel.style.display='block';
259                 var linkel = document.getElementById('aescrypt_a_'+i);
260                 if (!linkel) {
261                     alert("Cipher block not found: id="+i);
262                 } else {
263                     linkel.style.visibility='hidden';
264                     linkel.style.display='none';
265                 }
266             }
267         }
268         i++;
269     }
273   * Hide modal box and encrypt selection
274   */
275 AesCrypt.encSubmit = function(password) 
277     var tpart = AesCrypt.getSelection();
278     
279     var padding = AesCrypt.AesCryptPadding;
280     var tarr = AesCrypt.AesCryptCipherToken;
281     var markup_end = AesCrypt.AesCryptEndToken;
283     while ((tpart.length % padding) > 0) {
284         tpart = tpart.concat(' ');
285     }
286     tpart = tpart.concat(' ');
288     tarr +=AesCtr.encrypt(tpart, password, 256);
289     tarr += ' ';
290     tarr += markup_end;
292     AesCrypt.replaceSelection(tarr);
296  * Get selection to be encrypted (selection mode)
297  */
298 AesCrypt.saveSelection = function() 
300     var textarea = document.getElementById('text');
302     if (document.selection) { // IE variant
303         textarea.focus();
305         var range = document.selection.createRange();
306         var stored_range = range.duplicate();
307         stored_range.moveToElementText(textarea);
308         stored_range.setEndPoint( 'EndToEnd', range );
309         var start = stored_range.text.length - range.text.length;
310         var end = start + range.text.length;
312         var sel = textarea.value.substring(start, end);
313         var st = textarea.value.substring(0,start);
314         var et = textarea.value.substring(end);
315         return ['enc', st, sel, et];
316       
317     } else {
318         var start = textarea.selectionStart;
319         var end = textarea.selectionEnd;
320         if (start  < end) {
321             var sel = textarea.value.substring(start, end);
322             var st = textarea.value.substring(0,start);
323             var et = textarea.value.substring(end);
324             return ['enc',  st, sel, et];
325         }
326         else {
327             return null;
328         }
329     }
332 AesCrypt.getSelection = function()
334     return AesCrypt.mode[2];
337 AesCrypt.replaceSelection = function(replacement)
339     var textarea = document.getElementById('text');
340     var start = AesCrypt.mode[1];
341     var end = AesCrypt.mode[3];
342     textarea.value = start + replacement + end;