@tapni/auth 1.0.4 → 1.0.6-3.dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +2 -0
  2. package/dist/.vite/manifest.json +23 -40
  3. package/dist/.well-known/assetlinks.json +10 -12
  4. package/dist/.well-known/microsoft-identity-association.json +5 -5
  5. package/dist/Apps-XNA4_3B4.js +109 -0
  6. package/dist/Billing-Br0-fHed.js +256 -0
  7. package/dist/CustomApp-CrlbYDOm.js +83 -0
  8. package/dist/QR-Bvqb60-E.js +41 -0
  9. package/dist/TapniAuth.es.js +1 -1
  10. package/dist/TapniAuth.umd.js +49 -23
  11. package/dist/{install-BzPu9V_c.js → install-7FOVy8Ol.js} +6328 -4767
  12. package/dist/site.webmanifest +11 -1
  13. package/dist/style.css +1 -1
  14. package/dist/{web-IFGkBi0t.js → web-UrTMimK1.js} +2 -2
  15. package/package.json +65 -55
  16. package/src/.prettierrc.json +16 -0
  17. package/src/App.vue +329 -259
  18. package/src/eslint.config.js +15 -0
  19. package/src/index.js +4 -0
  20. package/src/install.js +9 -10
  21. package/src/main.js +54 -58
  22. package/src/mixins/apple.mixin.js +56 -54
  23. package/src/mixins/auth.mixin.js +3 -2
  24. package/src/mixins/global.mixin.js +3 -3
  25. package/src/mixins/google.mixin.js +53 -54
  26. package/src/mixins/microsoft.mixin.js +2 -8
  27. package/src/mixins/okta.mixin.js +2 -2
  28. package/src/mixins/qr-auth.mixin.js +111 -107
  29. package/src/mixins/saml.mixin.js +82 -45
  30. package/src/router/index.js +6 -6
  31. package/src/routes.js +7 -1
  32. package/src/services/Api.js +56 -58
  33. package/src/services/AuthService.js +13 -9
  34. package/src/services/CompanyService.js +10 -10
  35. package/src/services/DeviceService.js +3 -3
  36. package/src/services/MetadataService.js +10 -0
  37. package/src/services/UserService.js +48 -45
  38. package/src/services/UtilService.js +317 -225
  39. package/src/store/auth.js +485 -549
  40. package/src/store/constants.js +2 -2
  41. package/src/store/event-bus.js +22 -22
  42. package/src/store/locales/cn.js +476 -458
  43. package/src/store/locales/de.js +478 -517
  44. package/src/store/locales/en.js +454 -512
  45. package/src/store/locales/es.js +477 -524
  46. package/src/store/locales/fr.js +477 -516
  47. package/src/store/locales/it.js +477 -514
  48. package/src/store/locales/ja.js +488 -0
  49. package/src/store/locales/kr.js +477 -491
  50. package/src/store/locales/lang.js +51 -43
  51. package/src/store/locales/pt.js +488 -0
  52. package/src/store/locales/sr.js +477 -492
  53. package/src/store/locales/tr.js +477 -487
  54. package/src/store/store.js +6 -6
  55. package/src/views/Account.vue +36 -8
  56. package/src/views/Apps.vue +17 -30
  57. package/src/views/Billing.vue +538 -0
  58. package/src/views/Callback.vue +36 -33
  59. package/src/views/CustomApp.vue +14 -39
  60. package/src/views/General.vue +151 -184
  61. package/src/views/Login.vue +173 -161
  62. package/src/views/Register.vue +2 -12
  63. package/src/views/Reset.vue +132 -135
  64. package/src/views/Security.vue +13 -7
  65. package/src/views/Verify.vue +153 -151
  66. package/src/views/Welcome.vue +85 -71
  67. package/dist/Account-zep_QUuI.js +0 -153
  68. package/dist/Apps-B9XB7Z7q.js +0 -112
  69. package/dist/CustomApp-BzUsyycz.js +0 -112
  70. package/dist/General-DkcdjPYQ.js +0 -477
  71. package/dist/QR-PW6cAG5j.js +0 -41
  72. package/dist/index.css +0 -193
  73. package/dist/web-AXRKjAOB.js +0 -92
  74. package/src/components/DELETE_Language.vue +0 -168
  75. package/src/components/DELETE_LinkIcon.vue +0 -288
  76. package/src/components/DELETE_ModalOverlay.vue +0 -68
  77. package/src/components/DELETE_OTP.vue +0 -105
  78. package/src/components/SSO.vue +0 -126
  79. package/src/components/SSOPick.vue +0 -166
  80. package/src/mixins/DELETE_mfa-auth.mixin.js +0 -53
  81. package/src/mixins/facebook.mixin.js +0 -78
@@ -0,0 +1,538 @@
1
+ <template>
2
+ <div class="page-login content-boxed content-boxed-padding">
3
+ <a v-if="isModal" @click="close" class="color-black pull-right pointer" style="margin-top: 0px; position: absolute; right: -20px; text-align: right;">
4
+ <i class="font-17 color-black">
5
+ <img src="https://cdn.tapni.co/icons/down-arrow.png" class="responsive-image" style="width: 35%;"/>
6
+ </i>
7
+ </a>
8
+ <div class="subheaderContainer full-top">
9
+ <!-- Back Button -->
10
+ <router-link v-if="!isModal" to="/account" class="button gray-button pointer left-button">
11
+ <img
12
+ :src="getIcon('arrow-gray-right.svg')"
13
+ height="20"
14
+ width="20"
15
+ class="btn-icon"
16
+ style="rotate: 180deg;"
17
+ />
18
+ </router-link>
19
+
20
+ <!-- Centered Text -->
21
+ <h2 class="center-text" style="flex-grow: 1; text-align: center; margin: 0; font-weight: 600;">
22
+ {{ssoLang[appLanguage].billing }}
23
+ </h2>
24
+ </div>
25
+
26
+ <div class="container left-text">
27
+ <p class="center-text">{{ssoLang[appLanguage].billing_p }}</p>
28
+
29
+ <div class="full-top">
30
+ <!-- No subscriptions message -->
31
+ <div v-if="subscriptions.length === 0" class="no-subscriptions center-text full-top">
32
+ <p class="gray-text">There are no active subscriptions at this point.</p>
33
+ </div>
34
+
35
+ <!-- Subscriptions list -->
36
+ <div v-else>
37
+ <div v-for="sub in subscriptions" :key="sub.subscriptionId" class="subscription-card half-bottom">
38
+ <div class="subscription-header">
39
+ <div class="subscription-info">
40
+ <h3 class="subscription-name">{{ sub.subscriptionName }}</h3>
41
+ <span class="subscription-status" :class="getStatusClass(sub.status)">
42
+ {{ getStatusText(sub.status) }}
43
+ </span>
44
+ </div>
45
+ </div>
46
+
47
+ <div class="subscription-details">
48
+ <div class="detail-row">
49
+ <span class="detail-label">Amount:</span>
50
+ <span class="detail-value">{{ formatCurrency(sub.amount, sub.currency) }}</span>
51
+ </div>
52
+ <div class="detail-row">
53
+ <span class="detail-label">Billing:</span>
54
+ <span class="detail-value">{{ formatInterval(sub.interval) }}</span>
55
+ </div>
56
+ <div class="detail-row">
57
+ <span class="detail-label">Licenses:</span>
58
+ <span class="detail-value">{{ sub.licenses }}</span>
59
+ </div>
60
+ <div v-if="sub.isTrial" class="detail-row">
61
+ <span class="detail-label">Trial Ends:</span>
62
+ <span class="detail-value">{{ formatDate(sub.trialEnd) }}</span>
63
+ </div>
64
+ <div v-else-if="sub.endDate" class="detail-row">
65
+ <span class="detail-label">Next Billing:</span>
66
+ <span class="detail-value">{{ formatDate(sub.endDate) }}</span>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="subscription-actions" v-if="sub.status !== 'canceled'">
71
+ <button
72
+ @click="openCancelModal(sub)"
73
+ class="cancel-button"
74
+ :disabled="loading"
75
+ >
76
+ {{ loading ? 'Processing...' : 'Cancel Subscription' }}
77
+ </button>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </div>
83
+
84
+ <!-- Cancel Confirmation Modal -->
85
+ <div v-if="showCancelModal" class="modal-overlay" @click.self="closeCancelModal">
86
+ <div class="modal-content">
87
+ <div class="modal-header">
88
+ <h3>Cancel Subscription</h3>
89
+ <button @click="closeCancelModal" class="close-button">&times;</button>
90
+ </div>
91
+
92
+ <div class="modal-body">
93
+ <p class="modal-text">
94
+ Are you sure you want to cancel your subscription to <b>{{ selectedSubscription?.subscriptionName }}</b>?
95
+ </p>
96
+
97
+ <div class="feedback-section">
98
+ <label class="feedback-label">We'd love to know why you're canceling (optional):</label>
99
+ <textarea
100
+ v-model="cancelFeedback"
101
+ class="feedback-textarea"
102
+ placeholder="Your feedback helps us improve our service..."
103
+ rows="4"
104
+ ></textarea>
105
+ </div>
106
+ </div>
107
+
108
+ <div class="modal-footer">
109
+ <button @click="closeCancelModal" class="button-secondary">
110
+ Keep Subscription
111
+ </button>
112
+ <button
113
+ @click="confirmCancel"
114
+ class="button-danger"
115
+ :disabled="loading"
116
+ >
117
+ {{ loading ? 'Canceling...' : 'Confirm Cancellation' }}
118
+ </button>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ </template>
124
+
125
+
126
+ <script>
127
+ import AuthMixin from "../mixins/auth.mixin";
128
+ import {EventBus} from "@/store/event-bus.js";
129
+ import api from "@/services/Api.js";
130
+
131
+ export default {
132
+ name: "AuthBilling",
133
+ mixins: [AuthMixin],
134
+ props: {
135
+ payload: {
136
+ type: Object,
137
+ default: {}
138
+ },
139
+ },
140
+ data () {
141
+ return {
142
+ loading: false,
143
+ subscriptions: [],
144
+ showCancelModal: false,
145
+ selectedSubscription: null,
146
+ cancelFeedback: ''
147
+ }
148
+ },
149
+ async mounted() {
150
+ if (!this.isLoggedIn) this.$router.push('/login');
151
+ await this.getAccountSettings();
152
+ this.loadSubscriptions();
153
+ },
154
+ methods: {
155
+ close () {
156
+ EventBus.$emit('ssoEvent', {name: 'toggleAuthModal', data: true})
157
+ },
158
+ loadSubscriptions() {
159
+ // Extract subscriptions from account.billing
160
+ if (this.account.billing) {
161
+ const billing = this.account.billing;
162
+ const subs = [];
163
+
164
+ // Loop through billing object to find subscription objects
165
+ for (const key in billing) {
166
+ if (key !== 'region' && key !== 'currency' && key !== 'paymentProfiles' && typeof billing[key] === 'object' && billing[key].subscriptionId) {
167
+ subs.push(billing[key]);
168
+ }
169
+ }
170
+
171
+ this.subscriptions = subs;
172
+ }
173
+ },
174
+ formatCurrency(amount, currency) {
175
+ const currencySymbols = {
176
+ 'EUR': '€',
177
+ 'USD': '$',
178
+ 'GBP': '£'
179
+ };
180
+ const symbol = currencySymbols[currency?.toUpperCase()] || currency || '';
181
+ return `${symbol}${amount?.toFixed(2) || '0.00'}`;
182
+ },
183
+ formatInterval(interval) {
184
+ return interval ? `per ${interval}` : '';
185
+ },
186
+ formatDate(timestamp) {
187
+ if (!timestamp) return '';
188
+ const date = new Date(timestamp * 1000);
189
+ return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });
190
+ },
191
+ getStatusText(status) {
192
+ const statusMap = {
193
+ 'trialing': 'Trial',
194
+ 'active': 'Active',
195
+ 'past_due': 'Past Due',
196
+ 'canceled': 'Canceled',
197
+ 'unpaid': 'Unpaid'
198
+ };
199
+ return statusMap[status] || status;
200
+ },
201
+ getStatusClass(status) {
202
+ return `status-${status}`;
203
+ },
204
+ openCancelModal(subscription) {
205
+ this.selectedSubscription = subscription;
206
+ this.showCancelModal = true;
207
+ this.cancelFeedback = '';
208
+ },
209
+ closeCancelModal() {
210
+ this.showCancelModal = false;
211
+ this.selectedSubscription = null;
212
+ this.cancelFeedback = '';
213
+ },
214
+ async confirmCancel() {
215
+ if (!this.selectedSubscription) return;
216
+
217
+ // Check if this is a RevenueCat in-app purchase subscription
218
+ if (this.selectedSubscription.paymentGateway === 'revenuecat') {
219
+ // Fire event to redirect user to RevenueCat management URL
220
+ EventBus.$emit('ssoEvent', {
221
+ name: 'subscriptionCancelled',
222
+ data: {
223
+ subscriptionId: this.selectedSubscription.subscriptionId,
224
+ paymentGateway: this.selectedSubscription.paymentGateway,
225
+ feedback: this.cancelFeedback
226
+ }
227
+ });
228
+
229
+ // Close the modal
230
+ this.closeCancelModal();
231
+ return;
232
+ }
233
+
234
+ // For other payment gateways (like Stripe), proceed with API cancellation
235
+ this.loading = true;
236
+
237
+ try {
238
+ // Send cancel request to backend
239
+ const response = await api(false, 'v2').post('checkout/cancel/' + this.selectedSubscription.subscriptionId, {
240
+ feedback: this.cancelFeedback
241
+ });
242
+
243
+ if (response.data.success) {
244
+ // Show success message
245
+ EventBus.$emit('showToast', {
246
+ type: 'success',
247
+ message: 'Subscription canceled successfully'
248
+ });
249
+
250
+ // Refresh account settings to get updated billing info
251
+ await this.getAccountSettings();
252
+ this.loadSubscriptions();
253
+
254
+ // Close modal
255
+ this.closeCancelModal();
256
+ } else {
257
+ throw new Error(response.data.message || 'Failed to cancel subscription');
258
+ }
259
+ } catch (error) {
260
+ console.error('Error canceling subscription:', error);
261
+ EventBus.$emit('showToast', {
262
+ type: 'error',
263
+ message: error.response?.data?.message || 'Failed to cancel subscription. Please try again.'
264
+ });
265
+ } finally {
266
+ this.loading = false;
267
+ }
268
+ }
269
+ }
270
+ };
271
+ </script>
272
+
273
+ <style scoped>
274
+ .withBackground {
275
+ height: 50px;
276
+ }
277
+
278
+ .no-subscriptions {
279
+ padding: 40px 20px;
280
+ }
281
+
282
+ .gray-text {
283
+ color: #666;
284
+ font-size: 16px;
285
+ }
286
+
287
+ .subscription-card {
288
+ background: #fff;
289
+ border: 1px solid #e0e0e0;
290
+ border-radius: 12px;
291
+ padding: 20px;
292
+ margin-bottom: 16px;
293
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
294
+ }
295
+
296
+ .subscription-header {
297
+ display: flex;
298
+ justify-content: space-between;
299
+ align-items: flex-start;
300
+ margin-bottom: 16px;
301
+ padding-bottom: 16px;
302
+ border-bottom: 1px solid #f0f0f0;
303
+ }
304
+
305
+ .subscription-info {
306
+ flex: 1;
307
+ }
308
+
309
+ .subscription-name {
310
+ font-size: 20px;
311
+ font-weight: 600;
312
+ margin: 0 0 8px 0;
313
+ color: #000;
314
+ }
315
+
316
+ .subscription-status {
317
+ display: inline-block;
318
+ padding: 4px 12px;
319
+ border-radius: 12px;
320
+ font-size: 12px;
321
+ font-weight: 600;
322
+ text-transform: uppercase;
323
+ }
324
+
325
+ .status-trialing {
326
+ background: #e3f2fd;
327
+ color: #1976d2;
328
+ }
329
+
330
+ .status-active {
331
+ background: #e8f5e9;
332
+ color: #388e3c;
333
+ }
334
+
335
+ .status-past_due {
336
+ background: #fff3e0;
337
+ color: #f57c00;
338
+ }
339
+
340
+ .status-canceled {
341
+ background: #ffebee;
342
+ color: #d32f2f;
343
+ }
344
+
345
+ .subscription-details {
346
+ margin-bottom: 16px;
347
+ }
348
+
349
+ .detail-row {
350
+ display: flex;
351
+ justify-content: space-between;
352
+ padding: 8px 0;
353
+ font-size: 15px;
354
+ }
355
+
356
+ .detail-label {
357
+ color: #666;
358
+ font-weight: 500;
359
+ }
360
+
361
+ .detail-value {
362
+ color: #000;
363
+ font-weight: 600;
364
+ }
365
+
366
+ .subscription-actions {
367
+ display: flex;
368
+ justify-content: flex-end;
369
+ padding-top: 16px;
370
+ border-top: 1px solid #f0f0f0;
371
+ }
372
+
373
+ .cancel-button {
374
+ padding: 10px 20px;
375
+ background: #fff;
376
+ color: #d32f2f;
377
+ border: 1px solid #d32f2f;
378
+ border-radius: 8px;
379
+ font-size: 14px;
380
+ font-weight: 600;
381
+ cursor: pointer;
382
+ transition: all 0.2s;
383
+ }
384
+
385
+ .cancel-button:hover:not(:disabled) {
386
+ background: #d32f2f;
387
+ color: #fff;
388
+ }
389
+
390
+ .cancel-button:disabled {
391
+ opacity: 0.5;
392
+ cursor: not-allowed;
393
+ }
394
+
395
+ /* Modal Styles */
396
+ .modal-overlay {
397
+ position: fixed;
398
+ top: 0;
399
+ left: 0;
400
+ right: 0;
401
+ bottom: 0;
402
+ background: rgba(0, 0, 0, 0.5);
403
+ display: flex;
404
+ align-items: center;
405
+ justify-content: center;
406
+ z-index: 9999;
407
+ padding: 20px;
408
+ }
409
+
410
+ .modal-content {
411
+ background: #fff;
412
+ border-radius: 16px;
413
+ width: 100%;
414
+ max-width: 500px;
415
+ max-height: 90vh;
416
+ overflow-y: auto;
417
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
418
+ }
419
+
420
+ .modal-header {
421
+ display: flex;
422
+ justify-content: space-between;
423
+ align-items: center;
424
+ padding: 24px;
425
+ border-bottom: 1px solid #e0e0e0;
426
+ }
427
+
428
+ .modal-header h3 {
429
+ margin: 0;
430
+ font-size: 20px;
431
+ font-weight: 600;
432
+ color: #000;
433
+ }
434
+
435
+ .close-button {
436
+ background: none;
437
+ border: none;
438
+ font-size: 28px;
439
+ color: #666;
440
+ cursor: pointer;
441
+ padding: 0;
442
+ width: 32px;
443
+ height: 32px;
444
+ display: flex;
445
+ align-items: center;
446
+ justify-content: center;
447
+ border-radius: 50%;
448
+ transition: background 0.2s;
449
+ }
450
+
451
+ .close-button:hover {
452
+ background: #f0f0f0;
453
+ }
454
+
455
+ .modal-body {
456
+ padding: 24px;
457
+ }
458
+
459
+ .modal-text {
460
+ font-size: 16px;
461
+ line-height: 1.5;
462
+ color: #333;
463
+ margin-bottom: 24px;
464
+ }
465
+
466
+ .feedback-section {
467
+ margin-top: 20px;
468
+ }
469
+
470
+ .feedback-label {
471
+ display: block;
472
+ font-size: 14px;
473
+ font-weight: 600;
474
+ color: #333;
475
+ margin-bottom: 8px;
476
+ }
477
+
478
+ .feedback-textarea {
479
+ width: 100%;
480
+ padding: 12px;
481
+ border: 1px solid #e0e0e0;
482
+ border-radius: 8px;
483
+ font-size: 14px;
484
+ font-family: inherit;
485
+ resize: vertical;
486
+ transition: border-color 0.2s;
487
+ }
488
+
489
+ .feedback-textarea:focus {
490
+ outline: none;
491
+ border-color: #1976d2;
492
+ }
493
+
494
+ .modal-footer {
495
+ display: flex;
496
+ gap: 12px;
497
+ padding: 20px 24px;
498
+ border-top: 1px solid #e0e0e0;
499
+ justify-content: flex-end;
500
+ }
501
+
502
+ .button-secondary {
503
+ padding: 12px 24px;
504
+ background: #fff;
505
+ color: #333;
506
+ border: 1px solid #e0e0e0;
507
+ border-radius: 8px;
508
+ font-size: 14px;
509
+ font-weight: 600;
510
+ cursor: pointer;
511
+ transition: all 0.2s;
512
+ }
513
+
514
+ .button-secondary:hover {
515
+ background: #f5f5f5;
516
+ }
517
+
518
+ .button-danger {
519
+ padding: 12px 24px;
520
+ background: #d32f2f;
521
+ color: #fff;
522
+ border: none;
523
+ border-radius: 8px;
524
+ font-size: 14px;
525
+ font-weight: 600;
526
+ cursor: pointer;
527
+ transition: all 0.2s;
528
+ }
529
+
530
+ .button-danger:hover:not(:disabled) {
531
+ background: #b71c1c;
532
+ }
533
+
534
+ .button-danger:disabled {
535
+ opacity: 0.5;
536
+ cursor: not-allowed;
537
+ }
538
+ </style>
@@ -1,46 +1,49 @@
1
1
  <template>
2
- <div class="page-login content-boxed content-boxed-padding">
3
- <h5 v-if="($route.query.platform ==='android' || $route.query.platform ==='ios') && !isNative" style="text-align: center; width: 80%; margin: 0 auto; margin-top: 260px; ">
4
- {{ssoLang[this.appLanguage].you_will_be_redirected}}<br>
5
- {{ssoLang[this.appLanguage].if_redirect_not_directly}}, <span @click="inAppRedirect" style="color: blue; cursor: pointer">{{ssoLang[this.appLanguage].click_here}}</span>.</h5>
6
- <h4 v-else style="text-align: center; width: 80%; margin: 0 auto; margin-top: 260px; ">{{ssoLang[this.appLanguage].please_wait}}</h4>
7
- </div>
2
+ <div class="page-login content-boxed content-boxed-padding">
3
+ <h5 v-if="($route.query.platform === 'android' || $route.query.platform === 'ios') && !isNative" style="text-align: center; width: 80%; margin: 0 auto; margin-top: 260px">
4
+ {{ ssoLang[this.appLanguage].you_will_be_redirected }}<br />
5
+ {{ ssoLang[this.appLanguage].if_redirect_not_directly }}, <span @click="inAppRedirect" style="color: blue; cursor: pointer">{{ ssoLang[this.appLanguage].click_here }}</span
6
+ >.
7
+ </h5>
8
+ <h4 v-else style="text-align: center; width: 80%; margin: 0 auto; margin-top: 260px">{{ ssoLang[this.appLanguage].please_wait }}</h4>
9
+ </div>
8
10
  </template>
9
11
 
10
12
  <script>
11
13
  /* eslint-disable */
12
- import OktaMixin from "../mixins/okta.mixin";
13
- import SamlMixin from "../mixins/saml.mixin";
14
- import AuthMixin from "../mixins/auth.mixin";
14
+ import OktaMixin from '../mixins/okta.mixin';
15
+ import SamlMixin from '../mixins/saml.mixin';
16
+ import AuthMixin from '../mixins/auth.mixin';
15
17
  import { sanitizeUrl } from '@braintree/sanitize-url';
16
18
  export default {
17
- name: "AuthCallback",
18
- mixins: [OktaMixin, SamlMixin, AuthMixin],
19
+ name: 'AuthCallback',
20
+ mixins: [OktaMixin, SamlMixin, AuthMixin],
19
21
 
20
- data() {
21
- return {
22
+ data() {
23
+ return {};
24
+ },
22
25
 
23
- };
24
- },
25
-
26
- async mounted() {
27
- if(this.$route.path === '/callback/auth') {
28
- this.exchangeAuthCode({
29
- code: this.$route.query.code
30
- })
31
- }
32
- if(this.$route.path === '/callback/okta') return await this.handleOktaRedirect();
33
- if(this.$route.path === '/callback/saml') return await this.handleSamlRedirect();
34
- },
35
- methods: {
36
- inAppRedirect() {
37
- let url = sanitizeUrl(location.href);
38
- url = url.replace('http', 'tapni')
39
- url = url.replace('https', 'tapni')
40
- return window.open(url);
26
+ async mounted() {
27
+ if (this.$route.path === '/callback/redirect') {
28
+ return location.href = atob(this.$route.query.uri);
41
29
  }
42
- },
43
-
30
+ if (this.$route.path === '/callback/auth') {
31
+ this.exchangeAuthCode({
32
+ code: this.$route.query.code,
33
+ code_verifier: this.$route.query.code_verifier
34
+ });
35
+ }
36
+ if (this.$route.path === '/callback/okta') return await this.handleOktaRedirect();
37
+ if (this.$route.path === '/callback/saml') return await this.handleSamlRedirect();
38
+ },
39
+ methods: {
40
+ inAppRedirect() {
41
+ let url = sanitizeUrl(location.href);
42
+ url = url.replace('http', 'tapni');
43
+ url = url.replace('https', 'tapni');
44
+ return window.open(url);
45
+ }
46
+ }
44
47
  };
45
48
  </script>
46
49
 
@@ -7,7 +7,7 @@
7
7
  </a>
8
8
  <div class="subheaderContainer full-top">
9
9
  <!-- Back Button -->
10
- <router-link to="/account" class="button gray-button pointer left-button">
10
+ <router-link v-if="!isModal" to="/apps" class="button gray-button pointer left-button">
11
11
  <img
12
12
  :src="getIcon('arrow-gray-right.svg')"
13
13
  height="20"
@@ -19,7 +19,7 @@
19
19
 
20
20
  <!-- Centered Text -->
21
21
  <h2 class="center-text" style="flex-grow: 1; text-align: center; margin: 0; font-weight: 600;">
22
- {{$route.params.app }}
22
+ {{ app.t_apps_name }}
23
23
  </h2>
24
24
  </div>
25
25
 
@@ -27,43 +27,7 @@
27
27
  <p class="center-text">{{ssoLang[appLanguage].apps_p }}</p>
28
28
 
29
29
  <div class="full-top">
30
- <h3 v-if="false" class="full-top bold small-bottom">{{ssoLang[appLanguage].apps_my}}</h3>
31
30
 
32
- <router-link to="/apps/tapni" class="settingRow">
33
- <div class="firstRow">
34
- <img
35
- :src="getIcon('tapni-logo-small-black.png')"
36
- class="withBackground"
37
- />
38
- <h4>Tapni</h4>
39
-
40
- <img :src="getIcon('arrow-gray-right.svg')" />
41
- </div>
42
- </router-link>
43
-
44
- <router-link to="/apps/mailsign" class="settingRow half-top">
45
- <div class="firstRow">
46
- <img
47
- :src="getIcon('app-logo-mailsign.svg')"
48
- class="withBackground"
49
- />
50
- <h4>MailSign</h4>
51
-
52
- <img :src="getIcon('arrow-gray-right.svg')" />
53
- </div>
54
- </router-link>
55
-
56
- <router-link v-if="false" to="/apps/qrcodetoolkit" class="settingRow half-top">
57
- <div class="firstRow">
58
- <img
59
- :src="getIcon('app-logo-qrcodetoolkit.svg')"
60
- class="withBackground"
61
- />
62
- <h4>QRCode Toolkit</h4>
63
-
64
- <img :src="getIcon('arrow-gray-right.svg')" />
65
- </div>
66
- </router-link>
67
31
  </div>
68
32
  </div>
69
33
  </div>
@@ -73,9 +37,10 @@
73
37
  <script>
74
38
  import AuthMixin from "../mixins/auth.mixin";
75
39
  import {EventBus} from "@/store/event-bus.js";
40
+ import AuthService from "@/services/AuthService.js";
76
41
 
77
42
  export default {
78
- name: "AuthSecurity",
43
+ name: "AuthCustomApp",
79
44
  mixins: [AuthMixin],
80
45
  props: {
81
46
  payload: {
@@ -86,10 +51,20 @@ export default {
86
51
  data () {
87
52
  return {
88
53
  loading: false,
54
+ app: {}
89
55
  }
90
56
  },
91
57
  async mounted() {
92
58
  if (!this.isLoggedIn) this.$router.push('/login');
59
+
60
+ const response = await AuthService.getRecordById({
61
+ id: this.$route.params.app,
62
+ query: {
63
+ fields: ['t_apps_name', 't_apps_icon', 't_apps_url'],
64
+ relations: []
65
+ }
66
+ })
67
+ this.app = response.data.record;
93
68
  },
94
69
  methods: {
95
70
  close () {