main.js 19 KB

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