invites.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /* INVITES JS FILE */
  2. // FUNCTIONS
  3. inviteLaunch()
  4. function inviteLaunch(){
  5. if(typeof activeInfo == 'undefined'){
  6. setTimeout(function () {
  7. inviteLaunch();
  8. }, 1000);
  9. }else{
  10. var menuList = '';
  11. var htmlDOM = `
  12. <div id="invite-area" class="white-popup mfp-with-anim mfp-hide">
  13. <div class="col-md-10 col-md-offset-1">
  14. <div class="invite-div"></div>
  15. </div>
  16. </div>
  17. `;
  18. if(activeInfo.plugins["INVITES-enabled"] == true){
  19. if (activeInfo.user.loggedin === true && activeInfo.user.groupID <= 1) {
  20. menuList = `<li><a class="inline-popups inviteModal" href="#invite-area" data-effect="mfp-zoom-out"><i class="fa fa-ticket fa-fw"></i> <span lang="en">Manage Invites</span></a></li>`;
  21. htmlDOM += `
  22. <div id="new-invite-area" class="white-popup mfp-with-anim mfp-hide">
  23. <div class="col-md-10 col-md-offset-1">
  24. <div class="col-md-12">
  25. <div class="panel panel-info m-b-0">
  26. <div class="panel-heading" lang="en">New Invite</div>
  27. <div class="panel-wrapper collapse in" aria-expanded="true">
  28. <div class="panel-body">
  29. <form id="new-invite-form">
  30. <fieldset style="border:0;">
  31. <div class="form-group">
  32. <label class="control-label" for="new-invite-form-inputUsername" lang="en">Name or Username</label>
  33. <input type="text" class="form-control" id="new-invite-form-inputUsername" name="username" required="" autofocus="">
  34. </div>
  35. <div class="form-group">
  36. <label class="control-label" for="new-invite-form-inputEmail" lang="en">Email</label>
  37. <input type="text" class="form-control" id="new-invite-form-inputEmail" name="email" required="" autofocus="">
  38. </div>
  39. </fieldset>
  40. <button class="btn btn-sm btn-info btn-rounded waves-effect waves-light pull-right row b-none" onclick="createNewInvite();" type="button"><span class="btn-label"><i class="fa fa-plus"></i></span><span lang="en">Create/Send Invite</span></button>
  41. <div class="clearfix"></div>
  42. </form>
  43. </div>
  44. </div>
  45. </div>
  46. </div>
  47. <div class="clearfix"></div>
  48. </div>
  49. </div>`;
  50. }else if (activeInfo.user.loggedin === false){
  51. menuList = `<li><a class="inline-popups inviteModal" href="#invite-area" data-effect="mfp-zoom-out"><i class="fa fa-ticket fa-fw"></i> <span lang="en">Use Invite Code</span></a></li>`;
  52. }
  53. $('.append-menu').after(menuList);
  54. $('.organizr-area').after(htmlDOM);
  55. pageLoad();
  56. getInvite();
  57. }
  58. }
  59. }
  60. function joinPlex(){
  61. var username = $('#invitePlexJoinUsername');
  62. var email = $('#invitePlexJoinEmail');
  63. var password = $('#invitePlexJoinPassword');
  64. if(username.val() == ''){
  65. username.focus();
  66. message('Invite Error',' Please Enter Username',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  67. }else if(email.val() == ''){
  68. email.focus();
  69. message('Invite Error',' Please Enter Email',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  70. }else if(password.val() == ''){
  71. password.focus();
  72. message('Invite Error',' Please Enter Password',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  73. }
  74. if(email.val() !== '' && username.val() !== '' && password.val() !== ''){
  75. organizrAPI2('POST','api/v2/plex/register',{username:username.val(), email:email.val(), password:password.val()}).success(function(data) {
  76. var response = data.response;
  77. if(response.result === 'success'){
  78. $('.invite-step-3-plex-no').toggleClass('hidden');
  79. $('.invite-step-3-plex-yes').toggleClass('hidden');
  80. message('Invite Function',' User Created',activeInfo.settings.notifications.position,'#FFF','success','5000');
  81. $('#inviteUsernameInvite').val(username.val());
  82. hasPlexUsername();
  83. }else{
  84. message('Invite Error',' '+response.message,activeInfo.settings.notifications.position,'#FFF','warning','5000');
  85. }
  86. }).fail(function(xhr) {
  87. OrganizrApiError(xhr, 'Plex Signup Error');
  88. });
  89. }
  90. }
  91. function joinEmby(){
  92. var username = $('#inviteEmbyJoinUsername');
  93. var email = $('#inviteEmbyJoinEmail');
  94. var password = $('#inviteEmbyJoinPassword');
  95. if(username.val() == ''){
  96. username.focus();
  97. message('Invite Error',' Please Enter Username',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  98. }else if(email.val() == ''){
  99. email.focus();
  100. message('Invite Error',' Please Enter Email',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  101. }else if(password.val() == ''){
  102. password.focus();
  103. message('Invite Error',' Please Enter Password',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  104. }
  105. if(email.val() !== '' && username.val() !== '' && password.val() !== ''){
  106. organizrAPI2('POST','api/v2/emby/register',{username:username.val(), email:email.val(), password:password.val()}).success(function(data) {
  107. var response = data.response;
  108. if(response.result === 'success'){
  109. $('.invite-step-3-emby-no').toggleClass('hidden');
  110. $('.invite-step-3-emby-yes').toggleClass('hidden');
  111. message('Invite Function',' User Created',activeInfo.settings.notifications.position,'#FFF','success','5000');
  112. $('#inviteUsernameInviteEmby').val(username.val());
  113. hasEmbyUsername();
  114. }else{
  115. message('Invite Error',' '+response.message,activeInfo.settings.notifications.position,'#FFF','warning','5000');
  116. }
  117. }).fail(function(xhr) {
  118. OrganizrApiError(xhr, 'Emby Signup Error');
  119. });
  120. }
  121. }
  122. function inviteHasAccount(type,value){
  123. switch (type) {
  124. case 'plex':
  125. if(value){
  126. $('.invite-step-2').toggleClass('hidden');
  127. $('.invite-step-3-plex-yes').toggleClass('hidden');
  128. }else{
  129. $('.invite-step-2').toggleClass('hidden');
  130. $('.invite-step-3-plex-no').toggleClass('hidden');
  131. }
  132. break;
  133. case 'emby' :
  134. if(value){
  135. $('.invite-step-2').toggleClass('hidden');
  136. $('.invite-step-3-emby-yes').toggleClass('hidden');
  137. }else{
  138. $('.invite-step-2').toggleClass('hidden');
  139. $('.invite-step-3-emby-no').toggleClass('hidden');
  140. }
  141. break;
  142. default:
  143. alert(type+' is not set up yet');
  144. }
  145. }
  146. function hasPlexUsername(){
  147. var code = $('#inviteCodeInput').val().toUpperCase();
  148. var username = $('#inviteUsernameInvite');
  149. if(username.val() == ''){
  150. username.focus();
  151. message('Invite Error',' Please Enter Username',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  152. }else{
  153. var post = {
  154. usedby:username.val()
  155. };
  156. ajaxloader(".content-wrap","in");
  157. organizrAPI2('POST','api/v2/plugins/invites/' + code,post).success(function(data) {
  158. var response = data.response;
  159. if(response.result === 'success'){
  160. $('.invite-step-3-plex-yes').toggleClass('hidden');
  161. $('.invite-step-4-plex-accept').toggleClass('hidden');
  162. if(local('get', 'invite')){
  163. local('remove', 'invite');
  164. }
  165. }else{
  166. message('Invite Error',response.message,activeInfo.settings.notifications.position,'#FFF','warning','5000');
  167. }
  168. ajaxloader();;
  169. }).fail(function(xhr) {
  170. OrganizrApiError(xhr);
  171. ajaxloader();
  172. });
  173. }
  174. }
  175. function hasEmbyUsername(){
  176. var code = $('#inviteCodeInput').val().toUpperCase();
  177. var username = $('#inviteUsernameInviteEmby');
  178. if(username.val() == ''){
  179. username.focus();
  180. message('Invite Error',' Please Enter Username',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  181. }else{
  182. var post = {
  183. usedby:username.val()
  184. };
  185. ajaxloader(".content-wrap","in");
  186. organizrAPI2('POST','api/v2/plugins/invites/' + code,post).success(function(data) {
  187. var response = data.response;
  188. if(response.result === 'success'){
  189. $('.invite-step-3-emby-yes').toggleClass('hidden');
  190. $('.invite-step-4-emby-accept').toggleClass('hidden');
  191. if(local('get', 'invite')){
  192. local('remove', 'invite');
  193. }
  194. }else{
  195. message('Invite Error',response.message,activeInfo.settings.notifications.position,'#FFF','warning','5000');
  196. }
  197. ajaxloader();;
  198. }).fail(function(xhr) {
  199. OrganizrApiError(xhr);
  200. ajaxloader();
  201. });
  202. }
  203. }
  204. function verifyInvite(){
  205. var code = $('#inviteCodeInput').val().toUpperCase();
  206. ajaxloader(".content-wrap","in");
  207. organizrAPI2('GET','api/v2/plugins/invites/'+code).success(function(data) {
  208. var response = data.response;
  209. if(response.result === 'success'){
  210. $('.invite-step-1').toggleClass('hidden');
  211. $('.invite-step-2').toggleClass('hidden');
  212. }else{
  213. message('Invite Error',response.message,activeInfo.settings.notifications.position,'#FFF','warning','5000');
  214. }
  215. if(local('get', 'invite')){
  216. local('remove', 'invite');
  217. }
  218. ajaxloader();;
  219. }).fail(function(xhr) {
  220. OrganizrApiError(xhr);
  221. ajaxloader();
  222. });
  223. }
  224. function getInvite(invite=null){
  225. if(invite){
  226. local('set','invite',invite);
  227. }
  228. if($.urlParam('invite') !== null){
  229. local('set','invite',$.urlParam('invite'));
  230. }
  231. if(local('get', 'invite')){
  232. //show error page
  233. $('.inviteModal').trigger('click');
  234. $('#inviteCodeInput').val(local('get', 'invite'));
  235. window.history.pushState({}, document.title, "./" );
  236. local('remove', 'invite');
  237. }
  238. }
  239. function createNewInvite(){
  240. var username = $('#new-invite-form-inputUsername');
  241. var email = $('#new-invite-form-inputEmail');
  242. if(username.val() == ''){
  243. username.focus();
  244. message('Invite Error',' Please Enter Username',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  245. }else if(email.val() == ''){
  246. email.focus();
  247. message('Invite Error',' Please Enter Email',activeInfo.settings.notifications.position,'#FFF','warning','5000');
  248. }
  249. if(email.val() !== '' && username.val() !== ''){
  250. var post = {
  251. code:createRandomString(6).toUpperCase(),
  252. email:email.val(),
  253. username:username.val(),
  254. };
  255. ajaxloader(".content-wrap","in");
  256. organizrAPI2('POST','api/v2/plugins/invites',post).success(function(data) {
  257. var response = data.response;
  258. $.magnificPopup.close();
  259. ajaxloader();
  260. message('Invite',' Invite Created',activeInfo.settings.notifications.position,'#FFF','success','5000');
  261. }).fail(function(xhr) {
  262. OrganizrApiError(xhr);
  263. ajaxloader();
  264. message('Invite Error',' An Error Occured',activeInfo.settings.notifications.position,'#FFF','error','5000');
  265. });
  266. }
  267. }
  268. function deleteInvite(code, id){
  269. ajaxloader(".content-wrap","in");
  270. organizrAPI2('DELETE','api/v2/plugins/invites/' + code).success(function(data) {
  271. var response = data.response;
  272. $('#inviteItem-'+id).remove();
  273. //$.magnificPopup.close();
  274. ajaxloader();
  275. message('Invite',' Invite Deleted',activeInfo.settings.notifications.position,'#FFF','success','5000');
  276. }).fail(function(xhr) {
  277. console.error("Organizr Function: API Connection Failed");
  278. ajaxloader();
  279. message('Invite Error',' An Error Occured',activeInfo.settings.notifications.position,'#FFF','error','5000');
  280. });
  281. }
  282. // EVENTS and LISTENERS
  283. function buildInvites(array){
  284. if(array.length == 0){
  285. return '<h2 class="text-center" lang="en">No Invites</h2>';
  286. }
  287. var invites = '';
  288. $.each(array, function(i,v) {
  289. v.dateused = (v.dateused) ? v.dateused : '-';
  290. v.usedby = (v.usedby) ? v.usedby : '-';
  291. v.ip = (v.ip) ? v.ip : '-';
  292. invites += `
  293. <tr id="inviteItem-`+v.id+`">
  294. <td class="text-center">`+v.id+`</td>
  295. <td>`+v.username+`</td>
  296. <td>`+v.email+`</td>
  297. <td>`+v.code+`</td>
  298. <td>`+v.date+`</td>
  299. <td>`+v.dateused+`</td>
  300. <td>`+v.usedby+`</td>
  301. <td>`+v.ip+`</td>
  302. <td>`+v.valid+`</td>
  303. <td><button type="button" class="btn btn-danger btn-outline btn-circle btn-lg m-r-5" onclick="deleteInvite('`+v.code+`','`+v.id+`');"><i class="ti-trash"></i></button></td>
  304. </tr>
  305. `;
  306. });
  307. return invites;
  308. }
  309. $(document).on('click', '.inviteModal', function() {
  310. var htmlDOM = '';
  311. if (activeInfo.user.loggedin === true && activeInfo.user.groupID <= 1) {
  312. ajaxloader(".content-wrap","in");
  313. organizrAPI2('GET','api/v2/plugins/invites').success(function(data) {
  314. var response = data.response;
  315. var htmlDOM = '';
  316. htmlDOM = `
  317. <div class="col-md-12">
  318. <div class="panel bg-org panel-info">
  319. <div class="panel-heading">
  320. <span lang="en">Manage Invites</span>
  321. <button type="button" class="btn btn-info btn-circle pull-right popup-with-form" href="#new-invite-area" data-effect="mfp-3d-unfold"><i class="fa fa-plus"></i> </button>
  322. </div>
  323. <div class="table-responsive">
  324. <table class="table table-hover manage-u-table">
  325. <thead>
  326. <tr>
  327. <th width="70" class="text-center">#</th>
  328. <th lang="en">USERNAME</th>
  329. <th lang="en">EMAIL</th>
  330. <th lang="en">INVITE CODE</th>
  331. <th lang="en">DATE SENT</th>
  332. <th lang="en">DATE USED</th>
  333. <th lang="en">USED BY</th>
  334. <th lang="en">IP ADDRESS</th>
  335. <th lang="en">VALID</th>
  336. <th lang="en">DELETE</th>
  337. </tr>
  338. </thead>
  339. <tbody id="manageInviteTable">
  340. `+buildInvites(response.data)+`
  341. </tbody>
  342. </table>
  343. </div>
  344. </div>
  345. </div>
  346. <div class="clearfix"></div>
  347. `;
  348. $('.invite-div').html(htmlDOM);
  349. }).fail(function(xhr) {
  350. console.error("Organizr Function: API Connection Failed");
  351. });
  352. ajaxloader();
  353. }else if (activeInfo.user.loggedin === false){
  354. htmlDOM = `
  355. <div class="col-md-12">
  356. <div class="panel panel-info m-b-0">
  357. <div class="panel-heading" lang="en">Use Invite Code</div>
  358. <div class="panel-wrapper collapse in" aria-expanded="true">
  359. <div class="panel-body">
  360. <div class="form-group invite-step-1">
  361. <div class="input-group" style="width: 100%;">
  362. <div class="input-group-addon hidden-xs"><i class="ti-lock"></i></div>
  363. <input type="text" class="form-control text-uppercase" id="inviteCodeInput" placeholder="Code" autocomplete="off" autocorrect="off" autocapitalize="off" maxlength="6" spellcheck="false" autofocus="" required="">
  364. </div>
  365. <br />
  366. <button class="btn btn-block btn-info" onclick="verifyInvite();">Verify</button>
  367. </div>
  368. <div class="form-group invite-step-2 hidden">
  369. <div class="row">
  370. <h2 class="text-center" lang="en">Do you have a `+activeInfo.plugins.includes["INVITES-type-include"].toUpperCase()+` account?</h2>
  371. <div class="col-lg-6">
  372. <button class="btn btn-block btn-info m-b-10" onclick="inviteHasAccount('`+activeInfo.plugins.includes["INVITES-type-include"]+`',true);" lang="en">Yes</button>
  373. </div>
  374. <div class="col-lg-6">
  375. <button class="btn btn-block btn-primary m-b-10" onclick="inviteHasAccount('`+activeInfo.plugins.includes["INVITES-type-include"]+`',false);" lang="en">No</button>
  376. </div>
  377. </div>
  378. </div>
  379. <div class="form-group invite-step-3-plex-yes hidden">
  380. <div class="input-group" style="width: 100%;">
  381. <div class="input-group-addon hidden-xs"><i class="ti-user"></i></div>
  382. <input type="text" class="form-control" id="inviteUsernameInvite" placeholder="Plex Username or Email" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus="" required="">
  383. </div>
  384. <br />
  385. <button class="btn btn-block btn-info" onclick="hasPlexUsername();">Submit</button>
  386. </div>
  387. <div class="form-group invite-step-3-plex-no hidden">
  388. <div class="input-group" style="width: 100%;">
  389. <div class="input-group-addon hidden-xs"><i class="ti-user"></i></div>
  390. <input type="text" class="form-control" id="invitePlexJoinUsername" lang="en" placeholder="Username" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus="" required="">
  391. </div>
  392. <div class="input-group" style="width: 100%;">
  393. <div class="input-group-addon hidden-xs"><i class="ti-email"></i></div>
  394. <input type="text" class="form-control" id="invitePlexJoinEmail" lang="en" placeholder="E-Mail" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" required="">
  395. </div>
  396. <div class="input-group" style="width: 100%;">
  397. <div class="input-group-addon hidden-xs"><i class="ti-user"></i></div>
  398. <input type="password" class="form-control" id="invitePlexJoinPassword" lang="en" placeholder="Password" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" required="">
  399. </div>
  400. <br />
  401. <button class="btn btn-block btn-info" onclick="joinPlex();">Submit</button>
  402. </div>
  403. <div class="form-group invite-step-4-plex-accept hidden">
  404. <h4 class="" lang="en">You have been invited. Please check your email or goto <a href="https://plex.tv" target="_blank">PLEX.TV</a> and login to accept the invite. Once you have done that, you may head back here and login with your credentials.</h4>
  405. </div>
  406. <!-- Begin Emby Invites -->
  407. <div class="form-group invite-step-3-emby-yes hidden">
  408. <div class="input-group" style="width: 100%;">
  409. <div class="input-group-addon hidden-xs"><i class="ti-user"></i></div>
  410. <input type="text" class="form-control" id="inviteUsernameInviteEmby" placeholder="Emby Username" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus="" required="">
  411. </div>
  412. <br />
  413. <button class="btn btn-block btn-info" onclick="hasEmbyUsername();">Submit</button>
  414. </div>
  415. <div class="form-group invite-step-3-emby-no hidden">
  416. <div class="input-group" style="width: 100%;">
  417. <div class="input-group-addon hidden-xs"><i class="ti-user"></i></div>
  418. <input type="text" class="form-control" id="inviteEmbyJoinUsername" lang="en" placeholder="Username" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" autofocus="" required="">
  419. </div>
  420. <div class="input-group" style="width: 100%;">
  421. <div class="input-group-addon hidden-xs"><i class="ti-email"></i></div>
  422. <input type="text" class="form-control" id="inviteEmbyJoinEmail" lang="en" placeholder="E-Mail" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" required="">
  423. </div>
  424. <div class="input-group" style="width: 100%;">
  425. <div class="input-group-addon hidden-xs"><i class="ti-user"></i></div>
  426. <input type="password" class="form-control" id="inviteEmbyJoinPassword" lang="en" placeholder="Password" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" required="">
  427. </div>
  428. <br />
  429. <button class="btn btn-block btn-info" onclick="joinEmby();">Submit</button>
  430. </div>
  431. <div class="form-group invite-step-4-emby-accept hidden">
  432. <h4 class="" lang="en">You Have been added to emby!</h4>
  433. </div>
  434. </div>
  435. </div>
  436. </div>
  437. </div>
  438. <div class="clearfix"></div>
  439. `;
  440. $('.invite-div').html(htmlDOM);
  441. }
  442. });
  443. $(document).on('click', '#INVITES-settings-button', function() {
  444. ajaxloader(".content-wrap","in");
  445. organizrAPI2('GET','api/v2/plugins/invites/settings').success(function(data) {
  446. var response = data.response;
  447. $('#INVITES-settings-items').html(buildFormGroup(response.data));
  448. $('.selectpicker').selectpicker();
  449. }).fail(function(xhr) {
  450. console.error("Organizr Function: API Connection Failed");
  451. });
  452. ajaxloader();
  453. });