@live-change/user-frontend 0.9.177 → 0.9.179
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/front/locales/en.json +57 -0
- package/front/locales/pl.json +57 -0
- package/front/src/connected/ConnectFinished.vue +4 -3
- package/front/src/connected/Connected.vue +2 -2
- package/front/src/google-access/GoogleAccess.vue +8 -5
- package/front/src/google-access/GoogleAccessGained.vue +17 -7
- package/front/src/password/ResetPasswordForm.vue +6 -6
- package/front/src/sign/GoogleAuth.vue +13 -8
- package/front/src/sign/GoogleAuthReturn.vue +50 -11
- package/front/src/sign/LinkedinAuth.vue +11 -8
- package/front/src/sign/LinkedinAuthReturn.vue +10 -7
- package/front/src/sign/SignOut.vue +5 -2
- package/package.json +26 -26
package/front/locales/en.json
CHANGED
|
@@ -235,5 +235,62 @@
|
|
|
235
235
|
"openLink": "Or open authentication link:",
|
|
236
236
|
"seeYouSoon": "See you soon",
|
|
237
237
|
"teamSignature": "{brandName} Team"
|
|
238
|
+
},
|
|
239
|
+
"googleAuth": {
|
|
240
|
+
"title": "Google authentication",
|
|
241
|
+
"canceled": "Authentication canceled by user",
|
|
242
|
+
"waiting": "Waiting for server...",
|
|
243
|
+
"waitingForRedirect": "Authentication will open in this window.",
|
|
244
|
+
"error": "Error during authentication",
|
|
245
|
+
"errorWithColon": "Error during authentication:",
|
|
246
|
+
"unknownState": "Unknown authentication state: {state}",
|
|
247
|
+
"emailTaken": "Your account was created using email address. If you want to connect your Google account, you need to sign in with this email address. And connect your Google account using {link}.",
|
|
248
|
+
"emailTakenLink": "connected accounts page",
|
|
249
|
+
"invalidGrant": "Invalid grant. Please try again. You may used this link before, or google authentication failed.",
|
|
250
|
+
"connectedToAnotherUser": "This account is already connected to another user. Please sign in with your email address or google account.",
|
|
251
|
+
"emailAlreadyInUse": "Email is already in use",
|
|
252
|
+
"invalidGrantToast": "Invalid grant",
|
|
253
|
+
"connectedToAnotherUserToast": "Connected to another user",
|
|
254
|
+
"errorToast": "Error during google authentication"
|
|
255
|
+
},
|
|
256
|
+
"linkedinAuth": {
|
|
257
|
+
"title": "Linkedin authentication",
|
|
258
|
+
"canceled": "Authentication canceled by user",
|
|
259
|
+
"waiting": "Waiting for server...",
|
|
260
|
+
"waitingForRedirect": "Authentication will open in this window.",
|
|
261
|
+
"error": "Error during authentication",
|
|
262
|
+
"errorWithColon": "Error during authentication:",
|
|
263
|
+
"unknownState": "Unknown authentication state: {state}",
|
|
264
|
+
"errorToast": "Error during linkedin authentication"
|
|
265
|
+
},
|
|
266
|
+
"googleAccess": {
|
|
267
|
+
"title": "Google API Access",
|
|
268
|
+
"currentAccess": "You are currently granting us access to the following Google API features:",
|
|
269
|
+
"needAccess": "To use this feature, you need to grant us access to the Google APIs listed below:",
|
|
270
|
+
"clickButton": "Click the button below to go to the Google page where you can grant access.",
|
|
271
|
+
"authenticationButton": "Google Authentication",
|
|
272
|
+
"gainedTitle": "Signed In",
|
|
273
|
+
"gainedMessage": "Congratulations! You added offline access to your account. Now your account have access to:",
|
|
274
|
+
"next": "Next",
|
|
275
|
+
"redirectIn": "Redirect in {seconds}...",
|
|
276
|
+
"returnToIndex": "Return to {link}.",
|
|
277
|
+
"indexPage": "index page",
|
|
278
|
+
"signedInToast": "Signed in",
|
|
279
|
+
"signedInToastDetail": "Congratulations! You have successfully logged in to your account."
|
|
280
|
+
},
|
|
281
|
+
"password": {
|
|
282
|
+
"suggestions": "Suggestions",
|
|
283
|
+
"resetPasswordButton": "Reset password"
|
|
284
|
+
},
|
|
285
|
+
"common": {
|
|
286
|
+
"rememberMe": "Remember me"
|
|
287
|
+
},
|
|
288
|
+
"signOut": {
|
|
289
|
+
"title": "Sign Out",
|
|
290
|
+
"signingOut": "Signing out"
|
|
291
|
+
},
|
|
292
|
+
"connected": {
|
|
293
|
+
"accountConnected": "Account connected",
|
|
294
|
+
"accountConnectedSuccess": "Congratulations! You have successfully connected accounts."
|
|
238
295
|
}
|
|
239
296
|
}
|
package/front/locales/pl.json
CHANGED
|
@@ -235,5 +235,62 @@
|
|
|
235
235
|
"openLink": "Lub otwórz link uwierzytelniania:",
|
|
236
236
|
"seeYouSoon": "Do zobaczenia",
|
|
237
237
|
"teamSignature": "Zespół {brandName}"
|
|
238
|
+
},
|
|
239
|
+
"googleAuth": {
|
|
240
|
+
"title": "Uwierzytelnianie Google",
|
|
241
|
+
"canceled": "Uwierzytelnianie anulowane przez użytkownika",
|
|
242
|
+
"waiting": "Oczekiwanie na serwer...",
|
|
243
|
+
"waitingForRedirect": "Uwierzytelnianie otworzy się w tym oknie.",
|
|
244
|
+
"error": "Błąd podczas uwierzytelniania",
|
|
245
|
+
"errorWithColon": "Błąd podczas uwierzytelniania:",
|
|
246
|
+
"unknownState": "Nieznany stan uwierzytelniania: {state}",
|
|
247
|
+
"emailTaken": "Twoje konto zostało utworzone przy użyciu adresu email. Jeśli chcesz połączyć swoje konto Google, musisz zalogować się tym adresem email. I połączyć swoje konto Google używając {link}.",
|
|
248
|
+
"emailTakenLink": "strony połączonych kont",
|
|
249
|
+
"invalidGrant": "Nieprawidłowy grant. Spróbuj ponownie. Możesz użyć tego linku wcześniej lub uwierzytelnianie Google nie powiodło się.",
|
|
250
|
+
"connectedToAnotherUser": "To konto jest już połączone z innym użytkownikiem. Zaloguj się swoim adresem email lub kontem Google.",
|
|
251
|
+
"emailAlreadyInUse": "Email jest już w użyciu",
|
|
252
|
+
"invalidGrantToast": "Nieprawidłowy grant",
|
|
253
|
+
"connectedToAnotherUserToast": "Połączone z innym użytkownikiem",
|
|
254
|
+
"errorToast": "Błąd podczas uwierzytelniania Google"
|
|
255
|
+
},
|
|
256
|
+
"linkedinAuth": {
|
|
257
|
+
"title": "Uwierzytelnianie LinkedIn",
|
|
258
|
+
"canceled": "Uwierzytelnianie anulowane przez użytkownika",
|
|
259
|
+
"waiting": "Oczekiwanie na serwer...",
|
|
260
|
+
"waitingForRedirect": "Uwierzytelnianie otworzy się w tym oknie.",
|
|
261
|
+
"error": "Błąd podczas uwierzytelniania",
|
|
262
|
+
"errorWithColon": "Błąd podczas uwierzytelniania:",
|
|
263
|
+
"unknownState": "Nieznany stan uwierzytelniania: {state}",
|
|
264
|
+
"errorToast": "Błąd podczas uwierzytelniania LinkedIn"
|
|
265
|
+
},
|
|
266
|
+
"googleAccess": {
|
|
267
|
+
"title": "Dostęp do Google API",
|
|
268
|
+
"currentAccess": "Obecnie udzielasz nam dostępu do następujących funkcji Google API:",
|
|
269
|
+
"needAccess": "Aby użyć tej funkcji, musisz udzielić nam dostępu do wymienionych poniżej Google API:",
|
|
270
|
+
"clickButton": "Kliknij przycisk poniżej, aby przejść do strony Google, gdzie możesz udzielić dostępu.",
|
|
271
|
+
"authenticationButton": "Uwierzytelnianie Google",
|
|
272
|
+
"gainedTitle": "Zalogowany",
|
|
273
|
+
"gainedMessage": "Gratulacje! Dodałeś dostęp offline do swojego konta. Teraz Twoje konto ma dostęp do:",
|
|
274
|
+
"next": "Dalej",
|
|
275
|
+
"redirectIn": "Przekierowanie za {seconds}...",
|
|
276
|
+
"returnToIndex": "Wróć do {link}.",
|
|
277
|
+
"indexPage": "strony głównej",
|
|
278
|
+
"signedInToast": "Zalogowany",
|
|
279
|
+
"signedInToastDetail": "Gratulacje! Pomyślnie zalogowałeś się do swojego konta."
|
|
280
|
+
},
|
|
281
|
+
"password": {
|
|
282
|
+
"suggestions": "Sugestie",
|
|
283
|
+
"resetPasswordButton": "Resetuj hasło"
|
|
284
|
+
},
|
|
285
|
+
"common": {
|
|
286
|
+
"rememberMe": "Zapamiętaj mnie"
|
|
287
|
+
},
|
|
288
|
+
"signOut": {
|
|
289
|
+
"title": "Wyloguj się",
|
|
290
|
+
"signingOut": "Wylogowywanie"
|
|
291
|
+
},
|
|
292
|
+
"connected": {
|
|
293
|
+
"accountConnected": "Konto połączone",
|
|
294
|
+
"accountConnectedSuccess": "Gratulacje! Pomyślnie połączyłeś konta."
|
|
238
295
|
}
|
|
239
296
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="w-full lg:w-6/12 md:w-9/12 max-w-[32rem]" v-shared-element:form="{ duration: '300ms', includeChildren: true }">
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6">
|
|
4
|
-
<div class="text-surface-900 dark:text-surface-0 font-medium mb-6 text-xl">
|
|
5
|
-
<div class="mt-0 p-0 leading-normal">
|
|
4
|
+
<div class="text-surface-900 dark:text-surface-0 font-medium mb-6 text-xl">{{ t('connected.accountConnected') }}</div>
|
|
5
|
+
<div class="mt-0 p-0 leading-normal">{{ t('connected.accountConnectedSuccess') }}</div>
|
|
6
6
|
</div>
|
|
7
7
|
</div>
|
|
8
8
|
</template>
|
|
9
9
|
|
|
10
10
|
<script setup>
|
|
11
|
-
|
|
11
|
+
import { useI18n } from 'vue-i18n'
|
|
12
|
+
const { t } = useI18n()
|
|
12
13
|
</script>
|
|
13
14
|
|
|
14
15
|
<style>
|
|
@@ -152,12 +152,12 @@
|
|
|
152
152
|
|
|
153
153
|
await Promise.all([ ...contactPromises, ...accountPromises ])
|
|
154
154
|
|
|
155
|
-
const contacts = computed(() => contactsTypes.map((c,i) => c.contacts.value.map(v => ({
|
|
155
|
+
const contacts = computed(() => contactsTypes.map((c,i) => (c.contacts.value || []).map(v => ({
|
|
156
156
|
contactType: c,
|
|
157
157
|
...(v)
|
|
158
158
|
}))).flat())
|
|
159
159
|
|
|
160
|
-
const accounts = computed(() => accountTypes.map((c,i) => c.accounts.value.map(v => ({
|
|
160
|
+
const accounts = computed(() => accountTypes.map((c,i) => (c.accounts.value || []).map(v => ({
|
|
161
161
|
accountType: c,
|
|
162
162
|
...(v)
|
|
163
163
|
}))).flat())
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div v-if="additionalScopes.length > 0" class="w-full flex flex-row justify-center">
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6 w-[30rem]">
|
|
4
|
-
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">
|
|
4
|
+
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">{{ t('googleAccess.title') }}</div>
|
|
5
5
|
<div v-if="currentAccess.length > 0">
|
|
6
6
|
<p class="mt-0 p-0 leading-normal">
|
|
7
|
-
|
|
7
|
+
{{ t('googleAccess.currentAccess') }}
|
|
8
8
|
</p>
|
|
9
9
|
<ul>
|
|
10
10
|
<li v-for="scope in currentAccess">
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
<div>
|
|
16
16
|
<p>
|
|
17
|
-
|
|
17
|
+
{{ t('googleAccess.needAccess') }}
|
|
18
18
|
</p>
|
|
19
19
|
<ul>
|
|
20
20
|
<li v-for="scope in additionalScopes" class="font-semibold text-gray-700">
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</li>
|
|
23
23
|
</ul>
|
|
24
24
|
<p>
|
|
25
|
-
|
|
25
|
+
{{ t('googleAccess.clickButton') }}
|
|
26
26
|
</p>
|
|
27
27
|
</div>
|
|
28
28
|
<router-link
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
accessType: 'offline',
|
|
33
33
|
scopes: allScopes
|
|
34
34
|
} }">
|
|
35
|
-
<Button icon="pi pi-key" label="
|
|
35
|
+
<Button icon="pi pi-key" :label="t('googleAccess.authenticationButton')" />
|
|
36
36
|
</router-link>
|
|
37
37
|
</div>
|
|
38
38
|
</div>
|
|
@@ -43,6 +43,9 @@
|
|
|
43
43
|
|
|
44
44
|
import Button from 'primevue/button'
|
|
45
45
|
|
|
46
|
+
import { useI18n } from 'vue-i18n'
|
|
47
|
+
const { t } = useI18n()
|
|
48
|
+
|
|
46
49
|
import { onMounted, ref } from 'vue'
|
|
47
50
|
const isMounted = ref(false)
|
|
48
51
|
onMounted(() => isMounted.value = true)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="w-full lg:w-6/12 md:w-9/12 max-w-[32rem]" v-shared-element:form="{ duration: '300ms', includeChildren: true }">
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6">
|
|
4
|
-
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">
|
|
4
|
+
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">{{ t('googleAccess.gainedTitle') }}</div>
|
|
5
5
|
<p class="mt-0 p-0 leading-normal">
|
|
6
|
-
|
|
6
|
+
{{ t('googleAccess.gainedMessage') }}
|
|
7
7
|
<ul>
|
|
8
8
|
<li v-for="access in accessList">
|
|
9
9
|
{{ access }}
|
|
@@ -13,14 +13,18 @@
|
|
|
13
13
|
</p>
|
|
14
14
|
<div v-if="afterGoogleAccessGained" class="flex flex-row items-center">
|
|
15
15
|
<router-link :to="afterGoogleAccessGained" class="no-underline">
|
|
16
|
-
<Button label="
|
|
16
|
+
<Button :label="t('googleAccess.next')" v-ripple />
|
|
17
17
|
</router-link>
|
|
18
18
|
<p class="ml-6" v-if="isMounted && redirectTime">
|
|
19
|
-
|
|
19
|
+
{{ t('googleAccess.redirectIn', { seconds: pluralize('second', Math.ceil((redirectTime - currentTime) / 1000), true) }) }}
|
|
20
20
|
</p>
|
|
21
21
|
</div>
|
|
22
22
|
<div v-else>
|
|
23
|
-
|
|
23
|
+
<i18n-t keypath="googleAccess.returnToIndex" tag="span">
|
|
24
|
+
<template #link>
|
|
25
|
+
<router-link to="/">{{ t('googleAccess.indexPage') }}</router-link>
|
|
26
|
+
</template>
|
|
27
|
+
</i18n-t>
|
|
24
28
|
</div>
|
|
25
29
|
</div>
|
|
26
30
|
</div>
|
|
@@ -30,6 +34,9 @@
|
|
|
30
34
|
|
|
31
35
|
import Button from 'primevue/button'
|
|
32
36
|
|
|
37
|
+
import { useI18n } from 'vue-i18n'
|
|
38
|
+
const { t } = useI18n()
|
|
39
|
+
|
|
33
40
|
import { onMounted, ref } from 'vue'
|
|
34
41
|
const isMounted = ref(false)
|
|
35
42
|
onMounted(() => isMounted.value = true)
|
|
@@ -43,6 +50,9 @@
|
|
|
43
50
|
import { usePath, live, useApi } from "@live-change/vue3-ssr"
|
|
44
51
|
const api = useApi()
|
|
45
52
|
|
|
53
|
+
import { useToast } from 'primevue/usetoast'
|
|
54
|
+
const toast = useToast()
|
|
55
|
+
|
|
46
56
|
const userClientConfig = api.getServiceDefinition('user')?.clientConfig
|
|
47
57
|
|
|
48
58
|
import pluralize from 'pluralize'
|
|
@@ -68,8 +78,8 @@
|
|
|
68
78
|
setTimeout(() => { // it could be next tick
|
|
69
79
|
toast.add({
|
|
70
80
|
severity: 'info', life: 6000,
|
|
71
|
-
summary: '
|
|
72
|
-
detail: '
|
|
81
|
+
summary: t('googleAccess.signedInToast'),
|
|
82
|
+
detail: t('googleAccess.signedInToastDetail')
|
|
73
83
|
})
|
|
74
84
|
router.push(route)
|
|
75
85
|
}, 100)
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
v-model="data.passwordHash">
|
|
34
34
|
<template #footer>
|
|
35
35
|
<Divider />
|
|
36
|
-
<p class="p-mt-2">
|
|
36
|
+
<p class="p-mt-2">{{ t('password.suggestions') }}</p>
|
|
37
37
|
<ul class="p-pl-2 p-ml-2 p-mt-0" style="line-height: 1.5">
|
|
38
|
-
<li>
|
|
39
|
-
<li>
|
|
40
|
-
<li>
|
|
41
|
-
<li>
|
|
38
|
+
<li>{{ t('auth.suggestionLowercase') }}</li>
|
|
39
|
+
<li>{{ t('auth.suggestionUppercase') }}</li>
|
|
40
|
+
<li>{{ t('auth.suggestionNumeric') }}</li>
|
|
41
|
+
<li>{{ t('auth.suggestionMinLength') }}</li>
|
|
42
42
|
</ul>
|
|
43
43
|
</template>
|
|
44
44
|
</Password>
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
|
|
57
57
|
</template>
|
|
58
58
|
|
|
59
|
-
<Button type="submit" label="
|
|
59
|
+
<Button type="submit" :label="t('password.resetPasswordButton')" icon="pi pi-key" class="w-full"></Button>
|
|
60
60
|
|
|
61
61
|
</command-form>
|
|
62
62
|
</div>
|
|
@@ -3,28 +3,28 @@
|
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
|
|
4
4
|
|
|
5
5
|
<div class="text-center mb-8">
|
|
6
|
-
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">
|
|
6
|
+
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('googleAuth.title') }}</div>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
<div v-if="state === 'canceled'" class="text-center">
|
|
10
|
-
<div>
|
|
10
|
+
<div>{{ t('googleAuth.canceled') }}</div>
|
|
11
11
|
<div class="flex flex-row">
|
|
12
|
-
<Button @click="back" label="
|
|
13
|
-
<Button @click="googleAuth" label="
|
|
12
|
+
<Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
|
|
13
|
+
<Button @click="googleAuth" :label="t('auth.tryAgain')" icon="pi pi-google" class="w-full p-button-secondary mb-1" />
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<div v-else-if="state === 'waiting'" class="text-center">
|
|
17
|
-
|
|
17
|
+
{{ t('googleAuth.waitingForRedirect') }}
|
|
18
18
|
</div>
|
|
19
19
|
<div v-else-if="state === 'working'" class="text-center">
|
|
20
|
-
|
|
20
|
+
{{ t('googleAuth.waiting') }}
|
|
21
21
|
</div>
|
|
22
22
|
<div v-else-if="state === 'error'" class="text-center">
|
|
23
|
-
<div>
|
|
23
|
+
<div>{{ t('googleAuth.errorWithColon') }}</div>
|
|
24
24
|
<div>{{ error }}</div>
|
|
25
25
|
</div>
|
|
26
26
|
<div v-else>
|
|
27
|
-
|
|
27
|
+
{{ t('googleAuth.unknownState', { state }) }}
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
30
|
</div>
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
import { useRouter } from 'vue-router'
|
|
38
38
|
const router = useRouter()
|
|
39
39
|
|
|
40
|
+
import { useI18n } from 'vue-i18n'
|
|
41
|
+
const { t } = useI18n()
|
|
42
|
+
|
|
40
43
|
const workingZone = inject('workingZone')
|
|
41
44
|
|
|
42
45
|
import { googleAuthRedirect } from '../utils/googleAuth.js'
|
|
@@ -66,6 +69,8 @@
|
|
|
66
69
|
function googleAuth() {
|
|
67
70
|
state.value = 'waiting'
|
|
68
71
|
|
|
72
|
+
localStorage.googleAuthScopes = JSON.stringify(scopes.value)
|
|
73
|
+
|
|
69
74
|
workingZone.addPromise('google auth', new Promise((resolve, reject) => {
|
|
70
75
|
setTimeout(() => {
|
|
71
76
|
state.value = 'error'
|
|
@@ -3,32 +3,48 @@
|
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
|
|
4
4
|
|
|
5
5
|
<div class="text-center mb-8">
|
|
6
|
-
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">
|
|
6
|
+
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('googleAuth.title') }}</div>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
<div v-if="state === 'canceled'" class="text-center">
|
|
10
|
-
<div>
|
|
10
|
+
<div>{{ t('googleAuth.canceled') }}</div>
|
|
11
11
|
<div class="flex flex-row">
|
|
12
|
-
<Button @click="back" label="
|
|
12
|
+
<Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left"
|
|
13
13
|
class="w-full p-button-secondary mb-1" />
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<div v-else-if="state === 'working'" class="text-center">
|
|
17
|
-
|
|
17
|
+
{{ t('googleAuth.waiting') }}
|
|
18
18
|
</div>
|
|
19
19
|
<div v-else-if="state === 'error'" class="text-center">
|
|
20
|
-
<div>
|
|
20
|
+
<div>{{ t('googleAuth.error') }}</div>
|
|
21
21
|
<div>{{ error }}</div>
|
|
22
22
|
</div>
|
|
23
23
|
<div v-else-if="state === 'emailTaken'" class="text-center">
|
|
24
24
|
<div>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
<i18n-t keypath="googleAuth.emailTaken" tag="span">
|
|
26
|
+
<template #link>
|
|
27
|
+
<router-link :to="{ name: 'user:connected' }">{{ t('googleAuth.emailTakenLink') }}</router-link>
|
|
28
|
+
</template>
|
|
29
|
+
</i18n-t>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div v-else-if="state === 'invalidGrant'" class="text-center">
|
|
33
|
+
<div>
|
|
34
|
+
{{ t('googleAuth.invalidGrant') }}
|
|
35
|
+
<div class="flex flex-row">
|
|
36
|
+
<Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
|
|
37
|
+
<Button @click="googleAuth" :label="t('auth.tryAgain')" icon="pi pi-google" class="w-full p-button-secondary mb-1" />
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<div v-else-if="state === 'connectedToAnotherUser'" class="text-center">
|
|
42
|
+
<div>
|
|
43
|
+
{{ t('googleAuth.connectedToAnotherUser') }}
|
|
28
44
|
</div>
|
|
29
45
|
</div>
|
|
30
46
|
<div v-else>
|
|
31
|
-
|
|
47
|
+
{{ t('googleAuth.unknownState', { state }) }}
|
|
32
48
|
</div>
|
|
33
49
|
|
|
34
50
|
</div>
|
|
@@ -44,6 +60,9 @@
|
|
|
44
60
|
import { useToast } from 'primevue/usetoast'
|
|
45
61
|
const toast = useToast()
|
|
46
62
|
|
|
63
|
+
import { useI18n } from 'vue-i18n'
|
|
64
|
+
const { t } = useI18n()
|
|
65
|
+
|
|
47
66
|
const workingZone = inject('workingZone')
|
|
48
67
|
|
|
49
68
|
import { useRouter, useRoute } from 'vue-router'
|
|
@@ -81,6 +100,7 @@
|
|
|
81
100
|
while(user && api.client.value.user !== user) {
|
|
82
101
|
await new Promise(resolve => setTimeout(resolve, 100))
|
|
83
102
|
}
|
|
103
|
+
localStorage.removeItem('googleAuthScopes')
|
|
84
104
|
if(actionDone === 'signIn') {
|
|
85
105
|
router.push({ name: 'user:signInFinished' })
|
|
86
106
|
} else if(actionDone === 'signUp') {
|
|
@@ -94,12 +114,22 @@
|
|
|
94
114
|
}
|
|
95
115
|
} catch(err) {
|
|
96
116
|
if(err?.properties?.email == 'emailTaken') {
|
|
97
|
-
toast.add({ severity: 'error', summary: '
|
|
117
|
+
toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.emailAlreadyInUse'), life: 3000 })
|
|
98
118
|
state.value = 'emailTaken'
|
|
99
119
|
return
|
|
100
120
|
}
|
|
121
|
+
if((typeof err == 'string') && err.startsWith('invalid_grant')) {
|
|
122
|
+
toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.invalidGrantToast'), life: 3000 })
|
|
123
|
+
state.value = 'invalidGrant'
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
if(err === 'connectedToAnotherUser') {
|
|
127
|
+
toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.connectedToAnotherUserToast'), life: 3000 })
|
|
128
|
+
state.value = 'connectedToAnotherUser'
|
|
129
|
+
return
|
|
130
|
+
}
|
|
101
131
|
console.error("Google auth error", err)
|
|
102
|
-
toast.add({ severity: 'error', summary: '
|
|
132
|
+
toast.add({ severity: 'error', summary: t('common.error'), detail: t('googleAuth.errorToast'), life: 3000 })
|
|
103
133
|
state.value = 'error'
|
|
104
134
|
error.value = err
|
|
105
135
|
}
|
|
@@ -110,6 +140,15 @@
|
|
|
110
140
|
router.go(-1)
|
|
111
141
|
}
|
|
112
142
|
|
|
143
|
+
async function googleAuth() {
|
|
144
|
+
if(localStorage.googleAuthScopes) {
|
|
145
|
+
const scopes = JSON.parse(localStorage.googleAuthScopes)
|
|
146
|
+
router.push({ name: 'user:googleAuthScopes', params: { action: action.value, accessType: 'offline', scopes: scopes } })
|
|
147
|
+
} else {
|
|
148
|
+
router.push({ name: 'user:googleAuth', params: { action: action.value } })
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
113
152
|
</script>
|
|
114
153
|
|
|
115
154
|
<style scoped>
|
|
@@ -3,28 +3,28 @@
|
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
|
|
4
4
|
|
|
5
5
|
<div class="text-center mb-8">
|
|
6
|
-
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">
|
|
6
|
+
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('linkedinAuth.title') }}</div>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
<div v-if="state === 'canceled'" class="text-center">
|
|
10
|
-
<div class="mb-1">
|
|
10
|
+
<div class="mb-1">{{ t('linkedinAuth.canceled') }}</div>
|
|
11
11
|
<div class="flex flex-row">
|
|
12
|
-
<Button @click="back" label="
|
|
13
|
-
<Button @click="linkedinAuth" label="
|
|
12
|
+
<Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left" class="w-full p-button-secondary mb-1" />
|
|
13
|
+
<Button @click="linkedinAuth" :label="t('auth.tryAgain')" icon="pi pi-linkedin" class="w-full p-button-secondary mb-1" />
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<div v-else-if="state === 'waiting'" class="text-center">
|
|
17
|
-
|
|
17
|
+
{{ t('linkedinAuth.waitingForRedirect') }}
|
|
18
18
|
</div>
|
|
19
19
|
<div v-else-if="state === 'working'" class="text-center">
|
|
20
|
-
|
|
20
|
+
{{ t('linkedinAuth.waiting') }}
|
|
21
21
|
</div>
|
|
22
22
|
<div v-else-if="state === 'error'" class="text-center">
|
|
23
|
-
<div>
|
|
23
|
+
<div>{{ t('linkedinAuth.errorWithColon') }}</div>
|
|
24
24
|
<div>{{ error }}</div>
|
|
25
25
|
</div>
|
|
26
26
|
<div v-else>
|
|
27
|
-
|
|
27
|
+
{{ t('linkedinAuth.unknownState', { state }) }}
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
30
|
</div>
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
import { useRouter } from 'vue-router'
|
|
38
38
|
const router = useRouter()
|
|
39
39
|
|
|
40
|
+
import { useI18n } from 'vue-i18n'
|
|
41
|
+
const { t } = useI18n()
|
|
42
|
+
|
|
40
43
|
const workingZone = inject('workingZone')
|
|
41
44
|
|
|
42
45
|
import { linkedinAuthRedirect } from '../utils/linkedinAuth.js'
|
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 p-6 shadow rounded-border">
|
|
4
4
|
|
|
5
5
|
<div class="text-center mb-8">
|
|
6
|
-
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">
|
|
6
|
+
<div class="text-surface-900 dark:text-surface-0 text-3xl font-medium mb-4">{{ t('linkedinAuth.title') }}</div>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
<div v-if="state === 'canceled'" class="text-center">
|
|
10
|
-
<div class="mb-2 text-red-500">
|
|
10
|
+
<div class="mb-2 text-red-500">{{ t('linkedinAuth.canceled') }}</div>
|
|
11
11
|
<div class="flex flex-row">
|
|
12
|
-
<Button @click="back" label="
|
|
12
|
+
<Button @click="back" :label="t('auth.goBack')" icon="pi pi-arrow-left"
|
|
13
13
|
class="w-full p-button-secondary mb-1" />
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
<div v-else-if="state === 'working'" class="text-center">
|
|
17
|
-
|
|
17
|
+
{{ t('linkedinAuth.waiting') }}
|
|
18
18
|
</div>
|
|
19
19
|
<div v-else-if="state === 'error'" class="text-center">
|
|
20
|
-
<div>
|
|
20
|
+
<div>{{ t('linkedinAuth.error') }}</div>
|
|
21
21
|
<div>{{ error }}</div>
|
|
22
22
|
</div>
|
|
23
23
|
<div v-else>
|
|
24
|
-
|
|
24
|
+
{{ t('linkedinAuth.unknownState', { state }) }}
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
27
|
</div>
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
import { useToast } from 'primevue/usetoast'
|
|
38
38
|
const toast = useToast()
|
|
39
39
|
|
|
40
|
+
import { useI18n } from 'vue-i18n'
|
|
41
|
+
const { t } = useI18n()
|
|
42
|
+
|
|
40
43
|
const workingZone = inject('workingZone')
|
|
41
44
|
|
|
42
45
|
import { useRouter, useRoute } from 'vue-router'
|
|
@@ -88,7 +91,7 @@
|
|
|
88
91
|
}
|
|
89
92
|
} catch(error) {
|
|
90
93
|
console.error("Linkedin auth error", error)
|
|
91
|
-
toast.add({ severity: 'error', summary: '
|
|
94
|
+
toast.add({ severity: 'error', summary: t('common.error'), detail: t('linkedinAuth.errorToast'), life: 3000 })
|
|
92
95
|
state.value = 'error'
|
|
93
96
|
error.value = error
|
|
94
97
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="w-full lg:w-6/12 md:w-9/12 max-w-[32rem]" v-shared-element:form="{ duration: '300ms', includeChildren: true }">
|
|
3
3
|
<div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6">
|
|
4
|
-
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">
|
|
5
|
-
<p class="mt-0 p-0 leading-normal">
|
|
4
|
+
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl mb-6">{{ t('signOut.title') }}</div>
|
|
5
|
+
<p class="mt-0 p-0 leading-normal">{{ t('signOut.signingOut') }}</p>
|
|
6
6
|
<ProgressSpinner v-if="isMounted" class="m-4" />
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
<script setup>
|
|
12
12
|
import ProgressSpinner from "primevue/progressspinner"
|
|
13
13
|
|
|
14
|
+
import { useI18n } from 'vue-i18n'
|
|
15
|
+
const { t } = useI18n()
|
|
16
|
+
|
|
14
17
|
import { onMounted, ref } from 'vue'
|
|
15
18
|
const isMounted = ref(false)
|
|
16
19
|
onMounted(() => isMounted.value = true)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/user-frontend",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.179",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "tsx --inspect --expose-gc server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
|
|
6
6
|
"localDevInit": "tsx server/start.js localDev --enableSessions --initScript ./init.js --dbAccess",
|
|
@@ -36,29 +36,29 @@
|
|
|
36
36
|
},
|
|
37
37
|
"type": "module",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@live-change/cli": "^0.9.
|
|
40
|
-
"@live-change/dao": "^0.9.
|
|
41
|
-
"@live-change/dao-vue3": "^0.9.
|
|
42
|
-
"@live-change/dao-websocket": "^0.9.
|
|
43
|
-
"@live-change/email-service": "^0.9.
|
|
44
|
-
"@live-change/framework": "^0.9.
|
|
45
|
-
"@live-change/identicon-service": "^0.9.
|
|
46
|
-
"@live-change/image-frontend": "^0.9.
|
|
47
|
-
"@live-change/message-authentication-service": "^0.9.
|
|
48
|
-
"@live-change/notification-service": "^0.9.
|
|
49
|
-
"@live-change/password-authentication-service": "^0.9.
|
|
50
|
-
"@live-change/pattern": "^0.9.
|
|
51
|
-
"@live-change/secret-code-service": "^0.9.
|
|
52
|
-
"@live-change/secret-link-service": "^0.9.
|
|
53
|
-
"@live-change/security-frontend": "^0.9.
|
|
54
|
-
"@live-change/security-service": "^0.9.
|
|
55
|
-
"@live-change/session-service": "^0.9.
|
|
56
|
-
"@live-change/timer-service": "^0.9.
|
|
57
|
-
"@live-change/upload-service": "^0.9.
|
|
58
|
-
"@live-change/user-identification-service": "^0.9.
|
|
59
|
-
"@live-change/user-service": "^0.9.
|
|
60
|
-
"@live-change/vue3-components": "^0.9.
|
|
61
|
-
"@live-change/vue3-ssr": "^0.9.
|
|
39
|
+
"@live-change/cli": "^0.9.179",
|
|
40
|
+
"@live-change/dao": "^0.9.179",
|
|
41
|
+
"@live-change/dao-vue3": "^0.9.179",
|
|
42
|
+
"@live-change/dao-websocket": "^0.9.179",
|
|
43
|
+
"@live-change/email-service": "^0.9.179",
|
|
44
|
+
"@live-change/framework": "^0.9.179",
|
|
45
|
+
"@live-change/identicon-service": "^0.9.179",
|
|
46
|
+
"@live-change/image-frontend": "^0.9.179",
|
|
47
|
+
"@live-change/message-authentication-service": "^0.9.179",
|
|
48
|
+
"@live-change/notification-service": "^0.9.179",
|
|
49
|
+
"@live-change/password-authentication-service": "^0.9.179",
|
|
50
|
+
"@live-change/pattern": "^0.9.179",
|
|
51
|
+
"@live-change/secret-code-service": "^0.9.179",
|
|
52
|
+
"@live-change/secret-link-service": "^0.9.179",
|
|
53
|
+
"@live-change/security-frontend": "^0.9.179",
|
|
54
|
+
"@live-change/security-service": "^0.9.179",
|
|
55
|
+
"@live-change/session-service": "^0.9.179",
|
|
56
|
+
"@live-change/timer-service": "^0.9.179",
|
|
57
|
+
"@live-change/upload-service": "^0.9.179",
|
|
58
|
+
"@live-change/user-identification-service": "^0.9.179",
|
|
59
|
+
"@live-change/user-service": "^0.9.179",
|
|
60
|
+
"@live-change/vue3-components": "^0.9.179",
|
|
61
|
+
"@live-change/vue3-ssr": "^0.9.179",
|
|
62
62
|
"@vueuse/core": "^12.3.0",
|
|
63
63
|
"codeceptjs-assert": "^0.0.5",
|
|
64
64
|
"codeceptjs-video-helper": "0.1.3",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"wtfnode": "^0.9.1"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
|
-
"@live-change/codeceptjs-helper": "^0.9.
|
|
82
|
+
"@live-change/codeceptjs-helper": "^0.9.179",
|
|
83
83
|
"codeceptjs": "^3.6.10",
|
|
84
84
|
"generate-password": "1.7.1",
|
|
85
85
|
"playwright": "1.49.1",
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"author": "Michał Łaszczewski <michal@laszczewski.pl>",
|
|
91
91
|
"license": "BSD-3-Clause",
|
|
92
92
|
"description": "",
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "060955f28289df05d8f7da24191e42f5840c2e6b"
|
|
94
94
|
}
|