feat(protection): GET /api/protection/webcontent-domains — runtime-updatebare Layer-2-Domain-Liste
Neuer Nitro-Endpoint serviert die kuratierte Gambling-Domain-Liste pro Land (DE/GB/FR) aus backend/data/gambling-domains.json. Auth wie alle /api/protection/*-Routen (requireUser). 50-Domain-Cap pro Land serverseitig erzwungen. Liste pflegen = JSON editieren + _meta.version hochzaehlen + deploy. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
50d3c6a8e1
commit
86ed603a45
95
backend/data/gambling-domains.json
Normal file
95
backend/data/gambling-domains.json
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{
|
||||||
|
"_comment": "Kuratierte Gambling-Domain-Liste pro Land. APPLE-HARTLIMIT: max. 50 Domains pro Land-Key — NIE überschreiten. Schlüssel = ISO-3166-1-alpha-2 (Locale.current.region). Werte = registrierbare Domains ohne Schema/Subdomain (ManagedSettings WebDomain matched inkl. aller Subdomains). Pflege: Datei editieren, version hochzählen, updatedAt setzen, dann neu deployen.",
|
||||||
|
"_meta": {
|
||||||
|
"version": 1,
|
||||||
|
"updatedAt": "2026-05-21",
|
||||||
|
"maxDomainsPerCountry": 50,
|
||||||
|
"status": "starter"
|
||||||
|
},
|
||||||
|
"DE": [
|
||||||
|
"tipico.de",
|
||||||
|
"tipico.com",
|
||||||
|
"bwin.de",
|
||||||
|
"bwin.com",
|
||||||
|
"interwetten.de",
|
||||||
|
"interwetten.com",
|
||||||
|
"betano.de",
|
||||||
|
"bet-at-home.com",
|
||||||
|
"sportwetten.de",
|
||||||
|
"merkur-bets.de",
|
||||||
|
"merkurbets.de",
|
||||||
|
"happybet.de",
|
||||||
|
"neobet.de",
|
||||||
|
"winamax.de",
|
||||||
|
"betway.de",
|
||||||
|
"admiralbet.de",
|
||||||
|
"oddset.de",
|
||||||
|
"lottohelden.de",
|
||||||
|
"lotto.de",
|
||||||
|
"lotto24.de",
|
||||||
|
"jackpot.de",
|
||||||
|
"drueckglueck.de",
|
||||||
|
"loewen-play.de",
|
||||||
|
"merkur24.com",
|
||||||
|
"casino.de",
|
||||||
|
"casinos.de",
|
||||||
|
"betsson.de",
|
||||||
|
"leovegas.de",
|
||||||
|
"lapalingo.com",
|
||||||
|
"sunmaker.de"
|
||||||
|
],
|
||||||
|
"GB": [
|
||||||
|
"bet365.com",
|
||||||
|
"williamhill.com",
|
||||||
|
"skybet.com",
|
||||||
|
"skyvegas.com",
|
||||||
|
"ladbrokes.com",
|
||||||
|
"coral.co.uk",
|
||||||
|
"paddypower.com",
|
||||||
|
"betfair.com",
|
||||||
|
"betfred.com",
|
||||||
|
"unibet.co.uk",
|
||||||
|
"888.com",
|
||||||
|
"888sport.com",
|
||||||
|
"888casino.com",
|
||||||
|
"betway.com",
|
||||||
|
"virginbet.com",
|
||||||
|
"boylesports.com",
|
||||||
|
"betvictor.com",
|
||||||
|
"10bet.com",
|
||||||
|
"mrgreen.com",
|
||||||
|
"casumo.com",
|
||||||
|
"leovegas.com",
|
||||||
|
"grosvenorcasinos.com",
|
||||||
|
"mecca-bingo.com",
|
||||||
|
"gala-bingo.com",
|
||||||
|
"tombola.co.uk",
|
||||||
|
"lottoland.co.uk",
|
||||||
|
"national-lottery.co.uk",
|
||||||
|
"kwikfit-pools.co.uk",
|
||||||
|
"parimatch.co.uk",
|
||||||
|
"smarkets.com"
|
||||||
|
],
|
||||||
|
"FR": [
|
||||||
|
"winamax.fr",
|
||||||
|
"betclic.fr",
|
||||||
|
"betclic.com",
|
||||||
|
"pmu.fr",
|
||||||
|
"unibet.fr",
|
||||||
|
"parionssport.fdj.fr",
|
||||||
|
"fdj.fr",
|
||||||
|
"zebet.fr",
|
||||||
|
"vbet.fr",
|
||||||
|
"netbet.fr",
|
||||||
|
"bwin.fr",
|
||||||
|
"genybet.fr",
|
||||||
|
"zeturf.fr",
|
||||||
|
"feeling-bet.fr",
|
||||||
|
"barrierebet.fr",
|
||||||
|
"pokerstars.fr",
|
||||||
|
"partypoker.fr",
|
||||||
|
"lucien-barriere.com",
|
||||||
|
"casinobarriere.com",
|
||||||
|
"circus.be"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -12,6 +12,13 @@ export default defineNitroConfig({
|
|||||||
{ baseURL: "/", dir: "../public", maxAge: 60 * 60 },
|
{ baseURL: "/", dir: "../public", maxAge: 60 * 60 },
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Server-Assets: werden ins Build-Artifact gebundelt und sind via
|
||||||
|
// useStorage('assets:server') abrufbar. Kein process.cwd()-Trick nötig.
|
||||||
|
// gambling-domains.json: runtime-updatebare iOS-Layer-2-Domain-Liste.
|
||||||
|
serverAssets: [
|
||||||
|
{ baseName: "data", dir: "../data" },
|
||||||
|
],
|
||||||
|
|
||||||
// Supabase als external dep — nicht bundlen
|
// Supabase als external dep — nicht bundlen
|
||||||
externals: {
|
externals: {
|
||||||
inline: [/^(?!@supabase\/supabase-js)/],
|
inline: [/^(?!@supabase\/supabase-js)/],
|
||||||
|
|||||||
55
backend/server/api/protection/webcontent-domains.get.ts
Normal file
55
backend/server/api/protection/webcontent-domains.get.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { requireUser } from "../../utils/auth";
|
||||||
|
|
||||||
|
const MAX_DOMAINS_PER_COUNTRY = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/protection/webcontent-domains
|
||||||
|
*
|
||||||
|
* Liefert die runtime-updatebare iOS-Layer-2-Gambling-Domain-Liste.
|
||||||
|
* Datenquelle: backend/data/gambling-domains.json (file-based, v1).
|
||||||
|
* Im Build über Nitro serverAssets gebundelt → kein process.cwd()-Trick.
|
||||||
|
*
|
||||||
|
* Pflege: backend/data/gambling-domains.json editieren,
|
||||||
|
* _meta.version hochzählen, _meta.updatedAt setzen, dann neu deployen.
|
||||||
|
*
|
||||||
|
* Apple-Hartlimit: max. 50 Domains pro Land-Key. Wird serverseitig
|
||||||
|
* enforced (slice), damit ein versehentlicher Überschuss in der JSON-Datei
|
||||||
|
* nie zur App durchdringt.
|
||||||
|
*
|
||||||
|
* Auth: identisch zu allen anderen /api/protection/*-Routen (requireUser).
|
||||||
|
*/
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
await requireUser(event);
|
||||||
|
|
||||||
|
const storage = useStorage("assets:server");
|
||||||
|
const raw = await storage.getItem<{
|
||||||
|
_meta: { version: number; updatedAt: string; [k: string]: unknown };
|
||||||
|
_comment?: string;
|
||||||
|
[country: string]: unknown;
|
||||||
|
}>("data:gambling-domains.json");
|
||||||
|
|
||||||
|
if (!raw) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
message: "GAMBLING_DOMAINS_UNAVAILABLE",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { _meta, _comment: _c, ...countryEntries } = raw;
|
||||||
|
|
||||||
|
const countries: Record<string, string[]> = {};
|
||||||
|
for (const [key, value] of Object.entries(countryEntries)) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
// Apple-Hartlimit: niemals mehr als 50 Domains pro Land ausliefern
|
||||||
|
countries[key] = (value as string[]).slice(0, MAX_DOMAINS_PER_COUNTRY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
_meta: {
|
||||||
|
version: _meta.version,
|
||||||
|
updatedAt: _meta.updatedAt,
|
||||||
|
},
|
||||||
|
...countries,
|
||||||
|
};
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user