blob: 3ca8431fc0c069c51981eaf0c10e7d45657de279 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import type { IndexRouteObject, NonIndexRouteObject } from 'react-router-dom';
import { guard } from '@/utils';
import type { TGuardFunc } from '@/utils/guard';
import { editCheck } from '@/services';
import { isEditable } from '@/utils/guard';
type IndexRouteNode = Omit<IndexRouteObject, 'children'>;
type NonIndexRouteNode = Omit<NonIndexRouteObject, 'children'>;
type UnionRouteNode = IndexRouteNode | NonIndexRouteNode;
export type RouteNode = UnionRouteNode & {
page: string;
children?: RouteNode[];
/**
* a method to auto guard route before route enter
* if the `ok` field in guard returned `TGuardResult` is true,
* it means the guard passed then enter the route.
* if guard returned the `TGuardResult` has `redirect` field,
* then auto redirect route to the `redirect` target.
*/
guard?: TGuardFunc;
};
const routes: RouteNode[] = [
{
path: '/',
page: 'pages/Layout',
loader: async () => {
await guard.setupApp();
return null;
},
guard: () => {
const gr = guard.shouldLoginRequired();
if (!gr.ok) {
return gr;
}
return {
ok: true,
};
},
children: [
// question and answer
{
// side nav layout
page: 'pages/SideNavLayout',
children: [
{
index: true,
page: 'pages/Questions',
},
{
path: 'questions',
page: 'pages/Questions',
},
{
path: 'questions/ask',
page: 'pages/Questions/Ask',
guard: () => {
return guard.askRedirect();
},
},
{
path: 'questions/add',
page: 'pages/Questions/Ask',
guard: () => {
return guard.activated();
},
},
{
path: 'posts/:qid/edit',
page: 'pages/Questions/Ask',
guard: () => {
return guard.activated();
},
},
{
path: 'posts/:qid/:aid/edit',
page: 'pages/Questions/EditAnswer',
loader: async ({ params }) => {
const ret = await editCheck(params.aid as string, true);
return ret;
},
guard: (args) => {
return isEditable(args);
},
},
{
path: 'questions/:qid',
page: 'pages/Questions/Detail',
},
{
path: 'questions/:qid/:slugPermalink',
page: 'pages/Questions/Detail',
},
{
path: 'questions/:qid/:slugPermalink/:aid',
page: 'pages/Questions/Detail',
},
{
path: '/questions/linked/:qid',
page: 'pages/Questions/Linked',
guard: () => {
return guard.linkedRedirect();
},
},
{
path: '/linked/:qid',
page: 'pages/Questions/Linked',
},
{
path: '/search',
page: 'pages/Search',
},
// tags
{
path: 'tags',
page: 'pages/Tags',
},
{
path: 'tags/create',
page: 'pages/Tags/Create',
guard: () => {
return guard.isAdminOrModerator();
},
},
{
path: 'tags/:tagName',
page: 'pages/Tags/Detail',
},
{
path: 'tags/:tagName/questions',
page: 'pages/Tags/Detail',
},
{
path: 'tags/:tagName/info',
page: 'pages/Tags/Info',
},
{
path: 'tags/:tagId/edit',
page: 'pages/Tags/Edit',
guard: () => {
return guard.activated();
},
},
// for users
{
path: 'users',
page: 'pages/Users',
},
{
path: 'users/:username',
page: 'pages/Users/Personal',
},
{
path: 'users/:username/:tabName',
page: 'pages/Users/Personal',
},
{
path: 'users/settings',
page: 'pages/Users/Settings',
guard: () => {
return guard.logged();
},
children: [
{
index: true,
page: 'pages/Users/Settings/Profile',
},
{
path: 'profile',
page: 'pages/Users/Settings/Profile',
},
{
path: 'notify',
page: 'pages/Users/Settings/Notification',
},
{
path: 'account',
page: 'pages/Users/Settings/Account',
},
{
path: 'interface',
page: 'pages/Users/Settings/Interface',
},
{
path: ':slug_name',
page: 'pages/Users/Settings/Plugins',
},
],
},
{
path: 'users/notifications/:type/:subType?',
page: 'pages/Users/Notifications',
},
{
path: '/posts/:qid/timeline',
page: 'pages/Timeline',
guard: () => {
return guard.logged();
},
},
{
path: '/posts/:qid/:aid/timeline',
page: 'pages/Timeline',
guard: () => {
return guard.logged();
},
},
{
path: '/tags/:tid/timeline',
page: 'pages/Timeline',
guard: () => {
return guard.logged();
},
},
// for review
{
path: 'review',
page: 'pages/Review',
},
{
path: '/badges',
page: 'pages/Badges/index',
},
{
path: '/badges/:badge_id',
page: 'pages/Badges/Detail/index',
},
],
},
{
path: 'users/login',
page: 'pages/Users/Login',
guard: () => {
const notLogged = guard.notLogged();
if (notLogged.ok) {
return notLogged;
}
return guard.notActivated();
},
},
{
path: 'users/register',
page: 'pages/Users/Register',
guard: () => {
const allowNew = guard.allowNewRegistration();
if (!allowNew.ok) {
return allowNew;
}
const notLogged = guard.notLogged();
if (notLogged.ok) {
const sa = guard.singUpAgent();
if (!sa.ok) {
return sa;
}
}
return notLogged;
},
},
{
path: 'users/logout',
page: 'pages/Users/Logout',
guard: () => {
return guard.loggedRedirectHome();
},
},
{
path: 'users/account-recovery',
page: 'pages/Users/AccountForgot',
guard: () => {
return guard.notLogged();
},
},
{
path: 'users/change-email',
page: 'pages/Users/ChangeEmail',
},
{
path: 'users/password-reset',
page: 'pages/Users/PasswordReset',
},
{
path: 'users/account-activation',
page: 'pages/Users/ActiveEmail',
},
{
path: 'users/account-activation/success',
page: 'pages/Users/ActivationResult',
guard: () => {
return guard.activated();
},
},
{
path: '/users/account-activation/failed',
page: 'pages/Users/ActivationResult',
guard: () => {
return guard.notActivated();
},
},
{
path: '/users/confirm-new-email',
page: 'pages/Users/ConfirmNewEmail',
},
{
path: '/users/account-suspended',
page: 'pages/Users/Suspended',
guard: () => {
return guard.notLogged();
},
},
{
path: '/users/confirm-email',
page: 'pages/Users/OauthBindEmail',
},
{
path: '/users/auth-landing',
page: 'pages/Users/AuthCallback',
},
// for admin
{
path: 'admin',
page: 'pages/Admin',
loader: async () => {
await guard.pullLoggedUser();
return null;
},
guard: () => {
return guard.admin();
},
children: [
{
index: true,
page: 'pages/Admin/Dashboard',
},
{
path: 'dashboard',
page: 'pages/Admin/Dashboard',
},
{
path: 'answers',
page: 'pages/Admin/Answers',
},
{
path: 'themes',
page: 'pages/Admin/Themes',
},
{
path: 'customize',
page: 'pages/Admin/CssAndHtml',
},
{
path: 'general',
page: 'pages/Admin/General',
},
{
path: 'interface',
page: 'pages/Admin/Interface',
},
{
path: 'questions',
page: 'pages/Admin/Questions',
},
{
path: 'users',
page: 'pages/Admin/Users',
},
{
path: 'users/:user_id',
page: 'pages/Admin/UserOverview',
},
{
path: 'smtp',
page: 'pages/Admin/Smtp',
},
{
path: 'branding',
page: 'pages/Admin/Branding',
},
{
path: 'legal',
page: 'pages/Admin/Legal',
},
{
path: 'write',
page: 'pages/Admin/Write',
},
{
path: 'seo',
page: 'pages/Admin/Seo',
},
{
path: 'login',
page: 'pages/Admin/Login',
},
{
path: 'privileges',
page: 'pages/Admin/Privileges',
},
{
path: 'installed-plugins',
page: 'pages/Admin/Plugins/Installed',
},
{
path: ':slug_name',
page: 'pages/Admin/Plugins/Config',
},
{
path: 'badges',
page: 'pages/Admin/Badges',
},
],
},
{
path: '/user-center/auth',
page: 'pages/UserCenter/Auth',
guard: () => {
const notLogged = guard.notLogged();
return notLogged;
},
},
{
path: '/user-center/auth-failed',
page: 'pages/UserCenter/AuthFailed',
},
{
path: '*',
page: 'pages/404',
},
{
path: '50x',
page: 'pages/50X',
},
],
},
{
path: '/',
page: 'pages/Layout',
loader: async () => {
await guard.setupApp();
return null;
},
children: [
{
page: 'pages/SideNavLayout',
children: [
{
page: 'pages/Legal',
children: [
{
path: 'tos',
page: 'pages/Legal/Tos',
},
{
path: 'privacy',
page: 'pages/Legal/Privacy',
},
],
},
],
},
{
path: '/users/unsubscribe',
page: 'pages/Users/Unsubscribe',
},
{
path: '403',
page: 'pages/403',
},
],
},
{
path: '/install',
page: 'pages/Install',
},
{
path: '/maintenance',
page: 'pages/Maintenance',
},
];
export default routes;