UIWindowSaveAccount.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /**
  2. * Copyright (C) 2024 Puter Technologies Inc.
  3. *
  4. * This file is part of Puter.
  5. *
  6. * Puter is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published
  8. * by the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import UIWindow from './UIWindow.js'
  20. import UIWindowEmailConfirmationRequired from './UIWindowEmailConfirmationRequired.js'
  21. async function UIWindowSaveAccount(options){
  22. const internal_id = window.uuidv4();
  23. options = options ?? {};
  24. options.reload_on_success = options.reload_on_success ?? false;
  25. options.send_confirmation_code = options.send_confirmation_code ?? false;
  26. return new Promise(async (resolve) => {
  27. let h = '';
  28. h += `<div>`;
  29. // success
  30. h += `<div class="save-account-success">`;
  31. h += `<img src="${html_encode(window.icons['c-check.svg'])}" style="width:50px; height:50px; display: block; margin:10px auto;">`;
  32. h += `<p style="text-align:center; margin-bottom:10px;">${i18n('session_saved')}</p>`;
  33. h += `<button class="button button-action button-block save-account-success-ok-btn">${i18n('ok')}</button>`
  34. h+= `</div>`;
  35. // form
  36. h += `<div class="save-account-form" style="padding: 20px; border-bottom: 1px solid #ced7e1; width: 100%; box-sizing: border-box;">`;
  37. // title
  38. h += `<h1 class="signup-form-title" style="margin-bottom:0;">${i18n('create_account')}</h1>`;
  39. // description
  40. h += `<p class="create-account-desc">${options.message ?? i18n('save_session_c2a')}</p>`;
  41. // signup form
  42. h += `<form class="signup-form">`;
  43. // error msg
  44. h += `<div class="signup-error-msg"></div>`;
  45. // username
  46. h += `<div style="overflow: hidden;">`;
  47. h += `<label for="username-${internal_id}">${i18n('username')}</label>`;
  48. h += `<input id="username-${internal_id}" class="username" value="${options.default_username ?? ''}" type="text" autocomplete="username" spellcheck="false" autocorrect="off" autocapitalize="off" data-gramm_editor="false"/>`;
  49. h += `</div>`;
  50. // email
  51. h += `<div style="overflow: hidden; margin-top: 20px;">`;
  52. h += `<label for="email-${internal_id}">${i18n('email')}</label>`;
  53. h += `<input id="email-${internal_id}" class="email" type="email" autocomplete="email" spellcheck="false" autocorrect="off" autocapitalize="off" data-gramm_editor="false"/>`;
  54. h += `</div>`;
  55. // password
  56. h += `<div style="overflow: hidden; margin-top: 20px; margin-bottom: 20px;">`;
  57. h += `<label for="password-${internal_id}">${i18n('password')}</label>`;
  58. h += `<input id="password-${internal_id}" class="password" type="password" name="password" autocomplete="new-password" />`;
  59. h += `</div>`;
  60. // bot trap - if this value is submitted server will ignore the request
  61. h += `<input type="text" name="p102xyzname" class="p102xyzname" value="">`;
  62. // Create Account
  63. h += `<button class="signup-btn button button-primary button-block button-normal">${i18n('create_account')}</button>`
  64. h += `</form>`;
  65. h += `</div>`;
  66. h += `</div>`;
  67. const el_window = await UIWindow({
  68. title: null,
  69. icon: null,
  70. uid: null,
  71. app: 'save-account',
  72. single_instance: true,
  73. is_dir: false,
  74. body_content: h,
  75. has_head: true,
  76. selectable_body: false,
  77. draggable_body: true,
  78. allow_context_menu: false,
  79. is_draggable: true,
  80. is_droppable: false,
  81. is_resizable: false,
  82. stay_on_top: false,
  83. allow_native_ctxmenu: true,
  84. allow_user_select: true,
  85. width: 350,
  86. dominant: true,
  87. show_in_taskbar: false,
  88. ...options.window_options,
  89. onAppend: function(this_window){
  90. if(options.default_username)
  91. $(this_window).find('.email').get(0).focus({preventScroll:true});
  92. else
  93. $(this_window).find('.username').get(0).focus({preventScroll:true});
  94. },
  95. window_class: 'window-save-account',
  96. window_css:{
  97. height: 'initial',
  98. },
  99. on_close: ()=>{
  100. resolve(false)
  101. },
  102. body_css: {
  103. width: 'initial',
  104. 'background-color': 'rgba(231, 238, 245, .95)',
  105. 'backdrop-filter': 'blur(3px)',
  106. }
  107. })
  108. $(el_window).find('.signup-btn').on('click', function(e){
  109. // todo do some basic validation client-side
  110. //Username
  111. let username = $(el_window).find('.username').val();
  112. //Email
  113. let email = $(el_window).find('.email').val();
  114. //Password
  115. let password = $(el_window).find('.password').val();
  116. // disable 'Create Account' button
  117. $(el_window).find('.signup-btn').prop('disabled', true);
  118. $.ajax({
  119. url: api_origin + "/save_account",
  120. type: 'POST',
  121. async: true,
  122. contentType: "application/json",
  123. data: JSON.stringify({
  124. username: username,
  125. email: email,
  126. password: password,
  127. referrer: options.referrer,
  128. send_confirmation_code: options.send_confirmation_code,
  129. }),
  130. headers: {
  131. "Authorization": "Bearer "+auth_token
  132. },
  133. success: async function (data){
  134. update_auth_data(data.token, data.user)
  135. //close this window
  136. if(data.user.email_confirmation_required){
  137. let is_verified = await UIWindowEmailConfirmationRequired({
  138. stay_on_top: true,
  139. has_head: true
  140. });
  141. resolve(is_verified);
  142. }else{
  143. resolve(true);
  144. }
  145. $(el_window).find('.save-account-form').hide(100, ()=>{
  146. $(el_window).find('.save-account-success').show(100);
  147. })
  148. },
  149. error: function (err){
  150. $(el_window).find('.signup-error-msg').html(err.responseText);
  151. $(el_window).find('.signup-error-msg').fadeIn();
  152. // re-enable 'Create Account' button
  153. $(el_window).find('.signup-btn').prop('disabled', false);
  154. }
  155. });
  156. })
  157. $(el_window).find('.signup-form').on('submit', function(e){
  158. e.preventDefault();
  159. e.stopPropagation();
  160. return false;
  161. })
  162. $(el_window).find('.save-account-success-ok-btn').on('click', ()=>{
  163. $(el_window).close();
  164. })
  165. //remove login window
  166. $(el_window).find('.signup-c2a-clickable').parents('.window').close();
  167. })
  168. }
  169. export default UIWindowSaveAccount