diff --git a/src/app.module.ts b/src/app.module.ts index 2499576..30c182b 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,9 +1,11 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { UrlShortenerModule } from './url-shortener/url-shortener.module'; +import { DnsService } from './dns/dns.service'; @Module({ imports: [UrlShortenerModule], controllers: [AppController], + providers: [DnsService], }) export class AppModule {} diff --git a/src/dns/dns.service.spec.ts b/src/dns/dns.service.spec.ts new file mode 100644 index 0000000..91db9a2 --- /dev/null +++ b/src/dns/dns.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { DnsService } from './dns.service'; + +describe('DnsService', () => { + let service: DnsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [DnsService], + }).compile(); + + service = module.get(DnsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/dns/dns.service.ts b/src/dns/dns.service.ts new file mode 100644 index 0000000..a653464 --- /dev/null +++ b/src/dns/dns.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common'; +import * as dns from 'dns'; +import * as util from 'util'; + +@Injectable() +export class DnsService { + private lookup = util.promisify(dns.lookup); + + async isValidUrl(url: string): Promise { + console.log('HERE!!!') + try { + const hostname = new URL(url).hostname; + await this.lookup(hostname); + console.log('HERE!') + return true; + } catch { + return false; + } + } +} \ No newline at end of file diff --git a/src/url-shortener/url-shortener.controller.ts b/src/url-shortener/url-shortener.controller.ts index 689d03c..c76af6e 100644 --- a/src/url-shortener/url-shortener.controller.ts +++ b/src/url-shortener/url-shortener.controller.ts @@ -6,12 +6,12 @@ export class UrlShortenerController { constructor(private readonly urlShortenerService: UrlShortenerService) {} @Post('shorten') - shortenUrl(@Body('url') url: string): { shortUrl: string } { + async shortenUrl(@Body('url') url: string): Promise<{ shortUrl: string }> { // example route http://localhost:3000/url-shortener/shorten POST body { url: 'https://www.google.com' } if (!url) { throw new HttpException('URL is required', HttpStatus.BAD_REQUEST); } - const shortUrl = this.urlShortenerService.generateShortUrl(url); + const shortUrl = await this.urlShortenerService.generateShortUrl(url); return { shortUrl }; } diff --git a/src/url-shortener/url-shortener.module.ts b/src/url-shortener/url-shortener.module.ts index 7ef4c7c..9e3f3d8 100644 --- a/src/url-shortener/url-shortener.module.ts +++ b/src/url-shortener/url-shortener.module.ts @@ -1,9 +1,10 @@ import { Module } from '@nestjs/common'; import { UrlShortenerService } from './url-shortener.service'; import { UrlShortenerController } from './url-shortener.controller'; +import { DnsService } from '../dns/dns.service'; @Module({ - providers: [UrlShortenerService], - controllers: [UrlShortenerController] + providers: [UrlShortenerService, DnsService], + controllers: [UrlShortenerController], }) export class UrlShortenerModule {} diff --git a/src/url-shortener/url-shortener.service.ts b/src/url-shortener/url-shortener.service.ts index 01d30fc..6856703 100644 --- a/src/url-shortener/url-shortener.service.ts +++ b/src/url-shortener/url-shortener.service.ts @@ -1,14 +1,23 @@ import { Injectable } from '@nestjs/common'; import * as shortid from 'shortid'; +import { DnsService } from '../dns/dns.service'; + @Injectable() export class UrlShortenerService { - private urlMap = new Map(); - generateShortUrl(originalUrl: string): string { + private urlMap = new Map(); + + constructor(private readonly dnsService: DnsService) {} + + async generateShortUrl(originalUrl: string): Promise { if(!originalUrl) { throw new Error('URL is required'); } + let isValid = await this.dnsService.isValidUrl(originalUrl); + if(!isValid) { + throw new Error('URL is invalid'); + } let shortUrl = shortid.generate(); this.urlMap.set(shortUrl, originalUrl); return shortUrl