68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import {
|
|
Injectable,
|
|
NestInterceptor,
|
|
ExecutionContext,
|
|
CallHandler,
|
|
HttpException,
|
|
} from '@nestjs/common';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { Request, Response } from 'express';
|
|
import { resolve } from 'path';
|
|
import { from, Observable, of } from 'rxjs';
|
|
import { switchMap } from 'rxjs/operators';
|
|
import { DNSCacheService } from 'src/modules/objects/dns/dns-cache.service';
|
|
import { DatabaseService } from 'src/modules/objects/database/database.service';
|
|
import { CachedZone } from 'src/types/dns.interfaces';
|
|
|
|
@Injectable()
|
|
export class DomainInterceptor implements NestInterceptor {
|
|
constructor(
|
|
private dns: DNSCacheService,
|
|
private manage: DatabaseService,
|
|
private config: ConfigService,
|
|
) {}
|
|
|
|
async getOrLoad(domain: string): Promise<CachedZone> {
|
|
if (!this.dns.has(domain)) {
|
|
const exists = await this.manage.getZone(domain);
|
|
if (!exists) throw new HttpException('No such zonefile', 404);
|
|
return this.dns.load(
|
|
domain,
|
|
resolve(
|
|
process.cwd(),
|
|
this.config.get<string>('zoneDir'),
|
|
`${domain}.zone`,
|
|
),
|
|
);
|
|
}
|
|
|
|
const get = await this.dns.get(domain);
|
|
|
|
if (!get) {
|
|
throw new HttpException('Misconfigured domain zone file.', 400);
|
|
}
|
|
|
|
return get;
|
|
}
|
|
|
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
|
const request = context.switchToHttp().getRequest<Request>();
|
|
const response = context.switchToHttp().getResponse<Response>();
|
|
|
|
let base = of(null);
|
|
const domain = request.params.domain;
|
|
if (domain) {
|
|
base = from(
|
|
(async () => {
|
|
const domainCache = await this.getOrLoad(domain);
|
|
response.locals.domain = domain;
|
|
response.locals.cached = domainCache;
|
|
return null;
|
|
})(),
|
|
);
|
|
}
|
|
|
|
return base.pipe(switchMap(() => next.handle()));
|
|
}
|
|
}
|