Restrict public swarm participation and propagation to real public ICANN domains
Hop-State: A_06FP8GM0PKJTMF45B7016J0 Hop-Proposal: R_06FP8GKFXXZG84ETVCPS5ZG Hop-Task: T_06FP8F45T3G4Z4ESW9NZQQR Hop-Attempt: AT_06FP8F45T3QS81M2ZM4SJ3G
This commit is contained in:
@@ -12,6 +12,7 @@ import { upsertSwarmNode } from '@/lib/swarm/registry';
|
||||
import { buildAnnouncement } from '@/lib/swarm/discovery';
|
||||
import { verifySwarmRequest } from '@/lib/swarm/signature';
|
||||
import type { SwarmNodeInfo } from '@/lib/swarm/types';
|
||||
import { getPublicSwarmDomain, isPublicSwarmDomain } from '@/lib/swarm/node-domain';
|
||||
|
||||
const optionalUrlSchema = z.preprocess((value) => {
|
||||
if (typeof value !== 'string') {
|
||||
@@ -55,9 +56,23 @@ export async function POST(request: Request) {
|
||||
const data = signedAnnouncementSchema.parse(body);
|
||||
|
||||
const ourDomain = process.env.NEXT_PUBLIC_NODE_DOMAIN;
|
||||
|
||||
if (!isPublicSwarmDomain(ourDomain)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'This node is not configured for public swarm participation' },
|
||||
{ status: 503 }
|
||||
);
|
||||
}
|
||||
|
||||
if (!isPublicSwarmDomain(data.domain)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Swarm nodes must use a public ICANN domain' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Don't process announcements from ourselves
|
||||
if (data.domain === ourDomain) {
|
||||
if (getPublicSwarmDomain(data.domain) === getPublicSwarmDomain(ourDomain)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Cannot announce to self' },
|
||||
{ status: 400 }
|
||||
|
||||
@@ -12,6 +12,7 @@ import { processGossip } from '@/lib/swarm/gossip';
|
||||
import { markNodeSuccess } from '@/lib/swarm/registry';
|
||||
import { verifySwarmRequest } from '@/lib/swarm/signature';
|
||||
import type { SwarmGossipPayload } from '@/lib/swarm/types';
|
||||
import { getPublicSwarmDomain, isPublicSwarmDomain } from '@/lib/swarm/node-domain';
|
||||
|
||||
const handleSchema = z.object({
|
||||
handle: z.string(),
|
||||
@@ -61,9 +62,23 @@ export async function POST(request: Request) {
|
||||
const data = signedGossipSchema.parse(body);
|
||||
|
||||
const ourDomain = process.env.NEXT_PUBLIC_NODE_DOMAIN;
|
||||
|
||||
if (!isPublicSwarmDomain(ourDomain)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'This node is not configured for public swarm participation' },
|
||||
{ status: 503 }
|
||||
);
|
||||
}
|
||||
|
||||
if (!isPublicSwarmDomain(data.sender)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Swarm nodes must use a public ICANN domain' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Don't process gossip from ourselves
|
||||
if (data.sender === ourDomain) {
|
||||
if (getPublicSwarmDomain(data.sender) === getPublicSwarmDomain(ourDomain)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Cannot gossip with self' },
|
||||
{ status: 400 }
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
discoverNode,
|
||||
} from '@/lib/swarm/discovery';
|
||||
import { runGossipRound, gossipToNode } from '@/lib/swarm/gossip';
|
||||
import { isPublicSwarmDomain } from '@/lib/swarm/node-domain';
|
||||
|
||||
/**
|
||||
* GET /api/swarm/nodes
|
||||
@@ -75,6 +76,13 @@ export async function POST(request: Request) {
|
||||
const body = await request.json();
|
||||
const { action, domain, priority } = actionSchema.parse(body);
|
||||
|
||||
if (domain && !isPublicSwarmDomain(domain)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Swarm nodes must use a public ICANN domain' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'announce': {
|
||||
if (domain) {
|
||||
|
||||
Reference in New Issue
Block a user