You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

personal.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. /**
  2. * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
  3. * 2013, Morris Jobke <morris.jobke@gmail.com>
  4. * This file is licensed under the Affero General Public License version 3 or later.
  5. * See the COPYING-README file.
  6. */
  7. /* global OC, t */
  8. /**
  9. * The callback will be fired as soon as enter is pressed by the
  10. * user or 1 second after the last data entry
  11. *
  12. * @param callback
  13. */
  14. jQuery.fn.keyUpDelayedOrEnter = function (callback) {
  15. var cb = callback;
  16. var that = this;
  17. this.keyup(_.debounce(function (event) {
  18. // enter is already handled in keypress
  19. if (event.keyCode === 13) {
  20. return;
  21. }
  22. if (that.val() !== '') {
  23. cb();
  24. }
  25. }, 1000));
  26. this.keypress(function (event) {
  27. if (event.keyCode === 13 && that.val() !== '') {
  28. event.preventDefault();
  29. cb();
  30. }
  31. });
  32. };
  33. /**
  34. * Post the email address change to the server.
  35. */
  36. function changeEmailAddress () {
  37. var emailInfo = $('#email');
  38. if (emailInfo.val() === emailInfo.defaultValue) {
  39. return;
  40. }
  41. emailInfo.defaultValue = emailInfo.val();
  42. OC.msg.startSaving('#lostpassword .msg');
  43. var post = $("#lostpassword").serialize();
  44. $.post('ajax/lostpassword.php', post, function (data) {
  45. OC.msg.finishedSaving('#lostpassword .msg', data);
  46. });
  47. }
  48. /**
  49. * Post the display name change to the server.
  50. */
  51. function changeDisplayName () {
  52. if ($('#displayName').val() !== '') {
  53. OC.msg.startSaving('#displaynameform .msg');
  54. // Serialize the data
  55. var post = $("#displaynameform").serialize();
  56. // Ajax foo
  57. $.post('ajax/changedisplayname.php', post, function (data) {
  58. if (data.status === "success") {
  59. $('#oldDisplayName').val($('#displayName').val());
  60. // update displayName on the top right expand button
  61. $('#expandDisplayName').text($('#displayName').val());
  62. updateAvatar();
  63. }
  64. else {
  65. $('#newdisplayname').val(data.data.displayName);
  66. }
  67. OC.msg.finishedSaving('#displaynameform .msg', data);
  68. });
  69. }
  70. }
  71. function updateAvatar (hidedefault) {
  72. var $headerdiv = $('#header .avatardiv');
  73. var $displaydiv = $('#displayavatar .avatardiv');
  74. if (hidedefault) {
  75. $headerdiv.hide();
  76. $('#header .avatardiv').removeClass('avatardiv-shown');
  77. } else {
  78. $headerdiv.css({'background-color': ''});
  79. $headerdiv.avatar(OC.currentUser, 32, true);
  80. $('#header .avatardiv').addClass('avatardiv-shown');
  81. }
  82. $displaydiv.css({'background-color': ''});
  83. $displaydiv.avatar(OC.currentUser, 128, true);
  84. $('#removeavatar').show();
  85. }
  86. function showAvatarCropper () {
  87. var $cropper = $('#cropper');
  88. $cropper.prepend("<img>");
  89. var $cropperImage = $('#cropper img');
  90. $cropperImage.attr('src',
  91. OC.generateUrl('/avatar/tmp') + '?requesttoken=' + oc_requesttoken + '#' + Math.floor(Math.random() * 1000));
  92. // Looks weird, but on('load', ...) doesn't work in IE8
  93. $cropperImage.ready(function () {
  94. $('#displayavatar').hide();
  95. $cropper.show();
  96. $cropperImage.Jcrop({
  97. onChange: saveCoords,
  98. onSelect: saveCoords,
  99. aspectRatio: 1,
  100. boxHeight: 500,
  101. boxWidth: 500,
  102. setSelect: [0, 0, 300, 300]
  103. });
  104. });
  105. }
  106. function sendCropData () {
  107. cleanCropper();
  108. var cropperData = $('#cropper').data();
  109. var data = {
  110. x: cropperData.x,
  111. y: cropperData.y,
  112. w: cropperData.w,
  113. h: cropperData.h
  114. };
  115. $.post(OC.generateUrl('/avatar/cropped'), {crop: data}, avatarResponseHandler);
  116. }
  117. function saveCoords (c) {
  118. $('#cropper').data(c);
  119. }
  120. function cleanCropper () {
  121. var $cropper = $('#cropper');
  122. $('#displayavatar').show();
  123. $cropper.hide();
  124. $('.jcrop-holder').remove();
  125. $('#cropper img').removeData('Jcrop').removeAttr('style').removeAttr('src');
  126. $('#cropper img').remove();
  127. }
  128. function avatarResponseHandler (data) {
  129. var $warning = $('#avatar .warning');
  130. $warning.hide();
  131. if (data.status === "success") {
  132. updateAvatar();
  133. } else if (data.data === "notsquare") {
  134. showAvatarCropper();
  135. } else {
  136. $warning.show();
  137. $warning.text(data.data.message);
  138. }
  139. }
  140. $(document).ready(function () {
  141. $("#passwordbutton").click(function () {
  142. if ($('#pass1').val() !== '' && $('#pass2').val() !== '') {
  143. // Serialize the data
  144. var post = $("#passwordform").serialize();
  145. $('#passwordchanged').hide();
  146. $('#passworderror').hide();
  147. // Ajax foo
  148. $.post(OC.generateUrl('/settings/personal/changepassword'), post, function (data) {
  149. if (data.status === "success") {
  150. $('#pass1').val('');
  151. $('#pass2').val('');
  152. $('#passwordchanged').show();
  153. } else {
  154. if (typeof(data.data) !== "undefined") {
  155. $('#passworderror').html(data.data.message);
  156. } else {
  157. $('#passworderror').html(t('Unable to change password'));
  158. }
  159. $('#passworderror').show();
  160. }
  161. });
  162. return false;
  163. } else {
  164. $('#passwordchanged').hide();
  165. $('#passworderror').show();
  166. return false;
  167. }
  168. });
  169. $('#displayName').keyUpDelayedOrEnter(changeDisplayName);
  170. $('#email').keyUpDelayedOrEnter(changeEmailAddress);
  171. $("#languageinput").change(function () {
  172. // Serialize the data
  173. var post = $("#languageinput").serialize();
  174. // Ajax foo
  175. $.post('ajax/setlanguage.php', post, function (data) {
  176. if (data.status === "success") {
  177. location.reload();
  178. }
  179. else {
  180. $('#passworderror').html(data.data.message);
  181. }
  182. });
  183. return false;
  184. });
  185. $('button:button[name="submitDecryptAll"]').click(function () {
  186. var privateKeyPassword = $('#decryptAll input:password[id="privateKeyPassword"]').val();
  187. $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
  188. $('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", true);
  189. OC.Encryption.decryptAll(privateKeyPassword);
  190. });
  191. $('button:button[name="submitRestoreKeys"]').click(function () {
  192. $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", true);
  193. $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", true);
  194. OC.Encryption.restoreKeys();
  195. });
  196. $('button:button[name="submitDeleteKeys"]').click(function () {
  197. $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", true);
  198. $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", true);
  199. OC.Encryption.deleteKeys();
  200. });
  201. $('#decryptAll input:password[name="privateKeyPassword"]').keyup(function (event) {
  202. var privateKeyPassword = $('#decryptAll input:password[id="privateKeyPassword"]').val();
  203. if (privateKeyPassword !== '') {
  204. $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", false);
  205. if (event.which === 13) {
  206. $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
  207. $('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", true);
  208. OC.Encryption.decryptAll(privateKeyPassword);
  209. }
  210. } else {
  211. $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
  212. }
  213. });
  214. var uploadparms = {
  215. done: function (e, data) {
  216. avatarResponseHandler(data.result);
  217. }
  218. };
  219. $('#uploadavatarbutton').click(function () {
  220. $('#uploadavatar').click();
  221. });
  222. $('#uploadavatar').fileupload(uploadparms);
  223. $('#selectavatar').click(function () {
  224. OC.dialogs.filepicker(
  225. t('settings', "Select a profile picture"),
  226. function (path) {
  227. $.post(OC.generateUrl('/avatar/'), {path: path}, avatarResponseHandler);
  228. },
  229. false,
  230. ["image/png", "image/jpeg"]
  231. );
  232. });
  233. $('#removeavatar').click(function () {
  234. $.ajax({
  235. type: 'DELETE',
  236. url: OC.generateUrl('/avatar/'),
  237. success: function () {
  238. updateAvatar(true);
  239. $('#removeavatar').hide();
  240. }
  241. });
  242. });
  243. $('#abortcropperbutton').click(function () {
  244. cleanCropper();
  245. });
  246. $('#sendcropperbutton').click(function () {
  247. sendCropData();
  248. });
  249. $('#pass2').strengthify({
  250. zxcvbn: OC.linkTo('core','vendor/zxcvbn/zxcvbn.js'),
  251. titles: [
  252. t('core', 'Very weak password'),
  253. t('core', 'Weak password'),
  254. t('core', 'So-so password'),
  255. t('core', 'Good password'),
  256. t('core', 'Strong password')
  257. ]
  258. });
  259. // does the user have a custom avatar? if he does hide #removeavatar
  260. // needs to be this complicated because we can't check yet if an avatar has been loaded, because it's async
  261. var url = OC.generateUrl(
  262. '/avatar/{user}/{size}',
  263. {user: OC.currentUser, size: 1}
  264. ) + '?requesttoken=' + oc_requesttoken;
  265. $.get(url, function (result) {
  266. if (typeof(result) === 'object') {
  267. $('#removeavatar').hide();
  268. }
  269. });
  270. $('#sslCertificate').on('click', 'td.remove > img', function () {
  271. var row = $(this).parent().parent();
  272. $.post(OC.generateUrl('settings/ajax/removeRootCertificate'), {
  273. cert: row.data('name')
  274. });
  275. row.remove();
  276. return true;
  277. });
  278. $('#sslCertificate tr > td').tipsy({fade: true, gravity: 'n', live: true});
  279. $('#rootcert_import').fileupload({
  280. done: function (e, data) {
  281. var issueDate = new Date(data.result.validFrom * 1000);
  282. var expireDate = new Date(data.result.validTill * 1000);
  283. var now = new Date();
  284. var isExpired = !(issueDate <= now && now <= expireDate);
  285. var row = $('<tr/>');
  286. row.addClass(isExpired? 'expired': 'valid');
  287. row.append($('<td/>').attr('title', data.result.organization).text(data.result.commonName));
  288. row.append($('<td/>').attr('title', t('core,', 'Valid until {date}', {date: data.result.validFromString}))
  289. .text(data.result.validTillString));
  290. row.append($('<td/>').attr('title', data.result.issuerOrganization).text(data.result.issuer));
  291. row.append($('<td/>').addClass('remove').append(
  292. $('<img/>').attr({
  293. alt: t('core', 'Delete'),
  294. title: t('core', 'Delete'),
  295. src: OC.imagePath('core', 'actions/delete.svg')
  296. }).addClass('action')
  297. ));
  298. $('#sslCertificate tbody').append(row);
  299. }
  300. });
  301. $('#rootcert_import_button').click(function () {
  302. $('#rootcert_import').click();
  303. });
  304. });
  305. OC.Encryption = {
  306. decryptAll: function (password) {
  307. var message = t('settings', 'Decrypting files... Please wait, this can take some time.');
  308. OC.Encryption.msg.start('#decryptAll .msg', message);
  309. $.post('ajax/decryptall.php', {password: password}, function (data) {
  310. if (data.status === "error") {
  311. OC.Encryption.msg.finished('#decryptAll .msg', data);
  312. $('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", false);
  313. } else {
  314. OC.Encryption.msg.finished('#decryptAll .msg', data);
  315. }
  316. $('#restoreBackupKeys').removeClass('hidden');
  317. });
  318. },
  319. deleteKeys: function () {
  320. var message = t('settings', 'Delete encryption keys permanently.');
  321. OC.Encryption.msg.start('#restoreBackupKeys .msg', message);
  322. $.post('ajax/deletekeys.php', null, function (data) {
  323. if (data.status === "error") {
  324. OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
  325. $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", false);
  326. $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", false);
  327. } else {
  328. OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
  329. }
  330. });
  331. },
  332. restoreKeys: function () {
  333. var message = t('settings', 'Restore encryption keys.');
  334. OC.Encryption.msg.start('#restoreBackupKeys .msg', message);
  335. $.post('ajax/restorekeys.php', {}, function (data) {
  336. if (data.status === "error") {
  337. OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
  338. $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", false);
  339. $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", false);
  340. } else {
  341. OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
  342. }
  343. });
  344. }
  345. };
  346. OC.Encryption.msg = {
  347. start: function (selector, msg) {
  348. var spinner = '<img src="' + OC.imagePath('core', 'loading-small.gif') + '">';
  349. $(selector)
  350. .html(msg + ' ' + spinner)
  351. .removeClass('success')
  352. .removeClass('error')
  353. .stop(true, true)
  354. .show();
  355. },
  356. finished: function (selector, data) {
  357. if (data.status === "success") {
  358. $(selector).html(data.data.message)
  359. .addClass('success')
  360. .stop(true, true)
  361. .delay(3000);
  362. } else {
  363. $(selector).html(data.data.message).addClass('error');
  364. }
  365. }
  366. };