Files
dcrouter/ts/opsserver/handlers/domain.handler.ts

162 lines
5.9 KiB
TypeScript
Raw Normal View History

import * as plugins from '../../plugins.js';
import type { OpsServer } from '../classes.opsserver.js';
import * as interfaces from '../../../ts_interfaces/index.js';
/**
* CRUD handlers for DomainDoc.
*/
export class DomainHandler {
public typedrouter = new plugins.typedrequest.TypedRouter();
constructor(private opsServerRef: OpsServer) {
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
this.registerHandlers();
}
private async requireAuth(
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
requiredScope?: interfaces.data.TApiTokenScope,
): Promise<string> {
if (request.identity?.jwt) {
try {
const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
identity: request.identity,
});
if (isAdmin) return request.identity.userId;
} catch { /* fall through */ }
}
if (request.apiToken) {
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
if (tokenManager) {
const token = await tokenManager.validateToken(request.apiToken);
if (token) {
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
return token.createdBy;
}
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
}
}
}
throw new plugins.typedrequest.TypedResponseError('unauthorized');
}
private registerHandlers(): void {
// Get all domains
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDomains>(
'getDomains',
async (dataArg) => {
await this.requireAuth(dataArg, 'domains:read');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { domains: [] };
const docs = await dnsManager.listDomains();
return { domains: docs.map((d) => dnsManager.toPublicDomain(d)) };
},
),
);
// Get single domain
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDomain>(
'getDomain',
async (dataArg) => {
await this.requireAuth(dataArg, 'domains:read');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { domain: null };
const doc = await dnsManager.getDomain(dataArg.id);
return { domain: doc ? dnsManager.toPublicDomain(doc) : null };
},
),
);
// Create dcrouter-hosted domain
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateDomain>(
'createDomain',
async (dataArg) => {
const userId = await this.requireAuth(dataArg, 'domains:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
try {
const id = await dnsManager.createDcrouterDomain({
name: dataArg.name,
description: dataArg.description,
createdBy: userId,
});
return { success: true, id };
} catch (err: unknown) {
return { success: false, message: (err as Error).message };
}
},
),
);
// Import domains from a provider
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ImportDomain>(
'importDomain',
async (dataArg) => {
const userId = await this.requireAuth(dataArg, 'domains:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
try {
const importedIds = await dnsManager.importDomainsFromProvider({
providerId: dataArg.providerId,
domainNames: dataArg.domainNames,
createdBy: userId,
});
return { success: true, importedIds };
} catch (err: unknown) {
return { success: false, message: (err as Error).message };
}
},
),
);
// Update domain metadata
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateDomain>(
'updateDomain',
async (dataArg) => {
await this.requireAuth(dataArg, 'domains:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
const ok = await dnsManager.updateDomain(dataArg.id, {
description: dataArg.description,
});
return ok ? { success: true } : { success: false, message: 'Domain not found' };
},
),
);
// Delete domain
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteDomain>(
'deleteDomain',
async (dataArg) => {
await this.requireAuth(dataArg, 'domains:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
const ok = await dnsManager.deleteDomain(dataArg.id);
return ok ? { success: true } : { success: false, message: 'Domain not found' };
},
),
);
// Force-resync provider domain
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SyncDomain>(
'syncDomain',
async (dataArg) => {
await this.requireAuth(dataArg, 'domains:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
return await dnsManager.syncDomain(dataArg.id);
},
),
);
}
}