Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- Introduced OAuth-based login flow with session management and CSRF protection. - Added admin panel for managing events and gallery content with real-time editing functionality. - Integrated Gitea API for saving files and updating repository content. - Updated `.env.example` to include OAuth and Gitea-related configurations. - Added example event and gallery JSON files for demonstration.
95 lines
3.1 KiB
Plaintext
95 lines
3.1 KiB
Plaintext
---
|
|
import Layout from "../../components/Layout.astro";
|
|
import eventsData from "../../content/events.json";
|
|
import imagesData from "../../content/gallery.json";
|
|
import { getSessionFromRequest } from "../../utils/session";
|
|
|
|
const session = getSessionFromRequest(Astro.request);
|
|
if (!session?.user) {
|
|
// Not logged in: redirect to OAuth login
|
|
return Astro.redirect("/api/auth/login");
|
|
}
|
|
const csrf = session.csrf;
|
|
const events = eventsData;
|
|
const images = imagesData;
|
|
---
|
|
|
|
<Layout>
|
|
<section>
|
|
<h1>Admin</h1>
|
|
<p>Eingeloggt als {session.user.login}</p>
|
|
<form id="editor">
|
|
<h2>Events (JSON)</h2>
|
|
<textarea id="events" name="events" rows="16" style="width:100%;font-family:monospace;">{JSON.stringify(events, null, 2)}</textarea>
|
|
|
|
<h2>Galerie (JSON)</h2>
|
|
<textarea id="images" name="images" rows="10" style="width:100%;font-family:monospace;">{JSON.stringify(images, null, 2)}</textarea>
|
|
|
|
<h2>Bilder hochladen</h2>
|
|
<input type="file" id="fileInput" multiple accept="image/*" />
|
|
|
|
<div style="margin-top:1rem;display:flex;gap:.5rem;">
|
|
<button id="saveBtn" type="button">Speichern</button>
|
|
<button id="logoutBtn" type="button">Logout</button>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
<meta name="csrf" content={csrf} />
|
|
<script type="module">
|
|
const csrf = document.querySelector('meta[name="csrf"]').content;
|
|
|
|
async function uploadFiles(files){
|
|
const uploads = [];
|
|
for (const file of files){
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
|
|
uploads.push({ path: `public/images/${file.name}`, content: base64 });
|
|
}
|
|
return uploads;
|
|
}
|
|
|
|
async function save(){
|
|
let events, images;
|
|
try{
|
|
events = JSON.parse(document.getElementById('events').value);
|
|
images = JSON.parse(document.getElementById('images').value);
|
|
}catch(e){
|
|
alert('JSON fehlerhaft: ' + e.message);
|
|
return;
|
|
}
|
|
|
|
const files = [
|
|
{ path: 'src/content/events.json', content: JSON.stringify(events, null, 2) },
|
|
{ path: 'src/content/gallery.json', content: JSON.stringify(images, null, 2) },
|
|
];
|
|
|
|
const input = document.getElementById('fileInput');
|
|
if (input.files && input.files.length){
|
|
const imageFiles = await uploadFiles(input.files);
|
|
files.push(...imageFiles);
|
|
}
|
|
|
|
const res = await fetch('/api/save', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json', 'X-CSRF': csrf },
|
|
body: JSON.stringify({ files, message: 'Admin-Inhalte aktualisiert' })
|
|
});
|
|
if (!res.ok){
|
|
const t = await res.text();
|
|
alert('Fehler beim Speichern: ' + t);
|
|
return;
|
|
}
|
|
alert('Gespeichert! Build wird gestartet.');
|
|
// optional: Seite neu laden
|
|
location.reload();
|
|
}
|
|
|
|
document.getElementById('saveBtn').addEventListener('click', save);
|
|
document.getElementById('logoutBtn').addEventListener('click', async () => {
|
|
await fetch('/api/auth/logout', { method: 'POST' });
|
|
location.href = '/';
|
|
});
|
|
</script>
|
|
</Layout>
|