refactor(auth): replace dashboard sessions with stateless tokens and session control (#6329)
* refactor(auth): replace dashboard sessions with stateless tokens * feat(auth): harden session issuance and distributed enforcement * fix(proxy): preserve trusted proxy compatibility defaults * refactor: address dashboard auth review feedback * refactor: remove classic frontend and flatten web app
This commit is contained in:
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright (C) 2023-2026 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { api } from '@/lib/api'
|
||||
|
||||
import type { AboutResponse } from './types'
|
||||
|
||||
export async function getAboutContent() {
|
||||
const res = await api.get<AboutResponse>('/api/about')
|
||||
return res.data
|
||||
}
|
||||
Vendored
+185
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
Copyright (C) 2023-2026 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Construction } from 'lucide-react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { PublicLayout } from '@/components/layout'
|
||||
import { RichContent } from '@/components/rich-content'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { isHttpUrl, isLikelyHtml } from '@/lib/content-format'
|
||||
|
||||
import { getAboutContent } from './api'
|
||||
|
||||
function EmptyAboutState() {
|
||||
const { t } = useTranslation()
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
return (
|
||||
<div className='flex min-h-[60vh] items-center justify-center p-8'>
|
||||
<div className='max-w-2xl space-y-6 text-center'>
|
||||
<div className='flex justify-center'>
|
||||
<Construction className='text-muted-foreground h-24 w-24' />
|
||||
</div>
|
||||
<div className='space-y-2'>
|
||||
<h2 className='text-2xl font-bold'>{t('No About Content Set')}</h2>
|
||||
<p className='text-muted-foreground'>
|
||||
{t(
|
||||
'The administrator has not configured any about content yet. You can set it in the settings page, supporting HTML or URL.'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className='space-y-4 text-sm'>
|
||||
<p>
|
||||
{t('New API Project Repository:')}{' '}
|
||||
<a
|
||||
href='https://github.com/QuantumNous/new-api'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-primary hover:underline'
|
||||
>
|
||||
{t('https://github.com/QuantumNous/new-api')}
|
||||
</a>
|
||||
</p>
|
||||
<p className='text-muted-foreground'>
|
||||
<a
|
||||
href='https://github.com/QuantumNous/new-api'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-primary hover:underline'
|
||||
>
|
||||
{t('NewAPI')}
|
||||
</a>{' '}
|
||||
© {currentYear}{' '}
|
||||
<a
|
||||
href='https://github.com/QuantumNous'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-primary hover:underline'
|
||||
>
|
||||
{t('QuantumNous')}
|
||||
</a>{' '}
|
||||
{t('| Based on')}{' '}
|
||||
<a
|
||||
href='https://github.com/songquanpeng/one-api'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-primary hover:underline'
|
||||
>
|
||||
{t('One API')}
|
||||
</a>{' '}
|
||||
© 2023{' '}
|
||||
<a
|
||||
href='https://github.com/songquanpeng'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-primary hover:underline'
|
||||
>
|
||||
{t('JustSong')}
|
||||
</a>
|
||||
</p>
|
||||
<p className='text-muted-foreground'>
|
||||
{t('This project must be used in compliance with the')}{' '}
|
||||
<a
|
||||
href='https://github.com/QuantumNous/new-api/blob/main/LICENSE'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-primary hover:underline'
|
||||
>
|
||||
{t('AGPL v3.0 License')}
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function About() {
|
||||
const { t } = useTranslation()
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['about-content'],
|
||||
queryFn: getAboutContent,
|
||||
})
|
||||
|
||||
const rawContent = data?.data?.trim() ?? ''
|
||||
const hasContent = rawContent.length > 0
|
||||
const isUrl = hasContent && isHttpUrl(rawContent)
|
||||
const contentIsHtml = hasContent && isLikelyHtml(rawContent)
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<PublicLayout>
|
||||
<div className='mx-auto flex max-w-4xl flex-col gap-4 py-12'>
|
||||
<Skeleton className='h-8 w-[45%]' />
|
||||
<Skeleton className='h-4 w-full' />
|
||||
<Skeleton className='h-4 w-[90%]' />
|
||||
<Skeleton className='h-4 w-[80%]' />
|
||||
</div>
|
||||
</PublicLayout>
|
||||
)
|
||||
}
|
||||
|
||||
if (!hasContent) {
|
||||
return (
|
||||
<PublicLayout>
|
||||
<EmptyAboutState />
|
||||
</PublicLayout>
|
||||
)
|
||||
}
|
||||
|
||||
if (isUrl) {
|
||||
return (
|
||||
<PublicLayout showMainContainer={false}>
|
||||
<iframe
|
||||
src={rawContent}
|
||||
className='h-[calc(100vh-3.5rem)] w-full border-0'
|
||||
title={t('About')}
|
||||
sandbox='allow-forms allow-popups allow-popups-to-escape-sandbox allow-scripts'
|
||||
/>
|
||||
</PublicLayout>
|
||||
)
|
||||
}
|
||||
|
||||
if (contentIsHtml) {
|
||||
return (
|
||||
<PublicLayout showMainContainer={false}>
|
||||
<RichContent
|
||||
mode='html'
|
||||
htmlVariant='isolated'
|
||||
content={rawContent}
|
||||
className='prose-neutral dark:prose-invert max-w-none'
|
||||
/>
|
||||
</PublicLayout>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<PublicLayout>
|
||||
<div className='mx-auto max-w-6xl px-4 py-8'>
|
||||
<RichContent
|
||||
mode='markdown'
|
||||
content={rawContent}
|
||||
className='prose-neutral dark:prose-invert max-w-none'
|
||||
/>
|
||||
</div>
|
||||
</PublicLayout>
|
||||
)
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2023-2026 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
export type AboutResponse = {
|
||||
success: boolean
|
||||
message: string
|
||||
data?: string
|
||||
}
|
||||
Reference in New Issue
Block a user