mirror of
https://git.hexahost.dev/smueller/HexaHost-Frontend.git
synced 2026-06-02 10:28:43 +00:00
Compare commits
4 Commits
f7ea36f4f2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d54cea5ec | ||
|
|
fdd0367281 | ||
|
|
ded8778b6c | ||
|
|
7a03f5aa1b |
@@ -1,9 +1,9 @@
|
|||||||
name: Release Build (dev → main)
|
name: Release Build (ci → main)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- ci
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -16,29 +16,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout (volle History)
|
- name: Checkout ci (Integration)
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
repository-url: https://git.hexahost.dev/smueller/HexaHost-Frontend
|
repository-url: https://git.hexahost.dev/smueller/HexaHost-Frontend
|
||||||
ref: dev
|
ref: ci
|
||||||
|
|
||||||
- name: Merge dev in CI-Workspace (Basis main)
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
git config user.name "gitea-actions"
|
|
||||||
git config user.email "actions@local"
|
|
||||||
git remote set-url origin "https://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}.git"
|
|
||||||
git fetch origin main dev
|
|
||||||
|
|
||||||
if git show-ref --verify --quiet refs/remotes/origin/main; then
|
|
||||||
git checkout -B main origin/main
|
|
||||||
git merge origin/dev -X theirs --no-edit -m "ci: merge dev for release build"
|
|
||||||
else
|
|
||||||
echo "main branch missing, initializing from dev"
|
|
||||||
git checkout -B main origin/dev
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
@@ -60,10 +43,20 @@ jobs:
|
|||||||
git config user.name "gitea-actions"
|
git config user.name "gitea-actions"
|
||||||
git config user.email "actions@local"
|
git config user.email "actions@local"
|
||||||
git remote set-url origin "https://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}.git"
|
git remote set-url origin "https://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}.git"
|
||||||
|
git fetch origin main ci
|
||||||
|
|
||||||
git add -A
|
git add -A
|
||||||
if git diff --cached --quiet; then
|
if git diff --cached --quiet; then
|
||||||
echo "No release changes to publish."
|
echo "No release changes to publish."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
git commit -m "chore(release): obfuscate and hash production assets [skip ci]"
|
|
||||||
git push origin main
|
TREE=$(git write-tree)
|
||||||
|
MSG="chore(release): obfuscate and hash production assets [skip ci]"
|
||||||
|
if git show-ref --verify --quiet refs/remotes/origin/main; then
|
||||||
|
PARENT=$(git rev-parse origin/main)
|
||||||
|
COMMIT=$(git commit-tree "$TREE" -p "$PARENT" -m "$MSG")
|
||||||
|
else
|
||||||
|
COMMIT=$(git commit-tree "$TREE" -m "$MSG")
|
||||||
|
fi
|
||||||
|
git push origin "${COMMIT}:refs/heads/main"
|
||||||
|
|||||||
29
.githooks/commit-msg
Normal file
29
.githooks/commit-msg
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Validiert Commit-Messages nach Conventional Commits
|
||||||
|
# https://www.conventionalcommits.org/
|
||||||
|
|
||||||
|
commit_msg_file="$1"
|
||||||
|
|
||||||
|
first_line=$(sed '/^#/d;/^$/d' "$commit_msg_file" | head -n 1)
|
||||||
|
|
||||||
|
# Merge/Revert von Git erlauben
|
||||||
|
case "$first_line" in
|
||||||
|
Merge\ *|Revert\ *)
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\([a-z0-9._-]+\))?!?: .+'
|
||||||
|
|
||||||
|
if ! printf '%s\n' "$first_line" | grep -qE "$pattern"; then
|
||||||
|
echo >&2 "❌ Commit-Message entspricht nicht Conventional Commits."
|
||||||
|
echo >&2 ""
|
||||||
|
echo >&2 " Format: type(scope): description"
|
||||||
|
echo >&2 " Beispiel: feat(products): hide vpc in navigation"
|
||||||
|
echo >&2 ""
|
||||||
|
echo >&2 " Erlaubte types: feat, fix, docs, style, refactor, perf, test, build, ci, chore"
|
||||||
|
echo >&2 " Überspringen: git commit --no-verify"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
39
.github/workflows/obfuscate-main.yml
vendored
39
.github/workflows/obfuscate-main.yml
vendored
@@ -1,10 +1,10 @@
|
|||||||
# Hinweis: Gitea nutzt .gitea/workflows/obfuscate-main.yml (identischer Ablauf).
|
# Hinweis: Gitea nutzt .gitea/workflows/obfuscate-main.yml (identischer Ablauf).
|
||||||
name: Release Build (dev → main)
|
name: Release Build (ci → main)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- ci
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -17,29 +17,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout (volle History)
|
- name: Checkout ci (Integration)
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
repository-url: https://git.hexahost.dev/smueller/HexaHost-Frontend
|
repository-url: https://git.hexahost.dev/smueller/HexaHost-Frontend
|
||||||
ref: dev
|
ref: ci
|
||||||
|
|
||||||
- name: Merge dev in CI-Workspace (Basis main)
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
git config user.name "gitea-actions"
|
|
||||||
git config user.email "actions@local"
|
|
||||||
git remote set-url origin "https://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}.git"
|
|
||||||
git fetch origin main dev
|
|
||||||
|
|
||||||
if git show-ref --verify --quiet refs/remotes/origin/main; then
|
|
||||||
git checkout -B main origin/main
|
|
||||||
git merge origin/dev -X theirs --no-edit -m "ci: merge dev for release build"
|
|
||||||
else
|
|
||||||
echo "main branch missing, initializing from dev"
|
|
||||||
git checkout -B main origin/dev
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
@@ -61,10 +44,20 @@ jobs:
|
|||||||
git config user.name "gitea-actions"
|
git config user.name "gitea-actions"
|
||||||
git config user.email "actions@local"
|
git config user.email "actions@local"
|
||||||
git remote set-url origin "https://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}.git"
|
git remote set-url origin "https://oauth2:${GITEA_TOKEN}@${GITEA_HOST}/${REPO_PATH}.git"
|
||||||
|
git fetch origin main ci
|
||||||
|
|
||||||
git add -A
|
git add -A
|
||||||
if git diff --cached --quiet; then
|
if git diff --cached --quiet; then
|
||||||
echo "No release changes to publish."
|
echo "No release changes to publish."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
git commit -m "chore(release): obfuscate and hash production assets [skip ci]"
|
|
||||||
git push origin main
|
TREE=$(git write-tree)
|
||||||
|
MSG="chore(release): obfuscate and hash production assets [skip ci]"
|
||||||
|
if git show-ref --verify --quiet refs/remotes/origin/main; then
|
||||||
|
PARENT=$(git rev-parse origin/main)
|
||||||
|
COMMIT=$(git commit-tree "$TREE" -p "$PARENT" -m "$MSG")
|
||||||
|
else
|
||||||
|
COMMIT=$(git commit-tree "$TREE" -m "$MSG")
|
||||||
|
fi
|
||||||
|
git push origin "${COMMIT}:refs/heads/main"
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,6 +13,7 @@ build/
|
|||||||
# Environment variables
|
# Environment variables
|
||||||
.env
|
.env
|
||||||
.cursorrules
|
.cursorrules
|
||||||
|
.cursor/
|
||||||
.cursorrules.txt
|
.cursorrules.txt
|
||||||
.env.local
|
.env.local
|
||||||
.env.development.local
|
.env.development.local
|
||||||
|
|||||||
16
.gitmessage
Normal file
16
.gitmessage
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Conventional Commits – nur die erste nicht-kommentierte Zeile wird verwendet
|
||||||
|
# Format: type(scope): description
|
||||||
|
#
|
||||||
|
# feat Neues Feature
|
||||||
|
# fix Bugfix
|
||||||
|
# docs Dokumentation
|
||||||
|
# style Formatierung (keine Logik)
|
||||||
|
# refactor Umbau ohne Feature/Fix
|
||||||
|
# perf Performance
|
||||||
|
# test Tests
|
||||||
|
# build Build / Dependencies
|
||||||
|
# ci CI/CD
|
||||||
|
# chore Sonstiges
|
||||||
|
#
|
||||||
|
# Beispiel (diese Zeile anpassen und Kommentare löschen oder stehen lassen):
|
||||||
|
# feat(products): hide vpc and vps in navigation
|
||||||
31
README.md
31
README.md
@@ -169,16 +169,33 @@ Für den Produktivbetrieb `public/` als Webroot konfigurieren.
|
|||||||
| Branch | Zweck |
|
| Branch | Zweck |
|
||||||
|--------|--------|
|
|--------|--------|
|
||||||
| **`dev`** | Entwicklung (lesbarer Code, Kommentare) |
|
| **`dev`** | Entwicklung (lesbarer Code, Kommentare) |
|
||||||
| **`main`** | Release/Produktion (obfuskiert, gehashte Assets) |
|
| **`ci`** | Integration (du mergst `dev` hierher) |
|
||||||
|
| **`main`** | Release/Produktion (obfuskiert, gehashte Assets — nur per Pipeline) |
|
||||||
|
|
||||||
**Workflow:** Nur auf `dev` entwickeln und pushen — **nicht** `dev` manuell nach `main` mergen.
|
**Ablauf: `dev` → `ci` → `main`**
|
||||||
|
|
||||||
Bei jedem Push auf `dev` startet `.gitea/workflows/obfuscate-main.yml`:
|
1. Auf **`dev`** entwickeln und pushen
|
||||||
|
2. **`dev` nach `ci` mergen** (manuell, z. B. in Gitea oder lokal)
|
||||||
|
3. **`ci` pushen** → startet `.gitea/workflows/obfuscate-main.yml`
|
||||||
|
4. Pipeline obfuskiert im Runner-Workspace und publiziert nach **`main`**
|
||||||
|
|
||||||
1. Checkout in temporärem Runner-Workspace
|
```powershell
|
||||||
2. `dev` in CI mit `main` mergen (`-X theirs`, dev-Inhalte bei Konflikten)
|
# Nach fertigen Änderungen auf dev:
|
||||||
3. Obfuscation-Build (`scripts/obfuscate_release.py --hash-assets`)
|
git checkout ci
|
||||||
4. Ergebnis nach `main` pushen (Bot-Commit mit `[skip ci]`)
|
git pull origin ci
|
||||||
|
git merge dev
|
||||||
|
git push origin ci
|
||||||
|
```
|
||||||
|
|
||||||
|
Bei jedem Push auf **`ci`**:
|
||||||
|
|
||||||
|
1. Checkout von `ci` im temporären Runner-Workspace
|
||||||
|
2. Obfuscation-Build (`scripts/obfuscate_release.py --hash-assets`)
|
||||||
|
3. Ergebnis nach `main` pushen (Bot-Commit mit `[skip ci]`)
|
||||||
|
|
||||||
|
**Nicht** `dev` oder `ci` direkt nach `main` mergen. Der Branch **`ci` bleibt lesbar** — Obfuscation wird nur nach `main` publiziert.
|
||||||
|
|
||||||
|
`ci`-Branch einmalig anlegen (falls noch nicht vorhanden): `git checkout -b ci dev && git push -u origin ci`
|
||||||
|
|
||||||
Der Build führt aus:
|
Der Build führt aus:
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ define('SMTP_TO_EMAIL', 'info@hexahost.de');
|
|||||||
|
|
||||||
define('ENABLE_CSRF_PROTECTION', true);
|
define('ENABLE_CSRF_PROTECTION', true);
|
||||||
define('ENABLE_RATE_LIMITING', true);
|
define('ENABLE_RATE_LIMITING', true);
|
||||||
define('MAX_REQUESTS_PER_HOUR', 10);
|
define('MAX_REQUESTS_PER_HOUR', 5);
|
||||||
|
|
||||||
|
|
||||||
define('ENABLE_SPAM_PROTECTION', true);
|
define('ENABLE_SPAM_PROTECTION', true);
|
||||||
|
|||||||
@@ -444,12 +444,45 @@ $PRODUCTS['webhosting'] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$PRODUCT_VISIBILITY = [
|
||||||
|
'vpc' => false,
|
||||||
|
'vps' => false,
|
||||||
|
'mail-gateway' => false,
|
||||||
|
'webhosting' => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function isProductVisible(string $productId): bool {
|
||||||
|
global $PRODUCT_VISIBILITY;
|
||||||
|
return $PRODUCT_VISIBILITY[$productId] ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function productHiddenAttr(string $productId): string {
|
||||||
|
return isProductVisible($productId) ? '' : ' hidden';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getVisibleProductPageIds(): array {
|
||||||
|
global $PRODUCT_VISIBILITY;
|
||||||
|
return array_keys(array_filter($PRODUCT_VISIBILITY, static fn(bool $visible): bool => $visible));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function getAllProducts() {
|
function getAllProducts() {
|
||||||
global $PRODUCTS;
|
global $PRODUCTS;
|
||||||
return $PRODUCTS;
|
return $PRODUCTS;
|
||||||
|
|||||||
@@ -15,10 +15,17 @@
|
|||||||
<div class="footer-section">
|
<div class="footer-section">
|
||||||
<h4>Produkte</h4>
|
<h4>Produkte</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/vpc">Virtual Private Container</a></li>
|
<li<?php echo productHiddenAttr('vpc'); ?>><a href="/vpc">Virtual Private Container</a></li>
|
||||||
<li><a href="/vps">Virtual Private Server</a></li>
|
<li<?php echo productHiddenAttr('vps'); ?>><a href="/vps">Virtual Private Server</a></li>
|
||||||
<li><a href="/mail-gateway">Mail Gateway</a></li>
|
<li<?php echo productHiddenAttr('mail-gateway'); ?>><a href="/mail-gateway">Mail Gateway</a></li>
|
||||||
<li><a href="/webhosting">Webhosting</a></li>
|
<li<?php echo productHiddenAttr('webhosting'); ?>><a href="/webhosting">Webhosting</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="footer-section">
|
||||||
|
<h4>Andere Dienste</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://hexadns.de" target="_blank" rel="noopener noreferrer">hexadns.de</a></li>
|
||||||
|
<li><a href="https://www.hexa-mail.de/" target="_blank" rel="noopener noreferrer">hexa-mail.de</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-section">
|
<div class="footer-section">
|
||||||
@@ -156,8 +163,8 @@
|
|||||||
</script>
|
</script>
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-EF0E9VPMTD"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-EF0E9VPMTD"></script>
|
||||||
|
|
||||||
<script src="/assets/js/main.b83bb213abc1.js" defer></script>
|
<script src="/assets/js/main.9189c38109cf.js" defer></script>
|
||||||
<script src="/assets/js/cookie-consent.6f0657b52e18.js" defer></script>
|
<script src="/assets/js/cookie-consent.91c79812d22c.js" defer></script>
|
||||||
<?php if (isset($additional_scripts)): ?>
|
<?php if (isset($additional_scripts)): ?>
|
||||||
<?php foreach ($additional_scripts as $script): ?>
|
<?php foreach ($additional_scripts as $script): ?>
|
||||||
<script src="<?php echo htmlspecialchars($script, ENT_QUOTES, 'UTF-8'); ?>" defer></script>
|
<script src="<?php echo htmlspecialchars($script, ENT_QUOTES, 'UTF-8'); ?>" defer></script>
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../config/products-config.php';
|
||||||
|
|
||||||
|
|
||||||
if (session_status() === PHP_SESSION_NONE) {
|
if (session_status() === PHP_SESSION_NONE) {
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
<!-- Main Stylesheets -->
|
<!-- Main Stylesheets -->
|
||||||
<link rel="stylesheet" href="/assets/css/style.d01979e8c871.css">
|
<link rel="stylesheet" href="/assets/css/style.d01979e8c871.css">
|
||||||
<link rel="stylesheet" href="/assets/css/custom.0bc6a878fec2.css">
|
<link rel="stylesheet" href="/assets/css/custom.d35eb3499212.css">
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Russo+One&family=Source+Sans+Pro:wght@300;400;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Russo+One&family=Source+Sans+Pro:wght@300;400;600;700&display=swap" rel="stylesheet">
|
||||||
@@ -59,12 +59,12 @@
|
|||||||
<ul class="nav-menu">
|
<ul class="nav-menu">
|
||||||
<li><a href="/" class="nav-link <?php echo ($current_page === 'home') ? 'active' : ''; ?>">Home</a></li>
|
<li><a href="/" class="nav-link <?php echo ($current_page === 'home') ? 'active' : ''; ?>">Home</a></li>
|
||||||
<li class="nav-dropdown">
|
<li class="nav-dropdown">
|
||||||
<a href="#" class="nav-link <?php echo (in_array($current_page, ['vpc', 'vps', 'mail-gateway', 'webhosting'])) ? 'active' : ''; ?>">Produkte</a>
|
<a href="#" class="nav-link <?php echo (in_array($current_page, getVisibleProductPageIds(), true)) ? 'active' : ''; ?>">Produkte</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="/vpc" class="<?php echo ($current_page === 'vpc') ? 'active' : ''; ?>">Virtual Private Container</a></li>
|
<li<?php echo productHiddenAttr('vpc'); ?>><a href="/vpc" class="<?php echo ($current_page === 'vpc') ? 'active' : ''; ?>">Virtual Private Container</a></li>
|
||||||
<li><a href="/vps" class="<?php echo ($current_page === 'vps') ? 'active' : ''; ?>">Virtual Private Server</a></li>
|
<li<?php echo productHiddenAttr('vps'); ?>><a href="/vps" class="<?php echo ($current_page === 'vps') ? 'active' : ''; ?>">Virtual Private Server</a></li>
|
||||||
<li><a href="/mail-gateway" class="<?php echo ($current_page === 'mail-gateway') ? 'active' : ''; ?>">Mail Gateway</a></li>
|
<li<?php echo productHiddenAttr('mail-gateway'); ?>><a href="/mail-gateway" class="<?php echo ($current_page === 'mail-gateway') ? 'active' : ''; ?>">Mail Gateway</a></li>
|
||||||
<li><a href="/webhosting" class="<?php echo ($current_page === 'webhosting') ? 'active' : ''; ?>">Webhosting</a></li>
|
<li<?php echo productHiddenAttr('webhosting'); ?>><a href="/webhosting" class="<?php echo ($current_page === 'webhosting') ? 'active' : ''; ?>">Webhosting</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="/it-dienstleistungen" class="nav-link <?php echo ($current_page === 'it-dienstleistungen') ? 'active' : ''; ?>">IT-Dienstleistungen</a></li>
|
<li><a href="/it-dienstleistungen" class="nav-link <?php echo ($current_page === 'it-dienstleistungen') ? 'active' : ''; ?>">IT-Dienstleistungen</a></li>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
.btn-tertiary{color:var(--text-primary);background:transparent;border:1px solid rgba(255,255,255,0.25);transition:all 0.3s ease;}.btn-tertiary:hover{border-color:var(--primary-color);color:var(--primary-color);background:rgba(255,81,249,0.08);}.it-services-actions{justify-content:center;margin-top:2rem;}.legal-hero,.legal-content{background:#ffffff;color:#000000;}.legal-hero{margin-top:70px;padding:2rem 0 1.5rem;border-bottom:1px solid #e5e5e5;}.legal-content{padding-top:2rem;}.legal-hero-title{background:none;-webkit-text-fill-color:#000000;color:#000000;margin-bottom:0.5rem;}.legal-hero-description,.legal-section h2,.legal-section h3,.legal-block p,.legal-block li,.breadcrumb,.breadcrumb span{color:#000000;}.legal-section,.legal-section.glass-card{background:transparent;border:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;border-radius:0;padding:0;}.legal-section:hover,.legal-section.glass-card:hover{transform:none;box-shadow:none;border:none;background:transparent;}.legal-content .glass-card:hover{transform:none;box-shadow:none;}.legal-section h2{border-bottom:1px solid #e5e5e5;padding-bottom:0.5rem;margin-bottom:0.8rem;}.legal-block a,.breadcrumb a{color:#0b57d0;}.legal-block a:hover,.breadcrumb a:hover{color:#0b57d0;text-decoration:none;}.legal-hero *,.legal-content *,.legal-hero *:hover,.legal-content *:hover,.legal-hero *:focus,.legal-content *:focus,.legal-hero *:active,.legal-content *:active{transform:none !important;box-shadow:none !important;text-shadow:none !important;transition:none !important;animation:none !important;}
|
|
||||||
1
public/assets/css/custom.d35eb3499212.css
Normal file
1
public/assets/css/custom.d35eb3499212.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.btn-tertiary{color:var(--text-primary);background:transparent;border:1px solid rgba(255,255,255,0.25);transition:all 0.3s ease;}.btn-tertiary:hover{border-color:var(--primary-color);color:var(--primary-color);background:rgba(255,81,249,0.08);}.it-services-actions{justify-content:center;margin-top:2rem;}.legal-hero,.legal-content{background:#ffffff;color:#000000;}.legal-hero{margin-top:70px;padding:2rem 0 1.5rem;border-bottom:1px solid #e5e5e5;}.legal-content{padding-top:2rem;}.legal-hero-title{background:none;-webkit-text-fill-color:#000000;color:#000000;margin-bottom:0.5rem;}.legal-hero-description,.legal-section h2,.legal-section h3,.legal-block p,.legal-block li,.legal-hero .breadcrumb,.legal-hero .breadcrumb span,.legal-content .breadcrumb,.legal-content .breadcrumb span{color:#000000;}.legal-section,.legal-section.glass-card{background:transparent;border:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;border-radius:0;padding:0;}.legal-section:hover,.legal-section.glass-card:hover{transform:none;box-shadow:none;border:none;background:transparent;}.legal-content .glass-card:hover{transform:none;box-shadow:none;}.legal-section h2{border-bottom:1px solid #e5e5e5;padding-bottom:0.5rem;margin-bottom:0.8rem;}.legal-block a,.legal-hero .breadcrumb a,.legal-content .breadcrumb a{color:#0b57d0;}.legal-block a:hover,.legal-hero .breadcrumb a:hover,.legal-content .breadcrumb a:hover{color:#0b57d0;text-decoration:none;}.legal-hero *,.legal-content *,.legal-hero *:hover,.legal-content *:hover,.legal-hero *:focus,.legal-content *:focus,.legal-hero *:active,.legal-content *:active{transform:none !important;box-shadow:none !important;text-shadow:none !important;transition:none !important;animation:none !important;}
|
||||||
1
public/assets/js/contact.c2399194863d.js
Normal file
1
public/assets/js/contact.c2399194863d.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/assets/js/cookie-consent.91c79812d22c.js
Normal file
1
public/assets/js/cookie-consent.91c79812d22c.js
Normal file
File diff suppressed because one or more lines are too long
1
public/assets/js/main.9189c38109cf.js
Normal file
1
public/assets/js/main.9189c38109cf.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@ $preselected_subject = getPreselectedContactSubject();
|
|||||||
$page_title = 'Kontakt - HexaHost.de | Hosting aus Niederbayern';
|
$page_title = 'Kontakt - HexaHost.de | Hosting aus Niederbayern';
|
||||||
$page_description = 'Kontaktieren Sie HexaHost.de - Ihr Hosting-Partner aus Niederbayern. Persönlicher Support und kompetente Beratung.';
|
$page_description = 'Kontaktieren Sie HexaHost.de - Ihr Hosting-Partner aus Niederbayern. Persönlicher Support und kompetente Beratung.';
|
||||||
$current_page = 'contact';
|
$current_page = 'contact';
|
||||||
$additional_scripts = ['assets/js/contact.ee450029d017.js'];
|
$additional_scripts = ['assets/js/contact.c2399194863d.js'];
|
||||||
|
|
||||||
|
|
||||||
includeHeader($page_title, $page_description, $current_page, $additional_scripts);
|
includeHeader($page_title, $page_description, $current_page, $additional_scripts);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="products-grid">
|
<div class="products-grid">
|
||||||
<div class="product-card glass-card">
|
<div class="product-card glass-card"<?php echo productHiddenAttr('vpc'); ?>>
|
||||||
<div class="product-icon">
|
<div class="product-icon">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<path d="M4 7V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v3"/>
|
<path d="M4 7V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v3"/>
|
||||||
@@ -74,7 +74,7 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
</ul>
|
</ul>
|
||||||
<a href="/vpc" class="btn btn-primary">Mehr erfahren</a>
|
<a href="/vpc" class="btn btn-primary">Mehr erfahren</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="product-card glass-card">
|
<div class="product-card glass-card"<?php echo productHiddenAttr('vps'); ?>>
|
||||||
<div class="product-icon">
|
<div class="product-icon">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
|
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
|
||||||
@@ -92,7 +92,7 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
</ul>
|
</ul>
|
||||||
<a href="/vps" class="btn btn-primary">Mehr erfahren</a>
|
<a href="/vps" class="btn btn-primary">Mehr erfahren</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="product-card glass-card">
|
<div class="product-card glass-card"<?php echo productHiddenAttr('mail-gateway'); ?>>
|
||||||
<div class="product-icon">
|
<div class="product-icon">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
|
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ Disallow: /assets/css/
|
|||||||
|
|
||||||
# Allow CSS and JS files for better SEO
|
# Allow CSS and JS files for better SEO
|
||||||
Allow: /assets/css/style.d01979e8c871.css
|
Allow: /assets/css/style.d01979e8c871.css
|
||||||
Allow: /assets/js/main.b83bb213abc1.js
|
Allow: /assets/js/main.9189c38109cf.js
|
||||||
Allow: /assets/js/contact.ee450029d017.js
|
Allow: /assets/js/contact.c2399194863d.js
|
||||||
|
|
||||||
# Sitemap location
|
# Sitemap location
|
||||||
Sitemap: https://hexahost.de/sitemap.xml
|
Sitemap: https://hexahost.de/sitemap.xml
|
||||||
|
|||||||
17
scripts/setup-git-hooks.ps1
Normal file
17
scripts/setup-git-hooks.ps1
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Einmal pro Clone ausführen: Commit-Template + Conventional-Commits-Hook aktivieren
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||||||
|
|
||||||
|
Push-Location $repoRoot
|
||||||
|
try {
|
||||||
|
git config --local commit.template .gitmessage
|
||||||
|
git config --local core.hooksPath .githooks
|
||||||
|
|
||||||
|
Write-Host "Git Hooks aktiv:" -ForegroundColor Green
|
||||||
|
Write-Host " commit.template = .gitmessage"
|
||||||
|
Write-Host " core.hooksPath = .githooks"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Commit-Format: feat(scope): beschreibung"
|
||||||
|
} finally {
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
48
scripts/test-email.php
Normal file
48
scripts/test-email.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* HexaHost.de E-Mail Test (nur CLI oder lokale Entwicklung)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (PHP_SAPI !== 'cli') {
|
||||||
|
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? '';
|
||||||
|
$isLocal = in_array($remoteAddr, ['127.0.0.1', '::1'], true)
|
||||||
|
|| filter_var($remoteAddr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false;
|
||||||
|
|
||||||
|
if (!$isLocal) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Forbidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../backend/config/mail-config.php';
|
||||||
|
|
||||||
|
function testEmail() {
|
||||||
|
$config = getHexaHostConfig();
|
||||||
|
|
||||||
|
$subject = '[HexaHost.de] Test-E-Mail';
|
||||||
|
$message = "Test-E-Mail von HexaHost.de\n\n";
|
||||||
|
$message .= "Zeitstempel: " . date('d.m.Y H:i:s') . "\n";
|
||||||
|
|
||||||
|
$headers = [
|
||||||
|
'From: ' . $config['from_name'] . ' <' . $config['from_email'] . '>',
|
||||||
|
'MIME-Version: 1.0',
|
||||||
|
'Content-Type: text/plain; charset=UTF-8',
|
||||||
|
'X-Mailer: HexaHost Test Email',
|
||||||
|
];
|
||||||
|
|
||||||
|
return mail($config['to_email'], $subject, $message, implode("\r\n", $headers));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PHP_SAPI === 'cli') {
|
||||||
|
echo testEmail() ? "Test-E-Mail gesendet.\n" : "Fehler beim Senden.\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['test'])) {
|
||||||
|
echo testEmail()
|
||||||
|
? 'Test-E-Mail wurde gesendet.'
|
||||||
|
: 'Fehler beim Senden der Test-E-Mail.';
|
||||||
|
} else {
|
||||||
|
echo '<h1>HexaHost.de E-Mail Test</h1>';
|
||||||
|
echo '<p><a href="?test=1">Test-E-Mail senden</a></p>';
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user