@live-change/peer-connection-frontend 0.8.34 → 0.8.36

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.
@@ -0,0 +1,146 @@
1
+ <template>
2
+ <Dialog header="Permissions" v-model:visible="model.visible" modal>
3
+ <template #header>
4
+ <div class="flex flex-row align-items-center">
5
+ <i class="pi pi-unlock mr-2" />
6
+ <h3>{{ title }}</h3>
7
+ </div>
8
+ </template>
9
+ <template #default>
10
+ <slot name="introduction" />
11
+ <div class="mt-2">
12
+ <div v-for="permission in Object.entries(model.permissions)" class="flex flex-row align-items-center mb-2">
13
+ <i :class="permissionIcons[permission[0]]" />
14
+ <div class="ml-2">{{ permission[0] }}: </div>
15
+ <div v-if="permission[1] === 'granted'" class="ml-1 font-semibold text-green-400">
16
+ {{ permission[1] }}
17
+ </div>
18
+ <div v-else-if="permission[1] === 'denied'" class="ml-1 font-semibold text-red-400">
19
+ {{ permission[1] }}
20
+ </div>
21
+ <div v-else class="ml-1 font-semibold">{{ permission[1] }}</div>
22
+ </div>
23
+ </div>
24
+ </template>
25
+ <template #footer>
26
+ <slot name="buttons" :permissions="model.permissions" />
27
+ </template>
28
+ <!--
29
+
30
+ <div class="permissions-state">
31
+ <div class="permission-state card" v-for="permissionState in permissionsState">
32
+ <div class="permission-state-icon">
33
+ <img :src="permissionIcons[permissionState.name][+(permissionState.state!=='denied')]">
34
+ </div>
35
+ <div class="permission-description">
36
+ <p class="permission-name">{{ i18n.permissions[permissionState.name] }}</p>
37
+ <p>{{ i18n.state }} <span class="permission-state-name">{{ i18n.states[permissionState.state] }}</span></p>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ <div class="buttons permissions-buttons">
42
+ <button v-for="button in buttons" class="button" type="button"
43
+ :disabled="button.hasOwnProperty('needPermissions')
44
+ ? (button.needPermissions && !isOk) || (!button.needPermissions && isOk)
45
+ : false"
46
+ @click="() => { $emit(button.event); $emit('close') }">
47
+ <span>{{ button.name }}</span>
48
+ </button>
49
+ </div>
50
+ -->
51
+
52
+ </Dialog>
53
+ </template>
54
+
55
+ <script setup>
56
+ const permissionIcons = {
57
+ camera: 'pi pi-camera',
58
+ microphone: 'pi pi-microphone'
59
+ }
60
+
61
+ import { defineProps, defineModel, defineEmits, toRefs, ref, computed, watch } from 'vue'
62
+ import { useInterval } from '@vueuse/core'
63
+
64
+ const props = defineProps({
65
+ title: {
66
+ type: String
67
+ },
68
+ introduction: {
69
+ type: String
70
+ },
71
+ buttons: {
72
+ type: Array
73
+ },
74
+ requiredPermissions: {
75
+ type: Array
76
+ },
77
+ autoClose: {
78
+ type: Boolean
79
+ }
80
+ })
81
+ const { title, closeable, introduction, buttons, requiredPermissions, autoClose } = toRefs(props)
82
+
83
+ const model = defineModel({
84
+ required: true,
85
+ type: Object,
86
+ properties: {
87
+ visible: {
88
+ type: Boolean
89
+ },
90
+ permissions: {
91
+ type: Object
92
+ }
93
+ }
94
+ })
95
+
96
+ const emit = defineEmits(['ok'])
97
+
98
+ watch(() => JSON.stringify(requiredPermissions.value), async value => {
99
+ console.log("requiredPermissions", value)
100
+
101
+ for(const requiredPermission of JSON.parse(value)) {
102
+ console.log("check permission", requiredPermission)
103
+ const permissionState = await navigator.permissions.query(requiredPermission)
104
+ const state = permissionState ? permissionState.state : "unknown"
105
+ model.value = {
106
+ ...model.value,
107
+ permissions: {
108
+ ...model.value.permissions,
109
+ [requiredPermission.name]: state
110
+ }
111
+ }
112
+ if(permissionState) {
113
+ permissionState.onchange = () => {
114
+ model.value = {
115
+ ...model.value,
116
+ permissions: {
117
+ ...model.value.permissions,
118
+ [requiredPermission.name]: permissionState.state
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }, { immediate: true })
125
+
126
+ //useInterval(updatePermissionsState, 300)
127
+ const isOk = computed(() => {
128
+ if(!model.value.permissions) return false
129
+ return Object.values(model.value.permissions).every(state => state !== 'denied')
130
+ })
131
+
132
+ watch(isOk, ok => {
133
+ if(ok && autoClose) {
134
+ model.value = {
135
+ ...model.value,
136
+ visible: false
137
+ }
138
+ emit('ok', model.value.permissions)
139
+ }
140
+ })
141
+
142
+ </script>
143
+
144
+ <style scoped>
145
+
146
+ </style>
@@ -0,0 +1,60 @@
1
+ import { ref, isRef, onUnmounted, getCurrentInstance, unref, reactive, computed, watch } from 'vue'
2
+
3
+ export function mediaStreamsTracks(mediaStreamsRef) {
4
+ if(!mediaStreamsRef) throw new Error("mediaStreamsTracks: mediaStreams argument is required")
5
+ const tracks = ref([])
6
+
7
+ function removeLocalTrack(track, stream) {
8
+ const trackIndex = tracks.value.findIndex(t => t.track === track)
9
+ if(trackIndex === -1) return console.error(`removal of non existing track ${track.id}`)
10
+ const trackInfo = tracks.value[trackIndex]
11
+ trackInfo.track.removeEventListener('mute', track.muteHandler)
12
+ trackInfo.track.removeEventListener('unmute', track.unmuteHandler)
13
+ tracks.value.splice(trackIndex, 1)
14
+ }
15
+ function addLocalTrack(track, stream) {
16
+ const trackInfo = reactive({
17
+ track, stream, muted: track.muted, enabled: track.enabled,
18
+ muteHandler: () => trackInfo.muted = track.muted,
19
+ unmuteHandler: () => trackInfo.muted = track.muted
20
+ })
21
+ console.log("MEDIA STREAM ADD TRACK!", trackInfo)
22
+ trackInfo.track.addEventListener('mute', trackInfo.muteHandler)
23
+ trackInfo.track.addEventListener('unmute', trackInfo.unmuteHandler)
24
+ tracks.value.push(trackInfo)
25
+ }
26
+ function mediaStreamAddTrackHandler(event) {
27
+ addLocalTrack(event.track, event.target)
28
+ }
29
+ function mediaStreamRemoveTrackHandler(event) {
30
+ removeLocalTrack(event.track, event.target)
31
+ }
32
+
33
+ watch(() => mediaStreamsRef.value, (newStreams = [], oldStreams = []) => {
34
+ console.log("MEDIA STREAMS CHANGE",
35
+ newStreams.map(stream => ({
36
+ id: stream.id,
37
+ tracks: stream.getTracks().map(tr => tr.kind).join('/')
38
+ })),
39
+ oldStreams.map(stream => ({
40
+ id: stream.id,
41
+ tracks: stream.getTracks().map(tr => tr.kind).join('/')
42
+ }))
43
+ )
44
+
45
+ for(const oldStream of oldStreams) {
46
+ if(newStreams.indexOf(oldStream) !== -1) continue; // existing stream
47
+ for(const track of oldStream.getTracks()) removeLocalTrack(track, oldStream)
48
+ oldStream.removeEventListener('addtrack', mediaStreamAddTrackHandler)
49
+ oldStream.removeEventListener('removetrack', mediaStreamRemoveTrackHandler)
50
+ }
51
+ for(const newStream of newStreams) {
52
+ if(oldStreams.indexOf(newStream) !== -1) continue; // existing stream
53
+ for(const track of newStream.getTracks()) addLocalTrack(track, newStream)
54
+ newStream.addEventListener('addtrack', mediaStreamAddTrackHandler)
55
+ newStream.addEventListener('removetrack', mediaStreamRemoveTrackHandler)
56
+ }
57
+ }, { immediate: true })
58
+
59
+ return tracks
60
+ }
@@ -39,8 +39,8 @@ async function isUserMediaPermitted(constraints = { audio: true, video: true })
39
39
  ]))
40
40
  console.log("MICROPHONE PERMISSION", microphonePermission && microphonePermission.state)
41
41
  console.log("CAMERA PERMISSION", cameraPermission && cameraPermission.state)
42
- if(microphonePermission && microphonePermission.state == 'denied') return false
43
- if(cameraPermission && cameraPermission.state == 'denied') return false
42
+ if(microphonePermission && microphonePermission.state === 'denied') return false
43
+ if(cameraPermission && cameraPermission.state === 'denied') return false
44
44
  return true
45
45
  }
46
46
 
@@ -1,24 +1,6 @@
1
- import { createApp } from './main'
2
- import { clientApi } from '@live-change/vue3-ssr/clientApi.js'
1
+ import { clientEntry } from '@live-change/frontend-base/client-entry.js'
2
+ import App from './App.vue'
3
+ import { createRouter } from './router'
3
4
 
4
- import {
5
- createSharedElementDirective,
6
- SharedElementRouteGuard
7
- } from 'v-shared-element'
8
5
 
9
-
10
- window.api = clientApi({
11
- use: [ ]
12
- })
13
-
14
- const { app, router } = createApp(api)
15
-
16
- app.use(createSharedElementDirective())
17
- router.beforeEach(SharedElementRouteGuard)
18
- window.process = window.process || null
19
-
20
- // wait until router is ready before mounting to ensure hydration match
21
- router.isReady().then(() => {
22
- const instance = app.mount('#app', true)
23
- app._container._vnode = instance.$.vnode
24
- })
6
+ clientEntry(App, createRouter)
@@ -1,6 +1,7 @@
1
- import { serverEntry } from '@live-change/frontend-base/server-entry.js'
1
+ import { serverEntry, sitemapEntry } from '@live-change/frontend-base/server-entry.js'
2
2
  import App from './App.vue'
3
- import { createRouter } from './router'
3
+ import { createRouter, sitemap as routerSitemap } from './router'
4
4
 
5
- const render = serverEntry(App, createRouter, {})
6
- export { render }
5
+ const render = serverEntry(App, createRouter)
6
+ const sitemap = sitemapEntry(App, createRouter, routerSitemap)
7
+ export { render, sitemap }
@@ -4,22 +4,17 @@ import {
4
4
  createWebHistory
5
5
  } from 'vue-router'
6
6
 
7
+ import { dbAdminRoutes } from "@live-change/db-admin"
7
8
 
8
- export function routes(config = {}) {
9
+ export function peerConnectionRoutes(config = {}) {
9
10
  const { prefix = '/', route = (r) => r } = config
10
11
  return [
12
+
11
13
  route({
12
- name: 'debugger', path: prefix + '/debugger/:channelType/:channel', meta: { },
13
- component: () => import("./components/Debugger.vue")
14
- }),
15
- route({
16
- name: 'testDebugger', path: prefix + '', meta: { },
14
+ name: 'peer-connection:debugger', path: prefix + '/debugger/:channelType/:channel', meta: { },
17
15
  component: () => import("./components/Debugger.vue"),
18
- props: {
19
- channelType: 'example_Example',
20
- channel: 'one'
21
- }
22
- })
16
+ props: true
17
+ }),
23
18
 
24
19
  ]
25
20
  }
@@ -37,7 +32,18 @@ export function createRouter(app, config) {
37
32
  // use appropriate history implementation for server/client
38
33
  // import.meta.env.SSR is injected by Vite.
39
34
  history: import.meta.env.SSR ? createMemoryHistory() : createWebHistory(),
40
- routes: routes(config)
35
+ routes: [
36
+ ...dbAdminRoutes({ prefix: '/_db', route: r => ({ ...r, meta: { ...r.meta, raw: true }}) }),
37
+ ...peerConnectionRoutes(config),
38
+ {
39
+ name: 'peer-connection:test-debugger', path: '/', meta: { },
40
+ component: () => import("./components/Debugger.vue"),
41
+ props: {
42
+ channelType: 'example_Example',
43
+ channel: 'one'
44
+ }
45
+ }
46
+ ]
41
47
  })
42
48
  router.beforeEach(async (to, from) => {
43
49
  if(to?.matched.find(m => m?.meta.signedIn)) {
@@ -1,117 +1,18 @@
1
- const path = require('path')
2
- const vuePlugin = require('@vitejs/plugin-vue')
3
1
  import { defineConfig } from 'vite'
4
- import findFreePorts from "find-free-ports"
5
- import { visualizer } from 'rollup-plugin-visualizer'
6
- import viteImages from 'vite-plugin-vue-images'
7
- import viteCompression from 'vite-plugin-compression'
8
2
 
9
- const ssrTransformCustomDir = () => {
10
- return {
11
- props: [],
12
- needRuntime: true
13
- }
14
- }
3
+ import baseViteConfig from '@live-change/frontend-base/vite-config.js'
15
4
 
16
5
  export default defineConfig(async ({ command, mode }) => {
6
+ const baseConfig = (await baseViteConfig({ command, mode }))
17
7
  return {
18
- define: {
19
- ENV_BASE_HREF: JSON.stringify(process.env.BASE_HREF || 'http://localhost:8001')
20
- },
21
- server: {
22
- hmr: {
23
- port: (await findFreePorts())[0]
24
- }
25
- },
26
- plugins: [
27
- vuePlugin({
28
- template: {
29
- compilerOptions: {
30
- // whitespace: "preserve",
31
- directiveTransforms: {
32
- 'ripple': ssrTransformCustomDir,
33
- 'styleclass': ssrTransformCustomDir,
34
- 'badge': ssrTransformCustomDir,
35
- 'shared-element': ssrTransformCustomDir
36
- }
37
- }
38
- },
39
- }),
40
- viteImages({ extensions: ['jpg', 'jpeg', 'png', 'svg', 'webp'] }),
41
- viteCompression({ algorithm: 'brotliCompress', ext: '.br' }),
42
- viteCompression({ algorithm: 'gzip', ext: '.gz' }),
43
- viteCompression({ algorithm: 'deflate', ext: '.zz' }),
44
- visualizer({
45
- filename: '../stats.html'
46
- }),
47
- ],
48
- build: {
49
- minify: false,
50
- commonjsOptions: {
51
- transformMixedEsModules: true,
52
- include: [
53
- /node_modules/,
54
- /live-change-stack\/framework\//,
55
- /live-change-stack\/uid\//,
56
- /live-change-stack\/dao\//,
57
- /live-change-stack\/dao-sockjs\//,
58
- /live-change-stack\/dao-websocket\//,
59
- ]
60
- }
61
- },
62
- ssr: {
63
- external: [
64
- '@live-change/dao',
65
- '@live-change/vue-api',
66
- '@live-change/vue-api-session',
67
- '@live-change/uid',
68
- '@live-change/framework',
69
- '@live-change/framework/lib/utils/validators.js',
70
- 'debug',
71
- 'vite'
72
- ],
73
- noExternal: [
74
- '@live-change/vue3-components',
75
- '@live-change/dao-vue3',
76
- '@live-change/vue3-ssr',
77
- 'vue3-scroll-border'
78
- ]
79
- },
80
- optimizeDeps: {
81
- include: [
82
- '@live-change/vue-api',
83
- '@live-change/vue-api-session',
84
- '@live-change/dao',
85
- '@live-change/dao-sockjs',
86
- '@live-change/dao-websocket',
87
- '@live-change/uid',
88
- '@live-change/framework',
89
- '@live-change/framework/lib/utils/validators.js',
90
- 'debug'
91
- ]
92
- },
8
+ ...baseConfig,
93
9
 
94
10
  resolve: {
95
11
  alias: [
96
- { find: 'debug', replacement: 'debug/src/browser.js' },
97
- { find: 'universal-websocket-client', replacement: 'universal-websocket-client/browser.js' },
98
- { find: 'sockjs-client', replacement: 'sockjs-client/dist/sockjs.min.js' },
99
- { find: '@', replacement: path.resolve(__dirname, './src') },
100
- { find: '#user', replacement: path.resolve(__dirname, '.') }
101
- ],
102
- },
103
- resolvers: [{
104
- fileToRequest(filePath) {
105
- console.log('@@@', filePath);
106
- if (filePath.startsWith(srcPath)) {
107
- return `/@/${path.relative(srcPath, filePath)}`
108
- }
109
- },
110
- requestToFile(publicPath) {
111
- if (publicPath.startsWith('/@/')) {
112
- return path.join(srcPath, publicPath.replace(/^\/@\//, ''))
113
- }
114
- },
115
- }],
12
+ ...baseConfig.resolve.alias,
13
+ /* { find: 'vue', replacement: 'vue/dist/vue.esm-bundler.js' },
14
+ { find: 'vue/server-renderer', replacement: 'vue/server-renderer' },*/
15
+ ]
16
+ }
116
17
  }
117
18
  })
package/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import Debugger from './front/src/components/Debugger.vue'
2
+ import DeviceSelect from './front/src/components/DeviceSelect.vue'
3
+ import PermissionsDialog from './front/src/components/PermissionsDialog.vue'
4
+
5
+ export { Debugger, DeviceSelect, PermissionsDialog }
6
+
7
+ import { createPeer } from './front/src/components/Peer.js'
8
+ import { createPeerConnection } from './front/src/components/PeerConnection.js'
9
+ import { getUserMedia, getDisplayMedia, isUserMediaPermitted } from './front/src/components/userMedia.js'
10
+
11
+ export { createPeer, createPeerConnection, getUserMedia, getDisplayMedia, isUserMediaPermitted }
12
+
13
+ import { peerConnectionRoutes } from './front/src/router.js'
14
+ export { peerConnectionRoutes }
@@ -0,0 +1,41 @@
1
+ {
2
+ "dependencies": {
3
+ "@live-change/cli": "0.8.34",
4
+ "@live-change/dao": "0.8.34",
5
+ "@live-change/dao-vue3": "0.8.34",
6
+ "@live-change/dao-websocket": "0.8.34",
7
+ "@live-change/framework": "0.8.34",
8
+ "@live-change/password-authentication-service": "0.8.34",
9
+ "@live-change/secret-code-service": "0.8.34",
10
+ "@live-change/secret-link-service": "0.8.34",
11
+ "@live-change/session-service": "0.8.34",
12
+ "@live-change/user-frontend": "0.8.34",
13
+ "@live-change/user-service": "0.8.34",
14
+ "@live-change/vue3-components": "0.8.34",
15
+ "@live-change/vue3-ssr": "0.8.34",
16
+ "@vueuse/core": "^10.11.0",
17
+ "codeceptjs-assert": "^0.0.5",
18
+ "compression": "^1.7.4",
19
+ "cross-env": "^7.0.3",
20
+ "get-port-sync": "1.0.1",
21
+ "primeflex": "^3.3.1",
22
+ "primeicons": "^7.0.0",
23
+ "primevue": "^3.52.0",
24
+ "rollup-plugin-node-builtins": "^2.1.2",
25
+ "rollup-plugin-visualizer": "5.12.0",
26
+ "serialize-javascript": "^6.0.2",
27
+ "serve-static": "^1.15.0",
28
+ "v-shared-element": "3.1.1",
29
+ "vue-router": "^4.3.3",
30
+ "vue3-scroll-border": "0.1.6"
31
+ },
32
+ "devDependencies": {
33
+ "@live-change/codeceptjs-helper": "0.8.34",
34
+ "codeceptjs": "^3.5.12",
35
+ "generate-password": "1.7.1",
36
+ "playwright": "^1.41.2",
37
+ "random-profile-generator": "^2.3.0",
38
+ "txtgen": "^3.0.6",
39
+ "webdriverio": "^8.31.1"
40
+ }
41
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@live-change/peer-connection-frontend",
3
- "version": "0.8.34",
3
+ "version": "0.8.36",
4
4
  "scripts": {
5
- "memDev": "node server/start.js memDev --enableSessions --initScript ./init.js",
6
- "localDevInit": "rm tmp.db; lcli localDev --enableSessions --initScript ./init.js",
7
- "localDev": "node server/start.js localDev --enableSessions --dbAccess",
5
+ "memDev": "dotenvx run -- node server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
6
+ "localDevInit": "rm tmp.db; dotenvx run -- node server/start.js localDev --enableSessions --initScript ./init.js",
7
+ "localDev": "dotenvx run -- node server/start.js localDev --enableSessions --dbAccess",
8
8
  "dev": "node server/start.js dev --enableSessions",
9
9
  "ssrDev": "node server/start.js ssrDev --enableSessions",
10
10
  "serveAllMem": "cross-env NODE_ENV=production lcli ssrServer --withApi --withServices --updateServices --enableSessions --withDb --dbBackend mem --createDb",
@@ -17,23 +17,24 @@
17
17
  "build:client": "cd front; vite build --ssrManifest --outDir dist/client",
18
18
  "build:server": "cd front; vite build --ssr src/entry-server.js --outDir dist/server",
19
19
  "generate": "vite build --ssrManifest --outDir dist/static && yarn build:server && node prerender",
20
- "debug": "node --inspect-brk server"
20
+ "debug": "node --inspect-brk server",
21
+ "describe": "node server/start.js describe"
21
22
  },
22
23
  "type": "module",
23
24
  "dependencies": {
24
- "@live-change/cli": "^0.8.34",
25
- "@live-change/dao": "^0.8.34",
26
- "@live-change/dao-vue3": "^0.8.34",
27
- "@live-change/dao-websocket": "^0.8.34",
28
- "@live-change/framework": "^0.8.34",
29
- "@live-change/password-authentication-service": "^0.8.34",
30
- "@live-change/secret-code-service": "^0.8.34",
31
- "@live-change/secret-link-service": "^0.8.34",
32
- "@live-change/session-service": "^0.8.34",
33
- "@live-change/user-frontend": "^0.8.34",
34
- "@live-change/user-service": "^0.8.34",
35
- "@live-change/vue3-components": "^0.8.34",
36
- "@live-change/vue3-ssr": "^0.8.34",
25
+ "@live-change/cli": "^0.8.36",
26
+ "@live-change/dao": "^0.8.36",
27
+ "@live-change/dao-vue3": "^0.8.36",
28
+ "@live-change/dao-websocket": "^0.8.36",
29
+ "@live-change/framework": "^0.8.36",
30
+ "@live-change/password-authentication-service": "^0.8.36",
31
+ "@live-change/secret-code-service": "^0.8.36",
32
+ "@live-change/secret-link-service": "^0.8.36",
33
+ "@live-change/session-service": "^0.8.36",
34
+ "@live-change/user-frontend": "^0.8.36",
35
+ "@live-change/user-service": "^0.8.36",
36
+ "@live-change/vue3-components": "^0.8.36",
37
+ "@live-change/vue3-ssr": "^0.8.36",
37
38
  "@vueuse/core": "^10.11.0",
38
39
  "codeceptjs-assert": "^0.0.5",
39
40
  "compression": "^1.7.4",
@@ -51,7 +52,7 @@
51
52
  "vue3-scroll-border": "0.1.6"
52
53
  },
53
54
  "devDependencies": {
54
- "@live-change/codeceptjs-helper": "^0.8.34",
55
+ "@live-change/codeceptjs-helper": "^0.8.36",
55
56
  "codeceptjs": "^3.5.12",
56
57
  "generate-password": "1.7.1",
57
58
  "playwright": "^1.41.2",
@@ -62,5 +63,5 @@
62
63
  "author": "Michał Łaszczewski <michal@laszczewski.pl>",
63
64
  "license": "BSD-3-Clause",
64
65
  "description": "",
65
- "gitHead": "40e61928bf43b35352c76fc135f36a2d8bd76c4a"
66
+ "gitHead": "24694d1687f0ab2d6eb7edd95e5274428cfd44eb"
66
67
  }
@@ -0,0 +1,114 @@
1
+ import App from "@live-change/framework"
2
+ const app = App.app()
3
+
4
+ const contactTypes = ['email', 'phone']
5
+ const remoteAccountTypes = ['google']
6
+
7
+ import securityConfig from './security.config.js'
8
+
9
+ app.config = {
10
+ services: [
11
+ {
12
+ name: 'timer',
13
+ path: '@live-change/timer-service'
14
+ },
15
+ {
16
+ name: 'session',
17
+ path: '@live-change/session-service',
18
+ createSessionOnUpdate: true
19
+ },
20
+ {
21
+ name: 'user',
22
+ path: '@live-change/user-service',
23
+ remoteAccountTypes
24
+ },
25
+ {
26
+ name: 'email',
27
+ path: '@live-change/email-service'
28
+ },
29
+ {
30
+ name: 'phone',
31
+ path: '@live-change/phone-service'
32
+ },
33
+ {
34
+ name: 'secretLink',
35
+ path: '@live-change/secret-link-service'
36
+ },
37
+ {
38
+ name: 'secretCode',
39
+ path: '@live-change/secret-code-service'
40
+ },
41
+ {
42
+ name: 'messageAuthentication',
43
+ path: '@live-change/message-authentication-service',
44
+ contactTypes,
45
+ signUp: true,
46
+ signIn: true,
47
+ connect: true
48
+ },
49
+ {
50
+ name: 'passwordAuthentication',
51
+ path: '@live-change/password-authentication-service',
52
+ contactTypes,
53
+ signInWithoutPassword: true
54
+ },
55
+ {
56
+ name: 'googleAuthentication',
57
+ path: '@live-change/google-authentication-service',
58
+ },
59
+ {
60
+ name: 'security',
61
+ path: '@live-change/security-service',
62
+ ...securityConfig
63
+ },
64
+ {
65
+ name: 'userIdentification',
66
+ path: '@live-change/user-identification-service'
67
+ },
68
+ {
69
+ name: 'identicon',
70
+ path: '@live-change/identicon-service'
71
+ },
72
+ {
73
+ name: 'localeSettings'
74
+ },
75
+ {
76
+ name: 'notification',
77
+ path: '@live-change/notification-service',
78
+ contactTypes,
79
+ notificationTypes: ['example_TestNotification']
80
+ },
81
+ {
82
+ name: 'upload',
83
+ path: '@live-change/upload-service'
84
+ },
85
+ {
86
+ name: 'image',
87
+ path: '@live-change/image-service'
88
+ },
89
+ {
90
+ name: 'session',
91
+ path: '@live-change/session-service',
92
+ createSessionOnUpdate: true
93
+ },
94
+ {
95
+ name: 'online',
96
+ path: '@live-change/online-service',
97
+ createSessionOnUpdate: true
98
+ },
99
+ {
100
+ name: 'accessControl',
101
+ path: '@live-change/access-control-service',
102
+ createSessionOnUpdate: true,
103
+ contactTypes,
104
+ },
105
+ {
106
+ name: 'peerConnection',
107
+ path: '@live-change/peer-connection-service',
108
+ turn: {
109
+ urls: 'turn:turn.chaosu.pl:4433'
110
+ }
111
+ }
112
+ ]
113
+ }
114
+ export default app.config