@tapni/auth 0.0.169 → 0.0.171

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 (69) hide show
  1. package/README.md +2 -0
  2. package/dist/.vite/manifest.json +18 -10
  3. package/dist/.well-known/assetlinks.json +10 -12
  4. package/dist/.well-known/microsoft-identity-association.json +5 -5
  5. package/dist/{Account-ja1hZJy5.js → Account-BB71UmF3.js} +31 -32
  6. package/dist/{QR-ybXT1KGe.js → QR-BJnR_0ci.js} +3 -3
  7. package/dist/TapniAuth.es.js +1 -1
  8. package/dist/TapniAuth.umd.js +9 -9
  9. package/dist/blank.html +31 -0
  10. package/dist/{install-4aK3Wz63.js → install-Cx9Gi17U.js} +753 -997
  11. package/dist/site.webmanifest +11 -1
  12. package/dist/style.css +1 -1
  13. package/dist/{web-NrPZl3qD.js → web-XbruGdlD.js} +2 -5
  14. package/package.json +64 -55
  15. package/src/.prettierrc.json +16 -0
  16. package/src/App.vue +249 -265
  17. package/src/components/Language.vue +66 -143
  18. package/src/components/LinkIcon.vue +174 -225
  19. package/src/components/ModalOverlay.vue +47 -50
  20. package/src/components/OTP.vue +64 -94
  21. package/src/components/SSO.vue +80 -111
  22. package/src/components/SSOPick.vue +93 -148
  23. package/src/eslint.config.js +15 -0
  24. package/src/install.js +9 -10
  25. package/src/main.js +54 -57
  26. package/src/mixins/apple.mixin.js +56 -54
  27. package/src/mixins/auth.mixin.js +21 -74
  28. package/src/mixins/facebook.mixin.js +67 -66
  29. package/src/mixins/global.mixin.js +107 -109
  30. package/src/mixins/google.mixin.js +53 -54
  31. package/src/mixins/mfa-auth.mixin.js +68 -68
  32. package/src/mixins/microsoft.mixin.js +67 -75
  33. package/src/mixins/okta.mixin.js +50 -57
  34. package/src/mixins/qr-auth.mixin.js +111 -107
  35. package/src/mixins/saml.mixin.js +97 -48
  36. package/src/router/index.js +6 -6
  37. package/src/routes.js +60 -66
  38. package/src/services/Api.js +55 -57
  39. package/src/services/AuthService.js +75 -75
  40. package/src/services/CompanyService.js +10 -10
  41. package/src/services/DeviceService.js +3 -3
  42. package/src/services/UserService.js +45 -45
  43. package/src/services/UtilService.js +256 -218
  44. package/src/store/auth.js +471 -543
  45. package/src/store/constants.js +1 -1
  46. package/src/store/event-bus.js +22 -22
  47. package/src/store/locales/cn.js +442 -458
  48. package/src/store/locales/de.js +438 -517
  49. package/src/store/locales/en.js +449 -510
  50. package/src/store/locales/es.js +442 -524
  51. package/src/store/locales/fr.js +442 -516
  52. package/src/store/locales/it.js +442 -514
  53. package/src/store/locales/kr.js +442 -491
  54. package/src/store/locales/lang.js +43 -43
  55. package/src/store/locales/sr.js +439 -492
  56. package/src/store/locales/tr.js +436 -487
  57. package/src/store/store.js +6 -6
  58. package/src/views/Account.vue +169 -207
  59. package/src/views/Callback.vue +36 -33
  60. package/src/views/Login.vue +220 -392
  61. package/src/views/MFA.vue +89 -103
  62. package/src/views/QR.vue +25 -28
  63. package/src/views/Register.vue +201 -205
  64. package/src/views/Reset.vue +132 -135
  65. package/src/views/Verify.vue +153 -151
  66. package/src/views/Welcome.vue +61 -60
  67. /package/dist/{web-L3jORB19.js → web-AXRKjAOB.js} +0 -0
  68. /package/dist/{web-5VtGcKeU.js → web-IFGkBi0t.js} +0 -0
  69. /package/dist/{web-AImUTDQQ.js → web-LIfHmYL2.js} +0 -0
@@ -1,7 +1,7 @@
1
- import to from 'await-to-js'
2
- import AuthService from '../services/AuthService'
3
- import UtilService from '../services/UtilService'
4
- import { EventBus } from "../store/event-bus";
1
+ import to from 'await-to-js';
2
+ import AuthService from '../services/AuthService';
3
+ import UtilService from '../services/UtilService';
4
+ import { EventBus } from '../store/event-bus';
5
5
  import { Capacitor } from '@capacitor/core';
6
6
  import axios from 'axios';
7
7
  import { Browser } from '@capacitor/browser';
@@ -9,13 +9,12 @@ import { Browser } from '@capacitor/browser';
9
9
  // this tutorial was used for plain okta javascript implementation
10
10
  // https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead
11
11
  export default {
12
- data () {
12
+ data() {
13
13
  return {
14
- oktaAuth: null,
15
- }
16
- },
17
- computed: {
14
+ oktaAuth: null
15
+ };
18
16
  },
17
+ computed: {},
19
18
  watch: {
20
19
  /*
21
20
  '$route.path': async function(routePath) {
@@ -24,48 +23,45 @@ export default {
24
23
  */
25
24
  },
26
25
  methods: {
27
- async exchangeCode (data) {
28
- let [err, response] = await to(axios.post(data.domain + '/v1/token', new URLSearchParams({code: data.code, client_id: data.clientID, grant_type: "authorization_code", redirect_uri: this.isNative ? 'tapni://t.link/callback/okta' : (location.origin + '/callback/okta'), code_verifier: localStorage.getItem("pkce_code_verifier")})));
26
+ async exchangeCode(data) {
27
+ let [err, response] = await to(axios.post(data.domain + '/v1/token', new URLSearchParams({ code: data.code, client_id: data.clientID, grant_type: 'authorization_code', redirect_uri: this.isNative ? 'tapni://t.link/callback/okta' : location.origin + '/callback/okta', code_verifier: localStorage.getItem('pkce_code_verifier') })));
29
28
  if (err) return this.errorHandler(err);
30
- localStorage.removeItem("pkce_code_verifier");
29
+ localStorage.removeItem('pkce_code_verifier');
31
30
 
32
- let user = {accessToken: response.data?.access_token, domain: data.domain}
31
+ let user = { accessToken: response.data?.access_token, domain: data.domain };
33
32
  if (this.display === 'popup') user.response_type = 'code';
34
33
 
35
34
  [err, response] = await to(AuthService.oktaSDK(user, this.$storex));
36
35
  if (err) {
37
- this.oktaLoad = false
38
- EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
39
- return this.errorHandler(err)
36
+ this.oktaLoad = false;
37
+ EventBus.$emit('ssoEvent', { name: 'setLoading', data: false });
38
+ return this.errorHandler(err);
40
39
  }
41
40
  if (response.data.success) {
42
41
  if (this.display === 'popup') {
43
42
  return window.parent?.postMessage({ code: response.data.auth_code, state: this.$route.query.state }, '*');
44
43
  }
45
- await this.loginSetup(response)
46
- await this.getLoggedInAccounts()
47
- this.$router.push('/' + response.data.data.username + '#edit')
44
+ await this.loginSetup(response);
45
+ await this.getLoggedInAccounts();
46
+ this.$router.push('/' + response.data.data.username + '#edit');
48
47
  setTimeout(() => {
49
- this.appleLoad = false
50
- EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
51
- }, 1000)
52
- } else this.errorSnack(this.ssoLang[this.appLanguage].unexpected_err)
48
+ this.appleLoad = false;
49
+ EventBus.$emit('ssoEvent', { name: 'setLoading', data: false });
50
+ }, 1000);
51
+ } else this.errorSnack(this.ssoLang[this.appLanguage].unexpected_err);
53
52
  },
54
- async oktaLogin (data) {
55
- const platform = Capacitor.getPlatform() || 'web';
53
+ async oktaLogin(data) {
54
+ const platform = Capacitor.getPlatform() || 'web';
56
55
  //const state = btoa(`email=${email}&platform=${platform}`);
57
56
  //const state = btoa(`platform=${platform}`);
58
57
 
59
58
  // Create and store a random "state" value
60
59
  //localStorage.setItem("pkce_state", state);
61
- let state = btoa("domain="+data.domain
62
- + "&client_id="+data.clientID
63
- + "&platform="+platform
64
- + "&rand="+UtilService.generateRandomString(28));
60
+ let state = btoa('domain=' + data.domain + '&client_id=' + data.clientID + '&platform=' + platform + '&rand=' + UtilService.generateRandomString(28));
65
61
 
66
62
  // Create and store a new PKCE code_verifier (the plaintext random secret)
67
63
  let code_verifier = UtilService.generateRandomString(28);
68
- localStorage.setItem("pkce_code_verifier", code_verifier);
64
+ localStorage.setItem('pkce_code_verifier', code_verifier);
69
65
 
70
66
  // Hash and base64-urlencode the secret to use as the challenge
71
67
  let code_challenge = await UtilService.pkceChallengeFromVerifier(code_verifier);
@@ -76,30 +72,27 @@ export default {
76
72
  if (this.isNative) redirectURI = 'tapni://t.link/callback/okta';
77
73
  else redirectURI = location.origin + '/callback/okta';
78
74
 
79
- let url = authorization_endpoint
80
- + "?response_type=code"
81
- + "&client_id="+encodeURIComponent(data.clientID)
82
- + "&state="+encodeURIComponent(state)
83
- + "&scope="+encodeURIComponent('openid email profile')
84
- + "&redirect_uri="+encodeURIComponent(redirectURI)
85
- + "&code_challenge="+encodeURIComponent(code_challenge)
86
- + "&code_challenge_method=S256";
75
+ let url = authorization_endpoint + '?response_type=code' + '&client_id=' + encodeURIComponent(data.clientID) + '&state=' + encodeURIComponent(state) + '&scope=' + encodeURIComponent('openid email profile') + '&redirect_uri=' + encodeURIComponent(redirectURI) + '&code_challenge=' + encodeURIComponent(code_challenge) + '&code_challenge_method=S256';
87
76
 
88
77
  let self = this;
89
78
  //if (response && response.data && response.data.url) {
90
79
  let code;
91
- window.addEventListener("message", async (message)=> {
92
- if (!this.allowedOriginsAuth.includes(message.origin)) return console.log('Origin is not allowed!');
93
- if(message.data.type === 'okta') {
94
- code = message.data.code;
95
- await self.exchangeCode({domain: data.domain, code, clientID: data.clientID});
96
- }
97
- }, { once: true });
80
+ window.addEventListener(
81
+ 'message',
82
+ async (message) => {
83
+ if (!this.allowedOriginsAuth.includes(message.origin)) return console.log('Origin is not allowed!');
84
+ if (message.data.type === 'okta') {
85
+ code = message.data.code;
86
+ await self.exchangeCode({ domain: data.domain, code, clientID: data.clientID });
87
+ }
88
+ },
89
+ { once: true }
90
+ );
98
91
 
99
92
  let popupWindow;
100
- if(this.isNative) {
101
- popupWindow = await Browser.open({ url, presentationStyle: 'popover'});
102
- } else popupWindow = window.open(url, 'popup','width=600,height=600')
93
+ if (this.isNative) {
94
+ popupWindow = await Browser.open({ url, presentationStyle: 'popover' });
95
+ } else popupWindow = window.open(url, 'popup', 'width=600,height=600');
103
96
  },
104
97
  async handleOktaRedirect() {
105
98
  let code = this.$route.query.code;
@@ -107,7 +100,7 @@ export default {
107
100
  let clientID;
108
101
  let domain;
109
102
  let platform;
110
- let postMessageData = {type: 'okta'}
103
+ let postMessageData = { type: 'okta' };
111
104
  if (code) postMessageData.code = code;
112
105
  if (this.$route.query.state) {
113
106
  state = this.$route.query.state;
@@ -117,16 +110,16 @@ export default {
117
110
  domain = searchParams.get('domain');
118
111
  platform = searchParams.get('platform');
119
112
  }
120
- if(window.opener) {
113
+ if (window.opener) {
121
114
  window.opener.postMessage(postMessageData, location.origin);
122
- window.close()
115
+ window.close();
123
116
  } else {
124
- if(this.isNative && this.isIOS) await Browser.close();
125
- EventBus.$emit('ssoEvent', {name: 'setLoading', data: true})
126
- if (code && clientID && domain) await this.exchangeCode({code, clientID, domain, platform});
127
- localStorage.removeItem("pkce_code_verifier");
128
- EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
117
+ if (this.isNative && this.isiOS) await Browser.close();
118
+ EventBus.$emit('ssoEvent', { name: 'setLoading', data: true });
119
+ if (code && clientID && domain) await this.exchangeCode({ code, clientID, domain, platform });
120
+ localStorage.removeItem('pkce_code_verifier');
121
+ EventBus.$emit('ssoEvent', { name: 'setLoading', data: false });
129
122
  }
130
123
  }
131
124
  }
132
- }
125
+ };
@@ -1,117 +1,121 @@
1
- import to from 'await-to-js'
2
- import CompanyService from '../services/CompanyService'
3
- import {nextTick} from "vue";
4
- import QRCodeStyling from "qr-code-styling";
1
+ import to from 'await-to-js';
2
+ import CompanyService from '../services/CompanyService';
3
+ import { nextTick } from 'vue';
4
+ import QRCodeStyling from 'qr-code-styling';
5
5
 
6
6
  export default {
7
- data () {
8
- return {
9
- isQrCodeLogin: false,
10
- qrCode: null,
11
- qrCodeHash: null,
12
- qrCodeRefreshInterval: null,
13
- poolingInterval: null,
14
- }
15
- },
16
- props: {
17
- isModal: {
18
- type: Boolean,
19
- required: false,
20
- default: false,
21
- },
22
- },
23
- computed: {
24
- displayQRLogin () {
25
- return this.$route.name === 'AuthLogin' && this.display !== 'npm';
26
- }
27
- },
28
- mounted () {
29
- if (this.$route.name === 'AuthQR') this.changeLoginToQr();
30
- },
31
- methods: {
32
- async changeLoginToQr() {
33
- this.isQrCodeLogin = true;
34
- await nextTick();
35
- await this.initQrCodeLogin();
36
- },
37
- generateRandomHash() {
38
- const characters =
39
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
40
- const charactersLength = characters.length;
41
- let result = "";
7
+ data() {
8
+ return {
9
+ isQrCodeLogin: false,
10
+ qrCode: null,
11
+ qrCodeHash: null,
12
+ qrCodeRefreshInterval: null,
13
+ poolingInterval: null
14
+ };
15
+ },
16
+ props: {
17
+ isModal: {
18
+ type: Boolean,
19
+ required: false,
20
+ default: false
21
+ }
22
+ },
23
+ computed: {
24
+ displayQRLogin() {
25
+ return this.$route.name === 'AuthLogin' && this.display !== 'npm';
26
+ }
27
+ },
28
+ mounted() {
29
+ if (this.$route.name === 'AuthQR') this.changeLoginToQr();
30
+ },
31
+ methods: {
32
+ async changeLoginToQr() {
33
+ this.isQrCodeLogin = true;
34
+ await nextTick();
35
+ await this.initQrCodeLogin();
36
+ },
37
+ generateRandomHash() {
38
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
39
+ const charactersLength = characters.length;
40
+ let result = '';
42
41
 
43
- // Create an array of 32-bit unsigned integers
44
- const randomValues = new Uint32Array(32);
42
+ // Create an array of 32-bit unsigned integers
43
+ const randomValues = new Uint32Array(32);
45
44
 
46
- // Generate random values
47
- window.crypto.getRandomValues(randomValues);
48
- randomValues.forEach((value) => {
49
- result += characters.charAt(value % charactersLength);
50
- });
45
+ // Generate random values
46
+ window.crypto.getRandomValues(randomValues);
47
+ randomValues.forEach((value) => {
48
+ result += characters.charAt(value % charactersLength);
49
+ });
51
50
 
52
- return result;
53
- },
54
- refreshQrCode() {
55
- if (this.qrCode) {
56
- document.getElementById("qrCodeContainer")?.childNodes[0]?.remove();
57
- }
51
+ return result;
52
+ },
53
+ refreshQrCode() {
54
+ if (this.qrCode) {
55
+ document.getElementById('qrCodeContainer')?.childNodes[0]?.remove();
56
+ }
58
57
 
59
- this.qrCodeHash = this.generateRandomHash();
58
+ this.qrCodeHash = this.generateRandomHash();
60
59
 
61
- this.qrCode = new QRCodeStyling({
62
- width: 300,
63
- height: 300,
64
- type: "png",
65
- image: "",
66
- imageOptions: {
67
- margin: 15,
68
- },
69
- data: this.qrCodeHash,
70
- dotsOptions: {
71
- type: "extra-rounded",
72
- color: "#000000",
73
- },
74
- cornersSquareOptions: {
75
- type: "extra-rounded",
76
- color: "#000000",
77
- },
78
- cornersDotOptions: {
79
- type: "",
80
- color: "#000000",
81
- },
82
- backgroundOptions: {
83
- color: "#ffffff00",
84
- },
85
- });
60
+ this.qrCode = new QRCodeStyling({
61
+ width: 300,
62
+ height: 300,
63
+ type: 'png',
64
+ image: '',
65
+ imageOptions: {
66
+ margin: 15
67
+ },
68
+ data: this.qrCodeHash,
69
+ dotsOptions: {
70
+ type: 'extra-rounded',
71
+ color: '#000000'
72
+ },
73
+ cornersSquareOptions: {
74
+ type: 'extra-rounded',
75
+ color: '#000000'
76
+ },
77
+ cornersDotOptions: {
78
+ type: '',
79
+ color: '#000000'
80
+ },
81
+ backgroundOptions: {
82
+ color: '#ffffff00'
83
+ }
84
+ });
86
85
 
87
- this.qrCode.append(document.getElementById("qrCodeContainer"));
88
- },
89
- async startQrCodePooling() {
90
- this.poolingInterval = setInterval(async () => {
91
- const [err, response] = await to(CompanyService.qrCodePooling({
92
- qrToken: this.qrCodeHash,
93
- }, this.$storex));
94
- if (err) return this.errorHandler(err);
95
- if (response.data.auth_code) {
96
- if (this.display !== 'popup') {
97
- this.loginSetup({ ...response, isModal: this.isModal });
98
- await this.getLoggedInAccounts();
99
- }
86
+ this.qrCode.append(document.getElementById('qrCodeContainer'));
87
+ },
88
+ async startQrCodePooling() {
89
+ this.poolingInterval = setInterval(async () => {
90
+ const [err, response] = await to(
91
+ CompanyService.qrCodePooling(
92
+ {
93
+ qrToken: this.qrCodeHash
94
+ },
95
+ this.$storex
96
+ )
97
+ );
98
+ if (err) return this.errorHandler(err);
99
+ if (response.data.auth_code) {
100
+ if (this.display !== 'popup') {
101
+ this.loginSetup({ ...response, isModal: this.isModal });
102
+ await this.getLoggedInAccounts();
103
+ }
100
104
 
101
- this.loginSuccess({ ...response, isModal: this.isModal });
102
- clearInterval(this.poolingInterval);
103
- clearInterval(this.qrCodeRefreshInterval);
104
- }
105
- }, 2000);
106
- },
105
+ this.loginSuccess({ ...response, isModal: this.isModal });
106
+ clearInterval(this.poolingInterval);
107
+ clearInterval(this.qrCodeRefreshInterval);
108
+ }
109
+ }, 2000);
110
+ },
107
111
 
108
- async initQrCodeLogin() {
109
- this.refreshQrCode();
110
- await nextTick();
111
- await this.startQrCodePooling();
112
- this.qrCodeRefreshInterval = setInterval(() => {
113
- this.refreshQrCode();
114
- }, 60000);
115
- },
116
- }
117
- }
112
+ async initQrCodeLogin() {
113
+ this.refreshQrCode();
114
+ await nextTick();
115
+ await this.startQrCodePooling();
116
+ this.qrCodeRefreshInterval = setInterval(() => {
117
+ this.refreshQrCode();
118
+ }, 60000);
119
+ }
120
+ }
121
+ };
@@ -1,29 +1,37 @@
1
1
  import { Browser } from '@capacitor/browser';
2
2
  import UtilService from '@/services/UtilService';
3
- import { Capacitor } from "@capacitor/core";
3
+ import { Capacitor } from '@capacitor/core';
4
4
  import { EventBus } from '@/store/event-bus.js';
5
5
  export default {
6
- data () {
6
+ data() {
7
7
  return {
8
8
  code_verifier: '',
9
- code_challenge: ''
10
- }
11
- },
12
- computed: {
9
+ code_challenge: '',
10
+ shouldCloseWindow: false,
11
+ popupWindow: null,
12
+ checkInterval: null
13
+ };
13
14
  },
15
+ computed: {},
14
16
  watch: {
15
- /*
16
- '$route.path': async function(routePath) {
17
- await this.handleSamlRedirect(routePath)
17
+ '$route.path' (nv) {
18
+ if (nv === '/callback/saml') {
19
+ this.handleSamlRedirect(nv)
20
+ }
18
21
  }
19
- */
20
22
  },
21
23
  methods: {
22
- async samlLogin (loginUrl) {
23
-
24
+ closeWindow() {
25
+ try {
26
+ window.close()
27
+ } catch (e) {
28
+ console.log('Window close error', e);
29
+ }
30
+ },
31
+ async samlLogin(loginUrl) {
24
32
  // Create and store a new PKCE code_verifier (the plaintext random secret)
25
33
  this.code_verifier = UtilService.generateRandomString(28);
26
- localStorage.setItem("pkce_code_verifier", this.code_verifier);
34
+ localStorage.setItem('pkce_code_verifier', this.code_verifier);
27
35
 
28
36
  // Hash and base64-urlencode the secret to use as the challenge
29
37
  this.code_challenge = await UtilService.pkceChallengeFromVerifier(this.code_verifier);
@@ -31,58 +39,99 @@ export default {
31
39
  const platform = Capacitor.getPlatform();
32
40
 
33
41
  // append public key as relayState
34
- let dataString = `code_challenge=${this.code_challenge}&platform=${platform}&redirect_uri=${(location.origin + '/callback/saml')}&realm=${this.$storex.realm}`;
42
+ let dataString = `code_challenge=${this.code_challenge}&platform=${platform}&redirect_uri=${location.origin + '/callback/saml'}&realm=${this.realm}&display=${this.display}`;
35
43
  let relayState = btoa(dataString);
36
44
 
37
- loginUrl = `${loginUrl}&RelayState=${relayState}`
45
+ loginUrl = `${loginUrl}&RelayState=${relayState}`;
38
46
 
39
47
  let self = this;
40
48
 
41
- window.addEventListener("message", async (message)=> {
42
- if (!this.allowedOriginsAuth.includes(message.origin)) return console.log('Origin is not allowed!');
43
- if(message.data.type === 'saml' && message.data.code) {
44
- if (this.display === 'popup') {
45
- return window.parent?.postMessage({ code: message.data.code, state: this.$route.query.state, code_verifier: localStorage.getItem("pkce_code_verifier") }, '*');
49
+ window.addEventListener(
50
+ 'message',
51
+ async (message) => {
52
+ if (!this.allowedOriginsAuth.includes(message.origin)) return console.log('Origin is not allowed!');
53
+ if (message.data.code) {
54
+ console.log('post message from opener', message.data, self.display);
55
+
56
+ if (self.display === 'popup') {
57
+ return window.parent?.postMessage({ code: message.data.code, state: message.data.state, code_verifier: localStorage.getItem('pkce_code_verifier') }, '*');
58
+ }
59
+ await self.exchangeAuthCode({ code: message.data.code, code_verifier: localStorage.getItem('pkce_code_verifier') });
60
+ localStorage.removeItem('pkce_code_verifier');
46
61
  }
47
- await self.exchangeAuthCode({code: message.data.code, code_verifier: localStorage.getItem("pkce_code_verifier")});
48
- localStorage.removeItem("pkce_code_verifier");
49
- }
50
- }, { once: true });
62
+ },
63
+ { once: true }
64
+ );
65
+
66
+ if (this.isNative) {
67
+ this.popupWindow = await Browser.open({ url: loginUrl, presentationStyle: 'popover' });
68
+ } else {
69
+ this.checkInterval = setInterval(() => {
70
+ // check localStorage
71
+ const code = localStorage.getItem('auth_code');
72
+ const pkce = localStorage.getItem('pkce_code_verifier');
51
73
 
52
- let popupWindow;
53
- if(this.isNative) {
54
- popupWindow = await Browser.open({ url: loginUrl, presentationStyle: 'popover'});
74
+ console.log('interval', code, pkce);
75
+
76
+ if (code) {
77
+ clearInterval(this.checkInterval);
78
+ localStorage.removeItem('auth_code');
79
+ localStorage.removeItem('pkce_code_verifier');
80
+
81
+ // handle code exchange
82
+ window.parent?.postMessage({ code: code, state: this.$route.query.state, code_verifier: pkce }, '*');
83
+
84
+ // attempt to close child if possible
85
+ // if (this.popupWindow?.closed === false) this.popupWindow.close();
86
+ }
87
+ }, 500);
88
+
89
+ this.popupWindow = window.open('https://auth.tapni.com/callback/redirect?uri=' + btoa(loginUrl), 'popup', 'width=600,height=600');
90
+ }
91
+
92
+ if (this.popupWindow) {
93
+ this.popupWindow.addEventListener('beforeunload', () => {
94
+ console.log('popup window closed');
95
+ })
55
96
  }
56
- else popupWindow = window.open(loginUrl, 'popup','width=600,height=600')
57
- /*
58
- popupWindow.addEventListener('beforeunload', () => {
59
- console.log('window closed')
60
- })
61
- */
97
+
62
98
  },
63
99
  async handleSamlRedirect() {
64
100
  let code;
65
- let postMessageData = {type: 'saml'}
66
- if (this.$route.query.code) postMessageData.code = this.$route.query.code;
67
- if(window.opener) {
68
- window.opener.postMessage(postMessageData, location.origin);
69
- window.close()
101
+ if (this.$route.query.code) {
102
+ code = this.$route.query.code
103
+ }
104
+ console.log('window1', window.opener);
105
+ console.log('window2', window.parent);
106
+ if (window.opener) {
107
+ window.opener.postMessage({ type: 'saml', code }, '*');
108
+ this.closeWindow();
70
109
  } else {
71
- if(this.isNative && this.isIOS) await Browser.close();
72
- EventBus.$emit('ssoEvent', {name: 'setLoading', data: true})
73
- if (this.$route.query.code) code = this.$route.query.code
110
+ if (this.isNative && this.isiOS) await Browser.close();
111
+ EventBus.$emit('ssoEvent', { name: 'setLoading', data: true });
74
112
 
75
- console.log(this.display, {code});
113
+ console.log(this.display, { code }, window.parent, window.opener);
76
114
 
77
115
  if (code) {
78
116
  if (this.display === 'popup') {
79
- return window.parent?.postMessage({ code: code, state: this.$route.query.state }, '*');
117
+ localStorage.setItem('auth_code', code);
118
+ this.shouldCloseWindow = true;
119
+ window.parent?.postMessage({ code: code, state: this.$route.query.state }, '*');
120
+ this.closeWindow()
121
+ }
122
+ // TODO: Replace URLs with .env variables to support staging
123
+ if (this.display === 'redirect' || location.host === 'auth.tapni.com') {
124
+ let redirect_url = 'https://auth.tapni.com/callback/auth';
125
+ if (this.realm === 'dashboard') {
126
+ redirect_url = 'https://business.tapni.com/login'
127
+ }
128
+ return location.href = redirect_url + '?code=' + code + '&code_verifier=' + localStorage.getItem('pkce_code_verifier');
80
129
  }
81
- await this.exchangeAuthCode({code, code_verifier: localStorage.getItem("pkce_code_verifier")});
130
+ await this.exchangeAuthCode({ code, code_verifier: localStorage.getItem('pkce_code_verifier') });
82
131
  }
83
- localStorage.removeItem("pkce_code_verifier");
84
- EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
132
+ // localStorage.removeItem('pkce_code_verifier');
133
+ EventBus.$emit('ssoEvent', { name: 'setLoading', data: false });
85
134
  }
86
135
  }
87
- },
88
- }
136
+ }
137
+ };
@@ -1,9 +1,9 @@
1
- import { createRouter, createWebHistory } from 'vue-router'
2
- import routes from '../routes.js'
1
+ import { createRouter, createWebHistory } from 'vue-router';
2
+ import routes from '../routes.js';
3
3
 
4
4
  const router = createRouter({
5
- history: createWebHistory(import.meta.env.BASE_URL),
6
- routes
7
- })
5
+ history: createWebHistory(import.meta.env.BASE_URL),
6
+ routes
7
+ });
8
8
 
9
- export default router
9
+ export default router;