Compare commits
5 Commits
e96fa8f367
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ea0ebae1b | |||
| 2f2be739f2 | |||
| d1e9c2433c | |||
| f0c23cad35 | |||
| 39148bbb56 |
327
.gitignore
vendored
327
.gitignore
vendored
@@ -1,29 +1,342 @@
|
||||
# ============================================
|
||||
# Certigo Addon - Comprehensive .gitignore
|
||||
# ============================================
|
||||
|
||||
# ============================================
|
||||
# Go / Backend
|
||||
# ============================================
|
||||
|
||||
# Binaries and executables
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
backend/bin/
|
||||
backend/myapp
|
||||
backend/certigo-addon
|
||||
backend/certigo-addon-*
|
||||
/tmp/certigo-addon-*
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool
|
||||
*.out
|
||||
coverage.html
|
||||
coverage.txt
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
go.work.sum
|
||||
|
||||
# Go module cache (optional, but recommended for CI/CD)
|
||||
# .go/
|
||||
|
||||
# ============================================
|
||||
# Node.js / Frontend
|
||||
# ============================================
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
frontend/node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Build outputs
|
||||
dist/
|
||||
dist-ssr/
|
||||
frontend/dist/
|
||||
backend/bin/
|
||||
*.local
|
||||
|
||||
# Vite
|
||||
.vite/
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# ============================================
|
||||
# Database
|
||||
# ============================================
|
||||
|
||||
# SQLite databases
|
||||
*.db
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
backend/spaces.db
|
||||
backend/*.db
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
# Database backups
|
||||
*.sql.backup
|
||||
*.db.backup
|
||||
|
||||
# IDE
|
||||
# ============================================
|
||||
# Uploads & User-generated Content
|
||||
# ============================================
|
||||
|
||||
# User uploads (avatars, files, etc.)
|
||||
backend/uploads/
|
||||
backend/uploads/**
|
||||
!backend/uploads/.gitkeep
|
||||
frontend/public/uploads/
|
||||
|
||||
# ============================================
|
||||
# Logs
|
||||
# ============================================
|
||||
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
backend/*.log
|
||||
|
||||
# ============================================
|
||||
# IDE & Editors
|
||||
# ============================================
|
||||
|
||||
# VSCode
|
||||
.vscode/
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# IntelliJ IDEA / WebStorm
|
||||
.idea/
|
||||
*.iml
|
||||
*.iws
|
||||
*.ipr
|
||||
out/
|
||||
|
||||
# Sublime Text
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.vim/
|
||||
|
||||
# OS
|
||||
# Emacs
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# ============================================
|
||||
# OS Files
|
||||
# ============================================
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
Icon
|
||||
._*
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Windows
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
*.stackdump
|
||||
[Dd]esktop.ini
|
||||
$RECYCLE.BIN/
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
*.lnk
|
||||
|
||||
# Linux
|
||||
*~
|
||||
.fuse_hidden*
|
||||
.directory
|
||||
.Trash-*
|
||||
.nfs*
|
||||
|
||||
# ============================================
|
||||
# Temporary & Cache Files
|
||||
# ============================================
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
*.bak
|
||||
*.backup
|
||||
*.swp
|
||||
*~.nib
|
||||
*.orig
|
||||
|
||||
# Cache directories
|
||||
.cache/
|
||||
.parcel-cache/
|
||||
.eslintcache
|
||||
.stylelintcache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
.node_repl_history
|
||||
.yarn-integrity
|
||||
|
||||
# ============================================
|
||||
# Testing & Coverage
|
||||
# ============================================
|
||||
|
||||
# Test coverage
|
||||
coverage/
|
||||
*.lcov
|
||||
.nyc_output/
|
||||
.coverage/
|
||||
htmlcov/
|
||||
.pytest_cache/
|
||||
.tox/
|
||||
|
||||
# Jest
|
||||
.jest/
|
||||
|
||||
# ============================================
|
||||
# Build Tools & CI/CD
|
||||
# ============================================
|
||||
|
||||
# Build artifacts
|
||||
build/
|
||||
out/
|
||||
target/
|
||||
.next/
|
||||
.nuxt/
|
||||
.cache/
|
||||
|
||||
# CI/CD
|
||||
.github/workflows/*.yml.local
|
||||
.circleci/
|
||||
.travis.yml.local
|
||||
|
||||
# ============================================
|
||||
# Security & Secrets
|
||||
# ============================================
|
||||
|
||||
# Secrets and credentials
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.cert
|
||||
secrets/
|
||||
.secrets/
|
||||
*.secret
|
||||
config/secrets.*
|
||||
|
||||
# API keys and tokens
|
||||
.env.secret
|
||||
.env.production
|
||||
.env.staging
|
||||
|
||||
# ============================================
|
||||
# Documentation Build
|
||||
# ============================================
|
||||
|
||||
# Generated documentation
|
||||
docs/_build/
|
||||
site/
|
||||
|
||||
# ============================================
|
||||
# Misc
|
||||
# ============================================
|
||||
|
||||
# Package manager lock files (optional - uncomment if you want to ignore)
|
||||
# package-lock.json
|
||||
# yarn.lock
|
||||
# pnpm-lock.yaml
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env.development
|
||||
.env.test
|
||||
.env.production
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# ============================================
|
||||
# Project-specific
|
||||
# ============================================
|
||||
|
||||
# OpenAPI generated files (if any)
|
||||
backend/generated/
|
||||
backend/api/
|
||||
|
||||
# Provider test outputs
|
||||
backend/test-outputs/
|
||||
|
||||
# Script outputs
|
||||
backend/scripts/output/
|
||||
|
||||
# Keep directory structure but ignore contents
|
||||
!backend/uploads/.gitkeep
|
||||
!backend/config/providers/.gitkeep
|
||||
|
||||
BIN
backend/myapp
BIN
backend/myapp
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 90 KiB |
@@ -1,7 +1,8 @@
|
||||
import { useState } from 'react'
|
||||
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'
|
||||
import { AuthProvider, useAuth } from './contexts/AuthContext'
|
||||
import { PermissionsProvider, usePermissions } from './contexts/PermissionsContext'
|
||||
import { PermissionsProvider } from './contexts/PermissionsContext'
|
||||
import { usePermissions } from './hooks/usePermissions'
|
||||
import Sidebar from './components/Sidebar'
|
||||
import Footer from './components/Footer'
|
||||
import Home from './pages/Home'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useAuth } from '../contexts/AuthContext'
|
||||
import { usePermissions } from '../contexts/PermissionsContext'
|
||||
import { usePermissions } from '../hooks/usePermissions'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
const Sidebar = ({ isOpen, setIsOpen }) => {
|
||||
|
||||
1
frontend/src/hooks/usePermissions.js
Normal file
1
frontend/src/hooks/usePermissions.js
Normal file
@@ -0,0 +1 @@
|
||||
export { usePermissions } from '../contexts/PermissionsContext'
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState, useRef, useCallback } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useAuth } from '../contexts/AuthContext'
|
||||
import { usePermissions } from '../contexts/PermissionsContext'
|
||||
import { usePermissions } from '../hooks/usePermissions'
|
||||
|
||||
const Home = () => {
|
||||
const { authFetch } = useAuth()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useAuth } from '../contexts/AuthContext'
|
||||
import { usePermissions } from '../contexts/PermissionsContext'
|
||||
import { usePermissions } from '../hooks/usePermissions'
|
||||
|
||||
const Profile = () => {
|
||||
const { authFetch, user } = useAuth()
|
||||
|
||||
@@ -232,18 +232,50 @@ const SpaceDetail = () => {
|
||||
if (response.ok) {
|
||||
const csr = await response.json()
|
||||
|
||||
// Füge den neuen CSR zur History hinzu (nur wenn der Bereich bereits geöffnet ist)
|
||||
if (showCSRDropdown[fqdn.id]) {
|
||||
const newCsrWithFqdnId = { ...csr, fqdnId: fqdn.id }
|
||||
setCsrHistory(prev => {
|
||||
const filtered = prev.filter(csrItem => csrItem.fqdnId !== fqdn.id)
|
||||
// Füge den neuen CSR am Anfang hinzu (neuester zuerst)
|
||||
return [newCsrWithFqdnId, ...filtered]
|
||||
})
|
||||
}
|
||||
|
||||
setCsrData(csr)
|
||||
setSelectedFqdn(fqdn)
|
||||
|
||||
// Lade die komplette CSR History neu, um den neuen CSR anzuzeigen
|
||||
// WICHTIG: Warte auf die History bevor der Dropdown geöffnet wird
|
||||
try {
|
||||
const historyResponse = await authFetch(`/api/spaces/${id}/fqdns/${fqdn.id}/csr`)
|
||||
if (historyResponse.ok) {
|
||||
const history = await historyResponse.json()
|
||||
|
||||
// Stelle sicher, dass history ein Array ist
|
||||
const historyArray = Array.isArray(history) ? history : []
|
||||
|
||||
// Füge fqdnId zu jedem CSR hinzu und stelle sicher dass sie immer gesetzt ist
|
||||
// Auch wenn die API fqdnId bereits zurückgibt, überschreiben wir sie mit fqdn.id für Konsistenz
|
||||
// Stelle sicher dass alle CSRs gültig sind und fqdnId gesetzt ist
|
||||
const historyWithFqdnId = historyArray
|
||||
.filter(csrItem => csrItem && csrItem.id) // Stelle sicher dass CSR gültig ist
|
||||
.map(csrItem => ({
|
||||
...csrItem,
|
||||
fqdnId: String(fqdn.id) // Immer als String für konsistente Filterung
|
||||
}))
|
||||
|
||||
setCsrHistory(prev => {
|
||||
// Entferne alte CSRs für diesen FQDN und füge die neuen hinzu
|
||||
// Verwende String-Vergleich für Robustheit
|
||||
const filtered = prev.filter(csrItem => String(csrItem?.fqdnId) !== String(fqdn.id))
|
||||
return [...filtered, ...historyWithFqdnId]
|
||||
})
|
||||
|
||||
// Öffne den CSR History Dropdown NACH dem Laden der History
|
||||
setShowCSRDropdown(prev => ({ ...prev, [fqdn.id]: true }))
|
||||
} else {
|
||||
setCsrHistory(prev => {
|
||||
// Bei Fehler, entferne nur CSRs für diesen FQDN, behalte andere
|
||||
return prev.filter(csrItem => String(csrItem?.fqdnId) !== String(fqdn.id))
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching CSR history after upload:', err)
|
||||
// Bei Fehler, entferne nur CSRs für diesen FQDN
|
||||
setCsrHistory(prev => prev.filter(csrItem => String(csrItem?.fqdnId) !== String(fqdn.id)))
|
||||
}
|
||||
|
||||
setShowCSRModal(true)
|
||||
|
||||
// Aktualisiere die FQDN-Liste
|
||||
@@ -298,14 +330,23 @@ const SpaceDetail = () => {
|
||||
const historyResponse = await authFetch(`/api/spaces/${id}/fqdns/${fqdn.id}/csr`)
|
||||
if (historyResponse.ok) {
|
||||
const history = await historyResponse.json()
|
||||
setCsrHistory(Array.isArray(history) ? history : [])
|
||||
const historyArray = Array.isArray(history) ? history : []
|
||||
// Stelle sicher dass fqdnId gesetzt ist für konsistente Filterung
|
||||
const historyWithFqdnId = historyArray
|
||||
.filter(csr => csr && csr.id)
|
||||
.map(csr => ({ ...csr, fqdnId: String(fqdn.id) }))
|
||||
setCsrHistory(prev => {
|
||||
const filtered = prev.filter(csr => String(csr?.fqdnId) !== String(fqdn.id))
|
||||
return [...filtered, ...historyWithFqdnId]
|
||||
})
|
||||
} else {
|
||||
setCsrHistory([])
|
||||
setCsrHistory(prev => prev.filter(csr => String(csr?.fqdnId) !== String(fqdn.id)))
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching CSR:', err)
|
||||
setCsrData(null)
|
||||
setCsrHistory([])
|
||||
// Entferne nur CSRs für diesen FQDN, behalte andere
|
||||
setCsrHistory(prev => prev.filter(csr => String(csr?.fqdnId) !== String(fqdn.id)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +360,7 @@ const SpaceDetail = () => {
|
||||
setSelectedFqdn(null)
|
||||
setCsrData(null)
|
||||
setCsrError('')
|
||||
setCsrHistory([])
|
||||
// csrHistory NICHT zurücksetzen - bleibt für Dropdown-Anzeige erhalten
|
||||
}
|
||||
|
||||
const handleChange = (e) => {
|
||||
@@ -822,11 +863,12 @@ const SpaceDetail = () => {
|
||||
if (response.ok) {
|
||||
const history = await response.json()
|
||||
// Speichere History mit FQDN-ID als Key
|
||||
const historyWithFqdnId = Array.isArray(history)
|
||||
? history.map(csr => ({ ...csr, fqdnId: fqdn.id }))
|
||||
: []
|
||||
const historyArray = Array.isArray(history) ? history : []
|
||||
const historyWithFqdnId = historyArray
|
||||
.filter(csr => csr && csr.id)
|
||||
.map(csr => ({ ...csr, fqdnId: String(fqdn.id) }))
|
||||
setCsrHistory(prev => {
|
||||
const filtered = prev.filter(csr => csr.fqdnId !== fqdn.id)
|
||||
const filtered = prev.filter(csr => String(csr?.fqdnId) !== String(fqdn.id))
|
||||
return [...filtered, ...historyWithFqdnId]
|
||||
})
|
||||
}
|
||||
@@ -890,12 +932,13 @@ const SpaceDetail = () => {
|
||||
<div className="border-t border-slate-600/50 bg-slate-800/50 p-4">
|
||||
<h5 className="text-sm font-semibold text-slate-300 mb-3">CSR History</h5>
|
||||
{(() => {
|
||||
// Filtere CSRs für diesen FQDN - verwende String-Vergleich für Robustheit
|
||||
const fqdnHistory = csrHistory
|
||||
.filter(csr => csr.fqdnId === fqdn.id)
|
||||
.filter(csr => csr && String(csr.fqdnId) === String(fqdn.id))
|
||||
.sort((a, b) => {
|
||||
// Sortiere nach created_at, neueste zuerst
|
||||
const dateA = new Date(a.createdAt).getTime()
|
||||
const dateB = new Date(b.createdAt).getTime()
|
||||
const dateA = a.createdAt ? new Date(a.createdAt).getTime() : 0
|
||||
const dateB = b.createdAt ? new Date(b.createdAt).getTime() : 0
|
||||
return dateB - dateA
|
||||
})
|
||||
return fqdnHistory.length > 0 ? (
|
||||
|
||||
Reference in New Issue
Block a user