Skip to content

Commit

Permalink
Merge pull request #7875 from owncloud/introduce-meta-auth-context
Browse files Browse the repository at this point in the history
Introduce meta authContext
  • Loading branch information
kulmann authored Nov 3, 2022
2 parents f416954 + b27bc11 commit 775151d
Show file tree
Hide file tree
Showing 27 changed files with 451 additions and 362 deletions.
8 changes: 8 additions & 0 deletions changelog/unreleased/enhancement-route-meta-props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Enhancement: Auth context in route meta props

The route meta prop has been extended by a new "meta.authContext" property (can be one out of "anonymous", "user", "publicLink" or "hybrid"). With this, app developers can now define anonymous routes, which was hardcoded to a few well known route names before.
Anonymous routes are rendered in the application layout, i.e. with the top bar, as the ownCloud Web Chrome should always be visible to the user (except for a few handpicked exceptions in the web runtime, which are still rendered in the plain layout).

https://github.com/owncloud/web/issues/7234
https://github.com/owncloud/web/issues/7863
https://github.com/owncloud/web/pull/7874
2 changes: 1 addition & 1 deletion packages/web-app-draw-io/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const routes = [
path: '/:driveAliasAndItem*',
component: App,
meta: {
auth: false,
authContext: 'hybrid',
patchCleanPath: true
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-external/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const routes = [
path: '/:driveAliasAndItem*',
component: App,
meta: {
auth: false,
authContext: 'hybrid',
patchCleanPath: true
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/web-app-files/src/router/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: 'list/:page?',
component: components.SearchResults,
meta: {
authContext: 'user',
title: $gettext('Search results'),
contextQueryItems: ['term', 'provider']
}
Expand All @@ -40,6 +41,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: '',
component: components.Favorites,
meta: {
authContext: 'user',
title: $gettext('Favorite files')
}
}
Expand Down
8 changes: 1 addition & 7 deletions packages/web-app-files/src/router/deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const deprecatedRedirect = (routeConfig: {
redirect: (to: Route) => Location
}): RouteConfig => {
return {
meta: routeConfig.meta,
meta: { ...routeConfig.meta, authContext: 'anonymous' }, // authContext belongs to the redirect target, not to the redirect itself.
path: routeConfig.path,
redirect: (to) => {
const location = routeConfig.redirect(to)
Expand Down Expand Up @@ -82,9 +82,6 @@ export const buildRoutes = (): RouteConfig[] =>
},
{
path: '/public/list/:item*',
meta: {
auth: false
},
redirect: (to) => createLocationPublic('files-public-link', to)
},
{
Expand All @@ -93,9 +90,6 @@ export const buildRoutes = (): RouteConfig[] =>
},
{
path: '/public-link/:token',
meta: {
auth: false
},
redirect: (to) => ({ name: 'resolvePublicLink', params: { token: to.params.token } })
}
].map(deprecatedRedirect)
Expand Down
4 changes: 2 additions & 2 deletions packages/web-app-files/src/router/public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: ':driveAliasAndItem*',
component: components.Spaces.DriveResolver,
meta: {
auth: false,
authContext: 'publicLink',
patchCleanPath: true
}
}
Expand All @@ -46,7 +46,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: ':token?',
component: components.FilesDrop,
meta: {
auth: false,
authContext: 'publicLink',
title: $gettext('Public file upload')
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/web-app-files/src/router/shares.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: 'with-me',
component: components.Shares.SharedWithMe,
meta: {
authContext: 'user',
title: $gettext('Files shared with me')
}
},
Expand All @@ -36,6 +37,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: 'with-others',
component: components.Shares.SharedWithOthers,
meta: {
authContext: 'user',
title: $gettext('Files shared with others')
}
},
Expand All @@ -44,6 +46,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: 'via-link',
component: components.Shares.SharedViaLink,
meta: {
authContext: 'user',
title: $gettext('Files shared via link')
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/web-app-files/src/router/spaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
name: locationSpacesProjects.name,
component: components.Spaces.Projects,
meta: {
authContext: 'user',
title: $gettext('Spaces')
}
},
Expand All @@ -35,6 +36,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
name: locationSpacesGeneric.name,
component: components.Spaces.DriveResolver,
meta: {
authContext: 'user',
patchCleanPath: true
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/web-app-files/src/router/trash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [
path: ':driveAliasAndItem*',
component: components.Spaces.DriveResolver,
meta: {
authContext: 'user',
patchCleanPath: true
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-pdf-viewer/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const routes = [
component: App,
name: 'pdf-viewer',
meta: {
auth: false,
authContext: 'hybrid',
title: $gettext('PDF Viewer'),
patchCleanPath: true
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-preview/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const routes = [
component: App,
name: 'media',
meta: {
auth: false,
authContext: 'hybrid',
title: $gettext('Preview'),
patchCleanPath: true
}
Expand Down
1 change: 1 addition & 0 deletions packages/web-app-search/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default {
path: 'list/:page?',
component: List,
meta: {
authContext: 'user',
contextQueryItems: ['term', 'provider']
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-text-editor/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const routes = [
component: App,
name: 'text-editor',
meta: {
authContext: 'hybrid',
title: $gettext('Text Editor'),
auth: false,
patchCleanPath: true
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/web-app-user-management/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const routes = [
name: 'user-management-users',
component: Users,
meta: {
authContext: 'user',
title: $gettext('Users')
}
},
Expand All @@ -33,6 +34,7 @@ const routes = [
name: 'user-management-groups',
component: Groups,
meta: {
authContext: 'user',
title: $gettext('Groups')
}
}
Expand Down
12 changes: 12 additions & 0 deletions packages/web-pkg/src/composables/router/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import { RouteMeta } from 'vue-router'

type Dictionary<T> = { [key: string]: T }

export type QueryValue = string | (string | null)[]
export type LocationQuery = Dictionary<QueryValue>

export type ParamValue = string
export type LocationParams = Dictionary<ParamValue>

export const authContextValues = ['anonymous', 'user', 'publicLink', 'hybrid'] as const
export type AuthContext = typeof authContextValues[number]

export interface WebRouteMeta extends RouteMeta {
title?: string
authContext?: AuthContext
patchCleanPath?: boolean
contextQueryItems?: string[]
}
14 changes: 10 additions & 4 deletions packages/web-runtime/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import LayoutLoading from './layouts/Loading.vue'
import LayoutPlain from './layouts/Plain.vue'
import { getBackendVersion, getWebVersion } from './container/versions'
import { defineComponent } from '@vue/composition-api'
import { isPublicLinkContext, isUserContext, isAuthenticationRequired } from './router'
import { isPublicLinkContext, isUserContext } from './router'
import { additionalTranslations } from './helpers/additionalTranslations' // eslint-disable-line
import { eventBus } from 'web-pkg/src/services'
Expand All @@ -70,17 +70,23 @@ export default defineComponent({
...mapGetters(['configuration', 'capabilities', 'getSettingsValue']),
...mapGetters('runtime/auth', ['isUserContextReady', 'isPublicLinkContextReady']),
layout() {
if (!this.$route.name || !isAuthenticationRequired(this.$router, this.$route)) {
const plainLayoutRoutes = [
'login',
'logout',
'oidcCallback',
'oidcSilentRedirect',
'resolvePublicLink',
'accessDenied'
]
if (!this.$route.name || plainLayoutRoutes.includes(this.$route.name)) {
return LayoutPlain
}
if (isPublicLinkContext(this.$router, this.$route)) {
return this.isPublicLinkContextReady ? LayoutApplication : LayoutLoading
}
if (isUserContext(this.$router, this.$route)) {
return this.isUserContextReady ? LayoutApplication : LayoutLoading
}
return LayoutApplication
},
favicon() {
Expand Down
16 changes: 13 additions & 3 deletions packages/web-runtime/src/layouts/Application.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div id="web-content-main" class="oc-px-s oc-pb-s">
<div class="app-container oc-flex">
<sidebar-nav v-if="isSidebarVisible" class="app-navigation" :nav-items="sidebarNavItems" />
<app-loading-spinner v-if="areSpacesLoading" />
<app-loading-spinner v-if="isLoading" />
<template v-else>
<router-view
v-for="name in ['default', 'app', 'fullscreen']"
Expand Down Expand Up @@ -37,11 +37,12 @@ import UploadInfo from '../components/UploadInfo.vue'
import {
useActiveApp,
useRoute,
useRouteMeta,
useSpacesLoading,
useStore,
useUserContext
} from 'web-pkg/src/composables'
import { watch, defineComponent } from '@vue/composition-api'
import { computed, defineComponent, unref, watch } from '@vue/composition-api'
export default defineComponent({
name: 'ApplicationLayout',
Expand Down Expand Up @@ -73,8 +74,17 @@ export default defineComponent({
},
{ immediate: true }
)
const requiredAuthContext = useRouteMeta('authContext')
const { areSpacesLoading } = useSpacesLoading({ store })
const isLoading = computed(() => {
if (unref(requiredAuthContext) === 'anonymous') {
return false
}
return unref(areSpacesLoading)
})
return {
...useSpacesLoading({ store }),
isLoading,
activeApp: useActiveApp(),
isUserContext: useUserContext({ store })
}
Expand Down
28 changes: 25 additions & 3 deletions packages/web-runtime/src/layouts/Plain.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,35 @@
<template>
<div>
<div
class="oc-login oc-height-viewport"
:style="{ backgroundImage: 'url(' + backgroundImg + ')' }"
>
<h1 class="oc-invisible-sr" v-text="pageTitle" />
<router-view />
</div>
</template>

<script lang="ts">
import { defineComponent } from '@vue/composition-api'
import { computed, defineComponent, unref } from '@vue/composition-api'
import { useRouteMeta, useStore, useTranslations } from 'web-pkg'
export default defineComponent({
name: 'PlainLayout'
name: 'PlainLayout',
setup() {
const store = useStore()
const { $gettext } = useTranslations()
const title = useRouteMeta('title')
const pageTitle = computed(() => {
return $gettext(unref(title))
})
const backgroundImg = computed(() => {
return store.getters.configuration?.currentTheme?.loginPage?.backgroundImg
})
return {
pageTitle,
backgroundImg
}
}
})
</script>
Loading

0 comments on commit 775151d

Please sign in to comment.