AP6 DSGVO: Footer-Rollout, Datenschutz/Impressum, Datenexport, NeuralTest-Entfernung
- Footer-Fragment (fragments/layout :: footer) ueberall ausgerollt: 24 duplizierte Inline-Footer ersetzt, 11 bisher footerlose Seiten (Fehler-/Auth-Seiten + 8 Spielseiten) ergaenzt -> Rechtslinks von jeder Seite erreichbar. Support/Feedback von href="#" auf mailto-Platzhalter umgestellt. - Datenschutzerklaerung vervollstaendigt: NeuralNet-Messaging als Verarbeitungs- taetigkeit (Inhalte, Sender/Empfaenger, Lesebestaetigung, Loeschung via Kaskade), E-Mail-Token (SHA-256, 24h) + SMTP ueber mail.sysnaptik.de, konkrete Speicher- fristen, korrekte Drittland-/CDN-Aussage. - Impressum strukturiert: Pflichtfelder nach § 5 DDG (Name, Anschrift, Vertretung, Kontakt, MStV) als auffaellige Platzhalter (--warn). - Datenexport (Art. 20): GET /profile/export -> ProfileExportService sammelt Stammdaten, Scores, Achievements und NeuralNet-Daten (ohne Passwort) als JSON-Download; drei Repo-Query-Methoden ergaenzt. - V22-Migration: Demo-User NeuralTest entfernt (NeuralNet-Daten per Kaskade). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WFxcjtc9HNP4VECT6Ur1tE
This commit is contained in:
@@ -19,8 +19,13 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.example.mindflux.dto.WeeklyActivity;
|
||||
import com.example.mindflux.service.AvatarService;
|
||||
import com.example.mindflux.service.ProfileExportService;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
@Controller
|
||||
public class ProfileController {
|
||||
@@ -39,6 +44,9 @@ public class ProfileController {
|
||||
@Autowired
|
||||
private AvatarService avatarService;
|
||||
|
||||
@Autowired
|
||||
private ProfileExportService profileExportService;
|
||||
|
||||
@GetMapping("/profile")
|
||||
public String profile(Model model, Principal principal, @RequestParam(value = "success", required = false) Boolean success) {
|
||||
String username = principal.getName();
|
||||
@@ -73,6 +81,16 @@ public class ProfileController {
|
||||
return "settings";
|
||||
}
|
||||
|
||||
/** DSGVO-Datenexport (Art. 20): alle Kontodaten als JSON-Download. */
|
||||
@GetMapping("/profile/export")
|
||||
public ResponseEntity<Map<String, Object>> exportData(Principal principal) {
|
||||
Map<String, Object> data = profileExportService.export(principal.getName());
|
||||
return ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"mindflux-datenexport.json\"")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(data);
|
||||
}
|
||||
|
||||
@GetMapping("/profile/knowledge")
|
||||
public String knowledgeCenter(Model model, Principal principal) {
|
||||
String username = principal.getName();
|
||||
|
||||
@@ -27,6 +27,9 @@ public interface GameScoreRepository extends JpaRepository<GameScore, Long> {
|
||||
/** Alle Spielstände eines Spielers löschen (z. B. beim Löschen des Kontos). */
|
||||
void deleteByUsername(String username);
|
||||
|
||||
/** Alle Spielstände eines Spielers (für den DSGVO-Datenexport). */
|
||||
List<GameScore> findByUsernameOrderByPlayedAtDesc(String username);
|
||||
|
||||
/** Gesamtsumme aller Scores eines Spielers (XP-Basis). */
|
||||
@Query("select coalesce(sum(g.score), 0) from GameScore g where g.username = :username")
|
||||
long sumScoreByUsername(@Param("username") String username);
|
||||
|
||||
@@ -11,4 +11,6 @@ public interface NeuralNetConnectionRepository extends JpaRepository<NeuralNetCo
|
||||
List<NeuralNetConnection> acceptedFor(@Param("username") String username);
|
||||
@Query("select c from NeuralNetConnection c where c.status='ACCEPTED' and ((c.requester=:a and c.addressee=:b) or (c.requester=:b and c.addressee=:a))")
|
||||
Optional<NeuralNetConnection> acceptedBetween(@Param("a") String a, @Param("b") String b);
|
||||
@Query("select c from NeuralNetConnection c where c.requester=:u or c.addressee=:u order by c.createdAt asc")
|
||||
List<NeuralNetConnection> findAllInvolving(@Param("u") String u);
|
||||
}
|
||||
|
||||
@@ -7,4 +7,6 @@ public interface NeuralNetMessageRepository extends JpaRepository<NeuralNetMessa
|
||||
@Query("select m from NeuralNetMessage m where (m.sender=:a and m.recipient=:b) or (m.sender=:b and m.recipient=:a) order by m.sentAt asc")
|
||||
List<NeuralNetMessage> conversation(@Param("a") String a, @Param("b") String b);
|
||||
long countByRecipientAndReadAtIsNull(String recipient);
|
||||
@Query("select m from NeuralNetMessage m where m.sender=:u or m.recipient=:u order by m.sentAt asc")
|
||||
List<NeuralNetMessage> findAllInvolving(@Param("u") String u);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.example.mindflux.service;
|
||||
|
||||
import com.example.mindflux.model.Achievement;
|
||||
import com.example.mindflux.model.GameScore;
|
||||
import com.example.mindflux.model.NeuralNetConnection;
|
||||
import com.example.mindflux.model.NeuralNetMessage;
|
||||
import com.example.mindflux.model.User;
|
||||
import com.example.mindflux.repository.AchievementRepository;
|
||||
import com.example.mindflux.repository.GameScoreRepository;
|
||||
import com.example.mindflux.repository.NeuralNetConnectionRepository;
|
||||
import com.example.mindflux.repository.NeuralNetMessageRepository;
|
||||
import com.example.mindflux.repository.NeuralNetPrivacyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sammelt alle personenbezogenen Daten eines Kontos für den DSGVO-Datenexport
|
||||
* (Art. 20 – Datenübertragbarkeit). Bewusst OHNE das Passwort-Hash; nur Daten,
|
||||
* die die betroffene Person selbst erzeugt hat.
|
||||
*/
|
||||
@Service
|
||||
public class ProfileExportService {
|
||||
|
||||
private final UserService userService;
|
||||
private final GameScoreRepository scores;
|
||||
private final AchievementRepository achievements;
|
||||
private final NeuralNetPrivacyRepository privacy;
|
||||
private final NeuralNetConnectionRepository connections;
|
||||
private final NeuralNetMessageRepository messages;
|
||||
|
||||
public ProfileExportService(UserService userService, GameScoreRepository scores,
|
||||
AchievementRepository achievements, NeuralNetPrivacyRepository privacy,
|
||||
NeuralNetConnectionRepository connections, NeuralNetMessageRepository messages) {
|
||||
this.userService = userService;
|
||||
this.scores = scores;
|
||||
this.achievements = achievements;
|
||||
this.privacy = privacy;
|
||||
this.connections = connections;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public Map<String, Object> export(String username) {
|
||||
Map<String, Object> out = new LinkedHashMap<>();
|
||||
out.put("exportiertAm", LocalDateTime.now().toString());
|
||||
out.put("hinweis", "DSGVO-Datenexport (Art. 20). Enthält alle zu diesem Konto gespeicherten "
|
||||
+ "personenbezogenen Daten außer dem Passwort-Hash.");
|
||||
|
||||
User user = userService.findByUsername(username);
|
||||
Map<String, Object> account = new LinkedHashMap<>();
|
||||
if (user != null) {
|
||||
account.put("benutzername", user.getUsername());
|
||||
account.put("email", user.getEmail());
|
||||
account.put("rolle", user.getRole());
|
||||
account.put("emailBestaetigt", user.isEmailVerified());
|
||||
account.put("hatProfilbild", user.getProfilePicture() != null && !user.getProfilePicture().isBlank());
|
||||
}
|
||||
out.put("konto", account);
|
||||
|
||||
List<Map<String, Object>> scoreList = new ArrayList<>();
|
||||
for (GameScore s : scores.findByUsernameOrderByPlayedAtDesc(username)) {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("spiel", s.getGame());
|
||||
m.put("deck", s.getDeck());
|
||||
m.put("punkte", s.getScore());
|
||||
m.put("zuege", s.getMoves());
|
||||
m.put("dauerSekunden", s.getDurationSeconds());
|
||||
m.put("gespieltAm", s.getPlayedAt() != null ? s.getPlayedAt().toString() : null);
|
||||
scoreList.add(m);
|
||||
}
|
||||
out.put("spielstaende", scoreList);
|
||||
|
||||
List<Map<String, Object>> achievementList = new ArrayList<>();
|
||||
for (Achievement a : achievements.findByUsername(username)) {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("titel", a.getTitle());
|
||||
m.put("beschreibung", a.getDescription());
|
||||
m.put("erreichtAm", a.getDateAchieved() != null ? a.getDateAchieved().toString() : null);
|
||||
achievementList.add(m);
|
||||
}
|
||||
out.put("erfolge", achievementList);
|
||||
|
||||
Map<String, Object> neural = new LinkedHashMap<>();
|
||||
neural.put("nachrichtenAktiviert", privacy.findById(username).map(p -> p.isEnabled()).orElse(false));
|
||||
List<Map<String, Object>> connList = new ArrayList<>();
|
||||
for (NeuralNetConnection c : connections.findAllInvolving(username)) {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("anfragender", c.getRequester());
|
||||
m.put("empfaenger", c.getAddressee());
|
||||
m.put("status", c.getStatus());
|
||||
m.put("erstelltAm", c.getCreatedAt() != null ? c.getCreatedAt().toString() : null);
|
||||
connList.add(m);
|
||||
}
|
||||
neural.put("verbindungen", connList);
|
||||
List<Map<String, Object>> msgList = new ArrayList<>();
|
||||
for (NeuralNetMessage msg : messages.findAllInvolving(username)) {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("von", msg.getSender());
|
||||
m.put("an", msg.getRecipient());
|
||||
m.put("text", msg.getBody());
|
||||
m.put("gesendetAm", msg.getSentAt() != null ? msg.getSentAt().toString() : null);
|
||||
m.put("gelesen", msg.getReadAt() != null);
|
||||
msgList.add(m);
|
||||
}
|
||||
neural.put("nachrichten", msgList);
|
||||
out.put("neuralNet", neural);
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
-- V22: Entfernt das Demo-/Testkonto "NeuralTest" (per V17 fuer den NeuralNet-Flow
|
||||
-- geseedet) aus produktiven Datenbanken. Ein klar erkennbares Testkonto gehoert
|
||||
-- nicht in Produktion.
|
||||
--
|
||||
-- Die NeuralNet-Tabellen (neuralnet_privacy, neuralnet_connections, neuralnet_messages)
|
||||
-- referenzieren users(username) mit ON DELETE CASCADE und werden beim Loeschen des
|
||||
-- Kontos automatisch mitgeraeumt. game_scores hat keinen Fremdschluessel, daher wird
|
||||
-- ein evtl. vorhandener Spielstand des Demo-Kontos defensiv vorab entfernt.
|
||||
--
|
||||
-- Wird das Konto fuer die lokale Entwicklung gebraucht, sollte es ueber einen
|
||||
-- @Profile("dev")-gebundenen Runner neu angelegt werden, nicht per Migration.
|
||||
|
||||
DELETE FROM game_scores WHERE username = 'NeuralTest';
|
||||
DELETE FROM users WHERE username = 'NeuralTest';
|
||||
@@ -60,14 +60,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -59,14 +59,7 @@
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -99,10 +99,6 @@
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a><a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a><a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a><a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -87,10 +87,6 @@
|
||||
<p th:if="${games.isEmpty()}" class="empty">Noch keine Spiele. Lege oben das erste an.</p>
|
||||
</main>
|
||||
</div>
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a><a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a><a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a><a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -122,14 +122,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -164,14 +164,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -127,14 +127,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -126,14 +126,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -83,14 +83,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -55,14 +55,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -66,14 +66,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
<!doctype html><html lang="de" data-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>BugHunter · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/bughunter.css?v=3"><script src="/js/theme.js?v=5"></script></head><body class="bh-body"><main class="bh-app"><header class="bh-top"><div style="display:flex;align-items:center;gap:.65rem"><a href="/dashboard" class="bh-back">← Dashboard</a><a href="/bughunter" class="bh-btn">AKTENSCHRANK</a><button class="mf-theme" type="button" aria-label="Theme umschalten"></button></div><div class="bh-brand"><b>BUGHUNTER</b><span>DEBUG-FALLAKTEN</span></div><span class="mf-a11y-host"></span></header><section id="bhView" class="bh-view"><div class="bh-loading">FALLAKTEN WERDEN GEÖFFNET …</div></section></main><script src="/js/bughunter.js?v=5"></script></body></html>
|
||||
<!doctype html><html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>BugHunter · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/bughunter.css?v=3"><script src="/js/theme.js?v=5"></script></head><body class="bh-body"><main class="bh-app"><header class="bh-top"><div style="display:flex;align-items:center;gap:.65rem"><a href="/dashboard" class="bh-back">← Dashboard</a><a href="/bughunter" class="bh-btn">AKTENSCHRANK</a><button class="mf-theme" type="button" aria-label="Theme umschalten"></button></div><div class="bh-brand"><b>BUGHUNTER</b><span>DEBUG-FALLAKTEN</span></div><span class="mf-a11y-host"></span></header><section id="bhView" class="bh-view"><div class="bh-loading">FALLAKTEN WERDEN GEÖFFNET …</div></section></main><script src="/js/bughunter.js?v=5"></script> <footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body></html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
<!doctype html><html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SystemEscape · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/codeescape.css?v=2"><link rel="stylesheet" href="/css/codeescape-guide.css?v=3"><link rel="stylesheet" href="/css/codeescape-global.css?v=1"><script src="/js/theme.js?v=5"></script></head><body><main class="esc-app"><header class="esc-top"><a href="/dashboard" class="esc-back">← Dashboard</a><div class="esc-brand"><b>SYSTEMESCAPE</b><span>FACILITY ACCESS PROTOCOL</span></div><div class="esc-global-tools"><span class="mf-a11y-host"></span><div class="esc-timer" id="escTimer">--:--</div></div></header><section id="escView" class="esc-view"><div class="esc-loading">FACILITY WIRD INITIALISIERT …</div></section></main><script src="/js/codeescape.js?v=2"></script></body></html>
|
||||
<!doctype html><html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SystemEscape · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/codeescape.css?v=2"><link rel="stylesheet" href="/css/codeescape-guide.css?v=3"><link rel="stylesheet" href="/css/codeescape-global.css?v=1"><script src="/js/theme.js?v=5"></script></head><body><main class="esc-app"><header class="esc-top"><a href="/dashboard" class="esc-back">← Dashboard</a><div class="esc-brand"><b>SYSTEMESCAPE</b><span>FACILITY ACCESS PROTOCOL</span></div><div class="esc-global-tools"><span class="mf-a11y-host"></span><div class="esc-timer" id="escTimer">--:--</div></div></header><section id="escView" class="esc-view"><div class="esc-loading">FACILITY WIRD INITIALISIERT …</div></section></main><script src="/js/codeescape.js?v=2"></script> <footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body></html>
|
||||
|
||||
@@ -130,14 +130,7 @@
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
<script th:inline="none">
|
||||
const GI = {
|
||||
|
||||
@@ -83,5 +83,6 @@
|
||||
</div>
|
||||
|
||||
<script src="/js/devlabgame.js?v=3" defer></script>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -110,14 +110,7 @@
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
<script src="/js/devlab.js?v=4" defer></script>
|
||||
</body>
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" data-theme="dark">
|
||||
<html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>FinalProtocol - SysnaptiK Neural</title>
|
||||
@@ -123,14 +123,7 @@
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -25,5 +25,6 @@
|
||||
<p style="margin-top:1rem"><a href="/">Zur Anmeldung</a></p>
|
||||
</section>
|
||||
</main>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -85,8 +85,8 @@
|
||||
|
||||
<!-- ===== Footer ===== -->
|
||||
<footer class="mf-footer" th:fragment="footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="mailto:support@sysnaptik.de">Support</a>
|
||||
<a href="mailto:feedback@sysnaptik.de">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
border-radius:10px; text-align:left; margin-bottom:1.6rem; }
|
||||
.mf-cardbox .meta { color:var(--muted); font-size:.85rem; line-height:1.6; text-align:left; margin-bottom:1.6rem; }
|
||||
.mf-cardbox .mf-back { display:inline-block; }
|
||||
.mf-legal { text-align:left; margin:0 0 1.6rem; }
|
||||
.mf-legal dt { color:var(--heading); font-weight:700; font-size:.78rem; text-transform:uppercase; letter-spacing:.06em; margin-top:1rem; }
|
||||
.mf-legal dd { color:var(--text); margin:.25rem 0 0; font-size:.92rem; line-height:1.5; }
|
||||
.mf-legal dd.ph { color:var(--warn); font-style:italic; border:1px dashed color-mix(in srgb,var(--warn) 55%,var(--border)); background:color-mix(in srgb,var(--warn) 10%,transparent); border-radius:8px; padding:.45rem .65rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -27,34 +31,35 @@
|
||||
<div class="mf-cardbox">
|
||||
<div class="mf-doc">📄</div>
|
||||
<h1>Impressum</h1>
|
||||
<p class="slogan">Rechtliche Angaben – Platzhalter</p>
|
||||
<p class="slogan">Rechtliche Angaben gemäß § 5 DDG</p>
|
||||
|
||||
<p class="notice">
|
||||
SysnaptiK Neural befindet sich aktuell <strong>in aktiver Entwicklung</strong> und ist
|
||||
<strong>nicht für die öffentliche Nutzung</strong> bestimmt. Die hier dargestellten
|
||||
Inhalte sind ein Platzhalter und dienen ausschließlich internen Test- und
|
||||
Entwicklungszwecken.
|
||||
<strong>Hinweis:</strong> SysnaptiK Neural befindet sich in aktiver Entwicklung. Die folgenden
|
||||
Pflichtangaben sind bewusst als <strong>Platzhalter</strong> markiert und werden vor der
|
||||
öffentlichen Veröffentlichung mit den tatsächlichen Daten des Anbieters ausgefüllt.
|
||||
</p>
|
||||
|
||||
<p class="meta">
|
||||
Ein vollständiges Impressum gemäß den gesetzlichen Anforderungen wird vor einer
|
||||
öffentlichen Veröffentlichung ergänzt.<br>
|
||||
© 2026 Sysnaptik – Alle Rechte vorbehalten.
|
||||
</p>
|
||||
<dl class="mf-legal">
|
||||
<dt>Diensteanbieter</dt>
|
||||
<dd class="ph">[ Name bzw. Firmenbezeichnung ]</dd>
|
||||
<dt>Anschrift</dt>
|
||||
<dd class="ph">[ Straße und Hausnummer ]<br>[ PLZ und Ort ]<br>[ Land ]</dd>
|
||||
<dt>Vertreten durch</dt>
|
||||
<dd class="ph">[ vertretungsberechtigte Person ]</dd>
|
||||
<dt>Kontakt</dt>
|
||||
<dd class="ph">E-Mail: [ kontakt@sysnaptik.de ]</dd>
|
||||
<dt>Verantwortlich i. S. d. § 18 Abs. 2 MStV</dt>
|
||||
<dd class="ph">[ Name und Anschrift der verantwortlichen Person ]</dd>
|
||||
</dl>
|
||||
|
||||
<p class="meta">© 2026 Sysnaptik – Alle Rechte vorbehalten.</p>
|
||||
|
||||
<a th:href="@{/dashboard}" class="mf-back" sec:authorize="isAuthenticated()">⟵ Zurück zum Dashboard</a>
|
||||
<a th:href="@{/}" class="mf-back" sec:authorize="!isAuthenticated()">⟵ Zurück</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -133,14 +133,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,6 +38,6 @@
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="mf-footer"><a href="#">Support</a><a href="#">Feedback</a><a href="/nutzungsbedingungen">Nutzungsbedingungen</a><a href="/richtlinien">Richtlinien</a><a href="/datenschutz">Datenschutz</a><a href="/impressum">Impressum</a></footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
<tr><td>Profil</td><td>Optional hochgeladenes Profilbild (serverseitig auf max. 400 px skaliert, als JPEG gespeichert)</td></tr>
|
||||
<tr><td>Nutzungs-/Lerndaten</td><td>Spielstände (Spiel, Deck, Punktzahl, Züge, Dauer, Zeitpunkt) sowie erreichte Erfolge/Achievements</td></tr>
|
||||
<tr><td>Technische Daten</td><td>Sitzungs-Cookie zur Anmeldung, CSRF-Token; serverseitige Protokolldaten (z. B. IP-Adresse, Zeitpunkt, abgerufene Ressource) im Rahmen des technischen Betriebs</td></tr>
|
||||
<tr><td>NeuralNet-Nachrichten (nur bei Aktivierung)</td><td>Verbindungsanfragen (anfragende und empfangende Person, Status, Zeitpunkt) sowie Nachrichten (Absender, Empfänger, Nachrichteninhalt, Sende- und Lesezeitpunkt/Lesebestätigung)</td></tr>
|
||||
<tr><td>E-Mail-Bestätigung / Passwort-Reset</td><td>Bestätigungs- bzw. Reset-Token, ausschließlich als SHA-256-Hash gespeichert und 24 Stunden gültig, zur Verifizierung der E-Mail-Adresse bzw. zum Zurücksetzen des Passworts</td></tr>
|
||||
<tr><td>Anmeldeschutz</td><td>Fehlgeschlagene Anmeldeversuche (Benutzername, Zeitpunkt) zum Schutz vor automatisierten Anmeldeangriffen (Brute Force)</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>4. Zwecke und Rechtsgrundlagen</h2>
|
||||
@@ -69,6 +72,8 @@
|
||||
<li><strong>Bereitstellung des Dienstes und Kontoverwaltung</strong> (Registrierung, Anmeldung, Lernfunktionen, Spielstände, Achievements) – Art. 6 Abs. 1 lit. b DSGVO (Vertrag/Nutzungsverhältnis).</li>
|
||||
<li><strong>Technischer Betrieb, Sicherheit und Stabilität</strong> (Protokolldaten, Schutz vor Missbrauch) – Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse).</li>
|
||||
<li><strong>Profilbild</strong> – auf Grundlage der freiwilligen Bereitstellung durch die Nutzer:in.</li>
|
||||
<li><strong>NeuralNet-Community-Funktion</strong> (Verbindungsanfragen und Nachrichten) – nur nach ausdrücklicher Aktivierung (Opt-in, standardmäßig deaktiviert), Art. 6 Abs. 1 lit. a und b DSGVO. Die Funktion lässt sich jederzeit deaktivieren; beim Deaktivieren bzw. beim Löschen des Kontos werden die zugehörigen Nachrichten und Verbindungen per Datenbank-Kaskade mitgelöscht.</li>
|
||||
<li><strong>E-Mail-Verifizierung und Passwort-Zurücksetzung</strong> (Versand von Bestätigungs- und Reset-Links) – Art. 6 Abs. 1 lit. b und f DSGVO.</li>
|
||||
</ul>
|
||||
|
||||
<h2>5. Cookies</h2>
|
||||
@@ -79,12 +84,17 @@
|
||||
</p>
|
||||
|
||||
<h2>6. Speicherdauer</h2>
|
||||
<p>Wir speichern personenbezogene Daten nur so lange, wie es für den jeweiligen Zweck erforderlich ist:</p>
|
||||
<ul>
|
||||
<li><strong>Kontodaten, Spielstände, Erfolge:</strong> solange das Nutzerkonto besteht; werden bei Kontolöschung entfernt.</li>
|
||||
<li><strong>NeuralNet-Nachrichten und -Verbindungen:</strong> bis zur Löschung durch die Nutzer:in bzw. bis zur Kontolöschung (dann per Kaskade automatisch).</li>
|
||||
<li><strong>Bestätigungs- und Passwort-Reset-Token:</strong> 24 Stunden; danach automatisch ungültig und nicht mehr verwendbar.</li>
|
||||
<li><strong>Fehlgeschlagene Anmeldeversuche:</strong> nur kurzfristig für den Brute-Force-Schutz, anschließend verworfen.</li>
|
||||
<li><strong>Sitzungs-Cookie:</strong> verliert mit Ende der Sitzung bzw. der Abmeldung seine Gültigkeit.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Kontobezogene Daten werden gespeichert, solange das Nutzerkonto besteht. Nach Löschung des Kontos
|
||||
werden die zugehörigen personenbezogenen Daten gelöscht, soweit keine gesetzlichen
|
||||
Aufbewahrungspflichten entgegenstehen. Das Sitzungs-Cookie verliert mit dem Ende der Sitzung bzw.
|
||||
der Abmeldung seine Gültigkeit. Da sich der Dienst in der Entwicklung befindet, können Daten zudem
|
||||
im Rahmen von Tests zurückgesetzt werden.
|
||||
Gesetzliche Aufbewahrungspflichten bleiben unberührt. Da sich der Dienst in der Entwicklung befindet,
|
||||
können Daten zudem im Rahmen von Tests zurückgesetzt werden.
|
||||
</p>
|
||||
|
||||
<h2>6a. Lokale Einstellungen, Barrierefreiheit und NeuralPause</h2>
|
||||
@@ -102,9 +112,12 @@
|
||||
<h2>7. Empfänger und Hosting</h2>
|
||||
<p>
|
||||
Die Daten werden auf einer vom Anbieter betriebenen Server-Infrastruktur verarbeitet und nicht zu
|
||||
werblichen Zwecken an Dritte weitergegeben. Eine Übermittlung erfolgt nur, soweit dies für den
|
||||
Betrieb technisch erforderlich oder gesetzlich vorgeschrieben ist. Eine Datenübermittlung in
|
||||
Drittländer außerhalb der EU/des EWR findet nicht statt.
|
||||
werblichen Zwecken an Dritte weitergegeben. Für den Versand von Bestätigungs- und Passwort-Reset-E-Mails
|
||||
wird der Mailserver <code>mail.sysnaptik.de</code> genutzt; dabei werden E-Mail-Adresse und der jeweilige
|
||||
Link übermittelt. Alle statischen Inhalte (einschließlich der Diagramm-Bibliothek) werden ausschließlich
|
||||
von der eigenen Infrastruktur ausgeliefert – es werden keine externen Content-Delivery-Networks oder
|
||||
Drittanbieter-Skripte eingebunden. Eine Datenübermittlung in Drittländer außerhalb der EU/des EWR findet
|
||||
nicht statt.
|
||||
</p>
|
||||
|
||||
<h2>8. Datensicherheit</h2>
|
||||
@@ -134,14 +147,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -138,14 +138,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -104,14 +104,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -65,5 +65,6 @@
|
||||
</div>
|
||||
|
||||
<script src="/js/mindmatch.js?v=3" defer></script>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
<!doctype html><html lang="de" data-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>NetWorker · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/networker.css?v=2"><link rel="stylesheet" href="/css/networker-guide.css?v=1"><script src="/js/theme.js?v=5"></script></head><body class="nw-body"><main class="nw-app"><header class="nw-top"><div style="display:flex;align-items:center;gap:.65rem"><a href="/dashboard" class="nw-back">← Dashboard</a><a href="/networker" class="nw-btn">NETZPLÄNE</a><button class="mf-theme" type="button" aria-label="Theme umschalten"></button></div><div class="nw-brand"><b>NetWorker</b><span>NETZPLAN · DIAGNOSE</span></div><span class="mf-a11y-host"></span></header><section id="nwView" class="nw-view"><div class="nw-loading">NETZWERKPLÄNE WERDEN KALIBRIERT …</div></section></main><script src="/js/networker.js?v=1"></script><script src="/js/networker-guide.js?v=1"></script></body></html>
|
||||
<!doctype html><html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>NetWorker · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/networker.css?v=2"><link rel="stylesheet" href="/css/networker-guide.css?v=1"><script src="/js/theme.js?v=5"></script></head><body class="nw-body"><main class="nw-app"><header class="nw-top"><div style="display:flex;align-items:center;gap:.65rem"><a href="/dashboard" class="nw-back">← Dashboard</a><a href="/networker" class="nw-btn">NETZPLÄNE</a><button class="mf-theme" type="button" aria-label="Theme umschalten"></button></div><div class="nw-brand"><b>NetWorker</b><span>NETZPLAN · DIAGNOSE</span></div><span class="mf-a11y-host"></span></header><section id="nwView" class="nw-view"><div class="nw-loading">NETZWERKPLÄNE WERDEN KALIBRIERT …</div></section></main><script src="/js/networker.js?v=1"></script><script src="/js/networker-guide.js?v=1"></script> <footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body></html>
|
||||
|
||||
@@ -72,14 +72,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -149,14 +149,7 @@
|
||||
</script>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -29,5 +29,6 @@
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
<!doctype html><html lang="de" data-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>ServiceClash · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/serviceclash.css?v=2"><script src="/js/theme.js?v=5"></script></head><body class="sc-body"><main class="sc-app"><header class="sc-top"><div class="sc-nav"><a href="/dashboard">← Dashboard</a><a href="/serviceclash" class="sc-nav-button">SCHICHTEN</a><button class="mf-theme" type="button" aria-label="Theme umschalten"></button></div><div class="sc-brand"><b>ServiceClash</b><span>LEITSTAND · TRIAGE</span></div><span class="mf-a11y-host"></span></header><section id="scView" class="sc-view"><p class="sc-loading">LEITSTAND WIRD HOCHGEFAHREN …</p></section></main><script src="/js/serviceclash.js?v=2"></script></body></html>
|
||||
<!doctype html><html lang="de" data-theme="dark" xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>ServiceClash · SysnaptiK Neural</title><link rel="stylesheet" href="/css/theme.css?v=4"><link rel="stylesheet" href="/css/serviceclash.css?v=2"><script src="/js/theme.js?v=5"></script></head><body class="sc-body"><main class="sc-app"><header class="sc-top"><div class="sc-nav"><a href="/dashboard">← Dashboard</a><a href="/serviceclash" class="sc-nav-button">SCHICHTEN</a><button class="mf-theme" type="button" aria-label="Theme umschalten"></button></div><div class="sc-brand"><b>ServiceClash</b><span>LEITSTAND · TRIAGE</span></div><span class="mf-a11y-host"></span></header><section id="scView" class="sc-view"><p class="sc-loading">LEITSTAND WIRD HOCHGEFAHREN …</p></section></main><script src="/js/serviceclash.js?v=2"></script> <footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body></html>
|
||||
|
||||
@@ -127,14 +127,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<footer class="mf-footer">
|
||||
<a href="#">Support</a>
|
||||
<a href="#">Feedback</a>
|
||||
<a href="/nutzungsbedingungen">Nutzungsbedingungen</a>
|
||||
<a href="/richtlinien">Richtlinien</a>
|
||||
<a href="/datenschutz">Datenschutz</a>
|
||||
<a href="/impressum">Impressum</a>
|
||||
</footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -26,5 +26,5 @@
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="mf-footer"><a href="#">Support</a><a href="#">Feedback</a><a href="/nutzungsbedingungen">Nutzungsbedingungen</a><a href="/richtlinien">Richtlinien</a><a href="/datenschutz">Datenschutz</a><a href="/impressum">Impressum</a></footer>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body></html>
|
||||
|
||||
@@ -59,5 +59,6 @@
|
||||
</div>
|
||||
|
||||
<script src="/js/syntaxsaga.js?v=1" defer></script>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -77,5 +77,6 @@
|
||||
</div>
|
||||
|
||||
<script src="/js/techtacular.js?v=4" defer></script>
|
||||
<footer th:replace="~{fragments/layout :: footer}"></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user