@live-change/user-frontend 0.9.128 → 0.9.130
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/src/connected/Connected.vue +30 -16
- package/front/src/connected/accountTypes/GoogleAccountItem.vue +20 -0
- package/front/src/connected/accountTypes/LinkedinAccountItem.vue +19 -0
- package/front/src/connected/accountTypes/UnknownAccountItem.vue +25 -0
- package/front/src/connected/connected.js +2 -2
- package/front/src/message-auth/MessageSent.vue +16 -4
- package/front/src/sign/SignInEmail.vue +16 -4
- package/front/src/sign/SignUpEmail.vue +18 -4
- package/index.js +3 -0
- package/package.json +26 -26
|
@@ -25,17 +25,10 @@
|
|
|
25
25
|
</li>
|
|
26
26
|
<li v-for="account in accounts"
|
|
27
27
|
class="flex flex-row items-center justify-between mb-2">
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</div>
|
|
33
|
-
<div v-else-if="account.accountType.accountType === 'linkedin'"
|
|
34
|
-
class="flex flex-row items-center">
|
|
35
|
-
<i class="pi pi-linkedin mr-2"></i>
|
|
36
|
-
<span class="block text-surface-900 dark:text-surface-0 font-medium text-lg">{{ account.name }}</span>
|
|
37
|
-
</div>
|
|
38
|
-
<pre v-else>{{ account }}</pre>
|
|
28
|
+
<InjectComponent
|
|
29
|
+
:request="{ name: 'connectedAccountItem', accountType: account.accountType.accountType }"
|
|
30
|
+
:defaultComponent="UnknownAccountItem"
|
|
31
|
+
:props="{ account }" />
|
|
39
32
|
<Button class="p-button-text p-button-plain p-button-rounded mr-1" icon="pi pi-times"
|
|
40
33
|
v-if="canDelete"
|
|
41
34
|
@click="event => disconnectAccount(event, account, account.email)" />
|
|
@@ -43,7 +36,7 @@
|
|
|
43
36
|
|
|
44
37
|
</ul>
|
|
45
38
|
|
|
46
|
-
<div class="flex flex-row flex-wrap">
|
|
39
|
+
<div class="flex flex-row flex-wrap">
|
|
47
40
|
<router-link v-for="contactType in contactsTypes"
|
|
48
41
|
:to="{ name: 'user:connect-'+contactType.contactType }" class="mr-2 no-underline block mb-1">
|
|
49
42
|
<Button v-if="contactType.contactType === 'email'"
|
|
@@ -52,10 +45,12 @@
|
|
|
52
45
|
:label="'Add '+contactType.contactType" icon="pi pi-phone" id="connect" />
|
|
53
46
|
<Button v-else :label="'Add '+contactType.contactType" icon="pi pi-envelope" id="connect" />
|
|
54
47
|
</router-link>
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
<template v-for="accountType in accountTypes">
|
|
49
|
+
<router-link v-if="connectAccountRoute(accountType)"
|
|
50
|
+
:to="connectAccountRoute(accountType)" class="mr-2 no-underline block mb-1">
|
|
51
|
+
<Button v :label="'Add '+accountType.accountType" icon="pi pi-google" id="connect" />
|
|
52
|
+
</router-link>
|
|
53
|
+
</template>
|
|
59
54
|
|
|
60
55
|
</div>
|
|
61
56
|
</div>
|
|
@@ -66,6 +61,15 @@
|
|
|
66
61
|
<script setup>
|
|
67
62
|
import Button from "primevue/button"
|
|
68
63
|
|
|
64
|
+
import { provideComponent, InjectComponent } from '@live-change/vue3-components'
|
|
65
|
+
import GoogleAccountItem from './accountTypes/GoogleAccountItem.vue'
|
|
66
|
+
import LinkedinAccountItem from './accountTypes/LinkedinAccountItem.vue'
|
|
67
|
+
|
|
68
|
+
provideComponent({ name: 'connectedAccountItem', accountType: 'google' }, GoogleAccountItem)
|
|
69
|
+
provideComponent({ name: 'connectedAccountItem', accountType: 'linkedin' }, LinkedinAccountItem)
|
|
70
|
+
import UnknownAccountItem from './accountTypes/UnknownAccountItem.vue'
|
|
71
|
+
|
|
72
|
+
|
|
69
73
|
import { ref, onMounted, onUnmounted, inject, computed } from 'vue'
|
|
70
74
|
import ConfirmPopup from 'primevue/confirmpopup'
|
|
71
75
|
import Toast from 'primevue/toast'
|
|
@@ -77,6 +81,9 @@
|
|
|
77
81
|
onMounted(() => isMounted.value = true)
|
|
78
82
|
onUnmounted(() => isMounted.value = false)
|
|
79
83
|
|
|
84
|
+
import { useRouter } from 'vue-router'
|
|
85
|
+
const router = useRouter()
|
|
86
|
+
|
|
80
87
|
import { formatPhoneNumber } from '../phone/phoneNumber.js'
|
|
81
88
|
|
|
82
89
|
const workingZone = inject('workingZone')
|
|
@@ -155,6 +162,13 @@
|
|
|
155
162
|
const allAccountsCount = computed(() => contacts.value?.length + accounts.value?.length )
|
|
156
163
|
const canDelete = computed(() => allAccountsCount.value > 1 )
|
|
157
164
|
|
|
165
|
+
function connectAccountRoute(accountType) {
|
|
166
|
+
const route = { name: 'user:connect-'+accountType.accountType }
|
|
167
|
+
/// Check if the route is registered in the router
|
|
168
|
+
const routeExists = router.getRoutes().find(r => r.name === route.name)
|
|
169
|
+
return routeExists ? route : null
|
|
170
|
+
}
|
|
171
|
+
|
|
158
172
|
</script>
|
|
159
173
|
|
|
160
174
|
<style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-row items-center">
|
|
3
|
+
<i class="pi pi-google mr-2"></i>
|
|
4
|
+
<span class="block text-surface-900 dark:text-surface-0 font-medium text-lg">{{ account.email }}</span>
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
import { toRefs, computed, defineProps } from 'vue'
|
|
10
|
+
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
account: {
|
|
13
|
+
type: Object,
|
|
14
|
+
required: true
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const { account } = toRefs(props)
|
|
19
|
+
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-row items-center">
|
|
3
|
+
<i class="pi pi-linkedin mr-2"></i>
|
|
4
|
+
<span class="block text-surface-900 dark:text-surface-0 font-medium text-lg">{{ account.name }}</span>
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
import { toRefs, computed, defineProps } from 'vue'
|
|
10
|
+
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
account: {
|
|
13
|
+
type: Object,
|
|
14
|
+
required: true
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const { account } = toRefs(props)
|
|
19
|
+
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-row items-center">
|
|
3
|
+
<i class="pi pi-question-circle mr-2"></i>
|
|
4
|
+
<span class="block text-surface-900 dark:text-surface-0 font-medium text-lg">{{ cleanAccountInfo }}</span>
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
import { toRefs, computed, defineProps } from 'vue'
|
|
10
|
+
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
account: {
|
|
13
|
+
type: Object,
|
|
14
|
+
required: true
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const { account } = toRefs(props)
|
|
19
|
+
|
|
20
|
+
const cleanAccountInfo = computed(() => {
|
|
21
|
+
if(!account.value) return "Unknown account"
|
|
22
|
+
const { accountType, ...rest } = account.value
|
|
23
|
+
return { ...rest, accountType: accountType.accountType }
|
|
24
|
+
})
|
|
25
|
+
</script>
|
|
@@ -55,7 +55,7 @@ export function getAccountTypes(api = useApi()) {
|
|
|
55
55
|
path: accountsPath,
|
|
56
56
|
accounts: null,
|
|
57
57
|
async fetchAccounts(context, onUnmountedCb){
|
|
58
|
-
const accounts = await live(
|
|
58
|
+
const accounts = await live(accountsPath, context, onUnmountedCb)
|
|
59
59
|
this.accounts = accounts
|
|
60
60
|
return accounts
|
|
61
61
|
}
|
|
@@ -88,7 +88,7 @@ export async function getAccounts(context, onUnmountedCb) {
|
|
|
88
88
|
for(const accountType of accountTypes) {
|
|
89
89
|
await accountType.fetchAccounts(context, onUnmountedCb)
|
|
90
90
|
}
|
|
91
|
-
const accounts = computed(() => accountTypes.map((c,i) => c.accounts.value.map(v => ({
|
|
91
|
+
const accounts = computed(() => accountTypes.map((c,i) => (c.accounts.value ?? []).map(v => ({
|
|
92
92
|
accountType: c.contactType,
|
|
93
93
|
serviceName: c.serviceName,
|
|
94
94
|
...(v)
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<p class="mt-0 mb-1 p-0 leading-normal">You authenticated in a different tab.</p>
|
|
7
7
|
</div>
|
|
8
8
|
<div class="bg-surface-0 dark:bg-surface-900 rounded-border shadow p-6" v-else>
|
|
9
|
-
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl">
|
|
10
|
-
<p class="mt-0 mb-1 p-0 leading-normal">
|
|
11
|
-
<p class="mt-0 mb-6 p-0 leading-normal">
|
|
9
|
+
<div class="text-surface-900 dark:text-surface-0 font-medium mb-4 text-xl">{{ title }}</div>
|
|
10
|
+
<p class="mt-0 mb-1 p-0 leading-normal">{{ description }}</p>
|
|
11
|
+
<p class="mt-0 mb-6 p-0 leading-normal">{{ callToAction }}</p>
|
|
12
12
|
<Secured :events="['wrong-secret-code']" :actions="['checkSecretCode']">
|
|
13
13
|
<command-form service="messageAuthentication" action="finishMessageAuthentication"
|
|
14
14
|
:parameters="{ secretType: 'code', authentication }" :key="authentication"
|
|
@@ -64,7 +64,19 @@
|
|
|
64
64
|
authentication: {
|
|
65
65
|
type: String,
|
|
66
66
|
required: true
|
|
67
|
-
}
|
|
67
|
+
},
|
|
68
|
+
title: {
|
|
69
|
+
type: String,
|
|
70
|
+
default: 'Message sent',
|
|
71
|
+
},
|
|
72
|
+
description: {
|
|
73
|
+
type: String,
|
|
74
|
+
default: 'We sent special secret message to the contact you already provided.',
|
|
75
|
+
},
|
|
76
|
+
callToAction: {
|
|
77
|
+
type: String,
|
|
78
|
+
default: 'Click on the link or enter the code you found in that message.',
|
|
79
|
+
},
|
|
68
80
|
})
|
|
69
81
|
|
|
70
82
|
function handleAuthenticated({ parameters, result }) {
|
|
@@ -51,12 +51,12 @@
|
|
|
51
51
|
|
|
52
52
|
</command-form>
|
|
53
53
|
|
|
54
|
-
<Divider v-if="
|
|
54
|
+
<Divider v-if="availableAccountTypes.length > 0" align="center" class="my-6">
|
|
55
55
|
<span class="text-surface-600 dark:text-surface-200 font-normal text-sm">OR</span>
|
|
56
56
|
</Divider>
|
|
57
57
|
|
|
58
|
-
<router-link v-for="accountType in
|
|
59
|
-
:to="
|
|
58
|
+
<router-link v-for="accountType in availableAccountTypes"
|
|
59
|
+
:to="accountType.connectRoute"
|
|
60
60
|
class="no-underline">
|
|
61
61
|
<Button
|
|
62
62
|
:label="`Sign In with ${accountType.accountType[0].toUpperCase()}${accountType.accountType.slice(1)}`"
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
import Password from "../password/Password.vue"
|
|
79
79
|
import Message from "primevue/message"
|
|
80
80
|
|
|
81
|
-
import { onMounted, ref } from 'vue'
|
|
81
|
+
import { onMounted, ref, computed } from 'vue'
|
|
82
82
|
const isMounted = ref(false)
|
|
83
83
|
onMounted(() => isMounted.value = true)
|
|
84
84
|
|
|
@@ -92,6 +92,18 @@
|
|
|
92
92
|
const contactsTypes = getContactTypes()
|
|
93
93
|
const accountTypes = getAccountTypes()
|
|
94
94
|
|
|
95
|
+
const availableAccountTypes = computed(() => accountTypes.map(accountType => {
|
|
96
|
+
const route = { name: `user:${accountType.accountType}Auth`, params: { action: 'signInOrSignUp' } }
|
|
97
|
+
const routeExists = router.getRoutes().find(r => r.name === route.name)
|
|
98
|
+
if(routeExists) {
|
|
99
|
+
return {
|
|
100
|
+
...accountType,
|
|
101
|
+
connectRoute: route
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return null
|
|
105
|
+
}).filter(accountType => !!accountType))
|
|
106
|
+
|
|
95
107
|
function handleDone({ parameters, result }) {
|
|
96
108
|
console.log("DONE RESULT", result)
|
|
97
109
|
if(result.type === 'sent') {
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
<Button label="Sign Up with email" icon="pi pi-user" class="w-full" type="submit" />
|
|
28
28
|
</command-form>
|
|
29
29
|
|
|
30
|
-
<Divider v-if="
|
|
30
|
+
<Divider v-if="availableAccountTypes.length > 0" align="center" class="my-6">
|
|
31
31
|
<b>OR</b>
|
|
32
32
|
</Divider>
|
|
33
33
|
|
|
34
|
-
<router-link v-for="accountType in
|
|
35
|
-
:to="
|
|
34
|
+
<router-link v-for="accountType in availableAccountTypes"
|
|
35
|
+
:to="accountType.connectRoute"
|
|
36
36
|
class="no-underline">
|
|
37
37
|
<Button
|
|
38
38
|
:label="`Sign Up with ${accountType.accountType[0].toUpperCase()}${accountType.accountType.slice(1)}`"
|
|
@@ -60,13 +60,27 @@
|
|
|
60
60
|
import { useRouter } from 'vue-router'
|
|
61
61
|
const router = useRouter()
|
|
62
62
|
|
|
63
|
+
import { computed } from 'vue'
|
|
64
|
+
|
|
63
65
|
import { useI18n } from 'vue-i18n'
|
|
64
66
|
const { t } = useI18n()
|
|
65
67
|
|
|
66
|
-
import { getContactTypes, getAccountTypes} from '../connected/connected.js'
|
|
68
|
+
import { getContactTypes, getAccountTypes } from '../connected/connected.js'
|
|
67
69
|
const contactsTypes = getContactTypes()
|
|
68
70
|
const accountTypes = getAccountTypes()
|
|
69
71
|
|
|
72
|
+
const availableAccountTypes = computed(() => accountTypes.map(accountType => {
|
|
73
|
+
const route = { name: `user:${accountType.accountType}Auth`, params: { action: 'signInOrSignUp' } }
|
|
74
|
+
const routeExists = router.getRoutes().find(r => r.name === route.name)
|
|
75
|
+
if(routeExists) {
|
|
76
|
+
return {
|
|
77
|
+
...accountType,
|
|
78
|
+
connectRoute: route
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return null
|
|
82
|
+
}).filter(accountType => !!accountType))
|
|
83
|
+
|
|
70
84
|
function handleSent({ parameters, result }) {
|
|
71
85
|
const { authentication } = result
|
|
72
86
|
router.push({
|
package/index.js
CHANGED
|
@@ -22,6 +22,9 @@ import PhoneInput from "./front/src/phone/PhoneInput.vue"
|
|
|
22
22
|
import CountryInput from './front/src/phone/CountryInput.vue'
|
|
23
23
|
export { PhoneInput, CountryInput }
|
|
24
24
|
|
|
25
|
+
import MessageSent from "./front/src/message-auth/MessageSent.vue"
|
|
26
|
+
export { MessageSent }
|
|
27
|
+
|
|
25
28
|
export * from './front/src/connected/connected.js'
|
|
26
29
|
|
|
27
30
|
export * from "./front/src/router.js"
|
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.130",
|
|
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.130",
|
|
40
|
+
"@live-change/dao": "^0.9.130",
|
|
41
|
+
"@live-change/dao-vue3": "^0.9.130",
|
|
42
|
+
"@live-change/dao-websocket": "^0.9.130",
|
|
43
|
+
"@live-change/email-service": "^0.9.130",
|
|
44
|
+
"@live-change/framework": "^0.9.130",
|
|
45
|
+
"@live-change/identicon-service": "^0.9.130",
|
|
46
|
+
"@live-change/image-frontend": "^0.9.130",
|
|
47
|
+
"@live-change/message-authentication-service": "^0.9.130",
|
|
48
|
+
"@live-change/notification-service": "^0.9.130",
|
|
49
|
+
"@live-change/password-authentication-service": "^0.9.130",
|
|
50
|
+
"@live-change/pattern": "^0.9.130",
|
|
51
|
+
"@live-change/secret-code-service": "^0.9.130",
|
|
52
|
+
"@live-change/secret-link-service": "^0.9.130",
|
|
53
|
+
"@live-change/security-frontend": "^0.9.130",
|
|
54
|
+
"@live-change/security-service": "^0.9.130",
|
|
55
|
+
"@live-change/session-service": "^0.9.130",
|
|
56
|
+
"@live-change/timer-service": "^0.9.130",
|
|
57
|
+
"@live-change/upload-service": "^0.9.130",
|
|
58
|
+
"@live-change/user-identification-service": "^0.9.130",
|
|
59
|
+
"@live-change/user-service": "^0.9.130",
|
|
60
|
+
"@live-change/vue3-components": "^0.9.130",
|
|
61
|
+
"@live-change/vue3-ssr": "^0.9.130",
|
|
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.130",
|
|
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": "249279687126ae035353865197b6f3eff934794a"
|
|
94
94
|
}
|