@tapni/auth 1.0.5 → 1.0.6-4.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.
- package/README.md +2 -0
- package/dist/.vite/manifest.json +16 -43
- package/dist/.well-known/assetlinks.json +10 -12
- package/dist/.well-known/microsoft-identity-association.json +5 -5
- package/dist/{Apps-DMds3Dv-.js → Apps-DRhdYq0_.js} +34 -34
- package/dist/Billing-DkXdzGvS.js +256 -0
- package/dist/CustomApp-Dw80xmqU.js +83 -0
- package/dist/QR-ByY4IUiV.js +41 -0
- package/dist/TapniAuth.es.js +1 -1
- package/dist/TapniAuth.umd.js +49 -23
- package/dist/{install-L-cxSovH.js → install-Cb6nCJn_.js} +6265 -4741
- package/dist/site.webmanifest +11 -1
- package/dist/style.css +1 -1
- package/dist/{web-IFGkBi0t.js → web-UrTMimK1.js} +2 -2
- package/package.json +66 -55
- package/src/.prettierrc.json +16 -0
- package/src/App.vue +326 -269
- package/src/eslint.config.js +15 -0
- package/src/index.js +4 -0
- package/src/install.js +9 -10
- package/src/main.js +54 -57
- package/src/mixins/apple.mixin.js +56 -54
- package/src/mixins/auth.mixin.js +3 -2
- package/src/mixins/global.mixin.js +3 -3
- package/src/mixins/google.mixin.js +53 -54
- package/src/mixins/microsoft.mixin.js +2 -5
- package/src/mixins/okta.mixin.js +1 -1
- package/src/mixins/qr-auth.mixin.js +111 -107
- package/src/mixins/saml.mixin.js +82 -45
- package/src/router/index.js +6 -6
- package/src/routes.js +1 -1
- package/src/services/Api.js +56 -58
- package/src/services/AuthService.js +7 -9
- package/src/services/CompanyService.js +10 -10
- package/src/services/DeviceService.js +3 -3
- package/src/services/UserService.js +48 -45
- package/src/services/UtilService.js +317 -225
- package/src/store/auth.js +485 -549
- package/src/store/constants.js +2 -2
- package/src/store/event-bus.js +22 -22
- package/src/store/locales/cn.js +476 -458
- package/src/store/locales/de.js +478 -517
- package/src/store/locales/en.js +454 -513
- package/src/store/locales/es.js +477 -524
- package/src/store/locales/fr.js +477 -516
- package/src/store/locales/it.js +477 -514
- package/src/store/locales/ja.js +488 -0
- package/src/store/locales/kr.js +477 -491
- package/src/store/locales/lang.js +51 -43
- package/src/store/locales/pt.js +488 -0
- package/src/store/locales/sr.js +477 -492
- package/src/store/locales/tr.js +477 -487
- package/src/store/store.js +6 -6
- package/src/views/Account.vue +36 -8
- package/src/views/Billing.vue +464 -34
- package/src/views/Callback.vue +36 -33
- package/src/views/General.vue +151 -185
- package/src/views/Login.vue +2 -25
- package/src/views/Register.vue +2 -12
- package/src/views/Reset.vue +132 -135
- package/src/views/Security.vue +13 -7
- package/src/views/Verify.vue +153 -151
- package/src/views/Welcome.vue +85 -71
- package/dist/Account-Cuz87g_8.js +0 -153
- package/dist/Billing-BXlQEuNy.js +0 -113
- package/dist/CustomApp-CLCMXmMO.js +0 -83
- package/dist/General-dW73bMoR.js +0 -479
- package/dist/QR-D6ZGcPM0.js +0 -41
- package/dist/index.css +0 -193
- package/dist/web-AXRKjAOB.js +0 -92
- package/src/components/DELETE_Language.vue +0 -168
- package/src/components/DELETE_LinkIcon.vue +0 -288
- package/src/components/DELETE_ModalOverlay.vue +0 -68
- package/src/components/DELETE_OTP.vue +0 -105
- package/src/components/DELETE_SSO.vue +0 -120
- package/src/components/DELETE_SSOPick.vue +0 -166
- package/src/mixins/DELETE_mfa-auth.mixin.js +0 -53
- package/src/mixins/facebook.mixin.js +0 -78
|
@@ -1,49 +1,52 @@
|
|
|
1
1
|
import api from './Api.js';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
4
|
+
getMe() {
|
|
5
|
+
return api().get(`/users/me`);
|
|
6
|
+
},
|
|
7
|
+
getByUsername(data) {
|
|
8
|
+
let referrer = document.referrer || '';
|
|
9
|
+
let params = data.utmParams || {};
|
|
10
|
+
if (data.dontTap) params.dontTap = true;
|
|
11
|
+
return api().get(`/users/${data.username}`, {
|
|
12
|
+
params,
|
|
13
|
+
headers: { 'X-Referer': referrer }
|
|
14
|
+
});
|
|
15
|
+
},
|
|
16
|
+
getByNumber(data) {
|
|
17
|
+
let referrer = document.referrer || '';
|
|
18
|
+
let params = data.utmParams || {};
|
|
19
|
+
if (data.dontTap) params.dontTap = true;
|
|
20
|
+
return api().get(`/users/tag/${data.serial}`, {
|
|
21
|
+
params,
|
|
22
|
+
headers: { 'X-Referer': referrer }
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
save(data) {
|
|
26
|
+
return api().put(`/users`, data);
|
|
27
|
+
},
|
|
28
|
+
newPassword(data) {
|
|
29
|
+
return api().put(`/users/new-password`, data);
|
|
30
|
+
},
|
|
31
|
+
connect(data) {
|
|
32
|
+
return api().post(`/users/connect`, data);
|
|
33
|
+
},
|
|
34
|
+
eventLog(data) {
|
|
35
|
+
return api().post(`/users/log`, data);
|
|
36
|
+
},
|
|
37
|
+
deleteAccount(data) {
|
|
38
|
+
return api().post(`/users/profile/delete`, data);
|
|
39
|
+
},
|
|
40
|
+
registerDevice(data) {
|
|
41
|
+
return api().post(`/users/device/register`, data);
|
|
42
|
+
},
|
|
43
|
+
addFcmToken(data) {
|
|
44
|
+
return api().post(`/users/device/fcm`, data);
|
|
45
|
+
},
|
|
46
|
+
loginUsingQR(data) {
|
|
47
|
+
return api().post('/users/qr/login', data);
|
|
48
|
+
},
|
|
49
|
+
updateAccount(data) {
|
|
50
|
+
return api().put('/accounts/me', data);
|
|
51
|
+
}
|
|
49
52
|
};
|
|
@@ -1,228 +1,320 @@
|
|
|
1
|
-
import enLocale from '../store/locales/en';
|
|
2
|
-
import deLocale from '../store/locales/de';
|
|
3
|
-
import esLocale from '../store/locales/es';
|
|
4
|
-
import krLocale from '../store/locales/kr';
|
|
5
|
-
import itLocale from '../store/locales/it';
|
|
6
|
-
import frLocale from '../store/locales/fr';
|
|
7
|
-
import srLocale from '../store/locales/sr';
|
|
1
|
+
import enLocale from '../store/locales/en.js';
|
|
2
|
+
import deLocale from '../store/locales/de.js';
|
|
3
|
+
import esLocale from '../store/locales/es.js';
|
|
4
|
+
import krLocale from '../store/locales/kr.js';
|
|
5
|
+
import itLocale from '../store/locales/it.js';
|
|
6
|
+
import frLocale from '../store/locales/fr.js';
|
|
7
|
+
import srLocale from '../store/locales/sr.js';
|
|
8
8
|
import trLocale from '../store/locales/tr';
|
|
9
|
+
import { sha256 } from 'js-sha256';
|
|
10
|
+
|
|
11
|
+
// Helper function to safely get random values
|
|
12
|
+
const getRandomValues = (array) => {
|
|
13
|
+
try {
|
|
14
|
+
return window.crypto.getRandomValues(array);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
for (let i = 0; i < array.length; i++) {
|
|
17
|
+
array[i] = Math.floor(Math.random() * 256);
|
|
18
|
+
}
|
|
19
|
+
return array;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Helper function to safely perform crypto digest
|
|
24
|
+
const performDigest = async (data) => {
|
|
25
|
+
try {
|
|
26
|
+
return await window.crypto.subtle.digest('SHA-256', data);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
const hash = sha256(data);
|
|
29
|
+
return new Uint8Array(hash.match(/.{1,2}/g).map(byte => parseInt(byte, 16))).buffer;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Helper function to safely perform crypto encrypt
|
|
34
|
+
const performEncrypt = async (algorithm, key, data) => {
|
|
35
|
+
try {
|
|
36
|
+
return await window.crypto.subtle.encrypt(algorithm, key, data);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
throw new Error('Encryption not supported in this environment');
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Helper function to safely perform crypto decrypt
|
|
43
|
+
const performDecrypt = async (algorithm, key, data) => {
|
|
44
|
+
try {
|
|
45
|
+
return await window.crypto.subtle.decrypt(algorithm, key, data);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
throw new Error('Decryption not supported in this environment');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
9
50
|
|
|
10
51
|
export default {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
52
|
+
getFirstBrowserLanguage() {
|
|
53
|
+
let nav = window.navigator;
|
|
54
|
+
let browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'];
|
|
55
|
+
let i;
|
|
56
|
+
let language;
|
|
57
|
+
|
|
58
|
+
// support for HTML 5.1 "navigator.languages"
|
|
59
|
+
if (Array.isArray(nav.languages)) {
|
|
60
|
+
for (i = 0; i < nav.languages.length; i++) {
|
|
61
|
+
language = nav.languages[i];
|
|
62
|
+
if (language && language.length) {
|
|
63
|
+
return language.slice(0, 2);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// support for other well known properties in browsers
|
|
69
|
+
for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
|
|
70
|
+
language = nav[browserLanguagePropertyKeys[i]];
|
|
71
|
+
if (language && language.length) {
|
|
72
|
+
return language.slice(0, 2);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null;
|
|
77
|
+
},
|
|
78
|
+
compareLangKeys() {
|
|
79
|
+
const en = Object.keys(enLocale.state);
|
|
80
|
+
const de = Object.keys(deLocale.state);
|
|
81
|
+
const es = Object.keys(esLocale.state);
|
|
82
|
+
const kr = Object.keys(krLocale.state);
|
|
83
|
+
const it = Object.keys(itLocale.state);
|
|
84
|
+
const fr = Object.keys(frLocale.state);
|
|
85
|
+
const sr = Object.keys(srLocale.state);
|
|
86
|
+
const tr = Object.keys(trLocale.state);
|
|
87
|
+
|
|
88
|
+
// Compare en and de
|
|
89
|
+
console.log(
|
|
90
|
+
'In en but not in de',
|
|
91
|
+
en.filter((x) => !de.includes(x))
|
|
92
|
+
);
|
|
93
|
+
console.log(
|
|
94
|
+
'In de but not in en',
|
|
95
|
+
de.filter((x) => !en.includes(x))
|
|
96
|
+
);
|
|
97
|
+
console.log();
|
|
98
|
+
|
|
99
|
+
// Compare en and es
|
|
100
|
+
console.log(
|
|
101
|
+
'In en but not in es',
|
|
102
|
+
en.filter((x) => !es.includes(x))
|
|
103
|
+
);
|
|
104
|
+
console.log(
|
|
105
|
+
'In es but not in en',
|
|
106
|
+
es.filter((x) => !en.includes(x))
|
|
107
|
+
);
|
|
108
|
+
console.log();
|
|
109
|
+
|
|
110
|
+
// Compare en and kr
|
|
111
|
+
console.log(
|
|
112
|
+
'In en but not in kr',
|
|
113
|
+
en.filter((x) => !kr.includes(x))
|
|
114
|
+
);
|
|
115
|
+
console.log(
|
|
116
|
+
'In kr but not in en',
|
|
117
|
+
kr.filter((x) => !en.includes(x))
|
|
118
|
+
);
|
|
119
|
+
console.log();
|
|
120
|
+
|
|
121
|
+
// Compare en and it
|
|
122
|
+
console.log(
|
|
123
|
+
'In en but not in it',
|
|
124
|
+
en.filter((x) => !it.includes(x))
|
|
125
|
+
);
|
|
126
|
+
console.log(
|
|
127
|
+
'In it but not in en',
|
|
128
|
+
it.filter((x) => !en.includes(x))
|
|
129
|
+
);
|
|
130
|
+
console.log();
|
|
131
|
+
|
|
132
|
+
// Compare en and fr
|
|
133
|
+
console.log(
|
|
134
|
+
'In en but not in fr',
|
|
135
|
+
en.filter((x) => !fr.includes(x))
|
|
136
|
+
);
|
|
137
|
+
console.log(
|
|
138
|
+
'In fr but not in en',
|
|
139
|
+
fr.filter((x) => !en.includes(x))
|
|
140
|
+
);
|
|
141
|
+
console.log();
|
|
142
|
+
|
|
143
|
+
// Compare en and sr
|
|
144
|
+
console.log(
|
|
145
|
+
'In en but not in sr',
|
|
146
|
+
en.filter((x) => !sr.includes(x))
|
|
147
|
+
);
|
|
148
|
+
console.log(
|
|
149
|
+
'In sr but not in en',
|
|
150
|
+
sr.filter((x) => !en.includes(x))
|
|
151
|
+
);
|
|
152
|
+
console.log();
|
|
153
|
+
|
|
154
|
+
// Compare en and tr
|
|
155
|
+
console.log(
|
|
156
|
+
'In en but not in tr',
|
|
157
|
+
en.filter((x) => !tr.includes(x))
|
|
158
|
+
);
|
|
159
|
+
console.log(
|
|
160
|
+
'In tr but not in en',
|
|
161
|
+
tr.filter((x) => !en.includes(x))
|
|
162
|
+
);
|
|
163
|
+
console.log();
|
|
164
|
+
},
|
|
165
|
+
base64ImageToBlob(base64Image) {
|
|
166
|
+
// Split into two parts
|
|
167
|
+
const parts = base64Image.split(';base64,');
|
|
168
|
+
|
|
169
|
+
// Hold the content type
|
|
170
|
+
const imageType = parts[0].split(':')[1];
|
|
171
|
+
|
|
172
|
+
// Decode Base64 string
|
|
173
|
+
const decodedData = window.atob(parts[1]);
|
|
174
|
+
|
|
175
|
+
// Create UNIT8ARRAY of size same as row data length
|
|
176
|
+
const uInt8Array = new Uint8Array(decodedData.length);
|
|
177
|
+
|
|
178
|
+
// Insert all character code into uInt8Array
|
|
179
|
+
for (let i = 0; i < decodedData.length; ++i) {
|
|
180
|
+
uInt8Array[i] = decodedData.charCodeAt(i);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Return BLOB image after conversion
|
|
184
|
+
return new Blob([uInt8Array], { type: imageType });
|
|
185
|
+
},
|
|
186
|
+
blobToBase64(blob) {
|
|
187
|
+
const reader = new FileReader();
|
|
188
|
+
reader.readAsDataURL(blob);
|
|
189
|
+
return new Promise((resolve) => {
|
|
190
|
+
reader.onloadend = () => {
|
|
191
|
+
resolve(reader.result);
|
|
192
|
+
};
|
|
193
|
+
});
|
|
194
|
+
},
|
|
195
|
+
base64toFile(base64, filename) {
|
|
196
|
+
var arr = base64.split(','),
|
|
197
|
+
mime = arr[0].match(/:(.*?);/)[1],
|
|
198
|
+
bstr = atob(arr[1]),
|
|
199
|
+
n = bstr.length,
|
|
200
|
+
u8arr = new Uint8Array(n);
|
|
201
|
+
|
|
202
|
+
while (n--) {
|
|
203
|
+
u8arr[n] = bstr.charCodeAt(n);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return new File([u8arr], filename, { type: mime });
|
|
207
|
+
},
|
|
208
|
+
fileToBase64(file) {
|
|
209
|
+
new Promise((resolve, reject) => {
|
|
210
|
+
const reader = new FileReader();
|
|
211
|
+
reader.readAsDataURL(file);
|
|
212
|
+
reader.onload = () => resolve(reader.result);
|
|
213
|
+
reader.onerror = (error) => reject(error);
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
getUTMParams(data) {
|
|
217
|
+
let utm = {};
|
|
218
|
+
if (data.utm_source) utm.utm_source = data.utm_source;
|
|
219
|
+
if (data.utm_medium) utm.utm_medium = data.utm_medium;
|
|
220
|
+
if (data.utm_campaign) utm.utm_campaign = data.utm_campaign;
|
|
221
|
+
if (data.utm_term) utm.utm_term = data.utm_term;
|
|
222
|
+
if (data.utm_content) utm.utm_content = data.utm_content;
|
|
223
|
+
return utm;
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
cropCardScan(base64PictureData, callback) {
|
|
227
|
+
// image will contain ORIGINAL image
|
|
228
|
+
const image = new window.Image();
|
|
229
|
+
|
|
230
|
+
// image will contain CROPPED image
|
|
231
|
+
const canvas = document.createElement('canvas');
|
|
232
|
+
const ctx = canvas.getContext('2d');
|
|
233
|
+
|
|
234
|
+
// Load original image into image element
|
|
235
|
+
image.src = 'data:image/jpeg;base64,' + base64PictureData;
|
|
236
|
+
image.onload = () => {
|
|
237
|
+
const sw = image.width;
|
|
238
|
+
const sh = image.width / 1.65;
|
|
239
|
+
const sx = 0;
|
|
240
|
+
const sy = image.height / 2 - sh / 2;
|
|
241
|
+
const dw = sw;
|
|
242
|
+
const dh = sh;
|
|
243
|
+
canvas.width = dw;
|
|
244
|
+
canvas.height = dh;
|
|
245
|
+
// https://i.stack.imgur.com/USDAX.png
|
|
246
|
+
ctx.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); // Crop interpolated rectangle
|
|
247
|
+
const croppedBase64Image = canvas.toDataURL();
|
|
248
|
+
|
|
249
|
+
callback(croppedBase64Image);
|
|
250
|
+
|
|
251
|
+
return croppedBase64Image;
|
|
252
|
+
};
|
|
253
|
+
},
|
|
254
|
+
generateRandomString(length) {
|
|
255
|
+
let array = new Uint32Array(length);
|
|
256
|
+
getRandomValues(array);
|
|
257
|
+
return Array.from(array, (dec) => ('0' + dec.toString(16)).substr(-2)).join('');
|
|
258
|
+
},
|
|
259
|
+
async pkceChallengeFromVerifier(v) {
|
|
260
|
+
try {
|
|
261
|
+
const encoder = new TextEncoder();
|
|
262
|
+
const data = encoder.encode(v);
|
|
263
|
+
const hashed = await performDigest(data);
|
|
264
|
+
const base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(hashed)))
|
|
265
|
+
.replace(/\+/g, '-')
|
|
266
|
+
.replace(/\//g, '_')
|
|
267
|
+
.replace(/=+$/, '');
|
|
268
|
+
return base64;
|
|
269
|
+
} catch (error) {
|
|
270
|
+
const hash = sha256(v);
|
|
271
|
+
const base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(hash.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))))
|
|
272
|
+
.replace(/\+/g, '-')
|
|
273
|
+
.replace(/\//g, '_')
|
|
274
|
+
.replace(/=+$/, '');
|
|
275
|
+
return base64;
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
async encryptAES(key, iv, data) {
|
|
279
|
+
try {
|
|
280
|
+
let encoder = new TextEncoder();
|
|
281
|
+
let encoded = encoder.encode(data);
|
|
282
|
+
return await performEncrypt(
|
|
283
|
+
{
|
|
284
|
+
name: 'AES-CBC',
|
|
285
|
+
iv: iv
|
|
286
|
+
},
|
|
287
|
+
key,
|
|
288
|
+
encoded
|
|
289
|
+
);
|
|
290
|
+
} catch (error) {
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
async decryptAES(key, iv, data) {
|
|
295
|
+
try {
|
|
296
|
+
const fromBase64 = (base64String) => Uint8Array.from(atob(base64String), (c) => c.charCodeAt(0));
|
|
297
|
+
|
|
298
|
+
data = data.replace(/ /g, '+');
|
|
299
|
+
|
|
300
|
+
const encoder = new TextEncoder();
|
|
301
|
+
const decoder = new TextDecoder();
|
|
302
|
+
|
|
303
|
+
key = encoder.encode(key);
|
|
304
|
+
iv = encoder.encode(iv);
|
|
305
|
+
data = fromBase64(data);
|
|
306
|
+
|
|
307
|
+
const secretKey = await window.crypto.subtle.importKey('raw', key, 'AES-CBC', true, ['encrypt', 'decrypt']);
|
|
308
|
+
|
|
309
|
+
let decoded = await performDecrypt({ name: 'AES-CBC', iv }, secretKey, data);
|
|
310
|
+
|
|
311
|
+
decoded = decoder.decode(decoded);
|
|
312
|
+
decoded = decoded.replace(/ /g, '+');
|
|
313
|
+
decoded = atob(decoded);
|
|
314
|
+
|
|
315
|
+
return decoded;
|
|
316
|
+
} catch (err) {
|
|
317
|
+
throw err;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|