Files
dcrouter/ts/opsserver/handlers/dns-provider.handler.ts

160 lines
5.9 KiB
TypeScript

import * as plugins from '../../plugins.js';
import type { OpsServer } from '../classes.opsserver.js';
import * as interfaces from '../../../ts_interfaces/index.js';
/**
* CRUD + connection-test handlers for DnsProviderDoc.
*
* Auth: same dual-mode pattern as TargetProfileHandler — admin JWT or
* API token with the appropriate `dns-providers:read|write` scope.
*/
export class DnsProviderHandler {
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 providers
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDnsProviders>(
'getDnsProviders',
async (dataArg) => {
await this.requireAuth(dataArg, 'dns-providers:read');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { providers: [] };
return { providers: await dnsManager.listProviders() };
},
),
);
// Get single provider
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDnsProvider>(
'getDnsProvider',
async (dataArg) => {
await this.requireAuth(dataArg, 'dns-providers:read');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { provider: null };
return { provider: await dnsManager.getProvider(dataArg.id) };
},
),
);
// Create provider
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateDnsProvider>(
'createDnsProvider',
async (dataArg) => {
const userId = await this.requireAuth(dataArg, 'dns-providers:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) {
return { success: false, message: 'DnsManager not initialized (DB disabled?)' };
}
const id = await dnsManager.createProvider({
name: dataArg.name,
type: dataArg.type,
credentials: dataArg.credentials,
createdBy: userId,
});
return { success: true, id };
},
),
);
// Update provider
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateDnsProvider>(
'updateDnsProvider',
async (dataArg) => {
await this.requireAuth(dataArg, 'dns-providers:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
const ok = await dnsManager.updateProvider(dataArg.id, {
name: dataArg.name,
credentials: dataArg.credentials,
});
return ok ? { success: true } : { success: false, message: 'Provider not found' };
},
),
);
// Delete provider
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteDnsProvider>(
'deleteDnsProvider',
async (dataArg) => {
await this.requireAuth(dataArg, 'dns-providers:write');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
return await dnsManager.deleteProvider(dataArg.id, dataArg.force ?? false);
},
),
);
// Test provider connection
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_TestDnsProvider>(
'testDnsProvider',
async (dataArg) => {
await this.requireAuth(dataArg, 'dns-providers:read');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) {
return { ok: false, error: 'DnsManager not initialized', testedAt: Date.now() };
}
return await dnsManager.testProvider(dataArg.id);
},
),
);
// List domains visible to a provider's account (without importing them)
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListProviderDomains>(
'listProviderDomains',
async (dataArg) => {
await this.requireAuth(dataArg, 'dns-providers:read');
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
try {
const domains = await dnsManager.listProviderDomains(dataArg.providerId);
return { success: true, domains };
} catch (err: unknown) {
return { success: false, message: (err as Error).message };
}
},
),
);
}
}