102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
|
|
import * as plugins from '../../plugins.ts';
|
||
|
|
import type { OpsServer } from '../classes.opsserver.ts';
|
||
|
|
import * as interfaces from '../../../ts_interfaces/index.ts';
|
||
|
|
import { requireValidIdentity } from '../helpers/guards.ts';
|
||
|
|
|
||
|
|
export class DomainsHandler {
|
||
|
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||
|
|
|
||
|
|
constructor(private opsServerRef: OpsServer) {
|
||
|
|
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
||
|
|
this.registerHandlers();
|
||
|
|
}
|
||
|
|
|
||
|
|
private buildDomainViews(): interfaces.data.IDomainDetail[] {
|
||
|
|
const domains = this.opsServerRef.oneboxRef.database.getAllDomains();
|
||
|
|
const allServices = this.opsServerRef.oneboxRef.database.getAllServices();
|
||
|
|
|
||
|
|
return domains.map((domain: any) => {
|
||
|
|
const certificates = this.opsServerRef.oneboxRef.database.getCertificatesByDomain(domain.id!);
|
||
|
|
const requirements = this.opsServerRef.oneboxRef.database.getCertRequirementsByDomain(domain.id!);
|
||
|
|
|
||
|
|
const serviceCount = allServices.filter((service: any) => {
|
||
|
|
if (!service.domain) return false;
|
||
|
|
const baseDomain = service.domain.split('.').slice(-2).join('.');
|
||
|
|
return baseDomain === domain.domain;
|
||
|
|
}).length;
|
||
|
|
|
||
|
|
let certificateStatus: 'valid' | 'expiring-soon' | 'expired' | 'pending' | 'none' = 'none';
|
||
|
|
let daysRemaining: number | null = null;
|
||
|
|
|
||
|
|
const validCerts = certificates.filter((cert: any) => cert.isValid && cert.expiryDate > Date.now());
|
||
|
|
if (validCerts.length > 0) {
|
||
|
|
const latestCert = validCerts.reduce((latest: any, cert: any) =>
|
||
|
|
cert.expiryDate > latest.expiryDate ? cert : latest
|
||
|
|
);
|
||
|
|
daysRemaining = Math.floor((latestCert.expiryDate - Date.now()) / (24 * 60 * 60 * 1000));
|
||
|
|
certificateStatus = daysRemaining <= 30 ? 'expiring-soon' : 'valid';
|
||
|
|
} else if (certificates.some((cert: any) => !cert.isValid)) {
|
||
|
|
certificateStatus = 'expired';
|
||
|
|
} else if (requirements.some((req: any) => req.status === 'pending')) {
|
||
|
|
certificateStatus = 'pending';
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
domain,
|
||
|
|
certificates,
|
||
|
|
requirements,
|
||
|
|
serviceCount,
|
||
|
|
certificateStatus,
|
||
|
|
daysRemaining,
|
||
|
|
};
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
private registerHandlers(): void {
|
||
|
|
this.typedrouter.addTypedHandler(
|
||
|
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDomains>(
|
||
|
|
'getDomains',
|
||
|
|
async (dataArg) => {
|
||
|
|
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||
|
|
const domains = this.buildDomainViews();
|
||
|
|
return { domains };
|
||
|
|
},
|
||
|
|
),
|
||
|
|
);
|
||
|
|
|
||
|
|
this.typedrouter.addTypedHandler(
|
||
|
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDomain>(
|
||
|
|
'getDomain',
|
||
|
|
async (dataArg) => {
|
||
|
|
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||
|
|
const domain = this.opsServerRef.oneboxRef.database.getDomainByName(dataArg.domainName);
|
||
|
|
if (!domain) {
|
||
|
|
throw new plugins.typedrequest.TypedResponseError('Domain not found');
|
||
|
|
}
|
||
|
|
const views = this.buildDomainViews();
|
||
|
|
const domainView = views.find((v) => v.domain.domain === dataArg.domainName);
|
||
|
|
if (!domainView) {
|
||
|
|
throw new plugins.typedrequest.TypedResponseError('Domain not found');
|
||
|
|
}
|
||
|
|
return { domain: domainView };
|
||
|
|
},
|
||
|
|
),
|
||
|
|
);
|
||
|
|
|
||
|
|
this.typedrouter.addTypedHandler(
|
||
|
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SyncDomains>(
|
||
|
|
'syncDomains',
|
||
|
|
async (dataArg) => {
|
||
|
|
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||
|
|
if (!this.opsServerRef.oneboxRef.cloudflareDomainSync) {
|
||
|
|
throw new plugins.typedrequest.TypedResponseError('Cloudflare domain sync not configured');
|
||
|
|
}
|
||
|
|
await this.opsServerRef.oneboxRef.cloudflareDomainSync.syncZones();
|
||
|
|
const domains = this.buildDomainViews();
|
||
|
|
return { domains };
|
||
|
|
},
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|