@live-change/url-frontend 0.2.5 → 0.2.6

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,48 @@
1
+ <template>
2
+ <div class="surface-section px-4 py-8 md:px-6 lg:px-8">
3
+ <div class="text-center code404">
4
+ <span class="bg-white text-pink-500 font-bold text-2xl inline-block px-3">403</span>
5
+ </div>
6
+ <div class="mt-6 mb-5 font-bold text-6xl text-900 text-center">Not authorized</div>
7
+ <p class="text-700 text-3xl mt-0 mb-6 text-center">
8
+ You do not have sufficient privileges to see this page.
9
+ </p>
10
+ <div class="text-center">
11
+ <Button v-if="canGoBack" @click="goBack()"
12
+ class="p-button-text mr-2" label="Go Back" icon="pi pi-arrow-left" />
13
+ <router-link to="/" replace class="no-underline">
14
+ <Button label="Go to Home" icon="pi pi-home" />
15
+ </router-link>
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script setup>
21
+
22
+ import Button from "primevue/button"
23
+
24
+ import { computed, ref, onMounted } from 'vue'
25
+
26
+ const isMounted = ref(false)
27
+ onMounted(() => isMounted.value = true)
28
+
29
+ const canGoBack = computed(() => {
30
+ return isMounted.value && history.length > 1
31
+ })
32
+
33
+ import { useRouter } from 'vue-router'
34
+ const router = useRouter()
35
+ function goBack() {
36
+ router.back()
37
+ }
38
+
39
+ import { useResponse } from "@live-change/frontend-base"
40
+ useResponse({ status: 403 })
41
+
42
+ </script>
43
+
44
+ <style scoped>
45
+ .code404 {
46
+ background: radial-gradient(50% 109137.91% at 50% 50%, rgba(233, 30, 99, 0.1) 0%, rgba(254, 244, 247, 0) 100%);
47
+ }
48
+ </style>
@@ -34,6 +34,8 @@
34
34
  router.back()
35
35
  }
36
36
 
37
+ import { useResponse } from "@live-change/frontend-base"
38
+ useResponse({ status: 404 })
37
39
  </script>
38
40
 
39
41
  <style scoped>
@@ -1,22 +1,15 @@
1
1
  <template>
2
- <slot v-if="url" :url="url" :target="url.target" :class="clazz" :style="style">
2
+ <slot v-if="url && accessible" :url="url" :target="url.target" :class="clazz" :style="style">
3
3
  <div class="w-full surface-card p-4 shadow-2 border-round">
4
4
  <h2>Url resolved:</h2>
5
5
  <pre>{{ JSON.stringify(url, null, " ") }}</pre>
6
6
  </div>
7
7
  </slot>
8
+ <slot v-else-if="url">
9
+ <NotAuthorized></NotAuthorized>
10
+ </slot>
8
11
  <slot v-else name="notFound" :path="urlPath" :class="clazz" :style="style">
9
- <div class="surface-section px-4 py-8 md:px-6 lg:px-8">
10
- <div style="background: radial-gradient(50% 109137.91% at 50% 50%, rgba(233, 30, 99, 0.1) 0%, rgba(254, 244, 247, 0) 100%);" class="text-center">
11
- <span class="bg-white text-pink-500 font-bold text-2xl inline-block px-3">404</span>
12
- </div>
13
- <div class="mt-6 mb-5 font-bold text-6xl text-900 text-center">Page Not Found</div>
14
- <p class="text-700 text-3xl mt-0 mb-6 text-center">Sorry, we couldn't find the page.</p>
15
- <div class="text-center">
16
- <Button class="p-button-text mr-2" label="Go Back" icon="pi pi-arrow-left" />
17
- <Button label="Go to Dashboard" icon="pi pi-home" />
18
- </div>
19
- </div>
12
+ <NotFound />
20
13
  </slot>
21
14
  </template>
22
15
 
@@ -24,6 +17,9 @@
24
17
 
25
18
  import Button from "primevue/button"
26
19
 
20
+ import NotFound from "./NotFound.vue"
21
+ import NotAuthorized from "./NotAuthorized.vue"
22
+
27
23
  import { computed, watch, ref, onMounted } from 'vue'
28
24
  import { toRefs } from "@vueuse/core"
29
25
  import { useHost } from "@live-change/frontend-base"
@@ -40,6 +36,10 @@
40
36
  type: String,
41
37
  default: 'content_Page'
42
38
  },
39
+ requiredRoles: {
40
+ type: Array,
41
+ default: () => ['reader']
42
+ },
43
43
  fetchMore: {
44
44
  type: Array,
45
45
  default: () => []
@@ -47,7 +47,7 @@
47
47
  class: {},
48
48
  style: {}
49
49
  })
50
- const { path: urlPath, targetType, fetchMore, class: clazz, style } = toRefs(props)
50
+ const { path: urlPath, targetType, fetchMore, class: clazz, style, requiredRoles } = toRefs(props)
51
51
 
52
52
  const urlDomain = useHost()
53
53
 
@@ -59,12 +59,13 @@
59
59
  const p = path()
60
60
 
61
61
  const liveUrlPath = (targetType, domain, urlPath, more) => {
62
- let fetchPath = p.url.urlsByTargetAndPath({targetType, domain, path: urlPath})
62
+ let fetchPath = p.url.urlsByTargetAndPath({ targetType, domain, path: urlPath })
63
63
  //.with(url => p.url.targetOwnedCanonical({ targetType, target: url.target }).bind('canonical'))
64
64
  .with(url => url.type.$switch({
65
65
  'canonical': null,
66
- 'redirect': p.url.targetOwnedCanonical({targetType, target: url.target})
66
+ 'redirect': p.url.targetOwnedCanonical({ targetType, target: url.target })
67
67
  }).$bind('canonical'))
68
+ .with(url => p.accessControl.myAccessTo({ objectType: targetType, object: url.target }).bind('access'))
68
69
  for (let fetch of more) {
69
70
  fetchPath = fetchPath.with(url => fetch(url))
70
71
  }
@@ -77,15 +78,28 @@
77
78
  const livePathWithoutDomain = computed(
78
79
  () => liveUrlPath(targetType.value, '', urlPath.value, fetchMore.value)
79
80
  )
80
- const [domainUrls, globalUrls] = await Promise.all([
81
- live(livePathWithDomain),
81
+
82
+ const [/*domainUrls,*/ globalUrls] = await Promise.all([
83
+ // live(livePathWithDomain),
82
84
  live(livePathWithoutDomain)
83
85
  ])
86
+ const domainUrls = ref([])
87
+ console.log("OK!", domainUrls.value, globalUrls.value)
84
88
  const url = computed(() => {
85
89
  if(domainUrls.value.length > 0) return domainUrls.value[0]
86
90
  if(globalUrls.value.length > 0) return globalUrls.value[0]
87
91
  return null
88
92
  })
93
+ const accessible = computed(() => {
94
+ if(!(requiredRoles?.value?.length)) return true
95
+ if(!url.value) return undefined
96
+ const clientRoles = url.value.access?.roles ?? []
97
+ for(const requiredRolesOption of requiredRoles.value) {
98
+ if((Array.isArray(requiredRolesOption) ? requiredRolesOption : [requiredRolesOption])
99
+ .every(role => clientRoles.includes(role))
100
+ ) return true
101
+ }
102
+ })
89
103
 
90
104
  if(typeof window != 'undefined') {
91
105
  watch(() => url && isMounted.value, async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/url-frontend",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
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",
@@ -21,16 +21,16 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@fortawesome/fontawesome-free": "^6.1.1",
24
- "@live-change/cli": "0.7.2",
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/framework": "0.7.2",
29
- "@live-change/password-authentication-service": "0.3.0",
30
- "@live-change/prosemirror-service": "0.3.0",
31
- "@live-change/secret-code-service": "0.3.0",
32
- "@live-change/secret-link-service": "0.3.0",
33
- "@live-change/session-service": "0.3.0",
24
+ "@live-change/cli": "0.7.4",
25
+ "@live-change/dao": "0.5.8",
26
+ "@live-change/dao-vue3": "0.5.8",
27
+ "@live-change/dao-websocket": "0.5.8",
28
+ "@live-change/framework": "0.7.4",
29
+ "@live-change/password-authentication-service": "0.3.2",
30
+ "@live-change/prosemirror-service": "0.3.2",
31
+ "@live-change/secret-code-service": "0.3.2",
32
+ "@live-change/secret-link-service": "0.3.2",
33
+ "@live-change/session-service": "0.3.2",
34
34
  "@live-change/vue3-components": "0.2.15",
35
35
  "@live-change/vue3-ssr": "0.2.15",
36
36
  "@tiptap/extension-blockquote": "^2.0.0-beta.29",
@@ -73,7 +73,7 @@
73
73
  "vue3-scroll-border": "0.1.2"
74
74
  },
75
75
  "devDependencies": {
76
- "@live-change/codeceptjs-helper": "0.7.2",
76
+ "@live-change/codeceptjs-helper": "0.7.4",
77
77
  "@wdio/selenium-standalone-service": "^7.20.8",
78
78
  "codeceptjs": "^3.3.4",
79
79
  "generate-password": "1.7.0",
@@ -85,5 +85,5 @@
85
85
  "author": "",
86
86
  "license": "ISC",
87
87
  "description": "",
88
- "gitHead": "76ac0dd54acf671cb564a1aa943d81a9e2bc99e9"
88
+ "gitHead": "323185f6d910912093b3c92df102d0f938cef367"
89
89
  }