GettingStartedComponent.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <template>
  2. <div class="container remote-auth-getting-started">
  3. <div class="row mt-5 justify-content-center">
  4. <div class="col-12 col-xl-5 col-md-7">
  5. <div v-if="!error" class="card shadow-none border" style="border-radius: 20px;">
  6. <div v-if="!loaded && !existing && !maxUsesReached" class="card-body d-flex align-items-center flex-column" style="min-height: 400px;">
  7. <div class="w-100">
  8. <p class="lead text-center font-weight-bold">Sign-in with Mastodon</p>
  9. <hr />
  10. </div>
  11. <div class="w-100 d-flex align-items-center justify-content-center flex-grow-1 flex-column gap-1">
  12. <div class="position-relative w-100">
  13. <p class="pa-center">Please wait...</p>
  14. <instagram-loader></instagram-loader>
  15. </div>
  16. <div class="w-100">
  17. <hr>
  18. <p class="text-center mb-0">
  19. <a class="font-weight-bold" href="/login">Go back to login</a>
  20. </p>
  21. </div>
  22. </div>
  23. </div>
  24. <div v-else-if="!loaded && !existing && maxUsesReached" class="card-body d-flex align-items-center flex-column" style="min-height: 660px;">
  25. <div class="w-100">
  26. <p class="lead text-center font-weight-bold">Sign-in with Mastodon</p>
  27. <hr />
  28. </div>
  29. <div class="w-100 d-flex align-items-center justify-content-center flex-grow-1 flex-column gap-1">
  30. <p class="lead text-center font-weight-bold mt-3">Oops!</p>
  31. <p class="mb-2 text-center">We cannot complete your request at this time</p>
  32. <p class="mb-3 text-center text-xs">It appears that you've signed-in on other Pixelfed instances and reached the max limit that we accept.</p>
  33. </div>
  34. <div class="w-100">
  35. <p class="text-center mb-0">
  36. <a class="font-weight-bold" href="/site/contact">Contact Support</a>
  37. </p>
  38. <hr>
  39. <p class="text-center mb-0">
  40. <a class="font-weight-bold" href="/login">Go back to login</a>
  41. </p>
  42. </div>
  43. </div>
  44. <div v-else-if="!loaded && existing" class="card-body d-flex align-items-center flex-column" style="min-height: 660px;">
  45. <div class="w-100">
  46. <p class="lead text-center font-weight-bold">Sign-in with Mastodon</p>
  47. <hr />
  48. </div>
  49. <div class="w-100 d-flex align-items-center justify-content-center flex-grow-1 flex-column gap-1">
  50. <b-spinner />
  51. <div class="text-center">
  52. <p class="lead mb-0">Welcome back!</p>
  53. <p class="text-xs text-muted">One moment please, we're logging you in...</p>
  54. </div>
  55. </div>
  56. </div>
  57. <register-form v-else :initialData="prefill" v-on:setCanReload="setCanReload" />
  58. </div>
  59. <div v-else class="card shadow-none border">
  60. <div class="card-body d-flex align-items-center flex-column" style="min-height: 660px;">
  61. <div class="w-100">
  62. <p class="lead text-center font-weight-bold">Sign-in with Mastodon</p>
  63. <hr />
  64. </div>
  65. <div class="w-100 d-flex align-items-center justify-content-center flex-grow-1 flex-column gap-1">
  66. <p class="lead text-center font-weight-bold mt-3">Oops, something went wrong!</p>
  67. <p class="mb-3">We cannot complete your request at this time, please try again later.</p>
  68. <p class="text-xs text-muted mb-1">This can happen for a few different reasons:</p>
  69. <ul class="text-xs text-muted">
  70. <li>The remote instance cannot be reached</li>
  71. <li>The remote instance is not supported yet</li>
  72. <li>The remote instance has been disabled by admins</li>
  73. <li>The remote instance does not allow remote logins</li>
  74. </ul>
  75. </div>
  76. <div class="w-100">
  77. <hr>
  78. <p class="text-center mb-0">
  79. <a class="font-weight-bold" href="/login">Go back to login</a>
  80. </p>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. </template>
  88. <script type="text/javascript">
  89. import { InstagramLoader } from 'vue-content-loader';
  90. import RegisterForm from './partials/RegisterForm.vue';
  91. export default {
  92. components: {
  93. InstagramLoader,
  94. RegisterForm
  95. },
  96. data() {
  97. return {
  98. loaded: false,
  99. error: false,
  100. prefill: false,
  101. existing: undefined,
  102. maxUsesReached: undefined,
  103. tab: 'loading',
  104. canReload: false,
  105. }
  106. },
  107. mounted() {
  108. this.validateSession();
  109. window.onbeforeunload = function () {
  110. if(!this.canReload) {
  111. alert('You are trying to leave.');
  112. return false;
  113. }
  114. }
  115. },
  116. methods: {
  117. validateSession() {
  118. axios.post('/auth/raw/mastodon/s/check')
  119. .then(res => {
  120. if(!res && !res.hasOwnProperty('action')) {
  121. swal('Oops!', 'An unexpected error occured, please try again later', 'error');
  122. return;
  123. }
  124. switch(res.data.action) {
  125. case 'onboard':
  126. this.getPrefillData();
  127. return;
  128. break;
  129. case 'redirect_existing_user':
  130. this.existing = true;
  131. this.canReload = true;
  132. window.onbeforeunload = undefined;
  133. this.redirectExistingUser();
  134. return;
  135. break;
  136. case 'max_uses_reached':
  137. this.maxUsesReached = true;
  138. this.canReload = true;
  139. window.onbeforeunload = undefined;
  140. return;
  141. break;
  142. default:
  143. this.error = true;
  144. return;
  145. break;
  146. }
  147. })
  148. .catch(error => {
  149. this.canReload = true;
  150. window.onbeforeunload = undefined;
  151. this.error = true;
  152. })
  153. },
  154. setCanReload() {
  155. this.canReload = true;
  156. window.onbeforeunload = undefined;
  157. },
  158. redirectExistingUser() {
  159. this.canReload = true;
  160. setTimeout(() => {
  161. this.handleLogin();
  162. }, 1500);
  163. },
  164. handleLogin() {
  165. axios.post('/auth/raw/mastodon/s/login')
  166. .then(res => {
  167. setTimeout(() => {
  168. window.location.reload();
  169. }, 1500);
  170. })
  171. .catch(err => {
  172. this.canReload = false;
  173. this.error = true;
  174. })
  175. },
  176. getPrefillData() {
  177. axios.post('/auth/raw/mastodon/s/prefill')
  178. .then(res => {
  179. this.prefill = res.data;
  180. })
  181. .catch(error => {
  182. this.error = true;
  183. })
  184. .finally(() => {
  185. setTimeout(() => {
  186. this.loaded = true;
  187. }, 1000);
  188. })
  189. }
  190. }
  191. }
  192. </script>
  193. <style lang="scss">
  194. @use '../../../../node_modules/bootstrap/scss/bootstrap';
  195. .remote-auth-getting-started {
  196. .text-xs {
  197. font-size: 12px;
  198. }
  199. .gap-1 {
  200. gap: 1rem;
  201. }
  202. .opacity-50 {
  203. opacity: .3;
  204. }
  205. .server-btn {
  206. @extend .btn;
  207. @extend .btn-primary;
  208. @extend .btn-block;
  209. @extend .rounded-pill;
  210. @extend .font-weight-light;
  211. background: linear-gradient(#6364FF, #563ACC);
  212. }
  213. .other-server-btn {
  214. @extend .btn;
  215. @extend .btn-dark;
  216. @extend .btn-block;
  217. @extend .rounded-pill;
  218. @extend .font-weight-light;
  219. }
  220. .pa-center {
  221. position: absolute;
  222. left: 50%;
  223. top: 50%;
  224. transform: translate(-50%);
  225. font-weight: 600;
  226. font-size: 16px;
  227. }
  228. }
  229. </style>