@live-change/access-control-frontend 0.1.5 → 0.2.2
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/LICENSE.md +11 -0
- package/e2e/codecept.conf.js +4 -3
- package/e2e/inviteExistingUser.test.js +23 -0
- package/e2e/steps_file.js +23 -6
- package/front/src/App.vue +8 -1
- package/front/src/ConfigurationTestPage.vue +34 -0
- package/front/src/NavBar.vue +26 -1
- package/front/src/TestPage.vue +76 -0
- package/front/src/components/LimitedAccess.vue +19 -14
- package/front/src/configuration/AccessControl.vue +1 -6
- package/front/src/router.js +10 -1
- package/index.js +13 -0
- package/package.json +20 -19
- package/server/init.js +12 -24
package/LICENSE.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright 2019-2022 Michał Łaszczewski
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
9
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/e2e/codecept.conf.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { devices } = require('playwright')
|
|
2
2
|
|
|
3
|
-
const testServerPort = process.env.TEST_URL ? 0 : require('get-port-sync')()
|
|
3
|
+
const testServerPort = process.env.TEST_URL ? 0 : require('get-port-sync')()
|
|
4
4
|
const testServerUrl = process.env.TEST_URL || `http://localhost:${testServerPort}`
|
|
5
5
|
|
|
6
6
|
const device = devices['Pixel 2']
|
|
@@ -13,8 +13,9 @@ exports.config = {
|
|
|
13
13
|
require: '@live-change/codeceptjs-helper',
|
|
14
14
|
startServer: !process.env.TEST_URL,
|
|
15
15
|
enableSessions: true,
|
|
16
|
-
initScript: "./init.js",
|
|
16
|
+
//initScript: "./init.js",
|
|
17
17
|
port: testServerPort,
|
|
18
|
+
dbAccess: true,
|
|
18
19
|
dev: true
|
|
19
20
|
},
|
|
20
21
|
VideoHelper: {
|
|
@@ -57,4 +58,4 @@ exports.config = {
|
|
|
57
58
|
enabled: true
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const happyPath = false
|
|
2
|
+
|
|
3
|
+
Feature('access control invite')
|
|
4
|
+
|
|
5
|
+
Scenario('invite user that already exists', async ({ I }) => {
|
|
6
|
+
|
|
7
|
+
const adminUser = await I.haveUser()
|
|
8
|
+
const anotherUser = await I.haveUser()
|
|
9
|
+
await I.haveUserWithAccess(adminUser, 'example_Example', 'one', ['administrator'])
|
|
10
|
+
|
|
11
|
+
await I.amOnPage('/')
|
|
12
|
+
await I.amLoggedIn(adminUser)
|
|
13
|
+
|
|
14
|
+
I.see('Access Granted!')
|
|
15
|
+
I.click('Share')
|
|
16
|
+
I.see('Access Control')
|
|
17
|
+
I.click('Invite with email')
|
|
18
|
+
I.see('Invite user with email')
|
|
19
|
+
I.see('Email address')
|
|
20
|
+
I.fillField('input[id="email"]', anotherUser.email)
|
|
21
|
+
I.click('Invite')
|
|
22
|
+
I.click('Invite')
|
|
23
|
+
})
|
package/e2e/steps_file.js
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
const App = require('@live-change/framework')
|
|
2
|
+
const app = App.app()
|
|
2
3
|
|
|
3
|
-
const userSteps = require('../../user-frontend/e2e/steps_file.js')
|
|
4
|
+
const userSteps = require('../../user-frontend/e2e/steps_file.js').steps
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
const steps = {
|
|
7
|
+
|
|
8
|
+
...userSteps,
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
async haveUserWithAccess(user, objectType, object, roles = ['administrator']) {
|
|
11
|
+
const I = this
|
|
12
|
+
const Access = await I.haveModel('accessControl', 'Access')
|
|
13
|
+
await Access.create({
|
|
14
|
+
id: App.encodeIdentifier(['user_User', user.id, 'example_Example', 'one']),
|
|
15
|
+
sessionOrUserType: 'user_User', sessionOrUser: user.id,
|
|
16
|
+
objectType: 'example_Example', object: 'one',
|
|
17
|
+
roles
|
|
18
|
+
})
|
|
19
|
+
}
|
|
9
20
|
|
|
10
|
-
})
|
|
11
21
|
}
|
|
22
|
+
|
|
23
|
+
module.exports = function() {
|
|
24
|
+
return actor(steps)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports.steps = steps
|
|
28
|
+
|
package/front/src/App.vue
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import ViewRoot from "@live-change/frontend-base/ViewRoot.vue"
|
|
16
16
|
import "./notifications"
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
import { useMeta } from 'vue-meta'
|
|
19
20
|
const { meta } = useMeta({
|
|
20
21
|
title: 'Title',
|
|
@@ -25,10 +26,16 @@
|
|
|
25
26
|
})
|
|
26
27
|
|
|
27
28
|
import { watch } from 'vue'
|
|
28
|
-
import { client as useClient } from '@live-change/vue3-ssr'
|
|
29
|
+
import { client as useClient, useApi } from '@live-change/vue3-ssr'
|
|
29
30
|
const client = useClient()
|
|
30
31
|
watch(client, (newClient, oldClient) => {
|
|
31
32
|
console.log("WATCH CLIENT", oldClient, '=>', newClient)
|
|
32
33
|
})
|
|
33
34
|
|
|
35
|
+
const api = useApi()
|
|
36
|
+
import emailValidator from "@live-change/email-service/clientEmailValidator.js"
|
|
37
|
+
import passwordValidator from "@live-change/password-authentication-service/clientPasswordValidator.js"
|
|
38
|
+
api.validators.email = emailValidator
|
|
39
|
+
api.validators.password = passwordValidator
|
|
40
|
+
|
|
34
41
|
</script>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="w-full sm:w-9 md:w-8 lg:w-6 surface-card p-4 shadow-2 border-round">
|
|
3
|
+
<div class="text-center mb-5">
|
|
4
|
+
<div class="text-900 text-3xl font-medium mb-3">
|
|
5
|
+
Access Control
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<AccessControl :objectType="objectType" :object="object" />
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
|
|
15
|
+
import AccessControl from "./configuration/AccessControl.vue"
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
object, objectType
|
|
19
|
+
} = defineProps({
|
|
20
|
+
object: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: 'example_Example'
|
|
23
|
+
},
|
|
24
|
+
objectType: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: 'one'
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style scoped>
|
|
33
|
+
|
|
34
|
+
</style>
|
package/front/src/NavBar.vue
CHANGED
|
@@ -8,6 +8,27 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
<div class="flex flex-grow-1"></div>
|
|
10
10
|
<NotificationsIcon />
|
|
11
|
+
<UserIcon />
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<div class="static w-auto w-full surface-overlay left-0 top-100 z-1 shadow-none hidden">
|
|
15
|
+
<ul class="list-none p-0 m-0 flex align-items-center select-none flex-row border-top-none">
|
|
16
|
+
<li>
|
|
17
|
+
<a v-ripple class="flex p-3 px-3 align-items-center text-600 hover:text-900 hover:surface-100
|
|
18
|
+
font-medium border-round cursor-pointer transition-colors transition-duration-150 p-ripple">
|
|
19
|
+
<i class="pi pi-inbox text-base text-2xl mr-0"></i>
|
|
20
|
+
</a>
|
|
21
|
+
</li>
|
|
22
|
+
<li>
|
|
23
|
+
<a v-ripple class="flex p-3 px-3 align-items-center text-600 hover:text-900 hover:surface-100 font-medium
|
|
24
|
+
border-round cursor-pointer transition-colors transition-duration-150 p-ripple">
|
|
25
|
+
<i class="pi pi-bell text-base lg:text-2xl mr-2 lg:mr-0" v-badge.danger></i>
|
|
26
|
+
</a>
|
|
27
|
+
</li>
|
|
28
|
+
</ul>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
11
32
|
<a v-ripple class="cursor-pointer block lg:hidden text-700 p-ripple ml-2 hover:surface-100 p-2"
|
|
12
33
|
v-styleclass="{ selector: '@next', enterClass: 'hidden', leaveToClass: 'hidden', hideOnOutsideClick: true }">
|
|
13
34
|
<i class="pi pi-bars text-4xl"></i>
|
|
@@ -96,8 +117,12 @@
|
|
|
96
117
|
|
|
97
118
|
import { NotificationsIcon } from "@live-change/user-frontend"
|
|
98
119
|
|
|
120
|
+
import { UserIcon } from "@live-change/user-frontend"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
99
124
|
</script>
|
|
100
125
|
|
|
101
126
|
<style scoped>
|
|
102
127
|
|
|
103
|
-
</style>
|
|
128
|
+
</style>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Dialog v-model:visible="shareDialog"
|
|
3
|
+
:modal="true">
|
|
4
|
+
<template #header>
|
|
5
|
+
<div class="text-900 text-3xl font-medium">
|
|
6
|
+
Access Control
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
<AccessControl :objectType="objectType" :object="object" />
|
|
10
|
+
</Dialog>
|
|
11
|
+
<div class="w-full sm:w-9 md:w-8 lg:w-6 surface-card p-4 shadow-2 border-round">
|
|
12
|
+
<LimitedAccess :objectType="objectType" :object="object" :requiredRoles="requiredRoles"
|
|
13
|
+
v-slot="{ authorized, roles, accesses }">
|
|
14
|
+
<div v-if="authorized" class="text-right">
|
|
15
|
+
<Button label="Share" icon="pi pi-share-alt" class="p-button mb-4" @click="showShareDialog" />
|
|
16
|
+
</div>
|
|
17
|
+
<div v-if="authorized" class="text-900 text-3xl font-medium mb-3">
|
|
18
|
+
Access Granted!
|
|
19
|
+
</div>
|
|
20
|
+
<div>
|
|
21
|
+
<p>
|
|
22
|
+
<strong>Roles:</strong>
|
|
23
|
+
<span v-for="role in roles" class="mx-1">{{ role }}</span>
|
|
24
|
+
</p>
|
|
25
|
+
<div>
|
|
26
|
+
<strong>Accesses:</strong>
|
|
27
|
+
<ol>
|
|
28
|
+
<li v-for="access of accesses">
|
|
29
|
+
<em class="mr-2">{{ access.id.split(':').join(' : ') }}</em>
|
|
30
|
+
<span v-for="role in access.roles" class="mx-1">{{ role }}</span>
|
|
31
|
+
</li>
|
|
32
|
+
</ol>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</LimitedAccess>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup>
|
|
40
|
+
|
|
41
|
+
import Button from "primevue/button"
|
|
42
|
+
import Dialog from "primevue/dialog"
|
|
43
|
+
|
|
44
|
+
import { ref } from 'vue'
|
|
45
|
+
|
|
46
|
+
import LimitedAccess from "./components/LimitedAccess.vue"
|
|
47
|
+
import AccessControl from "./configuration/AccessControl.vue"
|
|
48
|
+
|
|
49
|
+
const {
|
|
50
|
+
object, objectType, requiredRoles
|
|
51
|
+
} = defineProps({
|
|
52
|
+
object: {
|
|
53
|
+
type: String,
|
|
54
|
+
default: 'example_Example'
|
|
55
|
+
},
|
|
56
|
+
objectType: {
|
|
57
|
+
type: String,
|
|
58
|
+
default: 'one'
|
|
59
|
+
},
|
|
60
|
+
requiredRoles: {
|
|
61
|
+
type: Array,
|
|
62
|
+
default: () => ['reader', 'writer', 'moderator', 'administrator']
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const shareDialog = ref(false)
|
|
67
|
+
|
|
68
|
+
function showShareDialog() {
|
|
69
|
+
shareDialog.value = true
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<style scoped>
|
|
75
|
+
|
|
76
|
+
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<slot v-if="!authorized" name="blocked" :authorized="authorized" :roles="accessRoles" :accesses="accesses">
|
|
2
|
+
<slot v-if="!hidden && !authorized" name="blocked" :authorized="authorized" :roles="accessRoles" :accesses="accesses">
|
|
3
3
|
<div class="flex align-items-start p-4 bg-pink-100 border-round border-1 border-pink-300 mb-4">
|
|
4
4
|
<i class="pi pi-times-circle text-pink-900 text-2xl mr-3" />
|
|
5
5
|
<div class="mr-3">
|
|
@@ -10,22 +10,18 @@
|
|
|
10
10
|
</div>
|
|
11
11
|
</div>
|
|
12
12
|
</slot>
|
|
13
|
-
<BlockUI :blocked="
|
|
13
|
+
<BlockUI v-if="!hidden" :blocked="!authorized">
|
|
14
14
|
<slot :authorized="authorized" :roles="accessRoles" :accesses="accesses"></slot>
|
|
15
15
|
</BlockUI>
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
<pre>{{ JSON.stringify(bansState, null, ' ') }}</pre>
|
|
19
|
-
<h4>Counters</h4>
|
|
20
|
-
<pre>{{ JSON.stringify(countersState, null, ' ') }}</pre>
|
|
21
|
-
</div>
|
|
16
|
+
<slot v-if="authorized && hidden" :roles="accessRoles" :accesses="accesses"></slot>
|
|
17
|
+
<slot v-if="!authorized && hidden" name="alternative" :roles="accessRoles" :accesses="accesses"></slot>
|
|
22
18
|
</template>
|
|
23
19
|
|
|
24
20
|
<script setup>
|
|
25
21
|
|
|
26
22
|
import BlockUI from 'primevue/blockui'
|
|
27
23
|
|
|
28
|
-
const
|
|
24
|
+
const props = defineProps({
|
|
29
25
|
objectType: {
|
|
30
26
|
type: String,
|
|
31
27
|
default: null
|
|
@@ -41,9 +37,15 @@
|
|
|
41
37
|
requiredRoles: {
|
|
42
38
|
type: Array,
|
|
43
39
|
default: () => []
|
|
44
|
-
}
|
|
40
|
+
},
|
|
41
|
+
hidden: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
default: false
|
|
44
|
+
},
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
+
const { objectType, object, objects, requiredRoles } = props
|
|
48
|
+
|
|
47
49
|
const allObjects = ((objectType && object) ? [{ objectType, object }] : []).concat(objects || [])
|
|
48
50
|
|
|
49
51
|
import { provide, computed } from 'vue'
|
|
@@ -62,14 +64,17 @@
|
|
|
62
64
|
for(const access of accessesList) {
|
|
63
65
|
roles = roles.filter(role => access.roles.includes(role))
|
|
64
66
|
}
|
|
67
|
+
return roles
|
|
65
68
|
})
|
|
66
69
|
|
|
67
70
|
const authorized = computed(() => {
|
|
68
|
-
const
|
|
69
|
-
for(const
|
|
70
|
-
if(
|
|
71
|
+
const clientRoles = accessRoles.value
|
|
72
|
+
for(const requiredRolesOption of requiredRoles) {
|
|
73
|
+
if((Array.isArray(requiredRolesOption) ? requiredRolesOption : [requiredRolesOption])
|
|
74
|
+
.every(role => clientRoles.includes(role))
|
|
75
|
+
) return true
|
|
71
76
|
}
|
|
72
|
-
return
|
|
77
|
+
return false
|
|
73
78
|
})
|
|
74
79
|
|
|
75
80
|
</script>
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
<div class="text-center mb-5">
|
|
4
|
-
<div class="text-900 text-3xl font-medium mb-3">
|
|
5
|
-
Access Control
|
|
6
|
-
</div>
|
|
7
|
-
</div>
|
|
2
|
+
<div>
|
|
8
3
|
|
|
9
4
|
<div class="text-center">
|
|
10
5
|
<Button label="Invite with email" icon="pi pi-envelope" class="p-button mb-4" @click="inviteDialog = true" />
|
package/front/src/router.js
CHANGED
|
@@ -20,7 +20,7 @@ export function routes(config = {}) {
|
|
|
20
20
|
...inviteRoutes(config),
|
|
21
21
|
|
|
22
22
|
route({
|
|
23
|
-
name: 'accessControl:
|
|
23
|
+
name: 'accessControl:configurationPage', path: prefix + 'configuration', meta: { },
|
|
24
24
|
component: () => import("./configuration/AccessControl.vue"),
|
|
25
25
|
props: {
|
|
26
26
|
objectType: 'example_Example',
|
|
@@ -28,6 +28,15 @@ export function routes(config = {}) {
|
|
|
28
28
|
}
|
|
29
29
|
}),
|
|
30
30
|
|
|
31
|
+
route({
|
|
32
|
+
name: 'accessControl:testPage', path: prefix + '', meta: { },
|
|
33
|
+
component: () => import("./TestPage.vue"),
|
|
34
|
+
props: {
|
|
35
|
+
objectType: 'example_Example',
|
|
36
|
+
object: 'one'
|
|
37
|
+
}
|
|
38
|
+
}),
|
|
39
|
+
|
|
31
40
|
...dbAdminRoutes({ prefix: '/_db', route: r => ({ ...r, meta: { ...r.meta, raw: true }}) })
|
|
32
41
|
]
|
|
33
42
|
}
|
package/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import LimitedAccess from "./front/src/components/LimitedAccess.vue"
|
|
2
|
+
export { LimitedAccess }
|
|
3
|
+
|
|
4
|
+
import AccessControl from "./front/src/configuration/AccessControl.vue"
|
|
5
|
+
import AccessInvitations from "./front/src/configuration/AccessInvitations.vue"
|
|
6
|
+
import AccessList from "./front/src/configuration/AccessList.vue"
|
|
7
|
+
import AccessRequests from "./front/src/configuration/AccessRequests.vue"
|
|
8
|
+
import PublicAccess from "./front/src/configuration/PublicAccess.vue"
|
|
9
|
+
export { AccessControl, AccessInvitations, AccessList, AccessRequests, PublicAccess }
|
|
10
|
+
|
|
11
|
+
import "./front/src/notifications/index.js"
|
|
12
|
+
|
|
13
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/access-control-frontend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "lcli memDev --enableSessions --initScript ./init.js --dbAccess",
|
|
6
6
|
"localDevInit": "rm tmp.db; lcli localDev --enableSessions --initScript ./init.js",
|
|
@@ -20,21 +20,22 @@
|
|
|
20
20
|
"debug": "node --inspect-brk server"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@live-change/access-control-service": "0.2.
|
|
24
|
-
"@live-change/cli": "0.6.
|
|
25
|
-
"@live-change/dao": "0.5.
|
|
26
|
-
"@live-change/dao-vue3": "0.5.
|
|
27
|
-
"@live-change/dao-websocket": "0.5.
|
|
28
|
-
"@live-change/db-admin": "0.5.
|
|
29
|
-
"@live-change/framework": "0.6.
|
|
30
|
-
"@live-change/
|
|
31
|
-
"@live-change/
|
|
32
|
-
"@live-change/secret-
|
|
33
|
-
"@live-change/
|
|
34
|
-
"@live-change/
|
|
35
|
-
"@live-change/user-
|
|
36
|
-
"@live-change/
|
|
37
|
-
"@live-change/vue3-
|
|
23
|
+
"@live-change/access-control-service": "0.2.51",
|
|
24
|
+
"@live-change/cli": "0.6.14",
|
|
25
|
+
"@live-change/dao": "0.5.6",
|
|
26
|
+
"@live-change/dao-vue3": "0.5.6",
|
|
27
|
+
"@live-change/dao-websocket": "0.5.6",
|
|
28
|
+
"@live-change/db-admin": "0.5.17",
|
|
29
|
+
"@live-change/framework": "0.6.14",
|
|
30
|
+
"@live-change/frontend-base": "^0.2.2",
|
|
31
|
+
"@live-change/password-authentication-service": "0.2.51",
|
|
32
|
+
"@live-change/secret-code-service": "0.2.51",
|
|
33
|
+
"@live-change/secret-link-service": "0.2.51",
|
|
34
|
+
"@live-change/session-service": "0.2.51",
|
|
35
|
+
"@live-change/user-frontend": "^0.2.2",
|
|
36
|
+
"@live-change/user-service": "0.2.51",
|
|
37
|
+
"@live-change/vue3-components": "0.2.15",
|
|
38
|
+
"@live-change/vue3-ssr": "0.2.15",
|
|
38
39
|
"@vueuse/core": "^9.1.0",
|
|
39
40
|
"codeceptjs-assert": "^0.0.5",
|
|
40
41
|
"compression": "^1.7.4",
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
"vue3-scroll-border": "0.1.2"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
|
-
"@live-change/codeceptjs-helper": "0.6.
|
|
56
|
+
"@live-change/codeceptjs-helper": "0.6.14",
|
|
56
57
|
"@wdio/selenium-standalone-service": "^7.20.8",
|
|
57
58
|
"codeceptjs": "^3.3.4",
|
|
58
59
|
"generate-password": "1.7.0",
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
"webdriverio": "^7.20.9"
|
|
63
64
|
},
|
|
64
65
|
"author": "",
|
|
65
|
-
"license": "
|
|
66
|
+
"license": "BSD-3-Clause",
|
|
66
67
|
"description": "",
|
|
67
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "f7abc1d907b85c321e629086c162e4b622eee91b"
|
|
68
69
|
}
|
package/server/init.js
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
1
|
const App = require('@live-change/framework')
|
|
2
2
|
const app = App.app()
|
|
3
3
|
|
|
4
|
+
const { createUser } = require('@live-change/user-frontend/server/init-functions.js')
|
|
5
|
+
|
|
4
6
|
module.exports = async function(services) {
|
|
5
7
|
|
|
6
8
|
const { PasswordAuthentication } = services.passwordAuthentication.models
|
|
7
9
|
const { PublicAccess, Access, AccessRequest, AccessInvitation } = services.accessControl.models
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
const passwordHash = PasswordAuthentication.definition.properties.passwordHash.preFilter(password)
|
|
11
|
-
await services.user.models.User.create({ id: user, roles: [] })
|
|
12
|
-
await PasswordAuthentication.create({ id: user, user, passwordHash })
|
|
13
|
-
await services.email.models.Email.create({ id: email, email, user })
|
|
14
|
-
await services.userIdentification.models.Identification.create({
|
|
15
|
-
id: App.encodeIdentifier(['user_User', user]), sessionOrUserType: 'user_User', sessionOrUser: user,
|
|
16
|
-
name
|
|
17
|
-
})
|
|
18
|
-
return {
|
|
19
|
-
id: user,
|
|
20
|
-
name,
|
|
21
|
-
email,
|
|
22
|
-
password
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const session = 'Q6OytlOJ54r0tF1BriDB8bEYoGEUIf+i__'
|
|
11
|
+
const session = 'l5W5GIeTfffiFpfUTkvpjNjrVR6buWDX'
|
|
27
12
|
|
|
28
13
|
//console.log("MDL", services.passwordAuthentication.models.PasswordAuthentication)
|
|
29
14
|
|
|
30
|
-
const user1 = await createUser(
|
|
31
|
-
|
|
32
|
-
const
|
|
15
|
+
const user1 = await createUser(services,
|
|
16
|
+
'Test User 1', 'test1@test.com', 'Testy123', 'u1')
|
|
17
|
+
const user2 = await createUser(services,
|
|
18
|
+
'Test User 2 with very long name!', 'test2@test.com', 'Testy123')
|
|
19
|
+
const user3 = await createUser(services,
|
|
20
|
+
'Test User 3', 'test3@test.com', 'Testy123')
|
|
33
21
|
|
|
34
22
|
await services.user.models.AuthenticatedUser.create({ id: session, session, user: user1.id })
|
|
35
23
|
|
|
@@ -37,7 +25,7 @@ module.exports = async function(services) {
|
|
|
37
25
|
"id": app.generateUid(),
|
|
38
26
|
"notificationType": "accessControl_Invitation",
|
|
39
27
|
"objectType": "example_Example",
|
|
40
|
-
"object": "
|
|
28
|
+
"object": "one",
|
|
41
29
|
"fromType": "user_User",
|
|
42
30
|
"from": user1.id,
|
|
43
31
|
"sessionOrUserType": "user_User",
|
|
@@ -46,12 +34,12 @@ module.exports = async function(services) {
|
|
|
46
34
|
"readState": "new"
|
|
47
35
|
})
|
|
48
36
|
|
|
49
|
-
|
|
37
|
+
/* await PublicAccess.create({
|
|
50
38
|
id: App.encodeIdentifier(['example_Example', 'one']),
|
|
51
39
|
objectType: 'example_Example', object: 'one',
|
|
52
40
|
userRoles: ['reader'],
|
|
53
41
|
sessionRoles: ['reader']
|
|
54
|
-
})
|
|
42
|
+
})*/
|
|
55
43
|
|
|
56
44
|
await Access.create({
|
|
57
45
|
id: App.encodeIdentifier(['user_User', user1.id, 'example_Example', 'one']),
|