Merge remote-tracking branch 'upstream/main'
commit
5b5b96943c
|
|
@ -1,3 +1,32 @@
|
|||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
}
|
||||
"extends": "next/core-web-vitals",
|
||||
"rules": {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"patterns": [
|
||||
{
|
||||
"group": [
|
||||
"**/uptime.config"
|
||||
],
|
||||
"importNames": [
|
||||
"workerConfig"
|
||||
],
|
||||
"message": "Do not import workerConfig in client-bundled files. See https://github.com/lyc8503/UptimeFlare/issues/198 for details."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"pages/api/data.ts",
|
||||
"middleware.ts"
|
||||
],
|
||||
"rules": {
|
||||
"no-restricted-imports": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
A more advanced, serverless, and free uptime monitoring & status page solution, powered by Cloudflare Workers, complete with a user-friendly interface.
|
||||
|
||||
📢 **[[SECURITY ADVISORY](https://github.com/lyc8503/UptimeFlare/security/advisories/GHSA-36q9-v7p3-vj6v) 2026/03/04]** A vulnerability (CVE-2026-29779) that could expose monitor configuration and credentials in `uptime.config.ts` to clients was fixed. Versions between 2025-09-21 (from commit `41257c6`) and 2026-03-04 are affected. **Affected users are strongly advised to upgrade to the latest version.**
|
||||
|
||||
🎉 **[UPDATE 2026/01/03]** I have just migrated UptimeFlare from KV to D1 Database. I also updated the Terraform Cloudflare provider to v5 and improved the deployment process. The data structure has been optimized to resolve long-standing performance issues.
|
||||
|
||||
New users can deploy directly, while existing users can have a simple auto migration process (upgrade docs below)! Feel free to open an issue if you run into any trouble deploying.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"Incidents": "Vorfälle",
|
||||
"No data yet": "Noch keine Daten",
|
||||
"All systems not operational": "Nicht alle Systeme funktionsfähig",
|
||||
"All systems operational": "Alle Systeme funktionsfähig",
|
||||
"Some systems not operational": "Manche Systeme sind nicht funktionsfähig ({{down}} von {{total}})",
|
||||
"Last updated on": "Letzte Aktualisierung: {{date}} (vor {{seconds}} Sekunden)",
|
||||
"upcoming maintenance": "{{count}} anstehende Wartung",
|
||||
"upcoming maintenance_plural": "{{count}} anstehende Wartungen",
|
||||
"Hide": "[verstecken]",
|
||||
"Show": "[zeigen]",
|
||||
"Operational": "Funktionsfähig",
|
||||
"No data available": "Keine Daten verfügbar, stelle sicher dass der Worker mit der letzten Config-Version deployed wurde und prüfe den Worker-Status!",
|
||||
"Overall": "Gesamt: {{percent}}%",
|
||||
"No Data": "Keine Daten",
|
||||
"percent at date": "{{percent}}% am {{date}}",
|
||||
"Down for": "Ausfall für {{duration}} (Klick für Details)",
|
||||
"incidents at": "🚨 {{name}} Vorfall am {{date}}",
|
||||
"Response times": "Antwortzeiten (ms)",
|
||||
"Upcoming": "[Geplant] ",
|
||||
"Scheduled Maintenance": "Geplante Wartung",
|
||||
"Scheduled for": "Geplant für:",
|
||||
"From": "Von:",
|
||||
"Expected end": "Voraussichtliches Ende:",
|
||||
"To": "Bis:",
|
||||
"Until further notice": "Bis auf Weiteres",
|
||||
"Affected components": "Betroffene Komponenten:",
|
||||
"MONITOR ID NOT FOUND": "[ERR: MONITOR ID NICHT GEFUNDEN]",
|
||||
"No incidents in this month": "Keine Vorfälle diesen Monat",
|
||||
"There are no incidents for this month": "Es gibt keine Vorfälle diesen Monat.",
|
||||
"Monitor not found": "Monitor mit ID {{id}} nicht gefunden!",
|
||||
"Monitor State not defined": "Monitor-Status ist nicht definiert. Prüfe den Worker-Status und das Binding!",
|
||||
"All": "Alle",
|
||||
"Select monitor": "Auswählen",
|
||||
"Backwards": "← Zurück",
|
||||
"Forward": "Vorwärts →"
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"Incidents": "Incidents",
|
||||
"No data yet": "Aucune donnée pour le moment",
|
||||
"All systems not operational": "Aucun système n'est opérationnel",
|
||||
"All systems operational": "Tous les systèmes sont opérationnels",
|
||||
"Some systems not operational": "Certains systèmes ne fonctionnent pas ({{down}} sur {{total}})",
|
||||
"Last updated on": "Dernière actualisation : {{date}} (il y a {{seconds}} secondes)",
|
||||
"upcoming maintenance": "{{count}} maintenance à venir",
|
||||
"upcoming maintenance_plural": "{{count}} maintenances à venir",
|
||||
"Hide": "[Masquer]",
|
||||
"Show": "[Afficher]",
|
||||
"Operational": "Opérationnel",
|
||||
"No data available": "Aucune donnée disponible. Veuillez vous assurer d'avoir déployé vos workers avec la dernière configuration et vérifiez leur statut !",
|
||||
"Overall": "Moyenne : {{percent}}%",
|
||||
"No Data": "Aucune donnée",
|
||||
"percent at date": "{{percent}}% le {{date}}",
|
||||
"Down for": "Interruption de {{duration}} (cliquez pour plus de détails)",
|
||||
"incidents at": "🚨 Incidents sur {{name}} le {{date}}",
|
||||
"Response times": "Temps de réponse (ms)",
|
||||
"Upcoming": "[À venir] ",
|
||||
"Scheduled Maintenance": "Maintenance planifiée",
|
||||
"Scheduled for": "Planifiée pour :",
|
||||
"From": "De :",
|
||||
"Expected end": "Fin prévue :",
|
||||
"To": "À :",
|
||||
"Until further notice": "Jusqu'à nouvel ordre",
|
||||
"Affected components": "Composants affectés :",
|
||||
"MONITOR ID NOT FOUND": "[ERR : ID DU MONITEUR INTROUVABLE]",
|
||||
"No incidents in this month": "Aucun incident ce mois-ci",
|
||||
"There are no incidents for this month": "Il n'y a aucun incident pour ce mois-ci.",
|
||||
"Monitor not found": "Le moniteur avec l'ID {{id}} est introuvable !",
|
||||
"Monitor State not defined": "L'état du moniteur n'est pas défini actuellement, veuillez vérifier le statut de votre worker et sa liaison !",
|
||||
"All": "Tous",
|
||||
"Select monitor": "Sélectionner un moniteur",
|
||||
"Backwards": "← Précédent",
|
||||
"Forward": "Suivant →"
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import Head from 'next/head'
|
|||
|
||||
import { Inter } from 'next/font/google'
|
||||
import { MaintenanceConfig, MonitorTarget } from '@/types/config'
|
||||
import { maintenances, pageConfig, workerConfig } from '@/uptime.config'
|
||||
import { maintenances, pageConfig } from '@/uptime.config'
|
||||
import Header from '@/components/Header'
|
||||
import { Box, Button, Center, Container, Group, Select } from '@mantine/core'
|
||||
import Footer from '@/components/Footer'
|
||||
|
|
@ -25,7 +25,8 @@ function getSelectedMonth() {
|
|||
|
||||
function filterIncidentsByMonth(
|
||||
incidents: MaintenanceConfig[],
|
||||
monthStr: string
|
||||
monthStr: string,
|
||||
monitors: MonitorTarget[]
|
||||
): (Omit<MaintenanceConfig, 'monitors'> & { monitors: MonitorTarget[] })[] {
|
||||
return incidents
|
||||
.filter((incident) => {
|
||||
|
|
@ -35,7 +36,7 @@ function filterIncidentsByMonth(
|
|||
})
|
||||
.map((e) => ({
|
||||
...e,
|
||||
monitors: (e.monitors || []).map((e) => workerConfig.monitors.find((mon) => mon.id === e)!),
|
||||
monitors: (e.monitors || []).map((e) => monitors.find((mon) => mon.id === e)!),
|
||||
}))
|
||||
.sort((a, b) => (new Date(a.start) > new Date(b.start) ? -1 : 1))
|
||||
}
|
||||
|
|
@ -53,7 +54,7 @@ function getPrevNextMonth(monthStr: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export default function IncidentsPage() {
|
||||
export default function IncidentsPage({ monitors }: { monitors: MonitorTarget[] }) {
|
||||
const { t } = useTranslation('common')
|
||||
const [selectedMonitor, setSelectedMonitor] = useState<string | null>('')
|
||||
const [selectedMonth, setSelectedMonth] = useState(getSelectedMonth())
|
||||
|
|
@ -64,7 +65,7 @@ export default function IncidentsPage() {
|
|||
return () => window.removeEventListener('hashchange', onHashChange)
|
||||
}, [])
|
||||
|
||||
const filteredIncidents = filterIncidentsByMonth(maintenances, selectedMonth)
|
||||
const filteredIncidents = filterIncidentsByMonth(maintenances, selectedMonth, monitors)
|
||||
const monitorFilteredIncidents = selectedMonitor
|
||||
? filteredIncidents.filter((i) => i.monitors.find((e) => e.id === selectedMonitor))
|
||||
: filteredIncidents
|
||||
|
|
@ -73,7 +74,7 @@ export default function IncidentsPage() {
|
|||
|
||||
const monitorOptions = [
|
||||
{ value: '', label: t('All') },
|
||||
...workerConfig.monitors.map((monitor) => ({
|
||||
...monitors.map((monitor) => ({
|
||||
value: monitor.id,
|
||||
label: monitor.name,
|
||||
})),
|
||||
|
|
@ -131,3 +132,13 @@ export default function IncidentsPage() {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getServerSideProps() {
|
||||
const { workerConfig } = await import('@/uptime.config')
|
||||
// Only present these values to client
|
||||
const monitors: MonitorTarget[] = workerConfig.monitors.map((monitor) => ({
|
||||
id: monitor.id,
|
||||
name: monitor.name,
|
||||
})) as MonitorTarget[]
|
||||
return { props: { monitors } }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import Head from 'next/head'
|
|||
|
||||
import { Inter } from 'next/font/google'
|
||||
import { MonitorTarget } from '@/types/config'
|
||||
import { maintenances, pageConfig, workerConfig } from '@/uptime.config'
|
||||
import { maintenances, pageConfig } from '@/uptime.config'
|
||||
import OverallStatus from '@/components/OverallStatus'
|
||||
import Header from '@/components/Header'
|
||||
import MonitorList from '@/components/MonitorList'
|
||||
|
|
@ -69,6 +69,7 @@ export default function Home({
|
|||
}
|
||||
|
||||
export async function getServerSideProps() {
|
||||
const { workerConfig } = await import('@/uptime.config')
|
||||
// Read state as string from storage, to avoid hitting server-side cpu time limit
|
||||
const compactedStateStr = await getFromStore(process.env as any, 'state')
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import LanguageDetector from 'i18next-browser-languagedetector'
|
|||
import en from '../locales/en/common.json'
|
||||
import zhCN from '../locales/zh-CN/common.json'
|
||||
import zhTW from '../locales/zh-TW/common.json'
|
||||
import frFR from '../locales/fr-FR/common.json'
|
||||
import deDE from '../locales/de-DE/common.json'
|
||||
|
||||
i18n
|
||||
.use(LanguageDetector)
|
||||
|
|
@ -14,6 +16,10 @@ i18n
|
|||
'zh-CN': { common: zhCN },
|
||||
zh: { common: zhCN },
|
||||
'zh-TW': { common: zhTW },
|
||||
fr: { common: frFR },
|
||||
'fr-FR': { common: frFR },
|
||||
de: { common: deDE },
|
||||
'de-DE': { common: deDE },
|
||||
},
|
||||
fallbackLng: 'en',
|
||||
interpolation: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue