You've already forked filebrowser
mirror of
https://github.com/filebrowser/filebrowser.git
synced 2025-11-26 14:25:26 +08:00
feat: migrate to vue 3 (#2689)
--------- Co-authored-by: Joep <jcbuhre@gmail.com> Co-authored-by: Omar Hussein <omarmohammad1951@gmail.com> Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
This commit is contained in:
@@ -1,194 +0,0 @@
|
||||
import Vue from "vue";
|
||||
import Router from "vue-router";
|
||||
import Login from "@/views/Login.vue";
|
||||
import Layout from "@/views/Layout.vue";
|
||||
import Files from "@/views/Files.vue";
|
||||
import Share from "@/views/Share.vue";
|
||||
import Users from "@/views/settings/Users.vue";
|
||||
import User from "@/views/settings/User.vue";
|
||||
import Settings from "@/views/Settings.vue";
|
||||
import GlobalSettings from "@/views/settings/Global.vue";
|
||||
import ProfileSettings from "@/views/settings/Profile.vue";
|
||||
import Shares from "@/views/settings/Shares.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
import store from "@/store";
|
||||
import { baseURL, name } from "@/utils/constants";
|
||||
import i18n, { rtlLanguages } from "@/i18n";
|
||||
|
||||
Vue.use(Router);
|
||||
|
||||
const titles = {
|
||||
Login: "sidebar.login",
|
||||
Share: "buttons.share",
|
||||
Files: "files.files",
|
||||
Settings: "sidebar.settings",
|
||||
ProfileSettings: "settings.profileSettings",
|
||||
Shares: "settings.shareManagement",
|
||||
GlobalSettings: "settings.globalSettings",
|
||||
Users: "settings.users",
|
||||
User: "settings.user",
|
||||
Forbidden: "errors.forbidden",
|
||||
NotFound: "errors.notFound",
|
||||
InternalServerError: "errors.internal",
|
||||
};
|
||||
|
||||
const router = new Router({
|
||||
base: import.meta.env.PROD ? baseURL : "",
|
||||
mode: "history",
|
||||
routes: [
|
||||
{
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
component: Login,
|
||||
beforeEnter: (to, from, next) => {
|
||||
if (store.getters.isLogged) {
|
||||
return next({ path: "/files" });
|
||||
}
|
||||
|
||||
next();
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/*",
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: "/share/*",
|
||||
name: "Share",
|
||||
component: Share,
|
||||
},
|
||||
{
|
||||
path: "/files/*",
|
||||
name: "Files",
|
||||
component: Files,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
name: "Settings",
|
||||
component: Settings,
|
||||
redirect: {
|
||||
path: "/settings/profile",
|
||||
},
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/settings/profile",
|
||||
name: "ProfileSettings",
|
||||
component: ProfileSettings,
|
||||
},
|
||||
{
|
||||
path: "/settings/shares",
|
||||
name: "Shares",
|
||||
component: Shares,
|
||||
},
|
||||
{
|
||||
path: "/settings/global",
|
||||
name: "GlobalSettings",
|
||||
component: GlobalSettings,
|
||||
meta: {
|
||||
requiresAdmin: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/settings/users",
|
||||
name: "Users",
|
||||
component: Users,
|
||||
meta: {
|
||||
requiresAdmin: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/settings/users/*",
|
||||
name: "User",
|
||||
component: User,
|
||||
meta: {
|
||||
requiresAdmin: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/403",
|
||||
name: "Forbidden",
|
||||
component: Errors,
|
||||
props: {
|
||||
errorCode: 403,
|
||||
showHeader: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "NotFound",
|
||||
component: Errors,
|
||||
props: {
|
||||
errorCode: 404,
|
||||
showHeader: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/500",
|
||||
name: "InternalServerError",
|
||||
component: Errors,
|
||||
props: {
|
||||
errorCode: 500,
|
||||
showHeader: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/files",
|
||||
redirect: {
|
||||
path: "/files/",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/*",
|
||||
redirect: (to) => `/files${to.path}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const title = i18n.t(titles[to.name]);
|
||||
document.title = title + " - " + name;
|
||||
|
||||
/*** RTL related settings per route ****/
|
||||
const rtlSet = document.querySelector("body").classList.contains("rtl");
|
||||
const shouldSetRtl = rtlLanguages.includes(i18n.locale);
|
||||
switch (true) {
|
||||
case shouldSetRtl && !rtlSet:
|
||||
document.querySelector("body").classList.add("rtl");
|
||||
break;
|
||||
case !shouldSetRtl && rtlSet:
|
||||
document.querySelector("body").classList.remove("rtl");
|
||||
break;
|
||||
}
|
||||
|
||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||
if (!store.getters.isLogged) {
|
||||
next({
|
||||
path: "/login",
|
||||
query: { redirect: to.fullPath },
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (to.matched.some((record) => record.meta.requiresAdmin)) {
|
||||
if (!store.state.user.perm.admin) {
|
||||
next({ path: "/403" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
export default router;
|
||||
220
frontend/src/router/index.ts
Normal file
220
frontend/src/router/index.ts
Normal file
@@ -0,0 +1,220 @@
|
||||
import { RouteLocation, createRouter, createWebHistory } from "vue-router";
|
||||
import Login from "@/views/Login.vue";
|
||||
import Layout from "@/views/Layout.vue";
|
||||
import Files from "@/views/Files.vue";
|
||||
import Share from "@/views/Share.vue";
|
||||
import Users from "@/views/settings/Users.vue";
|
||||
import User from "@/views/settings/User.vue";
|
||||
import Settings from "@/views/Settings.vue";
|
||||
import GlobalSettings from "@/views/settings/Global.vue";
|
||||
import ProfileSettings from "@/views/settings/Profile.vue";
|
||||
import Shares from "@/views/settings/Shares.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { baseURL, name } from "@/utils/constants";
|
||||
import i18n from "@/i18n";
|
||||
import { recaptcha, loginPage } from "@/utils/constants";
|
||||
import { login, validateLogin } from "@/utils/auth";
|
||||
|
||||
const titles = {
|
||||
Login: "sidebar.login",
|
||||
Share: "buttons.share",
|
||||
Files: "files.files",
|
||||
Settings: "sidebar.settings",
|
||||
ProfileSettings: "settings.profileSettings",
|
||||
Shares: "settings.shareManagement",
|
||||
GlobalSettings: "settings.globalSettings",
|
||||
Users: "settings.users",
|
||||
User: "settings.user",
|
||||
Forbidden: "errors.forbidden",
|
||||
NotFound: "errors.notFound",
|
||||
InternalServerError: "errors.internal",
|
||||
};
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
component: Login,
|
||||
},
|
||||
{
|
||||
path: "/share",
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
path: ":path*",
|
||||
name: "Share",
|
||||
component: Share,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/files",
|
||||
component: Layout,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: ":path*",
|
||||
name: "Files",
|
||||
component: Files,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
component: Layout,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
name: "Settings",
|
||||
component: Settings,
|
||||
redirect: {
|
||||
path: "/settings/profile",
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "profile",
|
||||
name: "ProfileSettings",
|
||||
component: ProfileSettings,
|
||||
},
|
||||
{
|
||||
path: "shares",
|
||||
name: "Shares",
|
||||
component: Shares,
|
||||
},
|
||||
{
|
||||
path: "global",
|
||||
name: "GlobalSettings",
|
||||
component: GlobalSettings,
|
||||
meta: {
|
||||
requiresAdmin: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "users",
|
||||
name: "Users",
|
||||
component: Users,
|
||||
meta: {
|
||||
requiresAdmin: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "users/:id",
|
||||
name: "User",
|
||||
component: User,
|
||||
meta: {
|
||||
requiresAdmin: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/403",
|
||||
name: "Forbidden",
|
||||
component: Errors,
|
||||
props: {
|
||||
errorCode: 403,
|
||||
showHeader: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/404",
|
||||
name: "NotFound",
|
||||
component: Errors,
|
||||
props: {
|
||||
errorCode: 404,
|
||||
showHeader: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/500",
|
||||
name: "InternalServerError",
|
||||
component: Errors,
|
||||
props: {
|
||||
errorCode: 500,
|
||||
showHeader: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/:catchAll(.*)*",
|
||||
redirect: (to: RouteLocation) =>
|
||||
`/files/${[...to.params.catchAll].join("/")}`,
|
||||
},
|
||||
];
|
||||
|
||||
async function initAuth() {
|
||||
if (loginPage) {
|
||||
await validateLogin();
|
||||
} else {
|
||||
await login("", "", "");
|
||||
}
|
||||
|
||||
if (recaptcha) {
|
||||
await new Promise<void>((resolve) => {
|
||||
const check = () => {
|
||||
if (typeof window.grecaptcha === "undefined") {
|
||||
setTimeout(check, 100);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
check();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(baseURL),
|
||||
routes,
|
||||
});
|
||||
|
||||
router.beforeResolve(async (to, from, next) => {
|
||||
const title = i18n.global.t(titles[to.name as keyof typeof titles]);
|
||||
document.title = title + " - " + name;
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
// this will only be null on first route
|
||||
if (from.name == null) {
|
||||
try {
|
||||
await initAuth();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (to.path.endsWith("/login") && authStore.isLoggedIn) {
|
||||
next({ path: "/files/" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||
if (!authStore.isLoggedIn) {
|
||||
next({
|
||||
path: "/login",
|
||||
query: { redirect: to.fullPath },
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (to.matched.some((record) => record.meta.requiresAdmin)) {
|
||||
if (authStore.user === null || !authStore.user.perm.admin) {
|
||||
next({ path: "/403" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
export { router, router as default };
|
||||
Reference in New Issue
Block a user