webinstaller.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * phpMeccano v0.2.0. Web-framework written with php programming language. Component of the web installer.
  3. * Copyright (C) 2015-2019 Alexei Muzarov
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. * e-mail: azexmail@gmail.com
  20. * e-mail: azexmail@mail.ru
  21. * https://bitbucket.org/azexmail/phpmeccano
  22. */
  23. "use strict";
  24. var WebInstaller = {};
  25. WebInstaller.enableSubmitByConf = 0;
  26. WebInstaller.enableSubmitByUser = 0;
  27. WebInstaller.stopValidating = 0;
  28. WebInstaller.isError = 0;
  29. WebInstaller.currentLanguage = "";
  30. WebInstaller.inputConfirm = { // important parameters of the form
  31. "groupname" : false,
  32. "username" : false,
  33. "passw" : false,
  34. "repassw" : false,
  35. "email" : false
  36. };
  37. WebInstaller.rid = Math.random(); // identifier to accept remove installer after framework was installed
  38. WebInstaller.xhrObject = function() { // XMLHttpRequest object
  39. var request;
  40. try {
  41. request = new ActiveXObject("Msxml2.XMLHTTP");
  42. }
  43. catch (e) {
  44. try {
  45. request = new ActiveXObject("Microsoft.XMLHTTP");
  46. }
  47. catch (E) {
  48. request = false;
  49. }
  50. }
  51. if (!request && typeof XMLHttpRequest!=='undefined') {
  52. request = new XMLHttpRequest();
  53. }
  54. return request;
  55. } ;
  56. WebInstaller.sendRequest = function(dataURL, execFunc) { // request file for AJAX
  57. var request = WebInstaller.xhrObject();
  58. request.open('GET', dataURL, true);
  59. request.onreadystatechange = function() {
  60. if (request.readyState === 4) {
  61. if (request.status === 200) {
  62. if (!WebInstaller.stopValidating && WebInstaller.isError) {
  63. WebInstaller.hideError();
  64. }
  65. var response = request.responseText;
  66. execFunc(response);
  67. }
  68. else {
  69. WebInstaller.showError("Location: " + dataURL + " | " + "Status code: " + request.status);
  70. window.setTimeout("WebInstaller.sendRequest('"+ dataURL +"', " + execFunc + ")", 5000);
  71. }
  72. }
  73. } ;
  74. request.send(null);
  75. } ;
  76. WebInstaller.submitForm = function (dataURL, form, execFunc) { // submit form with parameters
  77. var sendData = "";
  78. var elements = form.elements;
  79. var request = WebInstaller.xhrObject();
  80. request.open("POST", dataURL, true);
  81. request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  82. for (var i = 0; i < elements.length; i++) {
  83. sendData += encodeURIComponent(elements[i].name) + "=" + encodeURIComponent(elements[i].value) + "&";
  84. }
  85. sendData = sendData.substring(0, (sendData.length - 1));
  86. request.onreadystatechange = function() {
  87. if (request.readyState === 4) {
  88. if (request.status === 200) {
  89. var response = request.responseText;
  90. execFunc(response);
  91. }
  92. else {
  93. WebInstaller.showError("Location: " + dataURL + " | " + "Status code: " + request.status);
  94. }
  95. }
  96. }
  97. request.send(sendData);
  98. } ;
  99. WebInstaller.validateConf = function(respData) { // validation of conf.php
  100. if (!WebInstaller.stopValidating) {
  101. var i, key, span;
  102. try {
  103. var respJSON = JSON.parse(respData);
  104. var respKeys = Object.keys(respJSON);
  105. var doEnabled = 1;
  106. for (i = 0; i < respKeys.length; ++i) {
  107. key = respKeys[i];
  108. span = document.getElementById(key);
  109. if (respJSON[key][0]) {
  110. span.setAttribute("class", "true");
  111. }
  112. else {
  113. span.setAttribute("class", "false");
  114. doEnabled = 0;
  115. }
  116. span.innerHTML = respJSON[key][1];
  117. }
  118. WebInstaller.enableSubmitByConf = doEnabled;
  119. WebInstaller.enableSubmit();
  120. }
  121. catch (e) {
  122. WebInstaller.showError("validateConf: " + e);
  123. }
  124. finally {
  125. window.setTimeout("WebInstaller.sendRequest('valconf.php?' + Math.random(), WebInstaller.validateConf)", 2000);
  126. }
  127. }
  128. } ;
  129. WebInstaller.showLanguages = function(respData) { // show menu with available languages
  130. try {
  131. var i, key, languages;
  132. var respJSON = JSON.parse(respData);
  133. var respKeys = Object.keys(respJSON);
  134. var languages = document.getElementById("languages");
  135. languages.innerHTML = "";
  136. for (i = 0; i < respKeys.length; ++i) {
  137. key = respKeys[i];
  138. if (WebInstaller.currentLanguage != key) {
  139. var langButton = document.createElement("span");
  140. langButton.setAttribute("class", "lang");
  141. langButton.setAttribute("onClick", "WebInstaller.requireLanguage('" + key + "')");
  142. langButton.innerHTML = respJSON[key];
  143. languages.appendChild(langButton);
  144. }
  145. }
  146. }
  147. catch (e) {
  148. WebInstaller.showError("showLanguages: " + e);
  149. }
  150. } ;
  151. WebInstaller.requireLanguage = function(code) { // require titles at selected language from the server
  152. var languages = document.getElementById("languages");
  153. languages.innerHTML = '<iframe style="border: none;" src="svg/load-lang.svg" width="60" height="35"></iframe>';
  154. WebInstaller.currentLanguage = code;
  155. setTimeout("WebInstaller.sendRequest('lang/" + code + ".json?' + Math.random(), WebInstaller.loadLanguage)", 500);
  156. } ;
  157. WebInstaller.loadLanguage = function(respData) { // load the got titles of ui
  158. try {
  159. var i, key, uiElement;
  160. var respJSON = JSON.parse(respData);
  161. var respKeys = Object.keys(respJSON);
  162. for (i = 0; i < respKeys.length; ++i) {
  163. key = respKeys[i];
  164. if (key === "metadata") { // language properties
  165. uiElement = document.getElementById("main");
  166. uiElement.setAttribute("dir", respJSON[key]["dir"]);
  167. uiElement = document.getElementsByTagName("html")[0];
  168. uiElement.setAttribute("lang", respJSON[key]["code"]);
  169. }
  170. else if (key === "runinst") { // run installation button
  171. uiElement = document.getElementById(key);
  172. uiElement.setAttribute("value", respJSON[key]);
  173. }
  174. else { // other ui elements
  175. uiElement = document.getElementById(key);
  176. uiElement.innerHTML = respJSON[key];
  177. }
  178. }
  179. WebInstaller.sendRequest('langlist.php?' + Math.random(), WebInstaller.showLanguages);
  180. }
  181. catch (e) {
  182. WebInstaller.showError("loadLanguage: " + e);
  183. }
  184. } ;
  185. WebInstaller.validateForm = function() { // validation of required parameters of the form
  186. var i, key;
  187. var doEnabled = 1;
  188. var formKeys = ["groupname", "username", "passw", "repassw", "email"];
  189. for (i = 0; i < formKeys.length; ++i) {
  190. key = formKeys[i];
  191. if (!WebInstaller.inputConfirm[key]) {
  192. doEnabled = 0;
  193. }
  194. }
  195. WebInstaller.enableSubmitByUser = doEnabled;
  196. WebInstaller.enableSubmit();
  197. } ;
  198. WebInstaller.enableSubmit = function() { // enable/disable management of submit button
  199. var submit = document.forms.userconf.elements.submit;
  200. if (WebInstaller.enableSubmitByConf && WebInstaller.enableSubmitByUser && !WebInstaller.isError) {
  201. submit.removeAttribute("disabled");
  202. }
  203. else {
  204. submit.setAttribute("disabled", "");
  205. }
  206. } ;
  207. WebInstaller.showMeForm = function(respData) { // show a form to fill
  208. WebInstaller.validateConf(respData);
  209. document.getElementById("progress").setAttribute("class", "hidden");
  210. document.getElementById("loading").setAttribute("class", "hidden");
  211. document.getElementById("settings").removeAttribute("class");
  212. } ;
  213. WebInstaller.pregGroupName = function(value) { //check group name field
  214. var regEx = /^.{1,50}$/;
  215. if(regEx.test(document.forms.userconf.elements.groupname.value) && document.forms.userconf.elements.groupname.value.replace(/[\s\n\r\t]+/, "")) {
  216. WebInstaller.inputConfirm.groupname = true;
  217. document.forms.userconf.elements.groupname.setAttribute("class", "true");
  218. }
  219. else {
  220. document.forms.userconf.elements.groupname.setAttribute("class", "false");
  221. WebInstaller.inputConfirm.groupname = false;
  222. }
  223. WebInstaller.validateForm();
  224. } ;
  225. WebInstaller.pregUserName = function(value) { // check username field
  226. var regEx = /^[a-zA-Z\d]{3,20}$/;
  227. if(regEx.test(document.forms.userconf.elements.username.value)) {
  228. document.forms.userconf.elements.username.setAttribute("class", "true");
  229. WebInstaller.inputConfirm.username = true;
  230. }
  231. else {
  232. document.forms.userconf.elements.username.setAttribute("class", "false");
  233. WebInstaller.inputConfirm.username = false;
  234. }
  235. WebInstaller.validateForm();
  236. } ;
  237. WebInstaller.pregPassw = function(value) { // check 1st password field
  238. var regEx = /^[-+=_a-zA-Z\d@.,?!;:"'~`|#№*$%&^\][(){}<>\/\\]{8,50}$/;
  239. if(regEx.test(document.forms.userconf.elements.passw.value)) {
  240. document.forms.userconf.elements.passw.setAttribute("class", "true");
  241. WebInstaller.inputConfirm.passw = true;
  242. }
  243. else {
  244. document.forms.userconf.elements.passw.setAttribute("class", "false");
  245. WebInstaller.inputConfirm.passw = false;
  246. }
  247. WebInstaller.pregRePassw(value);
  248. } ;
  249. WebInstaller.pregRePassw = function(value) { // check 2nd password field
  250. var regEx = /^[-+=_a-zA-Z\d@.,?!;:"'~`|#№*$%&^\][(){}<>\/\\]{8,50}$/;
  251. if(regEx.test(document.forms.userconf.elements.repassw.value) && (document.forms.userconf.elements.passw.value === document.forms.userconf.elements.repassw.value)) {
  252. document.forms.userconf.elements.repassw.setAttribute("class", "true");
  253. WebInstaller.inputConfirm.repassw = true;
  254. }
  255. else {
  256. document.forms.userconf.elements.repassw.setAttribute("class", "false");
  257. WebInstaller.inputConfirm.repassw = false;
  258. }
  259. WebInstaller.validateForm();
  260. } ;
  261. WebInstaller.pregMail = function(value) { // check e-mail field
  262. // regex from Blink engine
  263. // https://chromium.googlesource.com/chromium/blink/+/master/Source/core/html/forms/EmailInputType.cpp
  264. // line 48
  265. var regEx = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/;
  266. if(regEx.test(document.forms.userconf.elements.email.value)) {
  267. document.forms.userconf.elements.email.setAttribute("class", "true");
  268. WebInstaller.inputConfirm.email = true;
  269. }
  270. else {
  271. document.forms.userconf.elements.email.setAttribute("class", "false");
  272. WebInstaller.inputConfirm.email = false;
  273. }
  274. WebInstaller.validateForm();
  275. } ;
  276. WebInstaller.pregControl = function(value) { // check mControl switcher
  277. if (document.forms.userconf.elements.mcontrol.checked) {
  278. document.forms.userconf.elements.mcontrol.value = "true";
  279. }
  280. else {
  281. document.forms.userconf.elements.mcontrol.value = "false";
  282. }
  283. };
  284. WebInstaller.errorGears = function() { // manage gears animation when error is raised while framework installation process
  285. if (window.gears.stepAngle > 0) {
  286. window.gears.stepAngle = -1;
  287. }
  288. else {
  289. window.gears.stepAngle = 1;
  290. }
  291. window.setTimeout("WebInstaller.errorGears()", 500);
  292. } ;
  293. WebInstaller.makeInstall = function(respData) { // management of framework installation
  294. try {
  295. var respJSON = JSON.parse(respData);
  296. if (!respJSON["response"]) {
  297. if (typeof respJSON["response"] === "boolean") {
  298. WebInstaller.errorGears();
  299. }
  300. WebInstaller.showError(respJSON["error"]);
  301. }
  302. else {
  303. WebInstaller.stopValidating = 1;
  304. switch (respJSON["response"]) {
  305. case 1: // create all needed tables
  306. document.getElementById("instprogress").removeAttribute("class");
  307. document.getElementById("creatingdb").removeAttribute("class");
  308. document.getElementById("settings").setAttribute("class", "hidden");
  309. document.getElementById("progress").setAttribute("class", "center");
  310. window.setTimeout("WebInstaller.submitForm('makeinstall.php?' + Math.random(), document.forms.userconf, WebInstaller.makeInstall)", 500);
  311. break;
  312. case 2: // install phpMeccano package
  313. window.gears.stepAngle = 4;
  314. document.getElementById("creatingdb").setAttribute("class", "true");
  315. document.getElementById("instpack").removeAttribute("class");
  316. window.setTimeout("WebInstaller.submitForm('makeinstall.php?' + Math.random(), document.forms.userconf, WebInstaller.makeInstall)", 500);
  317. break;
  318. case 3: // create root group and user
  319. window.gears.stepAngle = 12;
  320. document.getElementById("instpack").setAttribute("class", "true");
  321. document.getElementById("creatingroot").removeAttribute("class");
  322. window.setTimeout("WebInstaller.submitForm('makeinstall.php?' + Math.random(), document.forms.userconf, WebInstaller.makeInstall)", 500);
  323. break;
  324. case 4: // install mControl package
  325. window.gears.stepAngle = 15;
  326. document.getElementById("creatingroot").setAttribute("class", "true");
  327. document.getElementById("instmcontrol").removeAttribute("class");
  328. window.setTimeout("WebInstaller.submitForm('makeinstall.php?' + Math.random(), document.forms.userconf, WebInstaller.makeInstall)", 500);
  329. break;
  330. case 5: // finished installation
  331. window.gears.stepAngle = 19;
  332. if (!document.getElementById("instmcontrol").getAttribute("class")) { // in case if mControl is supposed to be installed
  333. document.getElementById("instmcontrol").setAttribute("class", "true");
  334. }
  335. else {// in case if mControl isn't supposed to be installed
  336. document.getElementById("creatingroot").setAttribute("class", "true");
  337. }
  338. document.getElementById("instprogress").setAttribute("class", "hidden");
  339. document.getElementById("completed").removeAttribute("class");
  340. document.getElementById("selfremove").setAttribute("class", "center false");
  341. WebInstaller.rid = respJSON["rid"];
  342. break;
  343. }
  344. }
  345. }
  346. catch (e) {
  347. WebInstaller.showError("makeInstall: " + e);
  348. }
  349. } ;
  350. WebInstaller.selfRemove = function(value) { // request to remove web installer
  351. document.getElementById("trash").setAttribute("class", "hidden");
  352. document.getElementById("waitgear").removeAttribute("class");
  353. window.setTimeout('WebInstaller.sendRequest("selfremove.php?rid=" + WebInstaller.rid + Math.random(), WebInstaller.selfRemoved)', 2000);
  354. } ;
  355. WebInstaller.selfRemoved = function(respData) { // answer about whether web installer was removed
  356. try {
  357. var respJSON = JSON.parse(respData);
  358. if (respJSON["response"]) {
  359. document.getElementById("selfremove").setAttribute("class", "hidden");
  360. document.getElementById("removed").setAttribute("class", "center true");
  361. }
  362. else {
  363. WebInstaller.showError(respJSON["error"]);
  364. }
  365. }
  366. catch (e) {
  367. WebInstaller.showError("selfRemoved: " + e);
  368. }
  369. } ;
  370. WebInstaller.showError = function(errorText) { // show a message about error
  371. var error = document.getElementById("errormsg");
  372. var errexp = document.getElementById("errexp");
  373. errexp.innerHTML = errorText;
  374. error.setAttribute("class", "center");
  375. WebInstaller.isError = 1;
  376. WebInstaller.enableSubmit();
  377. } ;
  378. WebInstaller.hideError = function() { // hide a message about error
  379. var error = document.getElementById("errormsg");
  380. error.setAttribute("class", "hidden");
  381. WebInstaller.isError = 0;
  382. } ;