Skip to content

Commit

Permalink
refactor(middleware): oops page for php bots (#218)
Browse files Browse the repository at this point in the history
* refactor(middleware): oops page for php bots

* refactor(middleware): wip

* refactor(middleware): simple ops page

* chore: fix skip logic

* chore: rename

* chore: rename
  • Loading branch information
mydearxym authored Mar 19, 2024
1 parent 7b7a754 commit d651ac7
Show file tree
Hide file tree
Showing 17 changed files with 182 additions and 43 deletions.
9 changes: 9 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ const nextConfig = {
},
],
},
{
source: '/oops',
headers: [
{
key: 'cache-control',
value: 's-maxage=6000, stale-while-revalidate=30',
},
],
},
]
},
}
Expand Down
7 changes: 7 additions & 0 deletions src/app/404.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ErrorPage from 'next/error'

const NotFound = () => {
return <ErrorPage statusCode={404} title="Page Not Found" />
}

export default NotFound
3 changes: 0 additions & 3 deletions src/app/[community]/error.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
'use client'

import ErrorPage from '@/widgets/ErrorPage'

const ErrorCommunity = () => {
return (
<div>
<h2>Community Page Error</h2>
<ErrorPage />
</div>
)
}
Expand Down
35 changes: 35 additions & 0 deletions src/app/oops/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use client'

import { useRouter } from 'next/navigation'

import { ROUTE } from '@/constant/route'

import Button from '@/widgets/Buttons/Button'
import { LinkAble } from '@/widgets/Common'

import { Wrapper, InnerWrapper, Footer } from './styles'
// import ErrorPage from 'next/error'

const OopsPage = () => {
const router = useRouter()

return (
<Wrapper>
<InnerWrapper>
<h1>Oops</h1>
<p>the content you looking for is not exist</p>
<Footer>
<Button type="primary" right={20} onClick={() => router.back()}>
返回
</Button>

<LinkAble href={`/${ROUTE.HOME}`}>
<Button ghost>Groupher 社区</Button>
</LinkAble>
</Footer>
</InnerWrapper>
</Wrapper>
)
}

export default OopsPage
18 changes: 18 additions & 0 deletions src/app/oops/styles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Link from 'next/link'

import styled, { css, theme } from '@/css'

export const Wrapper = styled.div`
${css.column('align-both')};
width: 100%;
height: 68vh;
position: relative;
`
export const InnerWrapper = styled.div`
${css.column('align-start')};
position: relative;
`
export const Footer = styled.div`
${css.row()};
margin-top: 20px;
`
21 changes: 16 additions & 5 deletions src/app/providers/RootStoreProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use client'

import { FC, ReactNode, memo } from 'react'
import { FC, ReactNode, memo, useEffect } from 'react'
import { Provider } from 'mobx-react'
import { enableStaticRendering } from 'mobx-react-lite'

import { useRouter } from 'next/navigation'

import { useStore } from '@/stores/init'

import {
Expand Down Expand Up @@ -31,6 +33,19 @@ type TProps = {

const RootStoreWrapper: FC<TProps> = ({ children }) => {
const userHasLogin = false
// const router = useRouter()

// useEffect(() => {
// const handleRedirect = async () => {
// if (!community) {
// await router.push('/oops')
// }
// }

// handleRedirect()
// }, [])

const theme = useThemeFromURL()

const metric = useMetric()
const activeThread = useThreadParam()
Expand All @@ -47,10 +62,6 @@ const RootStoreWrapper: FC<TProps> = ({ children }) => {
const wallpaper = useWallpaper(community)
const filterSearchParams = useFilterSearchParams()

// NOTE: 目前在没有启动后端的情况下,如果这行代码出现在 useCommunity 之前,会导致 build 后的代码疯狂
// post 到 /GraphiQL, 奇怪的行为。。,很怀疑是 URQL 客户端的 Bug ..
const theme = useThemeFromURL()

const store = useStore({
metric,
articles: {
Expand Down
18 changes: 9 additions & 9 deletions src/app/queries/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { THREAD } from '@/constant/thread'
import URL_PARAM from '@/constant/url_param'
import { nilOrEmpty } from '@/validator'
import {
LANDIN_ROUTES,
STATIC_ROUTES,
DASHBOARD_ROUTE,
DASHBOARD_BASEINFO_ROUTE,
DASHBOARD_SEO_ROUTE,
Expand All @@ -44,23 +44,23 @@ export const commonRes = (result): TGQSSRResult => {
}
}

export const useIsStaticQuery = (): boolean => {
export const useIsFrameworkQuery = (): boolean => {
const pathname = usePathname()

return startsWith('/_next', pathname) || startsWith('/_vercel', pathname)
}

export const useLandingPages = (): boolean => {
export const useIsStaticPages = (): boolean => {
const pathname = usePathname()

return includes(pathname, LANDIN_ROUTES)
return includes(pathname, STATIC_ROUTES)
}

export const useSkipLandingQuery = (): boolean => {
const isStaticQuery = useIsStaticQuery()
const isLandingPages = useLandingPages()
export const useSkipStaticQuery = (): boolean => {
const isFrameworkQuery = useIsFrameworkQuery()
const isStaticPages = useIsStaticPages()

return isStaticQuery || isLandingPages
return isFrameworkQuery || isStaticPages
}

export const useCommunityParam = (): string => {
Expand Down Expand Up @@ -114,7 +114,7 @@ export const useArticleParams = (): TArticleParams => {
}

export const parseCommunity = (communityPath: string): string => {
if (!communityPath) return HCN
if (!communityPath) return null // HCN
if (communityPath === '_next') return null

return communityPath
Expand Down
24 changes: 12 additions & 12 deletions src/app/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import {
useArticleParams,
useCommunityParam,
useThreadParam,
useIsStaticQuery,
useSkipLandingQuery,
useIsFrameworkQuery,
useSkipStaticQuery,
useIdParam,
//
parseWallpaper,
Expand Down Expand Up @@ -71,7 +71,7 @@ export const useMetric = (): TMetric => {
}

// export const useSession = (): TSessionRes => {
// const isStaticQuery = useIsStaticQuery()
// const isStaticQuery = useIsFrameworkQuery()

// const [result] = useQuery({
// query: P.sessionState,
Expand Down Expand Up @@ -99,7 +99,7 @@ export const useMetric = (): TMetric => {

export const useCommunity = (userHasLogin: boolean): TCommunityRes => {
const slug = useCommunityParam()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()

const [result] = useQuery({
query: P.community,
Expand All @@ -118,7 +118,7 @@ export const useCommunity = (userHasLogin: boolean): TCommunityRes => {

export const useTags = (): TTagsRes => {
const community = useCommunityParam()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()
const thread = useThreadParam()

const [result] = useQuery({
Expand All @@ -138,7 +138,7 @@ export const useTags = (): TTagsRes => {
export const usePagedPosts = (userHasLogin: boolean): TPagedPostsRes => {
const filter = usePagedArticlesParams()
const thread = useThreadParam()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()
const id = useIdParam()

const [result] = useQuery({
Expand All @@ -155,7 +155,7 @@ export const usePagedPosts = (userHasLogin: boolean): TPagedPostsRes => {

export const usePagedChangelogs = (userHasLogin: boolean): TPagedChangelogsRes => {
const filter = usePagedArticlesParams()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()
const thread = useThreadParam()

const [result] = useQuery({
Expand All @@ -172,7 +172,7 @@ export const usePagedChangelogs = (userHasLogin: boolean): TPagedChangelogsRes =

export const usePost = (userHasLogin: boolean): TPostRes => {
const { community, id } = useArticleParams()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()
const thread = useThreadParam()

const [result] = useQuery({
Expand All @@ -189,7 +189,7 @@ export const usePost = (userHasLogin: boolean): TPostRes => {

export const useChangelog = (userHasLogin: boolean): TChangelogRes => {
const { community, id } = useArticleParams()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()
const thread = useThreadParam()

const [result] = useQuery({
Expand All @@ -206,7 +206,7 @@ export const useChangelog = (userHasLogin: boolean): TChangelogRes => {

export const useGroupedKanbanPosts = (userHasLogin: boolean): TGroupedKanbanPostsRes => {
const community = useCommunityParam()
const skipLandingQuery = useSkipLandingQuery()
const skipLandingQuery = useSkipStaticQuery()
const thread = useThreadParam()

const [result] = useQuery({
Expand All @@ -225,7 +225,7 @@ export const useGroupedKanbanPosts = (userHasLogin: boolean): TGroupedKanbanPost
* wallpaper related settings for all page
*/
export const useWallpaper = (community: TCommunity): TParsedWallpaper => {
const isStaticQuery = useIsStaticQuery()
const isStaticQuery = useIsFrameworkQuery()

// @ts-ignore
return !isStaticQuery ? parseWallpaper(community) : {}
Expand All @@ -235,7 +235,7 @@ export const useWallpaper = (community: TCommunity): TParsedWallpaper => {
* general dashboard settings for all page
*/
export const useDashboard = (community: TCommunity): TParseDashboard => {
const isStaticQuery = useIsStaticQuery()
const isStaticQuery = useIsFrameworkQuery()
const pathname = usePathname()

// @ts-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const CommunityBrief: FC<TProps> = ({ show }) => {

<Space right={15} />
<Label>帖子</Label>
<Count>{meta.postsCount}</Count>
<Count>{meta?.postsCount}</Count>
</InfoBar>
</Brief>
</Wrapper>
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useMetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { includes } from 'ramda'
import type { TMetric } from '@/spec'
import METRIC from '@/constant/metric'
import { BANNER_LAYOUT } from '@/constant/layout'
import { LANDIN_ROUTES } from '@/constant/route'
import { STATIC_ROUTES } from '@/constant/route'

/**
* NOTE: should use observer to wrap the component who use this hook
Expand All @@ -21,7 +21,7 @@ const useMetric = (): TMetric => {

const pathname = usePathname()

if (includes(pathname, LANDIN_ROUTES)) {
if (includes(pathname, STATIC_ROUTES)) {
return METRIC.HOME
}

Expand Down
21 changes: 11 additions & 10 deletions src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

import { applyMiddleware } from './middlewares/helper'
// import { themeMiddleware } from './middlewares/theme'
import { queryWhitelistMiddleware } from './middlewares/query-whitelist'
import { oopsMiddleware } from './middlewares/oops'
import { avoidScanMiddleware } from './middlewares/avoid-scan'

export function middleware(request: NextRequest) {
// const response = themeMiddleware(request)
// if (response instanceof NextResponse) return response
// middleware in this array will be applied in order
const middlewareFunctions = [
avoidScanMiddleware,
oopsMiddleware,
queryWhitelistMiddleware,
// ... more middlewares
]

// whitelist the query parameters to improve CDN caching
const response = queryWhitelistMiddleware(request)
if (response instanceof NextResponse) return response

// return response instanceof NextResponse ? response : NextResponse.next()

return NextResponse.next()
return applyMiddleware(middlewareFunctions, request)
}
17 changes: 17 additions & 0 deletions src/middlewares/avoid-scan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

import { ROUTE } from '@/constant/route'

export function avoidScanMiddleware(req: NextRequest) {
const { pathname } = req.nextUrl

// 检查pathname是否以.php或.php7结束
if (pathname.endsWith('.php') || pathname.endsWith('.php7')) {
// 重定向到/oops页面
return NextResponse.redirect(new URL(ROUTE.OOPS, req.url))
}

// 如果路径不以.php或.php7结束,则继续处理后续中间件
return NextResponse.next()
}
20 changes: 20 additions & 0 deletions src/middlewares/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { NextResponse } from 'next/server'

/**
* chain the middlewares and apply them to the request
*/
export function applyMiddleware(middlewareFns, req) {
for (const middlewareFn of middlewareFns) {
const response = middlewareFn(req)
// 如果中间件执行结果是重定向或重写,那么就返回该响应并且不再执行后续中间件

if (response instanceof NextResponse) {
// 检查状态码是否代表重定向
if (response.status >= 300 && response.status < 400) {
return response
}
}
}

return NextResponse.next()
}
17 changes: 17 additions & 0 deletions src/middlewares/oops.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

import { ROUTE } from '@/constant/route'

export function oopsMiddleware(req: NextRequest) {
const { pathname } = req.nextUrl

// 若路径为 /404,则重定向到自定义404页面
// just demo
if (pathname === '/404') {
// return NextResponse.rewrite(new URL(ROUTE.OOPS, req.url))
return NextResponse.redirect(new URL(ROUTE.OOPS, req.url))
}

return NextResponse.next()
}
Loading

0 comments on commit d651ac7

Please sign in to comment.