Monorepo for Wisp.place. A static site hosting service built on top of the AT Protocol.

domain check api

Changed files
+71 -6
src
lib
routes
+37
src/lib/db.ts
···
return rows.length === 0;
};
+
export const isDomainRegistered = async (domain: string) => {
+
const domainLower = domain.toLowerCase().trim();
+
+
// Check wisp.place subdomains
+
const wispDomain = await db`
+
SELECT did, domain, rkey FROM domains WHERE domain = ${domainLower}
+
`;
+
+
if (wispDomain.length > 0) {
+
return {
+
registered: true,
+
type: 'wisp' as const,
+
domain: wispDomain[0].domain,
+
did: wispDomain[0].did,
+
rkey: wispDomain[0].rkey
+
};
+
}
+
+
// Check custom domains
+
const customDomain = await db`
+
SELECT id, domain, did, rkey, verified FROM custom_domains WHERE domain = ${domainLower}
+
`;
+
+
if (customDomain.length > 0) {
+
return {
+
registered: true,
+
type: 'custom' as const,
+
domain: customDomain[0].domain,
+
did: customDomain[0].did,
+
rkey: customDomain[0].rkey,
+
verified: customDomain[0].verified
+
};
+
}
+
+
return { registered: false };
+
};
+
export const claimDomain = async (did: string, handle: string): Promise<string> => {
const h = handle.trim().toLowerCase();
if (!isValidHandle(h)) throw new Error('invalid_handle');
+34 -6
src/routes/domain.ts
···
claimDomain,
getDomainByDid,
isDomainAvailable,
+
isDomainRegistered,
isValidHandle,
toDomain,
updateDomain,
···
export const domainRoutes = (client: NodeOAuthClient) =>
new Elysia({ prefix: '/api/domain' })
-
.derive(async ({ cookie }) => {
-
const auth = await requireAuth(client, cookie)
-
return { auth }
-
})
+
// Public endpoints (no auth required)
.get('/check', async ({ query }) => {
try {
const handle = (query.handle || "")
.trim()
.toLowerCase();
-
+
if (!isValidHandle(handle)) {
return {
available: false,
reason: "invalid"
};
}
-
+
const available = await isDomainAvailable(handle);
return {
available,
···
available: false
};
}
+
})
+
.get('/registered', async ({ query, set }) => {
+
try {
+
const domain = (query.domain || "").trim().toLowerCase();
+
+
if (!domain) {
+
set.status = 400;
+
return { error: 'Domain parameter required' };
+
}
+
+
const result = await isDomainRegistered(domain);
+
+
// For Caddy on-demand TLS: 200 = allow, 404 = deny
+
if (result.registered) {
+
set.status = 200;
+
return result;
+
} else {
+
set.status = 404;
+
return { registered: false };
+
}
+
} catch (err) {
+
console.error("domain/registered error", err);
+
set.status = 500;
+
return { error: 'Failed to check domain' };
+
}
+
})
+
// Authenticated endpoints (require auth)
+
.derive(async ({ cookie }) => {
+
const auth = await requireAuth(client, cookie)
+
return { auth }
})
.post('/claim', async ({ body, auth }) => {
try {