@live-change/user-frontend 0.8.12 → 0.8.13

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.
@@ -9,25 +9,28 @@
9
9
 
10
10
  <ul class="list-none p-0 m-0 mt-5 mb-4">
11
11
 
12
- <li v-for="connection in emails"
12
+ <li v-for="contact in contacts"
13
13
  class="flex flex-row align-items-center justify-content-between mb-2">
14
14
  <div class="flex flex-row align-items-center">
15
- <i class="pi pi-envelope mr-2"></i>
16
- <span class="block text-900 font-medium text-lg">{{ connection.email }}</span>
15
+ <i v-if="contact.contactType.contactType === 'email'" class="pi pi-envelope mr-2"></i>
16
+ <i v-if="contact.contactType.contactType === 'phone'" class="pi pi-mobile mr-2"></i>
17
+ <span class="block text-900 font-medium text-lg">{{ contact.id }}</span>
17
18
  </div>
18
19
  <Button class="p-button-text p-button-plain p-button-rounded mr-1" icon="pi pi-times"
19
20
  v-if="canDelete"
20
- @click="event => disconnect(event, 'email', connection.email)" />
21
+ @click="event => disconnect(event, contact.contactType, contact.id)" />
21
22
  </li>
22
23
 
24
+ <!-- {{ contacts }}-->
25
+
23
26
  </ul>
24
27
 
25
- <router-link :to="{ name: 'user:connect-email' }" class="mr-2 no-underline block mb-1">
26
- <Button label="Add email" icon="pi pi-envelope" id="connect"></Button>
27
- </router-link>
28
- <router-link :to="{ name: 'user:connect-phone' }" class="mr-2 no-underline block mb-1">
29
- <Button label="Add phone number" icon="pi pi-envelope" id="connect"></Button>
28
+ <div class="flex flex-row flex-wrap">
29
+ <router-link v-for="contactType in contactsTypes"
30
+ :to="{ name: 'user:connect-'+contactType.contactType }" class="mr-2 no-underline block mb-1">
31
+ <Button :label="'Add '+contactType.contactType" icon="pi pi-envelope" id="connect"></Button>
30
32
  </router-link>
33
+ </div>
31
34
  </div>
32
35
 
33
36
  </div>
@@ -35,7 +38,6 @@
35
38
 
36
39
  <script setup>
37
40
  import Button from "primevue/button"
38
- import SettingsTabs from "../SettingsTabs.vue"
39
41
 
40
42
  import { ref, onMounted, onUnmounted, inject, computed } from 'vue'
41
43
  import ConfirmPopup from 'primevue/confirmpopup'
@@ -48,22 +50,25 @@
48
50
  onMounted(() => isMounted.value = true)
49
51
  onUnmounted(() => isMounted.value = false)
50
52
 
51
-
52
53
  const workingZone = inject('workingZone')
53
54
 
54
- import { path, live, actions } from '@live-change/vue3-ssr'
55
- const messageAuthenticationApi = actions().messageAuthentication
55
+ import { useApi, live, usePath, useActions } from '@live-change/vue3-ssr'
56
+ const api = useApi()
57
+ const path = usePath()
58
+ const clientConfig = api.getServiceDefinition('messageAuthentication')?.clientConfig
59
+
60
+ const messageAuthenticationApi = useActions().messageAuthentication
56
61
 
57
62
  function disconnect(event, contactType, contact) {
58
63
  confirm.require({
59
64
  target: event.currentTarget,
60
- message: `Do you want to disconnect ${contactType} account ${contact}?`,
65
+ message: `Do you want to disconnect ${contactType.contactType} account ${contact}?`,
61
66
  icon: 'pi pi-info-circle',
62
67
  acceptClass: 'p-button-danger',
63
68
  accept: async () => {
64
- const upperCaseType = contactType[0].toUpperCase() + contactType.slice(1)
69
+ const upperCaseType = contactType.contactType[0].toUpperCase() + contactType.contactType.slice(1)
65
70
  workingZone.addPromise('disconnectContact', (async () => {
66
- await messageAuthenticationApi['disconnect'+upperCaseType]({ [contactType]: contact })
71
+ await messageAuthenticationApi['disconnect'+upperCaseType]({ [contactType.contactType]: contact })
67
72
  toast.add({ severity: 'info', summary: 'Account disconnected', life: 1500 })
68
73
  })())
69
74
  },
@@ -73,9 +78,41 @@
73
78
  })
74
79
  }
75
80
 
76
- const emails = await live(path().email.myUserEmails({}))
81
+ const contactTypesAvailable = clientConfig.contactTypes
82
+
83
+ const contactsTypes = contactTypesAvailable.map(contactType => {
84
+ const contactTypeUpper = contactType[0].toUpperCase() + contactType.slice(1)
77
85
 
78
- const allAccountsCount = computed(() => emails.value?.length )
86
+ let serviceName = 'myUser'+contactTypeUpper+'s'
87
+ let viewName = 'myUser'+contactTypeUpper+'s'
88
+ if(!path[serviceName]) { // find service by viewName
89
+ for(const s in path) {
90
+ if(path[s][viewName]) {
91
+ serviceName = s
92
+ break
93
+ }
94
+ }
95
+ }
96
+ console.log('contactType', contactType, 'serviceName', serviceName, 'viewName', viewName)
97
+ return {
98
+ contactType,
99
+ serviceName,
100
+ viewName,
101
+ path: path[serviceName][viewName]({}),
102
+ contacts: null
103
+ }
104
+ })
105
+
106
+ await Promise.all(contactsTypes.map(async contactType => {
107
+ contactType.contacts = await live(contactType.path)
108
+ }))
109
+
110
+ const contacts = computed(() => contactsTypes.map((c,i) => c.contacts.value.map(v => ({
111
+ contactType: c,
112
+ ...(v)
113
+ }))).flat())
114
+
115
+ const allAccountsCount = computed(() => contacts.value?.length )
79
116
  const canDelete = computed(() => allAccountsCount.value > 1 )
80
117
 
81
118
  </script>
@@ -10,7 +10,7 @@
10
10
  <p class="mt-0 mb-4 p-0 line-height-3">Click on the link or enter the code you found in that message.</p>
11
11
  <Secured :events="['wrong-secret-code']" :actions="['checkSecretCode']">
12
12
  <command-form service="messageAuthentication" action="finishMessageAuthentication"
13
- :parameters="{ secretType: 'code', authentication }"
13
+ :parameters="{ secretType: 'code', authentication }" :key="authentication"
14
14
  @submit="handleSubmit" @done="handleAuthenticated" @error="handleError"
15
15
  v-slot="{ data }">
16
16
  <div class="flex justify-content-center">
@@ -11,13 +11,28 @@ export function routes(config = {}) {
11
11
  component: () => import("./MessageLink.vue") }),
12
12
 
13
13
  route({ name: 'user:email:signUpWithMessage', path: '/_email/signUpWithMessage/:contact/:json', props: true,
14
- meta: { raw: true }, component: () => import("./SignUpEmail.vue") }),
14
+ meta: { raw: true }, component: () => import("./email/SignUpEmail.vue") }),
15
15
  route({ name: 'user:email:signInWithMessage', path: '/_email/signInWithMessage/:contact/:json', props: true,
16
- meta: { raw: true }, component: () => import("./SignInEmail.vue") }),
16
+ meta: { raw: true }, component: () => import("./email/SignInEmail.vue") }),
17
17
  route({ name: 'user:email:connectWithMessage', path: '/_email/connectWithMessage/:contact/:json', props: true,
18
- meta: { raw: true }, component: () => import("./ConnectEmail.vue") }),
19
- route({ name: 'user:email:startResetPasswordWithMessage', path: '/_email/startResetPasswordWithMessage/:contact/:json',
20
- props: true, meta: { raw: true }, component: () => import("./ResetPasswordEmail.vue") }),
18
+ meta: { raw: true }, component: () => import("./email/ConnectEmail.vue") }),
19
+ route({
20
+ name: 'user:email:startResetPasswordWithMessage',
21
+ path: '/_email/startResetPasswordWithMessage/:contact/:json',
22
+ props: true, meta: { raw: true }, component: () => import("./email/ResetPasswordEmail.vue")
23
+ }),
24
+
25
+ route({ name: 'user:sms:signUpWithMessage', path: '/_sms/signUpWithMessage/:contact/:json', props: true,
26
+ meta: { raw: true }, component: () => import("./sms/SignUpSms.vue") }),
27
+ route({ name: 'user:sms:signInWithMessage', path: '/_sms/signInWithMessage/:contact/:json', props: true,
28
+ meta: { raw: true }, component: () => import("./sms/SignInSms.vue") }),
29
+ route({ name: 'user:sms:connectWithMessage', path: '/_sms/connectWithMessage/:contact/:json', props: true,
30
+ meta: { raw: true }, component: () => import("./sms/ConnectSms.vue") }),
31
+ route({
32
+ name: 'user:sms:startResetPasswordWithMessage',
33
+ path: '/_sms/startResetPasswordWithMessage/:contact/:json',
34
+ props: true, meta: { raw: true }, component: () => import("./sms/ResetPasswordSms.vue")
35
+ }),
21
36
 
22
37
  ]
23
38
  }
@@ -0,0 +1,69 @@
1
+ <template>
2
+ <pre data-headers>{{ JSON.stringify(metadata, null, ' ') }}</pre>
3
+ <pre class="message" data-text>
4
+ Hello! Enter authentication code: {{ code }}
5
+ Or open authentication link: {{ linkAddress }}
6
+ See you soon
7
+ {{ brandName }} Team
8
+ </pre>
9
+ </template>
10
+
11
+ <script setup>
12
+ import Button from "primevue/button"
13
+
14
+ const { action, contact, json } = defineProps({
15
+ action: {
16
+ type: String,
17
+ required: true
18
+ },
19
+ contact: {
20
+ type: String,
21
+ required: true
22
+ },
23
+ json: {
24
+ type: String,
25
+ required: true
26
+ }
27
+ })
28
+
29
+ const data = JSON.parse(json)
30
+ const secrets = data.secrets
31
+
32
+ const secretLink = secrets.find(secret => secret.type == 'link')
33
+
34
+ const secretCode = secrets.find(secret => secret.type == 'code')
35
+
36
+ const brandName = ENV_BRAND_NAME
37
+ const metadata = {
38
+ from: ENV_BRAND_SMS_FROM,
39
+ to: contact
40
+ }
41
+
42
+ import { useRouter } from 'vue-router'
43
+ const router = useRouter()
44
+ const linkAddress = ENV_BASE_HREF + router.resolve({
45
+ name: 'user:link',
46
+ params: {
47
+ secretCode: secretLink.secret.secretCode
48
+ }
49
+ }).href
50
+
51
+ const code = secretCode.secret.secretCode
52
+
53
+ </script>
54
+
55
+ <style scoped>
56
+ img {
57
+ width: 100%;
58
+ max-width: 100px;
59
+ }
60
+ .message {
61
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
62
+ color: #495057;
63
+ font-weight: 400;
64
+ }
65
+ pre {
66
+ border-top: 1px solid black;
67
+ border-bottom: 1px solid black;
68
+ }
69
+ </style>
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <pre data-headers>{{ JSON.stringify(metadata, null, ' ') }}</pre>
3
+ <pre class="message" data-text>
4
+ Hello! Enter authentication code: {{ code }}
5
+ Or open authentication link: {{ linkAddress }}
6
+ See you soon
7
+ {{ brandName }} Team
8
+ </pre>
9
+ </template>
10
+
11
+ <script setup>
12
+ const { action, contact, json } = defineProps({
13
+ action: {
14
+ type: String,
15
+ required: true
16
+ },
17
+ contact: {
18
+ type: String,
19
+ required: true
20
+ },
21
+ json: {
22
+ type: String,
23
+ required: true
24
+ }
25
+ })
26
+
27
+ const data = JSON.parse(json)
28
+ const secrets = data.secrets
29
+
30
+ const secretLink = secrets.find(secret => secret.type == 'link')
31
+
32
+ const secretCode = secrets.find(secret => secret.type == 'code')
33
+
34
+ const brandName = ENV_BRAND_NAME
35
+ const metadata = {
36
+ from: ENV_BRAND_SMS_FROM,
37
+ to: contact
38
+ }
39
+
40
+ import { useRouter } from 'vue-router'
41
+ const router = useRouter()
42
+ const linkAddress = ENV_BASE_HREF + router.resolve({
43
+ name: 'user:link',
44
+ params: {
45
+ secretCode: secretLink.secret.secretCode
46
+ }
47
+ }).href
48
+
49
+ const code = secretCode.secret.secretCode
50
+
51
+ </script>
52
+
53
+ <style scoped>
54
+ img {
55
+ width: 100%;
56
+ max-width: 100px;
57
+ }
58
+ .message {
59
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
60
+ color: #495057;
61
+ font-weight: 400;
62
+ }
63
+ pre {
64
+ border-top: 1px solid black;
65
+ border-bottom: 1px solid black;
66
+ }
67
+ </style>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <pre data-headers>{{ JSON.stringify(metadata, null, ' ') }}</pre>
3
+ <pre class="message" data-text>
4
+ Hello! Enter authentication code: {{ code }}
5
+ Or open authentication link: {{ linkAddress }}
6
+ See you soon
7
+ {{ brandName }} Team
8
+ </pre>
9
+ </template>
10
+
11
+ <script setup>
12
+ const { action, contact, json } = defineProps({
13
+ action: {
14
+ type: String,
15
+ required: true
16
+ },
17
+ contact: {
18
+ type: String,
19
+ required: true
20
+ },
21
+ json: {
22
+ type: String,
23
+ required: true
24
+ }
25
+ })
26
+
27
+ const data = JSON.parse(json)
28
+ const secrets = data.secrets
29
+
30
+ const secretLink = secrets.find(secret => secret.type == 'link')
31
+
32
+ const secretCode = secrets.find(secret => secret.type == 'code')
33
+
34
+
35
+ const brandName = ENV_BRAND_NAME
36
+ const metadata = {
37
+ from: ENV_BRAND_SMS_FROM,
38
+ to: contact
39
+ }
40
+
41
+ import { useRouter } from 'vue-router'
42
+ const router = useRouter()
43
+ const linkAddress = ENV_BASE_HREF + router.resolve({
44
+ name: 'user:link',
45
+ params: {
46
+ secretCode: secretLink.secret.secretCode
47
+ }
48
+ }).href
49
+
50
+ const code = secretCode.secret.secretCode
51
+
52
+ </script>
53
+
54
+ <style scoped>
55
+ img {
56
+ width: 100%;
57
+ max-width: 100px;
58
+ }
59
+ .message {
60
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
61
+ color: #495057;
62
+ font-weight: 400;
63
+ }
64
+ pre {
65
+ border-top: 1px solid black;
66
+ border-bottom: 1px solid black;
67
+ }
68
+ </style>
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <pre data-headers>{{ JSON.stringify(metadata, null, ' ') }}</pre>
3
+ <pre class="message" data-text>
4
+ Hello! Enter authentication code: {{ code }}
5
+ Or open authentication link: {{ linkAddress }}
6
+ See you soon
7
+ {{ brandName }} Team
8
+ </pre>
9
+ </template>
10
+
11
+ <script setup>
12
+ const { action, contact, json } = defineProps({
13
+ action: {
14
+ type: String,
15
+ required: true
16
+ },
17
+ contact: {
18
+ type: String,
19
+ required: true
20
+ },
21
+ json: {
22
+ type: String,
23
+ required: true
24
+ }
25
+ })
26
+
27
+ const data = JSON.parse(json)
28
+ const secrets = data.secrets
29
+
30
+ const secretLink = secrets.find(secret => secret.type === 'link')
31
+ const secretCode = secrets.find(secret => secret.type === 'code')
32
+
33
+ const brandName = ENV_BRAND_NAME
34
+ const metadata = {
35
+ from: ENV_BRAND_SMS_FROM,
36
+ to: contact
37
+ }
38
+
39
+ import { useRouter } from 'vue-router'
40
+ const router = useRouter()
41
+ const linkAddress = ENV_BASE_HREF + router.resolve({
42
+ name: 'user:link',
43
+ params: {
44
+ secretCode: secretLink.secret.secretCode
45
+ }
46
+ }).href
47
+
48
+ const code = secretCode.secret.secretCode
49
+
50
+ </script>
51
+
52
+ <style scoped>
53
+ img {
54
+ width: 100%;
55
+ max-width: 100px;
56
+ }
57
+ .message {
58
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
59
+ color: #495057;
60
+ font-weight: 400;
61
+ }
62
+ pre {
63
+ border-top: 1px solid black;
64
+ border-bottom: 1px solid black;
65
+ }
66
+ </style>
@@ -6,7 +6,7 @@
6
6
  cursor-pointer transition-colors transition-duration-150 border-round">
7
7
  <Image v-if="myIdentification?.image" :image="myIdentification.image"
8
8
  class="mr-0 border-circle border-1 surface-border" style="width: 3rem; " />
9
- <img v-else-if="ownerType == 'session_Session'" src="/images/empty-user-photo.svg"
9
+ <img v-else-if="ownerData[0] === 'session_Session'" src="/images/empty-user-photo.svg"
10
10
  class="mr-0 border-circle" style="width: 3rem;" />
11
11
  <img v-else :src="identiconUrl"
12
12
  class="mr-0 border-circle border-1 surface-border" style="width: 3rem;" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/user-frontend",
3
- "version": "0.8.12",
3
+ "version": "0.8.13",
4
4
  "scripts": {
5
5
  "memDev": "node --inspect --expose-gc server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
6
6
  "localDevInit": "rm tmp.db; node server/start.js localDev --enableSessions --initScript ./init.js",
@@ -21,29 +21,29 @@
21
21
  },
22
22
  "type": "module",
23
23
  "dependencies": {
24
- "@live-change/cli": "^0.8.12",
25
- "@live-change/dao": "^0.8.12",
26
- "@live-change/dao-vue3": "^0.8.12",
27
- "@live-change/dao-websocket": "^0.8.12",
28
- "@live-change/email-service": "^0.8.12",
29
- "@live-change/framework": "^0.8.12",
30
- "@live-change/identicon-service": "^0.8.12",
31
- "@live-change/image-frontend": "^0.8.12",
32
- "@live-change/message-authentication-service": "^0.8.12",
33
- "@live-change/notification-service": "^0.8.12",
34
- "@live-change/password-authentication-service": "^0.8.12",
35
- "@live-change/pattern": "^0.8.12",
36
- "@live-change/secret-code-service": "^0.8.12",
37
- "@live-change/secret-link-service": "^0.8.12",
38
- "@live-change/security-frontend": "^0.8.12",
39
- "@live-change/security-service": "^0.8.12",
40
- "@live-change/session-service": "^0.8.12",
41
- "@live-change/timer-service": "^0.8.12",
42
- "@live-change/upload-service": "^0.8.12",
43
- "@live-change/user-identification-service": "^0.8.12",
44
- "@live-change/user-service": "^0.8.12",
45
- "@live-change/vue3-components": "^0.8.12",
46
- "@live-change/vue3-ssr": "^0.8.12",
24
+ "@live-change/cli": "^0.8.13",
25
+ "@live-change/dao": "^0.8.13",
26
+ "@live-change/dao-vue3": "^0.8.13",
27
+ "@live-change/dao-websocket": "^0.8.13",
28
+ "@live-change/email-service": "^0.8.13",
29
+ "@live-change/framework": "^0.8.13",
30
+ "@live-change/identicon-service": "^0.8.13",
31
+ "@live-change/image-frontend": "^0.8.13",
32
+ "@live-change/message-authentication-service": "^0.8.13",
33
+ "@live-change/notification-service": "^0.8.13",
34
+ "@live-change/password-authentication-service": "^0.8.13",
35
+ "@live-change/pattern": "^0.8.13",
36
+ "@live-change/secret-code-service": "^0.8.13",
37
+ "@live-change/secret-link-service": "^0.8.13",
38
+ "@live-change/security-frontend": "^0.8.13",
39
+ "@live-change/security-service": "^0.8.13",
40
+ "@live-change/session-service": "^0.8.13",
41
+ "@live-change/timer-service": "^0.8.13",
42
+ "@live-change/upload-service": "^0.8.13",
43
+ "@live-change/user-identification-service": "^0.8.13",
44
+ "@live-change/user-service": "^0.8.13",
45
+ "@live-change/vue3-components": "^0.8.13",
46
+ "@live-change/vue3-ssr": "^0.8.13",
47
47
  "@vueuse/core": "^10.7.2",
48
48
  "codeceptjs-assert": "^0.0.5",
49
49
  "codeceptjs-video-helper": "0.1.3",
@@ -64,7 +64,7 @@
64
64
  "wtfnode": "^0.9.1"
65
65
  },
66
66
  "devDependencies": {
67
- "@live-change/codeceptjs-helper": "^0.8.12",
67
+ "@live-change/codeceptjs-helper": "^0.8.13",
68
68
  "codeceptjs": "^3.5.12",
69
69
  "generate-password": "1.7.1",
70
70
  "playwright": "^1.41.2",
@@ -75,5 +75,5 @@
75
75
  "author": "",
76
76
  "license": "BSD-3-Clause",
77
77
  "description": "",
78
- "gitHead": "5c93162184742550bf6a5e7b37a5537c69f8a3c4"
78
+ "gitHead": "4453aa639a9fe1a857d93d73ebd28a82c97fdd87"
79
79
  }
@@ -25,8 +25,8 @@ app.config = {
25
25
  path: '@live-change/email-service'
26
26
  },
27
27
  {
28
- name: 'smsapi',
29
- path: '@live-change/email-service'
28
+ name: 'phone',
29
+ path: '@live-change/phone-service'
30
30
  },
31
31
  {
32
32
  name: 'secretLink',
@@ -1,7 +1,7 @@
1
1
  import session from '@live-change/session-service'
2
2
  import user from '@live-change/user-service'
3
3
  import email from '@live-change/email-service'
4
- import smsapi from '@live-change/smsapi-service'
4
+ import phone from '@live-change/phone-service'
5
5
  import passwordAuthentication from '@live-change/password-authentication-service'
6
6
  import userIdentification from '@live-change/user-identification-service'
7
7
  import identicon from '@live-change/identicon-service'
@@ -21,7 +21,7 @@ export {
21
21
  session,
22
22
  user,
23
23
  email,
24
- smsapi,
24
+ phone,
25
25
  passwordAuthentication,
26
26
  userIdentification,
27
27
  identicon,
package/server/start.js CHANGED
@@ -10,7 +10,7 @@ import { starter } from '@live-change/cli'
10
10
 
11
11
  starter(appConfig)
12
12
 
13
- //*
13
+ /*
14
14
  import os from 'os'
15
15
  const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
16
16
  const formatUptime = (data) => // dd:hh:mm:ss