a6c5646bb66e95e96e644157914ba5ac8255bfce
[Packages/TYPO3.CMS.git] / typo3 / sysext / rsaauth / Resources / Public / JavaScript / RsaEncryptionModule.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Rsaauth/RsaEncryptionModule
16 * Object that handles RSA encryption and submission of the form
17 */
18 define(['jquery', './RsaLibrary'], function($) {
19 'use strict';
20
21 /**
22 * @type {{$currentForm: null, fetchedRsaKey: boolean, initialize: Function, registerForm: Function, handleFormSubmitRequest: Function, handlePublicKeyResponse: Function}}
23 * @exports TYPO3/CMS/Rsaauth/RsaEncryptionModule
24 */
25 var RsaEncryption = {
26
27 /**
28 * Remember the form which was submitted
29 */
30 $currentForm: null,
31
32 /**
33 * Remember if we fetched the RSA key already
34 */
35 fetchedRsaKey: false,
36
37 /**
38 * Replace event handler of submit button for given form
39 *
40 * @param {Form} form Form DOM object
41 */
42 registerForm: function(form) {
43 var $form = $(form);
44
45 // Store the original submit handler that is executed later
46 $form.data('original-onsubmit', $form.attr('onsubmit'));
47
48 // Remove the original submit handler and register RsaEncryption.handleFormSubmitRequest instead
49 $form.removeAttr('onsubmit').on('submit', RsaEncryption.handleFormSubmitRequest);
50
51 // Bind submit event first (this is a dirty hack with jquery internals, but there is no way around that)
52 var handlers = $._data(form, 'events').submit;
53 var handler = handlers.pop();
54 handlers.unshift(handler);
55 },
56
57 /**
58 * Fetches a new public key by Ajax and encrypts the password for transmission
59 *
60 * @param {Event} event
61 */
62 handleFormSubmitRequest: function(event) {
63 if (!RsaEncryption.fetchedRsaKey) {
64 event.stopImmediatePropagation();
65
66 RsaEncryption.fetchedRsaKey = true;
67 RsaEncryption.$currentForm = $(this);
68
69 $.ajax({
70 url: TYPO3.settings.ajaxUrls['rsa_publickey'],
71 data: {'skipSessionUpdate': 1},
72 success: RsaEncryption.handlePublicKeyResponse
73 });
74
75 return false;
76 } else {
77 // we come here again when the submit is triggered below
78 // reset the variable to fetch a new key for next attempt
79 RsaEncryption.fetchedRsaKey = false;
80 }
81 },
82
83 /**
84 * Parses the Json response and triggers submission of the form
85 *
86 * @param {Object} response Ajax response object
87 */
88 handlePublicKeyResponse: function(response) {
89 var publicKey = response.split(':');
90 if (!publicKey[0] || !publicKey[1]) {
91 alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.');
92 return;
93 }
94
95 var rsa = new RSAKey();
96 rsa.setPublic(publicKey[0], publicKey[1]);
97 RsaEncryption.$currentForm.find(':input[data-rsa-encryption]').each(function() {
98 var $this = $(this);
99 var encryptedValue = rsa.encrypt($this.val());
100 var dataAttribute = $this.data('rsa-encryption');
101 var rsaValue = 'rsa:' + hex2b64(encryptedValue);
102
103 if (!dataAttribute) {
104 $this.val(rsaValue);
105 } else {
106 var $typo3Field = $('#' + dataAttribute);
107 $typo3Field.val(rsaValue);
108 // Reset user password field to prevent it from being submitted
109 $this.val('');
110 }
111 });
112
113 // Try to fetch the field which submitted the form
114 var $currentField = RsaEncryption.$currentForm.find('input[type=submit]:focus,input[type=image]:focus');
115 if ($currentField.length === 1) {
116 $currentField.trigger('click');
117 } else {
118 // Create a hidden input field to fake pressing the submit button
119 RsaEncryption.$currentForm.append('<input type="hidden" name="commandLI" value="Submit">');
120
121 // Restore the original submit handler
122 var originalOnSubmit = RsaEncryption.$currentForm.data('original-onsubmit');
123 if (typeof originalOnSubmit === 'string' && originalOnSubmit.length > 0) {
124 RsaEncryption.$currentForm.attr('onsubmit', originalOnSubmit);
125 RsaEncryption.$currentForm.removeData('original-onsubmit');
126 }
127
128 // Submit the form
129 RsaEncryption.$currentForm.trigger('submit');
130 }
131 }
132 };
133
134 /**
135 * Search for forms and add event handler
136 */
137 RsaEncryption.initialize = function() {
138 $(':input[data-rsa-encryption]').closest('form').each(function() {
139 RsaEncryption.registerForm(this);
140 });
141 rng_seed_time();
142 };
143
144 $(RsaEncryption.initialize);
145
146 return RsaEncryption;
147 });