@tapni/auth 0.0.109 → 0.0.118

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 (44) hide show
  1. package/dist/.vite/manifest.json +32 -0
  2. package/dist/Account-5DndxBQe.js +111 -0
  3. package/dist/QR-rB8KdJig.js +41 -0
  4. package/dist/TapniAuth.es.js +2 -16733
  5. package/dist/TapniAuth.umd.js +39 -39
  6. package/dist/install-QOxCq9FJ.js +18408 -0
  7. package/dist/style.css +1 -1
  8. package/dist/web-AImUTDQQ.js +54 -0
  9. package/package.json +6 -3
  10. package/src/App.vue +55 -11
  11. package/src/components/Language.vue +1 -1
  12. package/src/components/ModalOverlay.vue +1 -0
  13. package/src/components/OTP.vue +120 -0
  14. package/src/install.js +0 -3
  15. package/src/main.js +3 -11
  16. package/src/mixins/apple.mixin.js +2 -2
  17. package/src/mixins/auth.mixin.js +52 -509
  18. package/src/mixins/facebook.mixin.js +2 -2
  19. package/src/mixins/global.mixin.js +5 -4
  20. package/src/mixins/google.mixin.js +2 -2
  21. package/src/mixins/mfa-auth.mixin.js +76 -0
  22. package/src/mixins/microsoft.mixin.js +3 -7
  23. package/src/mixins/okta.mixin.js +1 -1
  24. package/src/mixins/qr-auth.mixin.js +6 -1
  25. package/src/mixins/saml.mixin.js +2 -1
  26. package/src/routes.js +13 -0
  27. package/src/services/Api.js +15 -28
  28. package/src/services/AuthService.js +42 -37
  29. package/src/services/CompanyService.js +7 -8
  30. package/src/services/DeviceService.js +5 -6
  31. package/src/services/UserService.js +22 -23
  32. package/src/services/UtilService.js +1 -1
  33. package/src/store/locales/en.js +8 -1
  34. package/src/store/store.js +563 -0
  35. package/src/views/Account.vue +236 -0
  36. package/src/views/Login.vue +29 -15
  37. package/src/views/MFA.vue +109 -0
  38. package/src/views/Register.vue +10 -10
  39. package/src/views/Reset.vue +3 -3
  40. package/src/views/Verify.vue +4 -4
  41. package/src/views/Welcome.vue +3 -2
  42. package/src/styles/framework.css +0 -4012
  43. package/src/styles/inter.ttf +0 -0
  44. package/src/styles/style.css +0 -618
@@ -0,0 +1,76 @@
1
+ import QRCodeStyling from "qr-code-styling";
2
+ import { authenticator } from "@otplib/preset-browser";
3
+ import {EventBus} from "@/store/event-bus.js";
4
+
5
+ export default {
6
+ data () {
7
+ return {
8
+ otpToken: null,
9
+ otpSecret: null,
10
+ mfaEnable: false,
11
+ qrCodeHash: null,
12
+ qrCodeRefreshInterval: null,
13
+ poolingInterval: null,
14
+ loading: false,
15
+ }
16
+ },
17
+ props: {
18
+ isModal: {
19
+ type: Boolean,
20
+ required: false,
21
+ default: false,
22
+ },
23
+ },
24
+ computed: {
25
+ promptMFA () {
26
+ return false;
27
+ }
28
+ },
29
+ async mounted () {
30
+ if (this.$route.name === 'AuthMFA') {
31
+ await this.getAccountSettings();
32
+ this.generateOTPQrCode();
33
+ }
34
+
35
+ EventBus.$on('otpSubmitted', this.otpSubmitted)
36
+ },
37
+ methods: {
38
+ otpSubmitted(code) {
39
+ this.otpToken = code;
40
+
41
+ // Assuming that the parent component had a method called submit
42
+ this.submit();
43
+ },
44
+ generateOTPQrCode() {
45
+ const user = this.account.email;
46
+
47
+ if (this.account.mfaEnabled) {
48
+ this.mfaEnable = true;
49
+ } else {
50
+ const service = "Tapni";
51
+
52
+ const secret = authenticator.generateSecret();
53
+ this.otpSecret = secret;
54
+
55
+ const otpQR = authenticator.keyuri(user, service, secret);
56
+
57
+ const otpQrCode = new QRCodeStyling({
58
+ width: 200,
59
+ height: 200,
60
+ data: otpQR,
61
+ });
62
+ otpQrCode.append(document.getElementById("qrCodeContainer"));
63
+ }
64
+ },
65
+ async cancelMFA() {
66
+ if (import.meta.env.VITE_APP_MODE === 'npm') {
67
+ EventBus.$emit('ssoEvent', {name: 'mfaCancel', data: true})
68
+ } else {
69
+ this.$router.push('/account');
70
+ }
71
+ },
72
+ async validateMFA() {
73
+ EventBus.$emit('toggleOTPModal', true);
74
+ },
75
+ }
76
+ }
@@ -12,9 +12,7 @@ export default {
12
12
  },
13
13
  computed: {
14
14
  displayMicrosoftSSOLogin() {
15
- return (
16
- (this.ssoCompany?.login?.microsoft_login && !this.isModal) ?? false
17
- );
15
+ return false;
18
16
  },
19
17
  },
20
18
  methods: {
@@ -22,8 +20,6 @@ export default {
22
20
  if (type === "sso") this.microsoftSSOLoad = true;
23
21
  else this.microsoftLoad = true;
24
22
 
25
- if (!Object.keys(sso).length) sso = this.ssoCompany.sso?.azure?.sso || {};
26
-
27
23
  const [errAuth, user] = await to(
28
24
  MsAuthPlugin.login({
29
25
  clientId: type === "sso" ? sso.clientID : import.meta.env.VITE_APP_SSO_ID,
@@ -32,7 +28,7 @@ export default {
32
28
  knownAuthorities: [],
33
29
  keyHash: "4+5wCp8QcLptlO0aeP5RDTTOWyg=", // Android,
34
30
  redirectUri:
35
- import.meta.env.NODE_ENV === "development"
31
+ import.meta.env.DEV
36
32
  ? `${window.location.origin}/login`
37
33
  : "https://" + window.location.host + "/login",
38
34
  })
@@ -50,7 +46,7 @@ export default {
50
46
 
51
47
  if (user && (user.accessToken || user.idToken)) {
52
48
  const [err, response] = await to(
53
- AuthService.microsoftSDK(user, this.$storage)
49
+ AuthService.microsoftSDK(user, this.$storex)
54
50
  );
55
51
  if (err) {
56
52
  this.microsoftLoad = false;
@@ -32,7 +32,7 @@ export default {
32
32
  let user = {accessToken: response.data?.access_token, domain: data.domain}
33
33
  if (this.display === 'popup') user.response_type = 'code';
34
34
 
35
- [err, response] = await to(AuthService.oktaSDK(user, this.$storage));
35
+ [err, response] = await to(AuthService.oktaSDK(user, this.$storex));
36
36
  if (err) {
37
37
  this.oktaLoad = false
38
38
  EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
@@ -20,6 +20,11 @@ export default {
20
20
  default: false,
21
21
  },
22
22
  },
23
+ computed: {
24
+ displayQRLogin () {
25
+ return this.$route.name === 'AuthLogin' && this.display !== 'npm';
26
+ }
27
+ },
23
28
  mounted () {
24
29
  if (this.$route.name === 'AuthQR') this.changeLoginToQr();
25
30
  },
@@ -85,7 +90,7 @@ export default {
85
90
  this.poolingInterval = setInterval(async () => {
86
91
  const [err, response] = await to(CompanyService.qrCodePooling({
87
92
  qrToken: this.qrCodeHash,
88
- }, this.$storage));
93
+ }, this.$storex));
89
94
  if (err) return this.errorHandler(err);
90
95
  if (response.data.auth_code) {
91
96
  if (this.display === 'npm') {
@@ -31,7 +31,8 @@ export default {
31
31
  const platform = Capacitor.getPlatform();
32
32
 
33
33
  // append public key as relayState
34
- let relayState = Buffer.from(`code_challenge=${this.code_challenge}&platform=${platform}&redirect_uri=${(location.origin + '/callback/saml')}&realm=${this.$storage.realm}`).toString('base64');
34
+ let dataString = `code_challenge=${this.code_challenge}&platform=${platform}&redirect_uri=${(location.origin + '/callback/saml')}&realm=${this.$storex.realm}`;
35
+ let relayState = btoa(dataString);
35
36
 
36
37
  loginUrl = `${loginUrl}&RelayState=${relayState}`
37
38
 
package/src/routes.js CHANGED
@@ -4,12 +4,15 @@ const Login = () => import("./views/Login.vue");
4
4
  const Register = () =>
5
5
  import("./views/Register.vue");
6
6
  const Reset = () => import("./views/Reset.vue");
7
+ const Account = () => import("./views/Account.vue");
7
8
  const Verify = () =>
8
9
  import("./views/Verify.vue");
9
10
  const Callback = () =>
10
11
  import("./views/Callback.vue");
11
12
  const QR = () =>
12
13
  import("./views/QR.vue");
14
+ const MFA = () =>
15
+ import("./views/MFA.vue");
13
16
 
14
17
  export default [
15
18
  {
@@ -33,6 +36,16 @@ export default [
33
36
  name: "AuthQR",
34
37
  component: QR,
35
38
  },
39
+ {
40
+ path: "/mfa",
41
+ name: "AuthMFA",
42
+ component: MFA,
43
+ },
44
+ {
45
+ path: "/account",
46
+ name: "AuthAccount",
47
+ component: Account,
48
+ },
36
49
  {
37
50
  path: "/reset",
38
51
  name: "AuthReset",
@@ -1,28 +1,21 @@
1
1
  import axios from 'axios'
2
2
  import { jwtDecode } from "jwt-decode";
3
3
  import { version } from "../../package.json"
4
- import AuthMixin from "../mixins/auth.mixin"
4
+ import store from '../store/store.js';
5
5
 
6
- let apiRootFromOptions;
7
-
8
-
9
- export default {
10
- setApiRootFromOptions(apiRoot) {
11
- apiRootFromOptions = apiRoot
12
- },
13
- instance(storage, refreshTokenAction = null) {
14
6
 
7
+ export default (refreshTokenAction = null) => {
15
8
  const appInfo = version;
16
9
  let baseURL = import.meta.env.VITE_APP_API_ROOT + '/v1/';
17
10
 
18
- if (apiRootFromOptions) {
19
- baseURL = apiRootFromOptions;
11
+ if (store.getters.apiRoot) {
12
+ baseURL = store.getters.apiRoot;
20
13
  }
21
14
 
22
15
  let apiInstance = axios.create({
23
16
  baseURL,
24
17
  headers: {
25
- ...(storage ? { Authorization: `Bearer ${storage.token}` } : {}),
18
+ Authorization: `Bearer ${store.getters.accessToken}`,
26
19
  "X-Client-Name": "sso-" + appInfo.platform,
27
20
  "X-Client-Version": appInfo.version
28
21
  }
@@ -34,33 +27,28 @@ export default {
34
27
  if (['post', 'put', 'delete'].includes(config.method.toLowerCase())) {
35
28
  config.data = {
36
29
  ...config.data,
37
- ...(storage ? {
38
- lang: storage.appLanguage,
39
- realm: storage.realm || 'app'
40
- } : {}),
30
+ lang: store.getters.appLanguage,
31
+ realm: store.getters.appRealm || 'app'
41
32
  }
42
33
  } else if (config.method.toLowerCase() === 'get') {
43
34
  config.params = {
44
35
  ...config.params,
45
- ...(storage ? {
46
- lang: storage.appLanguage,
47
- realm: storage.realm || 'app'
48
- } : {}),
36
+ lang: store.getters.appLanguage,
37
+ realm: store.getters.appRealm || 'app'
49
38
  }
50
39
  }
51
40
 
52
- // Check refresh token expiration before request is sent
53
- if (storage && storage.token && !refreshTokenAction) {
54
- const decoded = jwtDecode(storage.token)
41
+ // Check refresh token expiration before request is sent
42
+ if (store.getters.accessToken && !refreshTokenAction) {
43
+ const decoded = jwtDecode(store.getters.accessToken)
55
44
 
56
45
  // Check if access token expired
57
46
  if (decoded.exp - 30 < Math.floor(Date.now() / 1000)) {
58
-
59
- return AuthMixin.methods.refreshTokenAction({...decoded, refreshToken: storage.refreshTokens ? storage.refreshTokens.split(',')[0] : null, storage })
60
- .then((token) => {
47
+ return store.dispatch('refreshTokenAction', decoded)
48
+ .then(() => {
61
49
  config.headers = {
62
50
  ...config.headers,
63
- Authorization: `Bearer ${token}`
51
+ Authorization: `Bearer ${store.getters.accessToken}`
64
52
  }
65
53
  return config;
66
54
  })
@@ -70,5 +58,4 @@ export default {
70
58
  });
71
59
 
72
60
  return apiInstance;
73
- }
74
61
  }
@@ -1,76 +1,81 @@
1
- import Api from './Api';
1
+ import api from './Api';
2
2
  import { Device } from '@capacitor/device';
3
- const api = Api.instance;
4
3
 
5
4
  let deviceID;
6
5
  Device.getId().then((DeviceId)=> deviceID = DeviceId.uuid)
7
6
 
8
7
  export default {
9
- register (data, storage) {
8
+ register (data) {
10
9
  data.device_id = deviceID
11
- return api(storage).post('/users/register', data)
10
+ return api().post('/users/register', data)
12
11
  },
13
- login (data, storage) {
12
+ login (data) {
14
13
  data.device_id = deviceID
15
- return api(storage).post('/users/login', data)
14
+ return api().post('/users/login', data)
16
15
  },
17
- logout (data, storage) {
16
+ logout (data) {
18
17
  data.device_id = deviceID
19
- return api(storage).post('/users/logout', data)
18
+ return api().post('/users/logout', data)
20
19
  },
21
- refreshToken (data, storage) {
22
- return api(storage, true).get(`/users/refresh-token?UserId=${data.id}&token=${data.refreshToken}`)
20
+ refreshToken (data) {
21
+ return api( true).get(`/users/refresh-token?UserId=${data.id}&token=${data.refreshToken}`)
23
22
  },
24
- getLoggedInAccounts(data, storage) {
25
- return api(storage).post(`/users/tokens`, data);
23
+ getLoggedInAccounts(data) {
24
+ return api().post(`/users/tokens`, data);
26
25
  },
27
- sendResetEmail (data, storage) {
26
+ sendResetEmail (data) {
28
27
  data.device_id = deviceID
29
- return api(storage).post('/users/reset', data)
28
+ return api().post('/users/reset', data)
30
29
  },
31
- changePassword (data, storage) {
32
- return api(storage).put('/users/password', data, {
30
+ changePassword (data) {
31
+ return api().put('/users/password', data, {
33
32
  headers: { Authorization: 'Bearer ' + data.token }
34
33
  })
35
34
  },
36
- verify (data, storage) {
37
- return api(storage).get('/users/verify?c=' + data.code + '&e=' + data.email + '&captchatoken=' + data.captchaToken)
35
+ verify (data) {
36
+ return api().get('/users/verify?c=' + data.code + '&e=' + data.email + '&captchatoken=' + data.captchaToken)
38
37
  },
39
38
  googleUrl (storage) {
40
- return api(storage).get('/users/google/url')
39
+ return api().get('/users/google/url')
41
40
  },
42
- google (data, storage) {
41
+ google (data) {
43
42
  data.device_id = deviceID
44
- return api(storage).post('/users/google', data)
43
+ return api().post('/users/google', data)
45
44
  },
46
- facebook (data, storage) {
45
+ facebook (data) {
47
46
  data.device_id = deviceID
48
- return api(storage).post('/users/facebook', data)
47
+ return api().post('/users/facebook', data)
49
48
  },
50
- googleSDK (data, storage) {
49
+ googleSDK (data) {
51
50
  data.device_id = deviceID
52
- return api(storage).post('/users/google/sdk', data)
51
+ return api().post('/users/google/sdk', data)
53
52
  },
54
- facebookSDK (data, storage) {
53
+ facebookSDK (data) {
55
54
  data.device_id = deviceID
56
- return api(storage).post('/users/facebook/sdk', data)
55
+ return api().post('/users/facebook/sdk', data)
57
56
  },
58
- appleSDK (data, storage) {
57
+ appleSDK (data) {
59
58
  data.device_id = deviceID
60
- return api(storage).post('/users/apple/sdk', data)
59
+ return api().post('/users/apple/sdk', data)
61
60
  },
62
- microsoftSDK (data, storage) {
61
+ microsoftSDK (data) {
63
62
  data.device_id = deviceID
64
- return api(storage).post('/users/microsoft/sdk', data)
63
+ return api().post('/users/microsoft/sdk', data)
65
64
  },
66
- oktaSDK (data, storage) {
65
+ oktaSDK (data) {
67
66
  data.device_id = deviceID
68
- return api(storage).post('/users/okta/sdk', data)
67
+ return api().post('/users/okta/sdk', data)
69
68
  },
70
- samlLoginUrl (data, storage) {
71
- return api(storage).post('/saml/url', data)
69
+ samlLoginUrl (data) {
70
+ return api().post('/saml/url', data)
72
71
  },
73
- exchangeAuthCode (data, storage) {
74
- return api(storage).post('/users/auth-code', data)
72
+ exchangeAuthCode (data) {
73
+ return api().post('/users/auth-code', data)
74
+ },
75
+ setMfa(data) {
76
+ return api().post("/users/set-mfa", data);
77
+ },
78
+ getAccountSettings() {
79
+ return api().get("/users/settings");
75
80
  },
76
81
  }
@@ -1,14 +1,13 @@
1
- import Api from './Api';
2
- const api = Api.instance;
1
+ import api from './Api';
3
2
 
4
3
  export default {
5
- getBySSOEmail (email, storage) {
6
- return api(storage).get(`/company/sso/${email}`)
4
+ getBySSOEmail (email) {
5
+ return api().get(`/company/sso/${email}`)
7
6
  },
8
- acceptCompanyInvitation (code, storage) {
9
- return api(storage).get(`/users/invitation?ic=${code}`)
7
+ acceptCompanyInvitation (code) {
8
+ return api().get(`/users/invitation?ic=${code}`)
10
9
  },
11
- qrCodePooling(payload, storage) {
12
- return api(storage).post("/company/login/qr", payload);
10
+ qrCodePooling(payload) {
11
+ return api().post("/company/login/qr", payload);
13
12
  },
14
13
  }
@@ -1,11 +1,10 @@
1
- import Api from './Api';
2
- const api = Api.instance;
1
+ import api from './Api';
3
2
 
4
3
  export default {
5
- registerDevice(data, storage) {
6
- return api(storage).post(`/devices/add`, data)
4
+ registerDevice(data) {
5
+ return api().post(`/devices/add`, data)
7
6
  },
8
- addFcmToken(data, storage) {
9
- return api(storage).post(`/devices/fcm/add`, data)
7
+ addFcmToken(data) {
8
+ return api().post(`/devices/fcm/add`, data)
10
9
  }
11
10
  }
@@ -1,50 +1,49 @@
1
- import Api from './Api';
2
- const api = Api.instance;
1
+ import api from './Api.js';
3
2
 
4
3
  export default {
5
4
  getMe() {
6
- return Api(storage).get(`/users/me`);
5
+ return api().get(`/users/me`);
7
6
  },
8
- getByUsername(data, storage) {
7
+ getByUsername(data) {
9
8
  let referrer = document.referrer || "";
10
9
  let params = data.utmParams || {};
11
10
  if (data.dontTap) params.dontTap = true;
12
- return api(storage).get(`/users/${data.username}`, {
11
+ return api().get(`/users/${data.username}`, {
13
12
  params,
14
13
  headers: { "X-Referer": referrer },
15
14
  });
16
15
  },
17
- getByNumber(data, storage) {
16
+ getByNumber(data) {
18
17
  let referrer = document.referrer || "";
19
18
  let params = data.utmParams || {};
20
19
  if (data.dontTap) params.dontTap = true;
21
- return api(storage).get(`/users/tag/${data.serial}`, {
20
+ return api().get(`/users/tag/${data.serial}`, {
22
21
  params,
23
22
  headers: { "X-Referer": referrer },
24
23
  });
25
24
  },
26
- save(data, storage) {
27
- return api(storage).put(`/users`, data);
25
+ save(data) {
26
+ return api().put(`/users`, data);
28
27
  },
29
- newPassword(data, storage) {
30
- return api(storage).put(`/users/new-password`, data);
28
+ newPassword(data) {
29
+ return api().put(`/users/new-password`, data);
31
30
  },
32
- connect(data, storage) {
33
- return api(storage).post(`/users/connect`, data);
31
+ connect(data) {
32
+ return api().post(`/users/connect`, data);
34
33
  },
35
- eventLog(data, storage) {
36
- return api(storage).post(`/users/log`, data);
34
+ eventLog(data) {
35
+ return api().post(`/users/log`, data);
37
36
  },
38
- deleteAccount(data, storage) {
39
- return api(storage).post(`/users/profile/delete`, data);
37
+ deleteAccount(data) {
38
+ return api().post(`/users/profile/delete`, data);
40
39
  },
41
- registerDevice(data, storage) {
42
- return api(storage).post(`/users/device/register`, data);
40
+ registerDevice(data) {
41
+ return api().post(`/users/device/register`, data);
43
42
  },
44
- addFcmToken(data, storage) {
45
- return api(storage).post(`/users/device/fcm`, data);
43
+ addFcmToken(data) {
44
+ return api().post(`/users/device/fcm`, data);
46
45
  },
47
- loginUsingQR(data, storage) {
48
- return api(storage).post("/users/qr/login", data);
46
+ loginUsingQR(data) {
47
+ return api().post("/users/qr/login", data);
49
48
  }
50
49
  };
@@ -132,7 +132,7 @@ export default {
132
132
  reader.onerror = error => reject(error);
133
133
  });
134
134
  },
135
- getUTMParams(data, storage) {
135
+ getUTMParams(data) {
136
136
  let utm = {}
137
137
  if (data.utm_source) utm.utm_source = data.utm_source;
138
138
  if (data.utm_medium) utm.utm_medium = data.utm_medium;
@@ -495,7 +495,7 @@ export default {
495
495
  analyticsLinkVisits: "Link Visits",
496
496
  analyticsNewConnections: "New Connections",
497
497
  analyticsTopCountries: "Top Countries",
498
- analyticsTopReferers: "Top Referers",
498
+ analyticsTopReferers: "Top Referrers",
499
499
 
500
500
  please_wait: "Please wait...",
501
501
  click_here: "click here",
@@ -510,5 +510,12 @@ export default {
510
510
  choose_other_login_methods: "Choose other login methods",
511
511
  no_sso_logins:
512
512
  "Your company does not use SSO login, please contact your administrator",
513
+
514
+ mfa: "Multi-Factor Authentication",
515
+ otp_title: "Enter MFA Code to continue",
516
+ otp_code: "MFA Code",
517
+ otp_subtitle: "To continue, turn on or view your MFA device and type the authentication code below.",
518
+ otp_p1: "If you have trouble signing in, <br> please contact us at",
519
+ change_language: "Change language"
513
520
  },
514
521
  };