mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-17 17:55:42 +00:00
feat: add authentication banner
This commit is contained in:
parent
7b04d1889e
commit
5c2c74cfb4
@ -1,4 +1,4 @@
|
|||||||
import {Button, ConfigProvider, Drawer, Flex, Layout, message, theme, Typography} from 'antd'
|
import {Alert, Button, ConfigProvider, Drawer, Flex, Layout, message, theme, Typography} from 'antd'
|
||||||
import {Link, Navigate, Route, Routes, useLocation, useNavigate} from 'react-router-dom'
|
import {Link, Navigate, Route, Routes, useLocation, useNavigate} from 'react-router-dom'
|
||||||
import TextPage from './pages/TextPage'
|
import TextPage from './pages/TextPage'
|
||||||
import DomainSearchPage from './pages/search/DomainSearchPage'
|
import DomainSearchPage from './pages/search/DomainSearchPage'
|
||||||
@ -8,7 +8,7 @@ import StatisticsPage from './pages/StatisticsPage'
|
|||||||
import WatchlistPage from './pages/tracking/WatchlistPage'
|
import WatchlistPage from './pages/tracking/WatchlistPage'
|
||||||
import UserPage from './pages/UserPage'
|
import UserPage from './pages/UserPage'
|
||||||
import type {PropsWithChildren} from 'react'
|
import type {PropsWithChildren} from 'react'
|
||||||
import React, { useCallback, useEffect, useMemo, useState} from 'react'
|
import React, {useCallback, useEffect, useMemo, useState} from 'react'
|
||||||
import {getConfiguration, getUser, type InstanceConfig} from './utils/api'
|
import {getConfiguration, getUser, type InstanceConfig} from './utils/api'
|
||||||
import LoginPage from './pages/LoginPage'
|
import LoginPage from './pages/LoginPage'
|
||||||
import ConnectorPage from './pages/tracking/ConnectorPage'
|
import ConnectorPage from './pages/tracking/ConnectorPage'
|
||||||
@ -25,10 +25,15 @@ import {AuthenticatedContext, ConfigurationContext} from "./contexts"
|
|||||||
const PROJECT_LINK = 'https://github.com/maelgangloff/domain-watchdog'
|
const PROJECT_LINK = 'https://github.com/maelgangloff/domain-watchdog'
|
||||||
const LICENSE_LINK = 'https://www.gnu.org/licenses/agpl-3.0.txt'
|
const LICENSE_LINK = 'https://www.gnu.org/licenses/agpl-3.0.txt'
|
||||||
|
|
||||||
const ProjectLink = <Typography.Link key="projectLink" target='_blank' href={PROJECT_LINK}>Domain Watchdog</Typography.Link>
|
const ProjectLink = <Typography.Link key="projectLink" target='_blank' href={PROJECT_LINK}>Domain
|
||||||
const LicenseLink = <Typography.Link key="licenceLink" target='_blank' rel='license' href={LICENSE_LINK}>AGPL-3.0-or-later</Typography.Link>
|
Watchdog</Typography.Link>
|
||||||
|
const LicenseLink = <Typography.Link key="licenceLink" target='_blank' rel='license'
|
||||||
|
href={LICENSE_LINK}>AGPL-3.0-or-later</Typography.Link>
|
||||||
|
|
||||||
function SiderWrapper(props: PropsWithChildren<{sidebarCollapsed: boolean, setSidebarCollapsed: (collapsed: boolean) => void}>): React.ReactElement {
|
function SiderWrapper(props: PropsWithChildren<{
|
||||||
|
sidebarCollapsed: boolean,
|
||||||
|
setSidebarCollapsed: (collapsed: boolean) => void
|
||||||
|
}>): React.ReactElement {
|
||||||
const {sidebarCollapsed, setSidebarCollapsed, children} = props
|
const {sidebarCollapsed, setSidebarCollapsed, children} = props
|
||||||
const sm = useBreakpoint('sm')
|
const sm = useBreakpoint('sm')
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
@ -68,8 +73,7 @@ export default function App(): React.ReactElement {
|
|||||||
const sm = useBreakpoint('sm')
|
const sm = useBreakpoint('sm')
|
||||||
|
|
||||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
||||||
const [isAuthenticated, setIsAuthenticated] = useState(false)
|
const [isAuthenticated, setIsAuthenticated] = useState<boolean | undefined>(undefined)
|
||||||
|
|
||||||
const [configuration, setConfiguration] = useState<InstanceConfig | undefined>(undefined)
|
const [configuration, setConfiguration] = useState<InstanceConfig | undefined>(undefined)
|
||||||
|
|
||||||
const [darkMode, setDarkMode] = useState(false)
|
const [darkMode, setDarkMode] = useState(false)
|
||||||
@ -108,7 +112,7 @@ export default function App(): React.ReactElement {
|
|||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
setIsAuthenticated(false)
|
setIsAuthenticated(false)
|
||||||
const pathname = location.pathname
|
const pathname = location.pathname
|
||||||
if(configuration.publicRdapLookupEnabled) return navigate('/search/domain')
|
if (configuration.publicRdapLookupEnabled) return navigate('/search/domain')
|
||||||
if (!['/login', '/tos', '/faq', '/privacy'].includes(pathname)) return navigate('/home')
|
if (!['/login', '/tos', '/faq', '/privacy'].includes(pathname)) return navigate('/home')
|
||||||
})
|
})
|
||||||
}).catch(() => messageApi.error(t`Unable to contact the server, please reload the page.`))
|
}).catch(() => messageApi.error(t`Unable to contact the server, please reload the page.`))
|
||||||
@ -122,15 +126,23 @@ export default function App(): React.ReactElement {
|
|||||||
>
|
>
|
||||||
<ConfigurationContext.Provider value={configContextValue}>
|
<ConfigurationContext.Provider value={configContextValue}>
|
||||||
<AuthenticatedContext.Provider value={authContextValue}>
|
<AuthenticatedContext.Provider value={authContextValue}>
|
||||||
|
{(configuration?.registerEnabled || configuration?.ssoLogin) && isAuthenticated === false && location.pathname !== '/login' &&
|
||||||
|
<Alert
|
||||||
|
type="warning"
|
||||||
|
message={t`Please authenticate to take advantage of all features, monitor domains and manage your Connectors.`}
|
||||||
|
action={<Link to='/login'><Button>{t`Log in`}`</Button></Link>}
|
||||||
|
banner closable/>
|
||||||
|
}
|
||||||
<Layout hasSider style={{minHeight: '100vh'}}>
|
<Layout hasSider style={{minHeight: '100vh'}}>
|
||||||
<SiderWrapper sidebarCollapsed={sidebarCollapsed} setSidebarCollapsed={setSidebarCollapsed}>
|
<SiderWrapper sidebarCollapsed={sidebarCollapsed} setSidebarCollapsed={setSidebarCollapsed}>
|
||||||
<Sider />
|
<Sider/>
|
||||||
</SiderWrapper>
|
</SiderWrapper>
|
||||||
<Layout>
|
<Layout>
|
||||||
<Layout.Header style={{padding: 0}}>
|
<Layout.Header style={{padding: 0}}>
|
||||||
{sm &&
|
{sm &&
|
||||||
<Button type="text" style={{marginLeft: 8}} onClick={() => setSidebarCollapsed(!sidebarCollapsed)}>
|
<Button type="text" style={{marginLeft: 8}}
|
||||||
<MenuOutlined />
|
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}>
|
||||||
|
<MenuOutlined/>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
</Layout.Header>
|
</Layout.Header>
|
||||||
@ -142,7 +154,8 @@ export default function App(): React.ReactElement {
|
|||||||
>
|
>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path='/' element={<Navigate to={configuration?.publicRdapLookupEnabled ? '/search/domain' : '/home'}/>}/>
|
<Route path='/' element={<Navigate
|
||||||
|
to={configuration?.publicRdapLookupEnabled ? '/search/domain' : '/home'}/>}/>
|
||||||
<Route path='/home' element={<TextPage resource='home.md'/>}/>
|
<Route path='/home' element={<TextPage resource='home.md'/>}/>
|
||||||
|
|
||||||
<Route path='/search/domain' element={<DomainSearchPage/>}/>
|
<Route path='/search/domain' element={<DomainSearchPage/>}/>
|
||||||
@ -172,32 +185,24 @@ export default function App(): React.ReactElement {
|
|||||||
<Layout.Footer style={{textAlign: 'center'}}>
|
<Layout.Footer style={{textAlign: 'center'}}>
|
||||||
<Flex gap='middle' wrap justify='center'>
|
<Flex gap='middle' wrap justify='center'>
|
||||||
<Link to='/tos' rel='terms-of-service'><Button type='text'>{t`TOS`}</Button></Link>
|
<Link to='/tos' rel='terms-of-service'><Button type='text'>{t`TOS`}</Button></Link>
|
||||||
<Link to='/privacy' rel='privacy-policy'><Button type='text'>{t`Privacy Policy`}</Button></Link>
|
<Link to='/privacy' rel='privacy-policy'><Button
|
||||||
|
type='text'>{t`Privacy Policy`}</Button></Link>
|
||||||
<Link to='/faq'><Button type='text'>{t`FAQ`}</Button></Link>
|
<Link to='/faq'><Button type='text'>{t`FAQ`}</Button></Link>
|
||||||
<Typography.Link
|
<Button target='_blank'
|
||||||
target='_blank'
|
|
||||||
href='https://domainwatchdog.eu'
|
href='https://domainwatchdog.eu'
|
||||||
>
|
type='text'>
|
||||||
<Button type='text'>
|
|
||||||
{t`Documentation`}
|
{t`Documentation`}
|
||||||
</Button>
|
</Button>
|
||||||
</Typography.Link>
|
<Button target='_blank'
|
||||||
<Typography.Link
|
|
||||||
target='_blank'
|
|
||||||
href={PROJECT_LINK}
|
href={PROJECT_LINK}
|
||||||
>
|
type='text'>
|
||||||
<Button type='text'>
|
|
||||||
{t`Source code`}
|
{t`Source code`}
|
||||||
</Button>
|
</Button>
|
||||||
</Typography.Link>
|
<Button target='_blank'
|
||||||
<Typography.Link
|
|
||||||
target='_blank'
|
|
||||||
href={PROJECT_LINK + '/issues'}
|
href={PROJECT_LINK + '/issues'}
|
||||||
>
|
type='text'>
|
||||||
<Button type='text'>
|
|
||||||
{t`Submit an issue`}
|
{t`Submit an issue`}
|
||||||
</Button>
|
</Button>
|
||||||
</Typography.Link>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
<Typography.Paragraph style={{marginTop: '1em'}}>
|
<Typography.Paragraph style={{marginTop: '1em'}}>
|
||||||
{jt`${ProjectLink} is an open source project distributed under the ${LicenseLink} license.`}
|
{jt`${ProjectLink} is an open source project distributed under the ${LicenseLink} license.`}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ function getWhoisRemoveTimelineEvent(expiresInDays: number) {
|
|||||||
const locale = navigator.language.split('-')[0]
|
const locale = navigator.language.split('-')[0]
|
||||||
const sm = useBreakpoint('sm')
|
const sm = useBreakpoint('sm')
|
||||||
const eventName = t`Estimated removal`
|
const eventName = t`Estimated removal`
|
||||||
const eventDetail = t`Estimated date when the WHOIS record is removed`
|
const eventDetail = t`Estimated WHOIS removal date. This is the earliest date this record would be deleted, according to ICANN's standard lifecycle. Note that some registries have their own lifecycles.`
|
||||||
|
|
||||||
const dateStr =
|
const dateStr =
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
|
|||||||
@ -13,12 +13,12 @@ export const ConfigurationContext = createContext<ConfigurationContextType>({
|
|||||||
|
|
||||||
|
|
||||||
export type AuthContextType = {
|
export type AuthContextType = {
|
||||||
isAuthenticated: boolean
|
isAuthenticated?: boolean
|
||||||
setIsAuthenticated: React.Dispatch<React.SetStateAction<boolean>>
|
setIsAuthenticated: React.Dispatch<React.SetStateAction<boolean | undefined>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuthenticatedContext = createContext<AuthContextType>({
|
export const AuthenticatedContext = createContext<AuthContextType>({
|
||||||
isAuthenticated: false,
|
isAuthenticated: undefined,
|
||||||
setIsAuthenticated: () => {
|
setIsAuthenticated: () => {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import React, {useContext, useEffect, useState} from 'react'
|
import React, {useContext, useEffect, useState} from 'react'
|
||||||
import type {FormProps} from 'antd'
|
import type {FormProps} from 'antd'
|
||||||
import {Empty, Flex, FloatButton, message, Skeleton} from 'antd'
|
import { Empty, Flex, FloatButton, message, Skeleton} from 'antd'
|
||||||
import type {Domain, Watchlist} from '../../utils/api'
|
import type {Domain, Watchlist} from '../../utils/api'
|
||||||
import {addDomainToWatchlist, getDomain} from '../../utils/api'
|
import {addDomainToWatchlist, getDomain} from '../../utils/api'
|
||||||
import type {AxiosError} from 'axios'
|
import type {AxiosError} from 'axios'
|
||||||
|
|||||||
@ -3,35 +3,48 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||||
|
|
||||||
#: assets/App.tsx:114
|
#: assets/App.tsx:118
|
||||||
msgid "Unable to contact the server, please reload the page."
|
msgid "Unable to contact the server, please reload the page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:174
|
#: assets/App.tsx:132
|
||||||
|
msgid ""
|
||||||
|
"Please authenticate to take advantage of all features, monitor domains and "
|
||||||
|
"manage your Connectors."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: assets/App.tsx:133
|
||||||
|
#: assets/components/Sider.tsx:158
|
||||||
|
#: assets/pages/LoginPage.tsx:36
|
||||||
|
#: assets/pages/LoginPage.tsx:50
|
||||||
|
msgid "Log in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: assets/App.tsx:187
|
||||||
msgid "TOS"
|
msgid "TOS"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:175
|
#: assets/App.tsx:189
|
||||||
msgid "Privacy Policy"
|
msgid "Privacy Policy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:176
|
#: assets/App.tsx:190
|
||||||
msgid "FAQ"
|
msgid "FAQ"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:182
|
#: assets/App.tsx:194
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:190
|
#: assets/App.tsx:199
|
||||||
msgid "Source code"
|
msgid "Source code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:198
|
#: assets/App.tsx:204
|
||||||
msgid "Submit an issue"
|
msgid "Submit an issue"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/App.tsx:203
|
#: assets/App.tsx:208
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"${ ProjectLink } is an open source project distributed under the ${ "
|
"${ ProjectLink } is an open source project distributed under the ${ "
|
||||||
@ -177,7 +190,10 @@ msgid "Estimated removal"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/components/search/EventTimeline.tsx:15
|
#: assets/components/search/EventTimeline.tsx:15
|
||||||
msgid "Estimated date when the WHOIS record is removed"
|
msgid ""
|
||||||
|
"Estimated WHOIS removal date. This is the earliest date this record would "
|
||||||
|
"be deleted, according to ICANN's standard lifecycle. Note that some "
|
||||||
|
"registries have their own lifecycles."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/components/Sider.tsx:35
|
#: assets/components/Sider.tsx:35
|
||||||
@ -261,12 +277,6 @@ msgstr ""
|
|||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/components/Sider.tsx:158
|
|
||||||
#: assets/pages/LoginPage.tsx:36
|
|
||||||
#: assets/pages/LoginPage.tsx:50
|
|
||||||
msgid "Log in"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: assets/components/tracking/connector/ConnectorForm.tsx:36
|
#: assets/components/tracking/connector/ConnectorForm.tsx:36
|
||||||
#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51
|
#: assets/pages/infrastructure/IcannRegistrarPage.tsx:51
|
||||||
#: assets/utils/functions/rdapTranslation.ts:12
|
#: assets/utils/functions/rdapTranslation.ts:12
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user