@tapni/auth 0.0.2 → 0.0.3
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/dist/TapniAuth.es.js +1 -1
- package/dist/TapniAuth.umd.js +1 -1
- package/package.json +3 -2
- package/src/App.vue +269 -0
- package/src/components/Language.vue +158 -0
- package/src/components/LinkIcon.vue +288 -0
- package/src/components/ModalOverlay.vue +67 -0
- package/src/components/SSO.vue +126 -0
- package/src/components/SSOPick.vue +166 -0
- package/src/install.js +8 -0
- package/src/main.js +96 -0
- package/src/mixins/apple.mixin.js +60 -0
- package/src/mixins/auth.mixin.js +525 -0
- package/src/mixins/facebook.mixin.js +78 -0
- package/src/mixins/global.mixin.js +110 -0
- package/src/mixins/google.mixin.js +61 -0
- package/src/mixins/microsoft.mixin.js +88 -0
- package/src/mixins/okta.mixin.js +132 -0
- package/src/mixins/qr-auth.mixin.js +112 -0
- package/src/mixins/saml.mixin.js +84 -0
- package/src/router/index.js +9 -0
- package/src/routes.js +55 -0
- package/src/services/Api.js +55 -0
- package/src/services/AuthService.js +71 -0
- package/src/services/CompanyService.js +13 -0
- package/src/services/DeviceService.js +10 -0
- package/src/services/UserService.js +49 -0
- package/src/services/UtilService.js +221 -0
- package/src/store/constants.js +8 -0
- package/src/store/event-bus.js +30 -0
- package/src/store/locales/cn.js +462 -0
- package/src/store/locales/de.js +528 -0
- package/src/store/locales/en.js +514 -0
- package/src/store/locales/es.js +536 -0
- package/src/store/locales/fr.js +520 -0
- package/src/store/locales/it.js +518 -0
- package/src/store/locales/kr.js +496 -0
- package/src/store/locales/lang.js +47 -0
- package/src/store/locales/sr.js +497 -0
- package/src/store/locales/tr.js +491 -0
- package/src/styles/framework.css +4012 -0
- package/src/styles/inter.ttf +0 -0
- package/src/styles/style.css +618 -0
- package/src/views/Callback.vue +47 -0
- package/src/views/Login.vue +389 -0
- package/src/views/QR.vue +39 -0
- package/src/views/Register.vue +217 -0
- package/src/views/Reset.vue +155 -0
- package/src/views/Verify.vue +170 -0
- package/src/views/Welcome.vue +69 -0
package/src/main.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import "./styles/framework.css";
|
|
2
|
+
import "./styles/style.css";
|
|
3
|
+
|
|
4
|
+
import { createApp } from 'vue'
|
|
5
|
+
import RootApp from './App.vue'
|
|
6
|
+
import router from './router'
|
|
7
|
+
import GlobalMixin from './mixins/global.mixin'
|
|
8
|
+
import VueCookies from 'vue-cookies'
|
|
9
|
+
import { App } from '@capacitor/app';
|
|
10
|
+
import { Browser } from '@capacitor/browser';
|
|
11
|
+
|
|
12
|
+
const app = createApp(RootApp)
|
|
13
|
+
|
|
14
|
+
app.config.productionTip = false
|
|
15
|
+
|
|
16
|
+
// Cookies
|
|
17
|
+
app.use(VueCookies)
|
|
18
|
+
|
|
19
|
+
// Global Mixin
|
|
20
|
+
app.mixin(GlobalMixin)
|
|
21
|
+
|
|
22
|
+
app.use(router)
|
|
23
|
+
|
|
24
|
+
app.mount('#app')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
function hasQueryParams(route) {
|
|
28
|
+
return !!Object.keys(route.query).length
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
router.beforeEach((to, from, next) => {
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
window.scrollTo(0, 0)
|
|
34
|
+
}, 100)
|
|
35
|
+
|
|
36
|
+
if(!hasQueryParams(to) && hasQueryParams(from)){
|
|
37
|
+
next({name: to.name, query: from.query});
|
|
38
|
+
} else {
|
|
39
|
+
next()
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Redirect users to desired profile - DEEP LINKING
|
|
45
|
+
* @param data
|
|
46
|
+
*/
|
|
47
|
+
function redirectToProfile(data) {
|
|
48
|
+
if (data && data.url) {
|
|
49
|
+
let url = new URL(data.url)
|
|
50
|
+
let pathname = url.pathname || '';
|
|
51
|
+
let queryParams = url.search || ''
|
|
52
|
+
if(queryParams) queryParams = Object.fromEntries(new URLSearchParams(queryParams));
|
|
53
|
+
else queryParams = {};
|
|
54
|
+
let subdomain = '';
|
|
55
|
+
//['my', 'tapni', 'co']
|
|
56
|
+
let tempArr = url.hostname.split('.');
|
|
57
|
+
if(tempArr.length === 3) subdomain = tempArr[0];
|
|
58
|
+
if(subdomain) queryParams.s = subdomain;
|
|
59
|
+
|
|
60
|
+
// open t.link shorter links in browser
|
|
61
|
+
if(pathname && /[A-Z]/.test(pathname) && !pathname.startsWith('/t/')) {
|
|
62
|
+
Browser.open({url: url.toString()});
|
|
63
|
+
return router.push('/');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (pathname) {
|
|
67
|
+
router.push({
|
|
68
|
+
path: pathname,
|
|
69
|
+
query: queryParams
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* CAPACITOR_CONFIG
|
|
76
|
+
* Deep linking configuration
|
|
77
|
+
* Users who have an app should get the profiles opened in the app ie: tapni.co/tapni
|
|
78
|
+
*/
|
|
79
|
+
App.addListener('appUrlOpen', async function (data) {
|
|
80
|
+
if(data.url && data.url.startsWith('tapni://')) data.url = data.url.replace('tapni://', 'https://')
|
|
81
|
+
let url = new URL(data.url);
|
|
82
|
+
if(url.pathname.includes('/callback/')) {
|
|
83
|
+
await router.push({path: url.pathname, query: Object.fromEntries(new URLSearchParams(url.search))});
|
|
84
|
+
}
|
|
85
|
+
else redirectToProfile(data);
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// When the app is open and you trigger NFC event to open the app
|
|
89
|
+
// App.addListener('appStateChange', async function (l) {
|
|
90
|
+
// const data = await App.getLaunchUrl()
|
|
91
|
+
// })
|
|
92
|
+
|
|
93
|
+
// When the app is closed and NFC event opens the app
|
|
94
|
+
App.getLaunchUrl().then((data) => {
|
|
95
|
+
redirectToProfile(data)
|
|
96
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import to from 'await-to-js'
|
|
2
|
+
import AuthService from '../services/AuthService'
|
|
3
|
+
import {SignInWithApple} from '@capacitor-community/apple-sign-in';
|
|
4
|
+
|
|
5
|
+
import { jwtDecode } from "jwt-decode";
|
|
6
|
+
import {EventBus} from '../store/event-bus';
|
|
7
|
+
export default {
|
|
8
|
+
data () {
|
|
9
|
+
return {
|
|
10
|
+
appleLoad: false
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
computed: {
|
|
14
|
+
displayAppleLogin () {
|
|
15
|
+
return (this.ssoCompany?.login?.apple_login && !this.isModal) ?? ((Capacitor.isNativePlatform() && Capacitor.getPlatform() === 'ios') || (!Capacitor.isNativePlatform() && this.isiOS));
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
methods: {
|
|
19
|
+
async appleLogin () {
|
|
20
|
+
this.appleLoad = true
|
|
21
|
+
const [errAuth, user] = await to(SignInWithApple.authorize({
|
|
22
|
+
clientId: 'co.tapni.applelogin',
|
|
23
|
+
redirectURI: 'https://' + window.location.host + '/login',
|
|
24
|
+
scopes: 'email name'
|
|
25
|
+
}))
|
|
26
|
+
if (errAuth) return this.appleLoad = false
|
|
27
|
+
user.response.tokenData = jwtDecode(user.response.identityToken);
|
|
28
|
+
|
|
29
|
+
if (user && user.response && user.response.identityToken) {
|
|
30
|
+
// Track Referrals
|
|
31
|
+
if (this.referral) user.response.ref = this.referral;
|
|
32
|
+
|
|
33
|
+
// Code Login
|
|
34
|
+
if (this.display === 'popup') user.response_type = 'code';
|
|
35
|
+
|
|
36
|
+
const [err, response] = await to(AuthService.appleSDK(user.response, this.storage))
|
|
37
|
+
if (err) {
|
|
38
|
+
this.appleLoad = false
|
|
39
|
+
EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
|
|
40
|
+
return this.errorHandler(err)
|
|
41
|
+
}
|
|
42
|
+
if (response.data.success) {
|
|
43
|
+
if (this.display === 'popup') {
|
|
44
|
+
return window.parent?.postMessage({ code: response.data.auth_code, state: this.$route.query.state }, '*');
|
|
45
|
+
}
|
|
46
|
+
await this.loginSetup(response)
|
|
47
|
+
this.getLoggedInAccounts()
|
|
48
|
+
this.$router.push('/' + response.data.data.username + '#edit')
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
this.appleLoad = false
|
|
51
|
+
EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
|
|
52
|
+
}, 1000)
|
|
53
|
+
} else this.errorSnack(this.ssoLang[this.appLang].unexpected_err)
|
|
54
|
+
} else {
|
|
55
|
+
this.appleLoad = false
|
|
56
|
+
EventBus.$emit('ssoEvent', {name: 'setLoading', data: false})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
import to from "await-to-js";
|
|
2
|
+
|
|
3
|
+
import UserService from "../services/UserService";
|
|
4
|
+
import DeviceService from "../services/DeviceService";
|
|
5
|
+
import AuthService from "../services/AuthService";
|
|
6
|
+
import CompanyService from "../services/CompanyService";
|
|
7
|
+
|
|
8
|
+
import { EventBus } from "../store/event-bus";
|
|
9
|
+
import { Device } from "@capacitor/device";
|
|
10
|
+
import axios from "axios";
|
|
11
|
+
import en from "@/store/locales/en.js";
|
|
12
|
+
import de from "@/store/locales/de.js";
|
|
13
|
+
import es from "@/store/locales/es.js";
|
|
14
|
+
import fr from "@/store/locales/fr.js";
|
|
15
|
+
import it from "@/store/locales/it.js";
|
|
16
|
+
import sr from "@/store/locales/sr.js";
|
|
17
|
+
import tr from "@/store/locales/tr.js";
|
|
18
|
+
import cn from "@/store/locales/cn.js";
|
|
19
|
+
import kr from "@/store/locales/kr.js";
|
|
20
|
+
import { StorageMixin } from '@tapni/capacitor-reactive-localstorage-vue3'
|
|
21
|
+
export default {
|
|
22
|
+
mixins: [StorageMixin],
|
|
23
|
+
data() {
|
|
24
|
+
return {
|
|
25
|
+
appLanguage: "en",
|
|
26
|
+
token: "",
|
|
27
|
+
refreshToken: "",
|
|
28
|
+
loggedInUserId: "",
|
|
29
|
+
ssoUser: {},
|
|
30
|
+
ssoCompany: {},
|
|
31
|
+
device: {},
|
|
32
|
+
loggedInAccounts: {},
|
|
33
|
+
ssoLang: {
|
|
34
|
+
en: en.state,
|
|
35
|
+
de: de.state,
|
|
36
|
+
es: es.state,
|
|
37
|
+
fr: fr.state,
|
|
38
|
+
it: it.state,
|
|
39
|
+
sr: sr.state,
|
|
40
|
+
tr: tr.state,
|
|
41
|
+
cn: cn.state,
|
|
42
|
+
kr: kr.state,
|
|
43
|
+
},
|
|
44
|
+
display: import.meta.env.VITE_APP_MODE,
|
|
45
|
+
redirect_uri: import.meta.env.VITE_APP_APP_ROOT + "/callback/auth",
|
|
46
|
+
response_type: "token",
|
|
47
|
+
state: "",
|
|
48
|
+
allowedOrigins: [
|
|
49
|
+
"https://business.tapni.com",
|
|
50
|
+
"https://business-dev.tapni.com",
|
|
51
|
+
"https://tapni.com",
|
|
52
|
+
"https://tapni.co",
|
|
53
|
+
"https://t.link",
|
|
54
|
+
"https://my.tapni.com",
|
|
55
|
+
"https://my.tapni.co",
|
|
56
|
+
"https://dev.tapni.co",
|
|
57
|
+
"https://dev.tapni.com",
|
|
58
|
+
"https://auth.tapni.com",
|
|
59
|
+
"https://auth.tapni.co",
|
|
60
|
+
"https://mailsign.link",
|
|
61
|
+
"https://sign.tapni.com",
|
|
62
|
+
"https://qrcodetoolkit.com",
|
|
63
|
+
"https://qr.tapni.com",
|
|
64
|
+
"https://designer.tapni.com",
|
|
65
|
+
"https://designer-dev.tapni.com",
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
computed: {
|
|
70
|
+
appLang() {
|
|
71
|
+
return this.appLanguage;
|
|
72
|
+
},
|
|
73
|
+
isLoggedIn() {
|
|
74
|
+
return !!this.token && this.token !== "" && this.token !== "null";
|
|
75
|
+
},
|
|
76
|
+
renderView() {
|
|
77
|
+
if (this.display === "redirect") {
|
|
78
|
+
return false;
|
|
79
|
+
} else return this.view;
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
mounted() {
|
|
83
|
+
if (this.$route.query.redirect_uri)
|
|
84
|
+
this.redirect_uri = this.$route.query.redirect_uri;
|
|
85
|
+
if (this.$route.query.display) this.display = this.$route.query.display;
|
|
86
|
+
if (this.$route.query.state) this.state = this.$route.query.state;
|
|
87
|
+
if (this.$route.query.response_type)
|
|
88
|
+
this.response_type = this.$route.query.response_type;
|
|
89
|
+
if (this.$route.query.realm) this.storage.realm = this.$route.query.realm;
|
|
90
|
+
|
|
91
|
+
EventBus.$on("updateLang", this.updateLang);
|
|
92
|
+
|
|
93
|
+
if (import.meta.env.NODE_ENV === "development") {
|
|
94
|
+
this.allowedOrigins.push("http://localhost:8082");
|
|
95
|
+
this.allowedOrigins.push("http://localhost:7777");
|
|
96
|
+
this.allowedOrigins.push("http://localhost:5173");
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
methods: {
|
|
100
|
+
errorHandler(error) {
|
|
101
|
+
if (
|
|
102
|
+
error &&
|
|
103
|
+
error.response &&
|
|
104
|
+
error.response.data &&
|
|
105
|
+
error.response.data.error
|
|
106
|
+
) {
|
|
107
|
+
if (
|
|
108
|
+
error.response.data.error === "ACCESS_DENIED" ||
|
|
109
|
+
error.response.data.error === "TOKEN_EXPIRED"
|
|
110
|
+
) {
|
|
111
|
+
return this.logout();
|
|
112
|
+
}
|
|
113
|
+
// Link click network error bug fix
|
|
114
|
+
if (
|
|
115
|
+
!error.response.data.error.includes("Network Error") &&
|
|
116
|
+
!error.response.data.error.includes("Cannot read properties")
|
|
117
|
+
) {
|
|
118
|
+
this.errorSnack(error.response.data.error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return error;
|
|
122
|
+
},
|
|
123
|
+
errorSnack(message) {
|
|
124
|
+
let snackbar = document.getElementById("snackbar");
|
|
125
|
+
let errMessage = document.getElementById("errorMessage");
|
|
126
|
+
let errorSnack = document.getElementById("errorSnack");
|
|
127
|
+
errMessage.innerHTML = message;
|
|
128
|
+
snackbar.classList.add("show-snack");
|
|
129
|
+
errorSnack.classList.add("active-snack");
|
|
130
|
+
setTimeout(function () {
|
|
131
|
+
errorSnack.classList.remove("active-snack");
|
|
132
|
+
snackbar.classList.remove("show-snack");
|
|
133
|
+
}, 3000);
|
|
134
|
+
},
|
|
135
|
+
successSnack(message) {
|
|
136
|
+
let snackbar = document.getElementById("snackbar");
|
|
137
|
+
let successMessage = document.getElementById("successMessage");
|
|
138
|
+
let successSnack = document.getElementById("successSnack");
|
|
139
|
+
successMessage.innerHTML = message;
|
|
140
|
+
snackbar.classList.add("show-snack");
|
|
141
|
+
successSnack.classList.add("active-snack");
|
|
142
|
+
setTimeout(function () {
|
|
143
|
+
successSnack.classList.remove("active-snack");
|
|
144
|
+
snackbar.classList.remove("show-snack");
|
|
145
|
+
}, 3000);
|
|
146
|
+
},
|
|
147
|
+
closeSnacks() {
|
|
148
|
+
document.getElementById("snackbar").classList.remove("show-snack");
|
|
149
|
+
document.getElementById("successSnack").classList.remove("active-snack");
|
|
150
|
+
document.getElementById("errorSnack").classList.remove("active-snack");
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
async eventLog(data) {
|
|
154
|
+
const [err, response] = await to(
|
|
155
|
+
UserService.eventLog(data, this.storage)
|
|
156
|
+
);
|
|
157
|
+
if (err) return this.errorHandler(err);
|
|
158
|
+
return response;
|
|
159
|
+
},
|
|
160
|
+
async maintenance() {
|
|
161
|
+
const [err, response] = await to(
|
|
162
|
+
axios.get("https://status.tapni.co/data/maintenance.json")
|
|
163
|
+
);
|
|
164
|
+
if (err) return console.error(err);
|
|
165
|
+
if (response) {
|
|
166
|
+
let maintenanceState = response.data;
|
|
167
|
+
if (typeof response.data === "string") {
|
|
168
|
+
maintenanceState = JSON.parse(response.data);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (maintenanceState.api && maintenanceState.api.maintenanceActive) {
|
|
172
|
+
location.href =
|
|
173
|
+
"https://t.link/maintenance?msg=" + maintenanceState.api.msg;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
async getUser(data) {
|
|
178
|
+
if (data) {
|
|
179
|
+
let err, response;
|
|
180
|
+
if (data.username)
|
|
181
|
+
[err, response] = await to(
|
|
182
|
+
UserService.getByUsername(data, this.storage)
|
|
183
|
+
);
|
|
184
|
+
else if (data.serial)
|
|
185
|
+
[err, response] = await to(
|
|
186
|
+
UserService.getByNumber(data, this.storage)
|
|
187
|
+
);
|
|
188
|
+
if (err) return this.errorHandler(err);
|
|
189
|
+
if (response.data.success) {
|
|
190
|
+
if (!response.data.user && response.data.showDemoProfile) {
|
|
191
|
+
if (this.isLoggedIn) {
|
|
192
|
+
this.$router.push("/tags#activate");
|
|
193
|
+
throw new Error("Activate the tag");
|
|
194
|
+
} else {
|
|
195
|
+
return this.$router.push("/" + response.data.showDemoProfile);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (!response.data.user && data.login) {
|
|
200
|
+
this.logout();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
this.registerLang(
|
|
204
|
+
response.data.user ? response.data.user.ssoLang : "en"
|
|
205
|
+
);
|
|
206
|
+
this.setUser(response.data.user);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
async loginSetup(response) {
|
|
212
|
+
// Save Refresh Token
|
|
213
|
+
if (response.data.refreshToken)
|
|
214
|
+
this.setRefreshToken(response.data.refreshToken);
|
|
215
|
+
|
|
216
|
+
// Save Access Token
|
|
217
|
+
if (response.data.token) this.setToken(response.data.token);
|
|
218
|
+
|
|
219
|
+
// Update Language
|
|
220
|
+
if (response.data?.data?.ssoLang !== this.appLang) {
|
|
221
|
+
EventBus.$emit("ssoEvent", {
|
|
222
|
+
name: "saveProfile",
|
|
223
|
+
data: { lang: this.appLang, username: response.data.data.username },
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.setLoggedInUserId(response.data.data.id);
|
|
228
|
+
|
|
229
|
+
this.storage.UserId = response.data.data.id;
|
|
230
|
+
this.storage.username = response.data.data.username;
|
|
231
|
+
|
|
232
|
+
if (response.isModal === true) {
|
|
233
|
+
this.setLoggedInAccounts([
|
|
234
|
+
{
|
|
235
|
+
id: response.data.data.id,
|
|
236
|
+
username: response.data.data.username,
|
|
237
|
+
refreshToken: response.data.refreshToken,
|
|
238
|
+
photo: response.data.data.photo,
|
|
239
|
+
},
|
|
240
|
+
]);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// await this.registerDevice();
|
|
244
|
+
// if (Capacitor.isNativePlatform()) initPushNotifications();
|
|
245
|
+
},
|
|
246
|
+
async refreshTokenAction(data) {
|
|
247
|
+
|
|
248
|
+
const [err, response] = await to(
|
|
249
|
+
AuthService.refreshToken({
|
|
250
|
+
id: data.id,
|
|
251
|
+
refreshToken: this.refreshToken,
|
|
252
|
+
refreshTokenAction: true
|
|
253
|
+
}, this.storage)
|
|
254
|
+
);
|
|
255
|
+
if (err && err.response && err.response.data.error === "ACCESS_DENIED") {
|
|
256
|
+
this.logout(false);
|
|
257
|
+
return location.reload();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Set new access token
|
|
261
|
+
this.setToken(response.data.token);
|
|
262
|
+
},
|
|
263
|
+
async login(data) {
|
|
264
|
+
const [err, response] = await to(AuthService.login(data, this.storage));
|
|
265
|
+
if (err) return this.errorHandler(err);
|
|
266
|
+
if (response.data.success) {
|
|
267
|
+
if (this.display === "npm") {
|
|
268
|
+
this.loginSetup({ ...response, isModal: data.isModal });
|
|
269
|
+
this.getLoggedInAccounts();
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
this.loginSuccess({ ...response, isModal: data.isModal });
|
|
273
|
+
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
loginSuccess(response) {
|
|
278
|
+
if (this.display === "redirect") {
|
|
279
|
+
if (this.redirect_uri &&
|
|
280
|
+
!this.allowedOrigins.some((domain) =>
|
|
281
|
+
this.redirect_uri.startsWith(domain)
|
|
282
|
+
)
|
|
283
|
+
) {
|
|
284
|
+
return console.log("Redirect URI not allowed");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
location.href =
|
|
288
|
+
this.redirect_uri +
|
|
289
|
+
"?code=" +
|
|
290
|
+
response.data.auth_code +
|
|
291
|
+
"&state=" +
|
|
292
|
+
this.state;
|
|
293
|
+
} else if (this.display === "popup") {
|
|
294
|
+
this.allowedOrigins.forEach((domain) => {
|
|
295
|
+
window.parent?.postMessage(
|
|
296
|
+
{ code: response.data.auth_code, state: this.$route.query.state },
|
|
297
|
+
domain
|
|
298
|
+
);
|
|
299
|
+
});
|
|
300
|
+
} else if (this.display === "npm") {
|
|
301
|
+
EventBus.$emit('ssoEvent', {name: 'setLoading', data: true})
|
|
302
|
+
EventBus.$emit("ssoEvent", { name: "getUser", data: { login: true, username: response.data.data.username } });
|
|
303
|
+
|
|
304
|
+
if (response.isModal) {
|
|
305
|
+
EventBus.$emit("closeModal");
|
|
306
|
+
this.successSnack(this.ssoLang[this.appLang].success_login);
|
|
307
|
+
}
|
|
308
|
+
this.$router.push("/" + response.data.data.username + "#edit");
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
async register(data) {
|
|
312
|
+
const [err, response] = await to(
|
|
313
|
+
AuthService.register(data, this.storage)
|
|
314
|
+
);
|
|
315
|
+
if (err) return this.errorHandler(err);
|
|
316
|
+
return response;
|
|
317
|
+
},
|
|
318
|
+
async verify(data) {
|
|
319
|
+
const [err, response] = await to(AuthService.verify(data, this.storage));
|
|
320
|
+
if (err) return this.errorHandler(err);
|
|
321
|
+
return response;
|
|
322
|
+
},
|
|
323
|
+
async reset(data) {
|
|
324
|
+
const [err, response] = await to(
|
|
325
|
+
AuthService.sendResetEmail(data, this.storage)
|
|
326
|
+
);
|
|
327
|
+
if (err) return this.errorHandler(err);
|
|
328
|
+
if (response.data.success) {
|
|
329
|
+
this.successSnack(this.ssoLang[this.appLang].password_reset_success);
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
async exchangeAuthCode(data) {
|
|
333
|
+
const [err, response] = await to(
|
|
334
|
+
axios.post(import.meta.env.VITE_APP_API_ROOT + "/v1/users/auth-code", {
|
|
335
|
+
code: data.code,
|
|
336
|
+
code_verifier: data.code_verifier,
|
|
337
|
+
})
|
|
338
|
+
);
|
|
339
|
+
if (err) return this.errorHandler(err);
|
|
340
|
+
await this.loginSetup(response);
|
|
341
|
+
await this.getLoggedInAccounts();
|
|
342
|
+
this.loginSuccess(response);
|
|
343
|
+
},
|
|
344
|
+
async changePassword(data) {
|
|
345
|
+
const [err, response] = await to(
|
|
346
|
+
AuthService.changePassword(data, this.storage)
|
|
347
|
+
);
|
|
348
|
+
if (err) return this.errorHandler(err);
|
|
349
|
+
return response.data.success;
|
|
350
|
+
},
|
|
351
|
+
async newPassword(data) {
|
|
352
|
+
const [err, response] = await to(
|
|
353
|
+
UserService.newPassword(data, this.storage)
|
|
354
|
+
);
|
|
355
|
+
if (err) return this.errorHandler(err);
|
|
356
|
+
return response.data.success;
|
|
357
|
+
},
|
|
358
|
+
async deleteAccount(data) {
|
|
359
|
+
const [err, response] = await to(
|
|
360
|
+
UserService.deleteAccount(data, this.storage)
|
|
361
|
+
);
|
|
362
|
+
if (err) return this.errorHandler(err);
|
|
363
|
+
return response.data.success;
|
|
364
|
+
},
|
|
365
|
+
async registerDevice() {
|
|
366
|
+
const deviceID = await Device.getId();
|
|
367
|
+
const deviceInfo = await Device.getInfo();
|
|
368
|
+
let deviceData = {
|
|
369
|
+
device_id: deviceID.uuid,
|
|
370
|
+
platform: deviceInfo.platform,
|
|
371
|
+
device_info: {
|
|
372
|
+
model: deviceInfo.model,
|
|
373
|
+
manufacturer: deviceInfo.manufacturer,
|
|
374
|
+
operatingSystem: deviceInfo.operatingSystem,
|
|
375
|
+
osVersion: deviceInfo.osVersion,
|
|
376
|
+
isVirtual: deviceInfo.isVirtual,
|
|
377
|
+
webViewVersion: deviceInfo.webViewVersion,
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
const [err, response] = await to(
|
|
381
|
+
DeviceService.registerDevice(deviceData, this.storage)
|
|
382
|
+
);
|
|
383
|
+
if (err) return this.errorHandler(err);
|
|
384
|
+
return response;
|
|
385
|
+
},
|
|
386
|
+
async addFcmToken(data) {
|
|
387
|
+
const [err, response] = await to(
|
|
388
|
+
DeviceService.addFcmToken(data, this.storage)
|
|
389
|
+
);
|
|
390
|
+
if (err) return this.errorHandler(err);
|
|
391
|
+
return response;
|
|
392
|
+
},
|
|
393
|
+
async acceptCompanyInvitation(code) {
|
|
394
|
+
const [err, response] = await to(
|
|
395
|
+
CompanyService.acceptCompanyInvitation(code, this.storage)
|
|
396
|
+
);
|
|
397
|
+
if (err) return this.errorHandler(err);
|
|
398
|
+
return response;
|
|
399
|
+
},
|
|
400
|
+
async logout(sendRequest = true) {
|
|
401
|
+
if (sendRequest) {
|
|
402
|
+
AuthService.logout({ token: this.refreshToken }, this.storage);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
this.storage.username = null;
|
|
406
|
+
this.storage.ssoUser = null;
|
|
407
|
+
this.storage.UserId = null;
|
|
408
|
+
this.setLoggedInUserId(null);
|
|
409
|
+
this.setToken(null);
|
|
410
|
+
this.setRefreshToken(null);
|
|
411
|
+
|
|
412
|
+
if (this.refreshToken) {
|
|
413
|
+
Object.keys(this.loggedInAccounts).forEach((username) => {
|
|
414
|
+
if (
|
|
415
|
+
this.loggedInAccounts[username].refreshToken === this.refreshToken
|
|
416
|
+
) {
|
|
417
|
+
this.refreshTokenAction({
|
|
418
|
+
id: this.loggedInAccounts[username].id,
|
|
419
|
+
}).then(() => {
|
|
420
|
+
this.setLoggedInUserId(this.loggedInAccounts[username].id);
|
|
421
|
+
this.storage.username = username;
|
|
422
|
+
this.storage.UserId = this.loggedInAccounts[username].id;
|
|
423
|
+
this.getLoggedInAccounts();
|
|
424
|
+
return this.$router.push("/" + username);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
} else this.setUser(null);
|
|
429
|
+
await this.$router.push("/welcome");
|
|
430
|
+
},
|
|
431
|
+
async getCompanyBySSOEmail(data) {
|
|
432
|
+
const [err, response] = await to(
|
|
433
|
+
CompanyService.getBySSOEmail(data.email, this.storage)
|
|
434
|
+
);
|
|
435
|
+
if (err) return this.errorHandler(err);
|
|
436
|
+
if (response.data.success) {
|
|
437
|
+
return response.data;
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
async getLoggedInAccounts() {
|
|
441
|
+
const refreshTokens = this.getRefreshTokens();
|
|
442
|
+
const [err, response] = await to(
|
|
443
|
+
AuthService.getLoggedInAccounts({ refreshTokens }, this.storage)
|
|
444
|
+
);
|
|
445
|
+
if (err) return this.errorHandler(err);
|
|
446
|
+
if (response.data.success) {
|
|
447
|
+
this.setLoggedInAccounts(response.data.accounts);
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
async loginUsingQR(data) {
|
|
451
|
+
const [err, response] = await to(
|
|
452
|
+
UserService.loginUsingQR(data, this.storage)
|
|
453
|
+
);
|
|
454
|
+
if (err) return this.errorHandler(err);
|
|
455
|
+
return response.data.success;
|
|
456
|
+
},
|
|
457
|
+
setLoggedInAccounts(accounts) {
|
|
458
|
+
this.loggedInAccounts = {};
|
|
459
|
+
accounts.forEach((account) => {
|
|
460
|
+
this.loggedInAccounts[account.username] = account;
|
|
461
|
+
});
|
|
462
|
+
EventBus.$emit("ssoEvent", { name: "setLoggedInAccounts", data: accounts });
|
|
463
|
+
},
|
|
464
|
+
setLoggedInUserId(id) {
|
|
465
|
+
this.loggedInUserId = id;
|
|
466
|
+
},
|
|
467
|
+
setUser(user) {
|
|
468
|
+
this.ssoUser = user;
|
|
469
|
+
if (
|
|
470
|
+
this.storage &&
|
|
471
|
+
this.ssoUser &&
|
|
472
|
+
this.storage.username === this.ssoUser.username
|
|
473
|
+
) {
|
|
474
|
+
this.appLanguage = user.ssoLang;
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
getRefreshTokens() {
|
|
478
|
+
return this.storage.refreshTokens.split(',');
|
|
479
|
+
},
|
|
480
|
+
setRefreshToken(token) {
|
|
481
|
+
let refreshTokens = this.getRefreshTokens();
|
|
482
|
+
if (token && !refreshTokens.includes(token)) refreshTokens.unshift(token);
|
|
483
|
+
else refreshTokens = refreshTokens.filter((t) => t !== this.refreshToken);
|
|
484
|
+
|
|
485
|
+
if (refreshTokens.length >= 1) this.refreshToken = refreshTokens[0];
|
|
486
|
+
else this.refreshToken = token;
|
|
487
|
+
|
|
488
|
+
this.storage.refreshTokens = refreshTokens.join(",");
|
|
489
|
+
EventBus.$emit("ssoEvent", { name: "setRefreshToken", data: token });
|
|
490
|
+
},
|
|
491
|
+
setToken(token) {
|
|
492
|
+
this.storage.token = token;
|
|
493
|
+
this.token = token;
|
|
494
|
+
EventBus.$emit("ssoEvent", { name: "setToken", data: token });
|
|
495
|
+
},
|
|
496
|
+
setUserID(userID) {
|
|
497
|
+
this.storage.UserId = userID;
|
|
498
|
+
},
|
|
499
|
+
updateLang(lang) {
|
|
500
|
+
this.appLanguage = lang;
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
watch: {
|
|
504
|
+
"$route.query": {
|
|
505
|
+
handler: function handler() {
|
|
506
|
+
if (this.$route.query.redirect_uri)
|
|
507
|
+
this.redirect_uri = this.$route.query.redirect_uri;
|
|
508
|
+
if (this.$route.query.display) this.display = this.$route.query.display;
|
|
509
|
+
if (this.$route.query.state) this.state = this.$route.query.state;
|
|
510
|
+
if (this.$route.query.response_type)
|
|
511
|
+
this.response_type = this.$route.query.response_type;
|
|
512
|
+
if (this.$route.query.realm)
|
|
513
|
+
this.storage.realm = this.$route.query.realm;
|
|
514
|
+
if (this.$route.query.qrLogin) this.changeLoginToQr();
|
|
515
|
+
},
|
|
516
|
+
deep: true,
|
|
517
|
+
},
|
|
518
|
+
storage: {
|
|
519
|
+
async handler() {
|
|
520
|
+
await store.setRaw(this.storage);
|
|
521
|
+
},
|
|
522
|
+
deep: true
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
};
|