@tapni/auth 0.0.2 → 0.0.4

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 (50) hide show
  1. package/dist/TapniAuth.es.js +2 -2
  2. package/dist/TapniAuth.umd.js +2 -2
  3. package/package.json +3 -2
  4. package/src/App.vue +269 -0
  5. package/src/components/Language.vue +158 -0
  6. package/src/components/LinkIcon.vue +288 -0
  7. package/src/components/ModalOverlay.vue +67 -0
  8. package/src/components/SSO.vue +126 -0
  9. package/src/components/SSOPick.vue +166 -0
  10. package/src/install.js +8 -0
  11. package/src/main.js +96 -0
  12. package/src/mixins/apple.mixin.js +60 -0
  13. package/src/mixins/auth.mixin.js +525 -0
  14. package/src/mixins/facebook.mixin.js +78 -0
  15. package/src/mixins/global.mixin.js +110 -0
  16. package/src/mixins/google.mixin.js +61 -0
  17. package/src/mixins/microsoft.mixin.js +88 -0
  18. package/src/mixins/okta.mixin.js +132 -0
  19. package/src/mixins/qr-auth.mixin.js +112 -0
  20. package/src/mixins/saml.mixin.js +84 -0
  21. package/src/router/index.js +9 -0
  22. package/src/routes.js +55 -0
  23. package/src/services/Api.js +55 -0
  24. package/src/services/AuthService.js +71 -0
  25. package/src/services/CompanyService.js +13 -0
  26. package/src/services/DeviceService.js +10 -0
  27. package/src/services/UserService.js +49 -0
  28. package/src/services/UtilService.js +221 -0
  29. package/src/store/constants.js +8 -0
  30. package/src/store/event-bus.js +30 -0
  31. package/src/store/locales/cn.js +462 -0
  32. package/src/store/locales/de.js +528 -0
  33. package/src/store/locales/en.js +514 -0
  34. package/src/store/locales/es.js +536 -0
  35. package/src/store/locales/fr.js +520 -0
  36. package/src/store/locales/it.js +518 -0
  37. package/src/store/locales/kr.js +496 -0
  38. package/src/store/locales/lang.js +47 -0
  39. package/src/store/locales/sr.js +497 -0
  40. package/src/store/locales/tr.js +491 -0
  41. package/src/styles/framework.css +4012 -0
  42. package/src/styles/inter.ttf +0 -0
  43. package/src/styles/style.css +618 -0
  44. package/src/views/Callback.vue +47 -0
  45. package/src/views/Login.vue +389 -0
  46. package/src/views/QR.vue +39 -0
  47. package/src/views/Register.vue +217 -0
  48. package/src/views/Reset.vue +155 -0
  49. package/src/views/Verify.vue +170 -0
  50. package/src/views/Welcome.vue +69 -0
package/src/routes.js ADDED
@@ -0,0 +1,55 @@
1
+ const Welcome = () =>
2
+ import("./views/Welcome.vue");
3
+ const Login = () => import("./views/Login.vue");
4
+ const Register = () =>
5
+ import("./views/Register.vue");
6
+ const Reset = () => import("./views/Reset.vue");
7
+ const Verify = () =>
8
+ import("./views/Verify.vue");
9
+ const Callback = () =>
10
+ import("./views/Callback.vue");
11
+ const QR = () =>
12
+ import("./views/QR.vue");
13
+
14
+ export default [
15
+ {
16
+ path: "/welcome",
17
+ name: "AuthWelcome",
18
+ component: Welcome,
19
+ },
20
+ {
21
+ path: "/login",
22
+ name: "AuthLogin",
23
+ component: Login,
24
+ },
25
+ {
26
+ path: "/callback/*",
27
+ name: "Callback",
28
+ component: Callback,
29
+ },
30
+ {
31
+ path: "/qr",
32
+ name: "AuthQR",
33
+ component: QR,
34
+ },
35
+ {
36
+ path: "/reset",
37
+ name: "AuthReset",
38
+ component: Reset,
39
+ },
40
+ {
41
+ path: "/register",
42
+ name: "AuthRegister",
43
+ component: Register,
44
+ },
45
+ {
46
+ path: "/verify",
47
+ name: "AuthVerify",
48
+ component: Verify,
49
+ },
50
+ {
51
+ path: "/",
52
+ name: "404",
53
+ component: Welcome
54
+ },
55
+ ];
@@ -0,0 +1,55 @@
1
+ import axios from 'axios'
2
+ import { jwtDecode } from "jwt-decode";
3
+ import { version } from "../../package.json"
4
+ import AuthMixin from "../mixins/auth.mixin"
5
+
6
+ export default (storage, refreshTokenAction = false) => {
7
+ const appInfo = version
8
+ let apiInstance = axios.create({
9
+ baseURL: import.meta.env.VITE_APP_API_ROOT + '/v1/',
10
+ headers: {
11
+ Authorization: `Bearer ${storage.token}`,
12
+ "X-Client-Name": "sso-" + appInfo.platform,
13
+ "X-Client-Version": appInfo.version
14
+ }
15
+ })
16
+
17
+ // Add a request interceptor
18
+ apiInstance.interceptors.request.use(async function (config) {
19
+
20
+ if (['post', 'put', 'delete'].includes(config.method.toLowerCase())) {
21
+ config.data = {
22
+ ...config.data,
23
+ lang: storage.appLang,
24
+ realm: storage.realm || 'app'
25
+ }
26
+ } else if (config.method.toLowerCase() === 'get') {
27
+ config.params = {
28
+ ...config.params,
29
+ lang: storage.appLang,
30
+ realm: storage.realm || 'app'
31
+ }
32
+ }
33
+
34
+ // Check refresh token expiration before request is sent
35
+ if (storage.token && !refreshTokenAction) {
36
+ const decoded = jwtDecode(storage.token)
37
+
38
+ // Check if access token expired
39
+ if (decoded.exp - 30 < Math.floor(Date.now() / 1000)) {
40
+
41
+ return AuthMixin.methods.refreshTokenAction(decoded)
42
+ .then(() => {
43
+ config.headers = {
44
+ ...config.headers,
45
+ Authorization: `Bearer ${storage.token}`
46
+ }
47
+ return config;
48
+ })
49
+ }
50
+ }
51
+ return config;
52
+ });
53
+
54
+ return apiInstance;
55
+ }
@@ -0,0 +1,71 @@
1
+ import Api from './Api'
2
+ import { Device } from '@capacitor/device';
3
+ import axios from "axios";
4
+ let deviceID;
5
+ Device.getId().then((DeviceId)=> deviceID = DeviceId.uuid)
6
+ export default {
7
+ register (data, storage) {
8
+ data.device_id = deviceID
9
+ return Api(storage).post('/users/register', data)
10
+ },
11
+ login (data, storage) {
12
+ data.device_id = deviceID
13
+ return Api(storage).post('/users/login', data)
14
+ },
15
+ logout (data, storage) {
16
+ data.device_id = deviceID
17
+ return Api(storage).post('/users/logout', data)
18
+ },
19
+ refreshToken (data, storage) {
20
+ return Api(storage, true).get(`/users/refresh-token?UserId=${data.id}&token=${data.refreshToken}`)
21
+ },
22
+ getLoggedInAccounts(data, storage) {
23
+ return Api(storage).post(`/users/tokens`, data);
24
+ },
25
+ sendResetEmail (data, storage) {
26
+ data.device_id = deviceID
27
+ return Api(storage).post('/users/reset', data)
28
+ },
29
+ changePassword (data, storage) {
30
+ return Api(storage).put('/users/password', data, {
31
+ headers: { Authorization: 'Bearer ' + data.token }
32
+ })
33
+ },
34
+ verify (data, storage) {
35
+ return Api(storage).get('/users/verify?c=' + data.code + '&e=' + data.email + '&captchatoken=' + data.captchaToken)
36
+ },
37
+ googleUrl (storage) {
38
+ return Api(storage).get('/users/google/url')
39
+ },
40
+ google (data, storage) {
41
+ data.device_id = deviceID
42
+ return Api(storage).post('/users/google', data)
43
+ },
44
+ facebook (data, storage) {
45
+ data.device_id = deviceID
46
+ return Api(storage).post('/users/facebook', data)
47
+ },
48
+ googleSDK (data, storage) {
49
+ data.device_id = deviceID
50
+ return Api(storage).post('/users/google/sdk', data)
51
+ },
52
+ facebookSDK (data, storage) {
53
+ data.device_id = deviceID
54
+ return Api(storage).post('/users/facebook/sdk', data)
55
+ },
56
+ appleSDK (data, storage) {
57
+ data.device_id = deviceID
58
+ return Api(storage).post('/users/apple/sdk', data)
59
+ },
60
+ microsoftSDK (data, storage) {
61
+ data.device_id = deviceID
62
+ return Api(storage).post('/users/microsoft/sdk', data)
63
+ },
64
+ oktaSDK (data, storage) {
65
+ data.device_id = deviceID
66
+ return Api(storage).post('/users/okta/sdk', data)
67
+ },
68
+ samlLoginUrl (data, storage) {
69
+ return Api(storage).post('/saml/url', data)
70
+ }
71
+ }
@@ -0,0 +1,13 @@
1
+ import Api from './Api'
2
+
3
+ export default {
4
+ getBySSOEmail (email, storage) {
5
+ return Api(storage).get(`/company/sso/${email}`)
6
+ },
7
+ acceptCompanyInvitation (code, storage) {
8
+ return Api(storage).get(`/users/invitation?ic=${code}`)
9
+ },
10
+ qrCodePooling(payload, storage) {
11
+ return Api(storage).post("/company/login/qr", payload);
12
+ },
13
+ }
@@ -0,0 +1,10 @@
1
+ import Api from './Api'
2
+
3
+ export default {
4
+ registerDevice(data, storage) {
5
+ return Api(storage).post(`/devices/add`, data)
6
+ },
7
+ addFcmToken(data, storage) {
8
+ return Api(storage).post(`/devices/fcm/add`, data)
9
+ }
10
+ }
@@ -0,0 +1,49 @@
1
+ import Api from "./Api";
2
+
3
+ export default {
4
+ getMe() {
5
+ return Api(storage).get(`/users/me`);
6
+ },
7
+ getByUsername(data, storage) {
8
+ let referrer = document.referrer || "";
9
+ let params = data.utmParams || {};
10
+ if (data.dontTap) params.dontTap = true;
11
+ return Api(storage).get(`/users/${data.username}`, {
12
+ params,
13
+ headers: { "X-Referer": referrer },
14
+ });
15
+ },
16
+ getByNumber(data, storage) {
17
+ let referrer = document.referrer || "";
18
+ let params = data.utmParams || {};
19
+ if (data.dontTap) params.dontTap = true;
20
+ return Api(storage).get(`/users/tag/${data.serial}`, {
21
+ params,
22
+ headers: { "X-Referer": referrer },
23
+ });
24
+ },
25
+ save(data, storage) {
26
+ return Api(storage).put(`/users`, data);
27
+ },
28
+ newPassword(data, storage) {
29
+ return Api(storage).put(`/users/new-password`, data);
30
+ },
31
+ connect(data, storage) {
32
+ return Api(storage).post(`/users/connect`, data);
33
+ },
34
+ eventLog(data, storage) {
35
+ return Api(storage).post(`/users/log`, data);
36
+ },
37
+ deleteAccount(data, storage) {
38
+ return Api(storage).post(`/users/profile/delete`, data);
39
+ },
40
+ registerDevice(data, storage) {
41
+ return Api(storage).post(`/users/device/register`, data);
42
+ },
43
+ addFcmToken(data, storage) {
44
+ return Api(storage).post(`/users/device/fcm`, data);
45
+ },
46
+ loginUsingQR(data, storage) {
47
+ return Api(storage).post("/users/qr/login", data);
48
+ }
49
+ };
@@ -0,0 +1,221 @@
1
+ export default {
2
+ getFirstBrowserLanguage() {
3
+ let nav = window.navigator
4
+ let browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage']
5
+ let i
6
+ let language
7
+
8
+ // support for HTML 5.1 "navigator.languages"
9
+ if (Array.isArray(nav.languages)) {
10
+ for (i = 0; i < nav.languages.length; i++) {
11
+ language = nav.languages[i]
12
+ if (language && language.length) {
13
+ return language.slice(0, 2)
14
+ }
15
+ }
16
+ }
17
+
18
+ // support for other well known properties in browsers
19
+ for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
20
+ language = nav[browserLanguagePropertyKeys[i]]
21
+ if (language && language.length) {
22
+ return language.slice(0, 2)
23
+ }
24
+ }
25
+
26
+ return null
27
+ },
28
+ compareLangKeys() {
29
+ const en = Object.keys(require('../store/locales/en').default.state);
30
+ const de = Object.keys(require('../store/locales/de').default.state);
31
+ const es = Object.keys(require('../store/locales/es').default.state);
32
+ const kr = Object.keys(require('../store/locales/kr').default.state);
33
+ const it = Object.keys(require('../store/locales/it').default.state);
34
+ const fr = Object.keys(require('../store/locales/fr').default.state);
35
+ const sr = Object.keys(require('../store/locales/sr').default.state);
36
+ const tr = Object.keys(require('../store/locales/tr').default.state);
37
+
38
+ // Compare en and de
39
+ console.log('In en but not in de', en.filter(x => !de.includes(x)));
40
+ console.log('In de but not in en', de.filter(x => !en.includes(x)));
41
+ console.log();
42
+
43
+ // Compare en and es
44
+ console.log('In en but not in es', en.filter(x => !es.includes(x)));
45
+ console.log('In es but not in en', es.filter(x => !en.includes(x)));
46
+ console.log();
47
+
48
+ // Compare en and kr
49
+ console.log('In en but not in kr', en.filter(x => !kr.includes(x)));
50
+ console.log('In kr but not in en', kr.filter(x => !en.includes(x)));
51
+ console.log();
52
+
53
+ // Compare en and it
54
+ console.log('In en but not in it', en.filter(x => !it.includes(x)));
55
+ console.log('In it but not in en', it.filter(x => !en.includes(x)));
56
+ console.log();
57
+
58
+ // Compare en and fr
59
+ console.log('In en but not in fr', en.filter(x => !fr.includes(x)));
60
+ console.log('In fr but not in en', fr.filter(x => !en.includes(x)));
61
+ console.log();
62
+
63
+ // Compare en and sr
64
+ console.log('In en but not in sr', en.filter(x => !sr.includes(x)));
65
+ console.log('In sr but not in en', sr.filter(x => !en.includes(x)));
66
+ console.log();
67
+
68
+ // Compare en and tr
69
+ console.log('In en but not in tr', en.filter(x => !tr.includes(x)));
70
+ console.log('In tr but not in en', tr.filter(x => !en.includes(x)));
71
+ console.log();
72
+ },
73
+ base64ImageToBlob(base64Image) {
74
+ // Split into two parts
75
+ const parts = base64Image.split(';base64,');
76
+
77
+ // Hold the content type
78
+ const imageType = parts[0].split(':')[1];
79
+
80
+ // Decode Base64 string
81
+ const decodedData = window.atob(parts[1]);
82
+
83
+ // Create UNIT8ARRAY of size same as row data length
84
+ const uInt8Array = new Uint8Array(decodedData.length);
85
+
86
+ // Insert all character code into uInt8Array
87
+ for (let i = 0; i < decodedData.length; ++i) {
88
+ uInt8Array[i] = decodedData.charCodeAt(i);
89
+ }
90
+
91
+ // Return BLOB image after conversion
92
+ return new Blob([uInt8Array], {type: imageType});
93
+ },
94
+ blobToBase64(blob) {
95
+ const reader = new FileReader();
96
+ reader.readAsDataURL(blob);
97
+ return new Promise(resolve => {
98
+ reader.onloadend = () => {
99
+ resolve(reader.result);
100
+ };
101
+ });
102
+ },
103
+ base64toFile(base64, filename) {
104
+
105
+ var arr = base64.split(','),
106
+ mime = arr[0].match(/:(.*?);/)[1],
107
+ bstr = atob(arr[1]),
108
+ n = bstr.length,
109
+ u8arr = new Uint8Array(n);
110
+
111
+ while (n--) {
112
+ u8arr[n] = bstr.charCodeAt(n);
113
+ }
114
+
115
+ return new File([u8arr], filename, {type: mime});
116
+ },
117
+ fileToBase64(file) {
118
+ new Promise((resolve, reject) => {
119
+ const reader = new FileReader();
120
+ reader.readAsDataURL(file);
121
+ reader.onload = () => resolve(reader.result);
122
+ reader.onerror = error => reject(error);
123
+ });
124
+ },
125
+ getUTMParams(data, storage) {
126
+ let utm = {}
127
+ if (data.utm_source) utm.utm_source = data.utm_source;
128
+ if (data.utm_medium) utm.utm_medium = data.utm_medium;
129
+ if (data.utm_campaign) utm.utm_campaign = data.utm_campaign;
130
+ if (data.utm_term) utm.utm_term = data.utm_term;
131
+ if (data.utm_content) utm.utm_content = data.utm_content;
132
+ return utm;
133
+ },
134
+
135
+ cropCardScan(base64PictureData, callback) {
136
+
137
+ // image will contain ORIGINAL image
138
+ const image = new window.Image();
139
+
140
+ // image will contain CROPPED image
141
+ const canvas = document.createElement('canvas');
142
+ const ctx = canvas.getContext('2d');
143
+
144
+ // Load original image into image element
145
+ image.src = 'data:image/jpeg;base64,' + base64PictureData;
146
+ image.onload = () => {
147
+ const sw = image.width;
148
+ const sh = image.width / 1.65;
149
+ const sx = 0;
150
+ const sy = (image.height / 2) - (sh / 2)
151
+ const dw = sw;
152
+ const dh = sh;
153
+ canvas.width = dw;
154
+ canvas.height = dh
155
+ // https://i.stack.imgur.com/USDAX.png
156
+ ctx.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); // Crop interpolated rectangle
157
+ const croppedBase64Image = canvas.toDataURL();
158
+
159
+ callback(croppedBase64Image);
160
+
161
+ return croppedBase64Image;
162
+ };
163
+ },
164
+ generateRandomString(length) {
165
+ let array = new Uint32Array(length);
166
+ window.crypto.getRandomValues(array);
167
+ return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
168
+ },
169
+ async pkceChallengeFromVerifier(v) {
170
+ const encoder = new TextEncoder();
171
+ const data = encoder.encode(v);
172
+ const hashed = await window.crypto.subtle.digest('SHA-256', data);
173
+ // base64 url encode
174
+ return btoa(String.fromCharCode.apply(null, new Uint8Array(hashed))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
175
+ },
176
+ encryptAES(key, iv, data) {
177
+ let encoder = new TextEncoder();
178
+ let encoded = encoder.encode(data, storage);
179
+ return window.crypto.subtle.encrypt(
180
+ {
181
+ name: "AES-CBC",
182
+ iv: iv,
183
+ },
184
+ key,
185
+ encoded,
186
+ );
187
+ },
188
+ async decryptAES(key, iv, data) {
189
+ try {
190
+ const fromBase64 = base64String => Uint8Array.from(atob(base64String), c => c.charCodeAt(0));
191
+
192
+ //console.log("key: " + key);
193
+ //console.log("iv: " + iv);
194
+
195
+ data = data.replace(/ /g, '+');
196
+
197
+ const encoder = new TextEncoder();
198
+ const decoder = new TextDecoder();
199
+
200
+ key = encoder.encode(key);
201
+ iv = encoder.encode(iv);
202
+ data = fromBase64(data, storage);
203
+
204
+
205
+ const secretKey = await window.crypto.subtle.importKey('raw', key, 'AES-CBC', true, ['encrypt', 'decrypt']);
206
+
207
+
208
+ let decoded = await window.crypto.subtle.decrypt({name: "AES-CBC", iv}, secretKey, data);
209
+
210
+ decoded = decoder.decode(decoded);
211
+ decoded = decoded.replace(/ /g, '+');
212
+ decoded = atob(decoded);
213
+
214
+ return decoded;
215
+
216
+
217
+ } catch (err) {
218
+ console.log(err)
219
+ }
220
+ }
221
+ }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ ANDROID_VERSION: '5.6',
3
+ IOS_VERSION: '5.6',
4
+ WEB_VERSION: '5.6.0',
5
+ SUPPORTED_LANGUAGES: ['en', 'de', 'es', 'kr', 'it', 'fr'],
6
+ METAPIXEL_ID: '1203678696914368',
7
+ GOOGLE_ANALYTICS_ID: ''
8
+ }
@@ -0,0 +1,30 @@
1
+ import { reactive, readonly } from 'vue';
2
+
3
+ const listeners = reactive(new Map());
4
+
5
+ export const EventBus = {
6
+ $on(event, listener) {
7
+ let eventListeners = listeners.get(event);
8
+ if (!eventListeners) {
9
+ eventListeners = new Set();
10
+ listeners.set(event, eventListeners);
11
+ }
12
+ eventListeners.add(listener);
13
+ },
14
+ $emit(event, ...args) {
15
+ const eventListeners = listeners.get(event);
16
+ if (eventListeners) {
17
+ for (const listener of eventListeners) {
18
+ listener(...args);
19
+ }
20
+ }
21
+ },
22
+ $off(event, listener) {
23
+ const eventListeners = listeners.get(event);
24
+ if (eventListeners) {
25
+ eventListeners.delete(listener);
26
+ }
27
+ }
28
+ };
29
+
30
+ export default readonly(EventBus);