diff --git a/changelog/unreleased/enhancement-route-meta-props b/changelog/unreleased/enhancement-route-meta-props new file mode 100644 index 00000000000..5d175e25463 --- /dev/null +++ b/changelog/unreleased/enhancement-route-meta-props @@ -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 diff --git a/packages/web-app-draw-io/src/index.js b/packages/web-app-draw-io/src/index.js index eece4850391..0312bbe70e1 100644 --- a/packages/web-app-draw-io/src/index.js +++ b/packages/web-app-draw-io/src/index.js @@ -7,7 +7,7 @@ const routes = [ path: '/:driveAliasAndItem*', component: App, meta: { - auth: false, + authContext: 'hybrid', patchCleanPath: true } } diff --git a/packages/web-app-external/src/index.js b/packages/web-app-external/src/index.js index d7d87fef322..92c6449d552 100644 --- a/packages/web-app-external/src/index.js +++ b/packages/web-app-external/src/index.js @@ -13,7 +13,7 @@ const routes = [ path: '/:driveAliasAndItem*', component: App, meta: { - auth: false, + authContext: 'hybrid', patchCleanPath: true } } diff --git a/packages/web-app-files/src/router/common.ts b/packages/web-app-files/src/router/common.ts index cf91457fcfb..74e22b9ddb6 100644 --- a/packages/web-app-files/src/router/common.ts +++ b/packages/web-app-files/src/router/common.ts @@ -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'] } @@ -40,6 +41,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [ path: '', component: components.Favorites, meta: { + authContext: 'user', title: $gettext('Favorite files') } } diff --git a/packages/web-app-files/src/router/deprecated.ts b/packages/web-app-files/src/router/deprecated.ts index c7f189cff92..96a50c20b76 100644 --- a/packages/web-app-files/src/router/deprecated.ts +++ b/packages/web-app-files/src/router/deprecated.ts @@ -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) @@ -82,9 +82,6 @@ export const buildRoutes = (): RouteConfig[] => }, { path: '/public/list/:item*', - meta: { - auth: false - }, redirect: (to) => createLocationPublic('files-public-link', to) }, { @@ -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) diff --git a/packages/web-app-files/src/router/public.ts b/packages/web-app-files/src/router/public.ts index ab638976a90..706ee7a3d2c 100644 --- a/packages/web-app-files/src/router/public.ts +++ b/packages/web-app-files/src/router/public.ts @@ -28,7 +28,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [ path: ':driveAliasAndItem*', component: components.Spaces.DriveResolver, meta: { - auth: false, + authContext: 'publicLink', patchCleanPath: true } } @@ -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') } } diff --git a/packages/web-app-files/src/router/shares.ts b/packages/web-app-files/src/router/shares.ts index 7e4690457b6..a4f1c87cc4a 100644 --- a/packages/web-app-files/src/router/shares.ts +++ b/packages/web-app-files/src/router/shares.ts @@ -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') } }, @@ -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') } }, @@ -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') } } diff --git a/packages/web-app-files/src/router/spaces.ts b/packages/web-app-files/src/router/spaces.ts index 3f84b9343b7..f3d5eb5bde0 100644 --- a/packages/web-app-files/src/router/spaces.ts +++ b/packages/web-app-files/src/router/spaces.ts @@ -27,6 +27,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [ name: locationSpacesProjects.name, component: components.Spaces.Projects, meta: { + authContext: 'user', title: $gettext('Spaces') } }, @@ -35,6 +36,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [ name: locationSpacesGeneric.name, component: components.Spaces.DriveResolver, meta: { + authContext: 'user', patchCleanPath: true } } diff --git a/packages/web-app-files/src/router/trash.ts b/packages/web-app-files/src/router/trash.ts index 8b9daaf2e5a..b770f33ce39 100644 --- a/packages/web-app-files/src/router/trash.ts +++ b/packages/web-app-files/src/router/trash.ts @@ -21,6 +21,7 @@ export const buildRoutes = (components: RouteComponents): RouteConfig[] => [ path: ':driveAliasAndItem*', component: components.Spaces.DriveResolver, meta: { + authContext: 'user', patchCleanPath: true } } diff --git a/packages/web-app-pdf-viewer/src/index.js b/packages/web-app-pdf-viewer/src/index.js index 2a7ad1ccb31..ec17da753c6 100644 --- a/packages/web-app-pdf-viewer/src/index.js +++ b/packages/web-app-pdf-viewer/src/index.js @@ -12,7 +12,7 @@ const routes = [ component: App, name: 'pdf-viewer', meta: { - auth: false, + authContext: 'hybrid', title: $gettext('PDF Viewer'), patchCleanPath: true } diff --git a/packages/web-app-preview/src/index.js b/packages/web-app-preview/src/index.js index 22c3d529531..18167c46cc9 100644 --- a/packages/web-app-preview/src/index.js +++ b/packages/web-app-preview/src/index.js @@ -14,7 +14,7 @@ const routes = [ component: App, name: 'media', meta: { - auth: false, + authContext: 'hybrid', title: $gettext('Preview'), patchCleanPath: true } diff --git a/packages/web-app-search/src/index.ts b/packages/web-app-search/src/index.ts index a3cc316ddfa..1d4527d6b44 100644 --- a/packages/web-app-search/src/index.ts +++ b/packages/web-app-search/src/index.ts @@ -35,6 +35,7 @@ export default { path: 'list/:page?', component: List, meta: { + authContext: 'user', contextQueryItems: ['term', 'provider'] } } diff --git a/packages/web-app-text-editor/src/index.js b/packages/web-app-text-editor/src/index.js index be9014c2d03..f495d6470ea 100644 --- a/packages/web-app-text-editor/src/index.js +++ b/packages/web-app-text-editor/src/index.js @@ -14,8 +14,8 @@ const routes = [ component: App, name: 'text-editor', meta: { + authContext: 'hybrid', title: $gettext('Text Editor'), - auth: false, patchCleanPath: true } } diff --git a/packages/web-app-user-management/src/index.js b/packages/web-app-user-management/src/index.js index 7662c6c8e52..353b07d3821 100644 --- a/packages/web-app-user-management/src/index.js +++ b/packages/web-app-user-management/src/index.js @@ -25,6 +25,7 @@ const routes = [ name: 'user-management-users', component: Users, meta: { + authContext: 'user', title: $gettext('Users') } }, @@ -33,6 +34,7 @@ const routes = [ name: 'user-management-groups', component: Groups, meta: { + authContext: 'user', title: $gettext('Groups') } } diff --git a/packages/web-pkg/src/composables/router/types.ts b/packages/web-pkg/src/composables/router/types.ts index ac707736603..f0880de49b6 100644 --- a/packages/web-pkg/src/composables/router/types.ts +++ b/packages/web-pkg/src/composables/router/types.ts @@ -1,3 +1,5 @@ +import { RouteMeta } from 'vue-router' + type Dictionary = { [key: string]: T } export type QueryValue = string | (string | null)[] @@ -5,3 +7,13 @@ export type LocationQuery = Dictionary export type ParamValue = string export type LocationParams = Dictionary + +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[] +} diff --git a/packages/web-runtime/src/App.vue b/packages/web-runtime/src/App.vue index adaf7941e5d..9806c01086e 100644 --- a/packages/web-runtime/src/App.vue +++ b/packages/web-runtime/src/App.vue @@ -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' @@ -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() { diff --git a/packages/web-runtime/src/layouts/Application.vue b/packages/web-runtime/src/layouts/Application.vue index cb7d557ffa9..cfed206f6d3 100644 --- a/packages/web-runtime/src/layouts/Application.vue +++ b/packages/web-runtime/src/layouts/Application.vue @@ -9,7 +9,7 @@
- +