Files
directus/app/src/router.ts
Rijk van Zanten dbf35a1736 Add ability to share items with people outside the platform (#10663)
* Add directus_shares

* Don't check for usage limit on refresh

* Add all endpoints to the shares controller

* Move route `/auth/shared` to `/shared/auth`

* Add password protection

* Add `share` action in permissions

* Add `shares/:pk/info`

* Start on shared-view

* Add basic styling for full shared view

* Fixed migrations

* Add inline style for shared view

* Allow title override

* Finish /info endpoint for shares

* Add basic UUID validation to share/info endpont

* Add UUID validation to other routes

* Add not found state

* Cleanup /extract/finish share login endpoint

* Cleanup auth

* Added `share_start` and `share_end`

* Add share sidebar details.

* Allow share permissions configuration

* Hide the `new_share` button for unauthorized users

* Fix uses_left displayed value

* Show expired / upcoming shares

* Improved expired/upcoming styling

* Fixed share login query

* Fix check-ip and get-permissions middlewares behaviour when role is null

* Simplify cache key

* Fix typescript linting issues

* Handle app auth flow for shared page

* Fixed /users/me response

* Show when user is authenticated

* Try showing item drawer in shared page

* Improved shared card styling

* Add shares permissions and change share card styling

* Pull in schema/permissions on share

* Create getPermissionForShare file

* Change getPermissionsForShare signature

* Render form + item on share after auth

* Finalize public front end

* Handle fake o2m field in applyQuery

* [WIP]

* New translations en-US.yaml (Bulgarian) (#10585)

* smaller label height (#10587)

* Update to the latest Material Icons (#10573)

The icons are based on https://fonts.google.com/icons

* New translations en-US.yaml (Arabic) (#10593)

* New translations en-US.yaml (Arabic) (#10594)

* New translations en-US.yaml (Portuguese, Brazilian) (#10604)

* New translations en-US.yaml (French) (#10605)

* New translations en-US.yaml (Italian) (#10613)

* fix M2A list not updating (#10617)

* Fix filters

* Add admin filter on m2o role selection

* Add admin filter on m2o role selection

* Add o2m permissions traversing

* Finish relational tree permissions generation

* Handle implicit a2o relation

* Update implicit relation regex

* Fix regex

* Fix implicitRelation unnesting for new regex

* Fix implicitRelation length check

* Rename m2a to a2o internally

* Add auto-gen permissions for a2o

* [WIP] Improve share UX

* Add ctx menu options

* Add share dialog

* Add email notifications

* Tweak endpoint

* Tweak file interface disabled state

* Add nicer invalid state to password input

* Dont return info for expired/upcoming shares

* Tweak disabled state for relational interfaces

* Fix share button for non admin roles

* Show/hide edit/delete based on permissions to shares

* Fix imports of mutationtype

* Resolve (my own) suggestions

* Fix migration for ms sql

* Resolve last suggestion

Co-authored-by: Oreilles <oreilles.github@nitoref.io>
Co-authored-by: Oreilles <33065839+oreilles@users.noreply.github.com>
Co-authored-by: Ben Haynes <ben@rngr.org>
Co-authored-by: Thien Nguyen <72242664+tatthien@users.noreply.github.com>
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
2021-12-23 18:51:59 -05:00

132 lines
2.9 KiB
TypeScript

import { refresh } from '@/auth';
import { hydrate } from '@/hydrate';
import AcceptInviteRoute from '@/routes/accept-invite';
import LoginRoute from '@/routes/login';
import LogoutRoute from '@/routes/logout';
import ShareRoute from '@/routes/shared';
import PrivateNotFoundRoute from '@/routes/private-not-found';
import ResetPasswordRoute from '@/routes/reset-password';
import { useAppStore, useServerStore, useUserStore } from '@/stores';
import { getRootPath } from '@/utils/get-root-path';
import { createRouter, createWebHistory, NavigationGuard, NavigationHookAfter, RouteRecordRaw } from 'vue-router';
export const defaultRoutes: RouteRecordRaw[] = [
{
path: '/',
redirect: '/login',
},
{
name: 'login',
path: '/login',
component: LoginRoute,
props: (route) => ({
ssoErrorCode: route.query.error ? route.query.code : null,
logoutReason: route.query.reason,
}),
meta: {
public: true,
},
},
{
name: 'reset-password',
path: '/reset-password',
component: ResetPasswordRoute,
meta: {
public: true,
},
},
{
name: 'accept-invite',
path: '/accept-invite',
component: AcceptInviteRoute,
meta: {
public: true,
},
},
{
name: 'logout',
path: '/logout',
component: LogoutRoute,
meta: {
public: true,
},
},
{
name: 'shared',
path: '/shared/:id([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})',
component: ShareRoute,
meta: {
public: true,
},
},
{
name: 'private-404',
path: '/:_(.+)+',
component: PrivateNotFoundRoute,
},
];
export const router = createRouter({
history: createWebHistory(getRootPath() + 'admin/'),
routes: defaultRoutes,
});
let firstLoad = true;
export const onBeforeEach: NavigationGuard = async (to) => {
const appStore = useAppStore();
const serverStore = useServerStore();
// First load
if (firstLoad) {
firstLoad = false;
// Try retrieving a fresh access token on first load
try {
await refresh({ navigate: false });
} catch {
// Ignore error
}
}
if (serverStore.info === null) {
await serverStore.hydrate();
}
if (to.meta?.public !== true && appStore.hydrated === false) {
appStore.hydrating = false;
if (appStore.authenticated === true && appStore.hydrating === false) {
await hydrate();
return to.fullPath;
} else {
if (to.fullPath) {
return '/login?redirect=' + encodeURIComponent(to.fullPath);
} else {
return '/login';
}
}
}
};
let trackTimeout: number | null = null;
export const onAfterEach: NavigationHookAfter = (to) => {
const userStore = useUserStore();
if (to.meta.public !== true) {
// The timeout gives the page some breathing room to load. No need to clog up the thread with
// this call while more important things are loading
if (trackTimeout) {
clearTimeout(trackTimeout);
trackTimeout = null;
}
setTimeout(() => {
userStore.trackPage(to.fullPath);
}, 500);
}
};
router.beforeEach(onBeforeEach);
router.afterEach(onAfterEach);