a814e644b1be3ec22906047ee5ae958f2e98ee90
[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 if ($form.data('rsaRegistered')) {
46 // Do not register form twice
47 return;
48 }
49 // Mark form as registered
50 $form.data('rsaRegistered', true);
51
52 // Store the original submit handler that is executed later
53 $form.data('original-onsubmit', $form.attr('onsubmit'));
54
55 // Remove the original submit handler and register RsaEncryption.handleFormSubmitRequest instead
56 $form.removeAttr('onsubmit').on('submit', RsaEncryption.handleFormSubmitRequest);
57
58 // Bind submit event first (this is a dirty hack with jquery internals, but there is no way around that)
59 var handlers = $._data(form, 'events').submit;
60 var handler = handlers.pop();
61 handlers.unshift(handler);
62 },
63
64 /**
65 * Fetches a new public key by Ajax and encrypts the password for transmission
66 *
67 * @param {Event} event
68 */
69 handleFormSubmitRequest: function(event) {
70 if (!RsaEncryption.fetchedRsaKey) {
71 event.stopImmediatePropagation();
72
73 RsaEncryption.fetchedRsaKey = true;
74 RsaEncryption.$currentForm = $(this);
75
76 $.ajax({
77 url: TYPO3.settings.ajaxUrls['rsa_publickey'],
78 success: RsaEncryption.handlePublicKeyResponse
79 });
80
81 return false;
82 } else {
83 // we come here again when the submit is triggered below
84 // reset the variable to fetch a new key for next attempt
85 RsaEncryption.fetchedRsaKey = false;
86 }
87 },
88
89 /**
90 * Parses the Json response and triggers submission of the form
91 *
92 * @param {Object} response Ajax response object
93 */
94 handlePublicKeyResponse: function(response) {
95 var publicKey = response.split(':');
96 if (!publicKey[0] || !publicKey[1]) {
97 alert('No public key could be generated. Please inform your TYPO3 administrator to check the OpenSSL settings.');
98 return;
99 }
100
101 var rsa = new RSAKey();
102 rsa.setPublic(publicKey[0], publicKey[1]);
103 RsaEncryption.$currentForm.find(':input[data-rsa-encryption]').each(function() {
104 var $this = $(this);
105 var encryptedValue = rsa.encrypt($this.val());
106 var dataAttribute = $this.data('rsa-encryption');
107 var rsaValue = 'rsa:' + hex2b64(encryptedValue);
108
109 if (!dataAttribute) {
110 $this.val(rsaValue);
111 } else {
112 var $typo3Field = $('#' + dataAttribute);
113 $typo3Field.val(rsaValue);
114 // Reset user password field to prevent it from being submitted
115 $this.val('');
116 }
117 });
118
119 // Try to fetch the field which submitted the form
120 var $currentField = RsaEncryption.$currentForm.find('input[type=submit]:focus,input[type=image]:focus,button:focus');
121 if ($currentField.length === 1) {
122 RsaEncryption.$currentForm.trigger('submit');
123 } else {
124 // Create a hidden input field to fake pressing the submit button
125 var name = 'commandLI',
126 value = 'Submit';
127 var $submitField = RsaEncryption.$currentForm.find('input[type=submit],input[type=image],input[type=button],button[name][type=submit]').first();
128 if ($submitField.length === 1) {
129 name = $submitField.attr('name') || name;
130 value = $submitField.attr('value') || value ;
131 }
132 var $hiddenField = $('<input type="hidden">')
133 .attr('name', name)
134 .val(value);
135 RsaEncryption.$currentForm.append($hiddenField);
136
137 // Restore the original submit handler
138 var originalOnSubmit = RsaEncryption.$currentForm.data('original-onsubmit');
139 if (typeof originalOnSubmit === 'string' && originalOnSubmit.length > 0) {
140 RsaEncryption.$currentForm.attr('onsubmit', originalOnSubmit);
141 RsaEncryption.$currentForm.removeData('original-onsubmit');
142 }
143
144 // Submit the form
145 RsaEncryption.$currentForm.trigger('submit');
146 }
147 }
148 };
149
150 /**
151 * Search for forms and add event handler
152 */
153 RsaEncryption.initialize = function() {
154 $(':input[data-rsa-encryption]').closest('form').each(function() {
155 RsaEncryption.registerForm(this);
156 });
157 rng_seed_time();
158 };
159
160 $(RsaEncryption.initialize);
161
162 return RsaEncryption;
163 });