diff --git a/src/app.module.ts b/src/app.module.ts index 5f935c2..229c476 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,9 +1,9 @@ -import { KeysModule } from './keys/keys.module.js'; -import { Module } from '@nestjs/common'; -import { ViewsController } from './views.controller.js'; +import { KeysModule } from './keys/keys.module.js' +import { Module } from '@nestjs/common' +import { ViewsController } from './views.controller.js' @Module({ - controllers: [ ViewsController ], - imports: [ KeysModule ] + controllers: [ViewsController], + imports: [KeysModule], }) export class AppModule {} diff --git a/src/keys/controllers/hkp.controller.ts b/src/keys/controllers/hkp.controller.ts index 97dc08e..e685715 100644 --- a/src/keys/controllers/hkp.controller.ts +++ b/src/keys/controllers/hkp.controller.ts @@ -1,43 +1,55 @@ -import { BadRequestException, Controller, Get, Query, Req } from "@nestjs/common"; -import { Address4, Address6 } from "ip-address"; +import { + BadRequestException, + Controller, + Get, + Query, + Req, +} from '@nestjs/common' +import { Address4, Address6 } from 'ip-address' -import type { FastifyRequest } from 'fastify'; +import type { FastifyRequest } from 'fastify' -import { HKPOperation, VALID_OPS } from "../providers/abstract.provider.js"; -import { AllKeysProvider } from "../providers/all.provider.js"; -import { serializeIndexes } from "../indexes.js"; +import { HKPOperation, VALID_OPS } from '../providers/abstract.provider.js' +import { AllKeysProvider } from '../providers/all.provider.js' +import { serializeIndexes } from '../indexes.js' @Controller() export class HKPController { - - constructor( - private allKeysProvider: AllKeysProvider - ) {} + constructor(private allKeysProvider: AllKeysProvider) {} @Get('pks/lookup') - async lookup(@Req() req: FastifyRequest, @Query('search') search: string, @Query('op') op: HKPOperation) { + async lookup( + @Req() req: FastifyRequest, + @Query('search') search: string, + @Query('op') op: HKPOperation + ) { if (VALID_OPS.indexOf(op) === -1) { - throw new BadRequestException('op MUST be one of: ' + VALID_OPS.join(', ')); + throw new BadRequestException( + 'op MUST be one of: ' + VALID_OPS.join(', ') + ) } - let ip: Address4 | Address6 | null = null; + let ip: Address4 | Address6 | null = null if (Address4.isValid(req.ip.replace(/^.*:/, ''))) { ip = new Address4(req.ip.replace(/^.*:/, '')) } else if (Address6.isValid(req.ip)) { ip = new Address6(req.ip) } if (ip === null) { - ip = new Address4('127.0.0.1'); + ip = new Address4('127.0.0.1') } const miscData = { ip } - + switch (op) { case 'get': - return this.allKeysProvider.get(search, miscData); + return this.allKeysProvider.get(search, miscData) case 'index': - const indexes = await this.allKeysProvider.index(search, miscData); - return serializeIndexes(indexes); + const indexes = await this.allKeysProvider.index( + search, + miscData + ) + return serializeIndexes(indexes) } } -} \ No newline at end of file +} diff --git a/src/keys/indexes.ts b/src/keys/indexes.ts index 173b4eb..0dc3c00 100644 --- a/src/keys/indexes.ts +++ b/src/keys/indexes.ts @@ -1,139 +1,173 @@ // as per https://www.ietf.org/archive/id/draft-gallagher-openpgp-hkp-05.html#name-machine-readable-indexes export interface Index { - prefix: 'info' | 'pub' | 'uid'; + prefix: 'info' | 'pub' | 'uid'; } export type Indexes = Index[]; export class InfoLine implements Index { - prefix: 'info'; - version: 1; - count: number; + prefix: 'info'; + version: 1; + count: number; - constructor(indexLine: string) { - parseIndex(this, indexLine, [ 'version', 'count' ]); + constructor(indexLine: string) { + parseIndex(this, indexLine, ['version', 'count']); - this.prefix = 'info'; + this.prefix = 'info'; - if (this.version != 1) { - throw new Error('InfoLine\'s version MUST be 1! Got ' + this.version) - } - if (this.count) { - if (typeof this.count !== 'number') { - if (isNaN(this.count)) { - throw new Error('InfoLine\'s count MUST NOT be NaN!'); - } - } - } + if (this.version != 1) { + throw new Error("InfoLine's version MUST be 1! Got " + this.version); } + if (this.count) { + if (typeof this.count !== 'number') { + if (isNaN(this.count)) { + throw new Error("InfoLine's count MUST NOT be NaN!"); + } + } + } + } } export class PubLine implements Index { - prefix: 'pub'; - keyid?: string; - keylen?: number; - algorithm?: string; - creationdate?: number; - expirationdate?: number; - flags?: string; - version?: string; + prefix: 'pub'; + keyid?: string; + keylen?: number; + algorithm?: string; + creationdate?: number; + expirationdate?: number; + flags?: string; + version?: string; - constructor(indexLine: string) { - parseIndex(this, indexLine, [ 'keyid', 'keylen', 'algorithm', 'creationdate', 'expirationdate', 'flags', 'version' ]); + constructor(indexLine: string) { + parseIndex(this, indexLine, [ + 'keyid', + 'keylen', + 'algorithm', + 'creationdate', + 'expirationdate', + 'flags', + 'version', + ]); - this.prefix = 'pub'; + this.prefix = 'pub'; - if (this.creationdate && typeof this.creationdate !== 'number') { - this.creationdate = parseFloat(this.creationdate); - if (isNaN(this.creationdate)) { - throw new Error('PubLine\'s creationdate MUST NOT be NaN!'); - } - } - if (this.expirationdate && typeof this.expirationdate !== 'number') { - this.expirationdate = parseFloat(this.expirationdate); - if (isNaN(this.expirationdate)) { - throw new Error('PubLine\'s expirationdate MUST NOT be NaN!'); - } - } + if (this.creationdate && typeof this.creationdate !== 'number') { + this.creationdate = parseFloat(this.creationdate); + if (isNaN(this.creationdate)) { + throw new Error("PubLine's creationdate MUST NOT be NaN!"); + } } + if (this.expirationdate && typeof this.expirationdate !== 'number') { + this.expirationdate = parseFloat(this.expirationdate); + if (isNaN(this.expirationdate)) { + throw new Error("PubLine's expirationdate MUST NOT be NaN!"); + } + } + } } export class UidLine implements Index { - prefix: 'uid'; - uidstring?: string; - creationdate?: string; - expirationdate?: string; - flags?: string; + prefix: 'uid'; + uidstring?: string; + creationdate?: string; + expirationdate?: string; + flags?: string; - constructor(indexLine: string) { - parseIndex(this, indexLine, [ 'uidstring', 'creationdate', 'expirationdate', 'flags' ]); + constructor(indexLine: string) { + parseIndex(this, indexLine, [ + 'uidstring', + 'creationdate', + 'expirationdate', + 'flags', + ]); - this.prefix = 'uid'; - } + this.prefix = 'uid'; + } } export function assertValidPrefix(prefix: string, throwError = true): boolean { - if ([ 'info', 'pub', 'uid' ].indexOf(prefix) == -1) { - if (!throwError) { - return false; - } - throw new Error('Prefix must be one of: info, pub, uid') + if (['info', 'pub', 'uid'].indexOf(prefix) == -1) { + if (!throwError) { + return false; } - return true + throw new Error('Prefix must be one of: info, pub, uid'); + } + return true; } export function parseIndexes(untyped: string[]): Indexes { - return untyped - .filter(x => x.split(':').length > 1) - .filter(x => assertValidPrefix(x.split(':')[0], false)) - .map(x => { - const prefix = x.split(':')[0] as 'info' | 'pub' | 'uid'; - switch (prefix) { - case 'info': return new InfoLine(x) - case 'pub': return new PubLine(x) - case 'uid': return new UidLine(x) - } - }) + return untyped + .filter((x) => x.split(':').length > 1) + .filter((x) => assertValidPrefix(x.split(':')[0], false)) + .map((x) => { + const prefix = x.split(':')[0] as 'info' | 'pub' | 'uid'; + switch (prefix) { + case 'info': return new InfoLine(x) + case 'pub': return new PubLine(x) + case 'uid': return new UidLine(x) + } + }); } -export function parseIndex(self: any, index: string, keys: (keyof T)[]): void { - let exploded = index.replaceAll('\r', '').split(':'); +export function parseIndex( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + self: any, + index: string, + keys: (keyof T)[], +): void { + let exploded = index.replaceAll('\r', '').split(':'); - if (keys.length > exploded.length) { - throw new Error('keys MUST NOT be longer than index'); - } + if (keys.length > exploded.length) { + throw new Error('keys MUST NOT be longer than index'); + } - const prefix = exploded[0] as 'info' | 'pub' | 'uid'; - assertValidPrefix(prefix, true); - self.prefix = prefix; - exploded = exploded.slice(1, exploded.length); + const prefix = exploded[0] as 'info' | 'pub' | 'uid'; + assertValidPrefix(prefix, true); + self.prefix = prefix; + exploded = exploded.slice(1, exploded.length); - for (let i = 0; i != keys.length; i++) { - self[keys[i]] = decodeURIComponent(exploded[i]); - } + for (let i = 0; i != keys.length; i++) { + self[keys[i]] = decodeURIComponent(exploded[i]); + } } export function serializeIndexes(indexes: Indexes): string { - let out: (string | number | undefined)[][] = []; - for (const index of indexes) { - if (index instanceof InfoLine) { - out.push([ 'info', index.version, index.count ]); - } - if (index instanceof PubLine) { - out.push([ 'pub', index.keyid, index.algorithm, index.keylen, index.creationdate, index.expirationdate, index.flags, index.version ]); - } - if (index instanceof UidLine) { - out.push([ 'uid', index.uidstring, index.creationdate, index.expirationdate, index.flags ]); - } + const out: (string | number | undefined)[][] = []; + for (const index of indexes) { + if (index instanceof InfoLine) { + out.push(['info', index.version, index.count]); } + if (index instanceof PubLine) { + out.push([ + 'pub', + index.keyid, + index.algorithm, + index.keylen, + index.creationdate, + index.expirationdate, + index.flags, + index.version, + ]); + } + if (index instanceof UidLine) { + out.push([ + 'uid', + index.uidstring, + index.creationdate, + index.expirationdate, + index.flags, + ]); + } + } - return out - .map( - x => x - .map(x => x ?? '') - .map(encodeURIComponent) - .join(':') - ) - .join('\n') + '\n' + return ( + out + .map((x) => + x.map(x => x ?? '') + .map(encodeURIComponent) + .join(':') + ) + .join('\n') + '\n' + ); } diff --git a/src/keys/keys.module.ts b/src/keys/keys.module.ts index a26fa35..fb197b8 100644 --- a/src/keys/keys.module.ts +++ b/src/keys/keys.module.ts @@ -1,11 +1,11 @@ -import { Module } from "@nestjs/common"; -import { HKPController } from "./controllers/hkp.controller.js"; -import { OpenPGPKeysProvider } from "./providers/openpgp.provider.js"; -import { AllKeysProvider } from "./providers/all.provider.js"; +import { Module } from '@nestjs/common' +import { HKPController } from './controllers/hkp.controller.js' +import { OpenPGPKeysProvider } from './providers/openpgp.provider.js' +import { AllKeysProvider } from './providers/all.provider.js' @Module({ - providers: [ OpenPGPKeysProvider, AllKeysProvider ], - controllers: [ HKPController ], - exports: [ OpenPGPKeysProvider, AllKeysProvider ] + providers: [OpenPGPKeysProvider, AllKeysProvider], + controllers: [HKPController], + exports: [OpenPGPKeysProvider, AllKeysProvider], }) -export class KeysModule {} \ No newline at end of file +export class KeysModule {} diff --git a/src/keys/providers/abstract.provider.ts b/src/keys/providers/abstract.provider.ts index ca9e0ff..b981707 100644 --- a/src/keys/providers/abstract.provider.ts +++ b/src/keys/providers/abstract.provider.ts @@ -1,18 +1,20 @@ -import { Get, Injectable } from '@nestjs/common'; -import { Indexes } from '../indexes.js'; -import { Address4, Address6 } from 'ip-address'; +import { Get, Injectable } from '@nestjs/common' +import { Indexes } from '../indexes.js' +import { Address4, Address6 } from 'ip-address' -export type AdditionalData = { ip: Address4 | Address6 }; -export type HKPOperation = keyof AbstractKeysProvider; -export type GetOperationReturn = string | 404; +export type AdditionalData = { ip: Address4 | Address6 } +export type HKPOperation = keyof AbstractKeysProvider +export type GetOperationReturn = string | 404 -export const VALID_OPS: readonly HKPOperation[] = Object.freeze([ 'get', 'index' ]) +export const VALID_OPS: readonly HKPOperation[] = Object.freeze([ + 'get', + 'index', +]) /** https://www.ietf.org/archive/id/draft-gallagher-openpgp-hkp-05.html#name-the-op-operation-field */ @Injectable() export abstract class AbstractKeysProvider { - - readonly url = Object.freeze('http://none'); + readonly url = Object.freeze('http://none') /** The "get" operation requests keys from the keyserver by textual search. A string that specifies which key(s) to return is provided in the "search" field. @@ -24,8 +26,15 @@ export abstract class AbstractKeysProvider { If no keys match the request, the keyserver SHOULD return an appropriate HTTP error code such as 404 ("Not Found"). */ @Get() - async get(search: string, data: AdditionalData): Promise { return 404 } + async get( + search: string, + data: AdditionalData + ): Promise { + return 404 + } @Get() - async index(search: string, data: AdditionalData): Promise { return [] } + async index(search: string, data: AdditionalData): Promise { + return [] + } } diff --git a/src/keys/providers/all.provider.ts b/src/keys/providers/all.provider.ts index 53653ed..d103132 100644 --- a/src/keys/providers/all.provider.ts +++ b/src/keys/providers/all.provider.ts @@ -1,7 +1,10 @@ -import { Get, Injectable } from "@nestjs/common"; -import { AbstractKeysProvider, type AdditionalData } from "./abstract.provider.js"; -import { Indexes, InfoLine } from "../indexes.js"; -import { OpenPGPKeysProvider } from "./openpgp.provider.js"; +import { Get, Injectable } from '@nestjs/common' +import { + AbstractKeysProvider, + type AdditionalData, +} from './abstract.provider.js' +import { Indexes, InfoLine } from '../indexes.js' +import { OpenPGPKeysProvider } from './openpgp.provider.js' /** * This provider searches all key providers and returns their combined result @@ -9,40 +12,41 @@ import { OpenPGPKeysProvider } from "./openpgp.provider.js"; @Injectable() export class AllKeysProvider implements AbstractKeysProvider { - constructor( - private openPgpKeysProvider: OpenPGPKeysProvider - ) {} + readonly url = Object.freeze('http://none'); + + constructor(private openPgpKeysProvider: OpenPGPKeysProvider) {} getAll(): AbstractKeysProvider[] { - return [ - this.openPgpKeysProvider - ] + return [this.openPgpKeysProvider] } @Get() async get(search: string, data: AdditionalData): Promise { - const all = this.getAll(); - const promises = await Promise.all(all.map(x => x.get(search, data))) + const all = this.getAll() + const promises = await Promise.all(all.map((x) => x.get(search, data))) - if (promises.filter(x => x == 404).length == promises.length) { // all failed + if (promises.filter((x) => x == 404).length == promises.length) { + // all failed return 404 } else { // if there are multiple keys, join them together to avoid missing data - return promises - .filter(x => typeof x === 'string') - .join('\n') + return promises.filter((x) => typeof x === 'string').join('\n') } } @Get() async index(search: string, data: AdditionalData): Promise { - const all = this.getAll(); - const promises = await Promise.all(all.map(x => x.index(search, data))) + const all = this.getAll() + const promises = await Promise.all( + all.map((x) => x.index(search, data)) + ) // merge indexes if there are multiple - const out = [ new InfoLine('info:1:1') ] as Indexes; - promises.forEach(x => x.filter(x => x.prefix !== 'info').forEach(y => out.push(y))); + const out = [new InfoLine('info:1:1')] as Indexes + promises.forEach((x) => + x.filter((x) => x.prefix !== 'info').forEach((y) => out.push(y)) + ) - return out; + return out } -} \ No newline at end of file +} diff --git a/src/keys/providers/openpgp.provider.ts b/src/keys/providers/openpgp.provider.ts index cef754d..a44ef05 100644 --- a/src/keys/providers/openpgp.provider.ts +++ b/src/keys/providers/openpgp.provider.ts @@ -1,22 +1,21 @@ -import { Get, Injectable } from "@nestjs/common"; +import { Get, Injectable } from '@nestjs/common' -import { AbstractKeysProvider } from "./abstract.provider.js"; -import type { AdditionalData } from "./abstract.provider.js"; -import { proxyGetOp, proxyIndexOp } from "./utils.js"; -import { Indexes } from "../indexes.js"; +import { AbstractKeysProvider } from './abstract.provider.js' +import type { AdditionalData } from './abstract.provider.js' +import { proxyGetOp, proxyIndexOp } from './utils.js' +import { Indexes } from '../indexes.js' @Injectable() export class OpenPGPKeysProvider implements AbstractKeysProvider { - - readonly url = Object.freeze('https://keys.openpgp.org'); + readonly url = Object.freeze('https://keys.openpgp.org') @Get() async get(search: string, data: AdditionalData): Promise { - return proxyGetOp(this.url + '/pks/lookup', search, data); + return proxyGetOp(this.url + '/pks/lookup', search, data) } @Get() async index(search: string, data: AdditionalData): Promise { - return proxyIndexOp(this.url + '/pks/lookup', search, data); + return proxyIndexOp(this.url + '/pks/lookup', search, data) } -} \ No newline at end of file +} diff --git a/src/keys/providers/ubuntu.provider.ts b/src/keys/providers/ubuntu.provider.ts index ab5edce..3be15d8 100644 --- a/src/keys/providers/ubuntu.provider.ts +++ b/src/keys/providers/ubuntu.provider.ts @@ -1,22 +1,21 @@ -import { Get, Injectable } from "@nestjs/common"; +import { Get, Injectable } from '@nestjs/common' -import { AbstractKeysProvider } from "./abstract.provider.js"; -import type { AdditionalData } from "./abstract.provider.js"; -import { proxyGetOp, proxyIndexOp } from "./utils.js"; -import { Indexes } from "../indexes.js"; +import { AbstractKeysProvider } from './abstract.provider.js' +import type { AdditionalData } from './abstract.provider.js' +import { proxyGetOp, proxyIndexOp } from './utils.js' +import { Indexes } from '../indexes.js' @Injectable() export class UbuntuKeysProvider implements AbstractKeysProvider { - - readonly url = Object.freeze('https://keyserver.ubuntu.com'); + readonly url = Object.freeze('https://keyserver.ubuntu.com') @Get() async get(search: string, data: AdditionalData): Promise { - return proxyGetOp(this.url + '/pks/lookup', search, data); + return proxyGetOp(this.url + '/pks/lookup', search, data) } @Get() async index(search: string, data: AdditionalData): Promise { - return proxyIndexOp(this.url + '/pks/lookup', search, data); + return proxyIndexOp(this.url + '/pks/lookup', search, data) } -} \ No newline at end of file +} diff --git a/src/keys/providers/utils.ts b/src/keys/providers/utils.ts index 0b214c6..da10538 100644 --- a/src/keys/providers/utils.ts +++ b/src/keys/providers/utils.ts @@ -1,47 +1,63 @@ -import ky, { ResponsePromise } from "ky"; -import { AdditionalData, GetOperationReturn, HKPOperation } from "./abstract.provider.js"; -import { Indexes, parseIndexes } from "../indexes.js"; +import ky, { ResponsePromise } from 'ky' +import { + AdditionalData, + GetOperationReturn, + HKPOperation, +} from './abstract.provider.js' +import { Indexes, parseIndexes } from '../indexes.js' -const BEGIN_HEADER = '-----BEGIN PGP PUBLIC KEY BLOCK-----'; -const END_HEADER = '-----END PGP PUBLIC KEY BLOCK-----'; +const BEGIN_HEADER = '-----BEGIN PGP PUBLIC KEY BLOCK-----' +const END_HEADER = '-----END PGP PUBLIC KEY BLOCK-----' export function getKey(raw: string): string { - return ( - raw - .replace(new RegExp(`.*${BEGIN_HEADER}`, 'gm'), BEGIN_HEADER) - .replace(new RegExp(`${END_HEADER}.*`, 'gm'), END_HEADER) - ); + return raw + .replace(new RegExp(`.*${BEGIN_HEADER}`, 'gm'), BEGIN_HEADER) + .replace(new RegExp(`${END_HEADER}.*`, 'gm'), END_HEADER) } /** * Proxy request to a 3rd party keyserver via ky */ -export function proxyRequest(url: string, op: HKPOperation, search: string, data: AdditionalData): ResponsePromise { - return ky( - url, - { - headers: { - 'User-Agent': 'Cupid (https://cupid.blek.codes)' - }, - searchParams: { - op, - search - } - } - ) +export function proxyRequest( + url: string, + op: HKPOperation, + search: string, + data: AdditionalData +): ResponsePromise { + return ky(url, { + headers: { + 'User-Agent': 'Cupid (https://cupid.blek.codes)', + }, + searchParams: { + op, + search, + }, + }) } -export async function proxyGetOp(url: string, search: string, data: AdditionalData): Promise { - const httpRes = await proxyRequest(url, 'get', search, data); - if (httpRes.status !== 200) { return 404 } +export async function proxyGetOp( + url: string, + search: string, + data: AdditionalData +): Promise { + const httpRes = await proxyRequest(url, 'get', search, data) + if (httpRes.status !== 200) { + return 404 + } return getKey(await httpRes.text()) } -export async function proxyIndexOp(url: string, search: string, data: AdditionalData): Promise { - const httpRes = await proxyRequest(url, 'index', search, data); - if (httpRes.status !== 200) { return [] } - - const rawIndexes = await httpRes.text(); +export async function proxyIndexOp( + url: string, + search: string, + data: AdditionalData +): Promise { + const httpRes = await proxyRequest(url, 'index', search, data) + if (httpRes.status !== 200) { + return [] + } + + const rawIndexes = await httpRes.text() return parseIndexes(rawIndexes.split('\n')) -} \ No newline at end of file +} diff --git a/src/main.ts b/src/main.ts index 53a92d4..8b26c79 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,28 +1,34 @@ -import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; -import { NestFactory } from '@nestjs/core'; -import handlebars from 'hbs'; +import { + FastifyAdapter, + NestFastifyApplication, +} from '@nestjs/platform-fastify' +import { NestFactory } from '@nestjs/core' +import handlebars from 'hbs' -import { join } from 'path'; +import { join } from 'path' -import { AppModule } from './app.module.js'; +import { AppModule } from './app.module.js' async function bootstrap() { - const app = await NestFactory.create(AppModule, new FastifyAdapter()); + const app = await NestFactory.create( + AppModule, + new FastifyAdapter() + ) - const root = import.meta.dirname; + const root = import.meta.dirname - app.useStaticAssets({ - root: join(root, '..', 'public'), - prefix: '/public/' - }); + app.useStaticAssets({ + root: join(root, '..', 'public'), + prefix: '/public/', + }) - app.setViewEngine({ - engine: { - handlebars - }, - templates: join(root, '..', 'views') - }) + app.setViewEngine({ + engine: { + handlebars, + }, + templates: join(root, '..', 'views'), + }) - await app.listen(3000); + await app.listen(3000) } -bootstrap(); +bootstrap() diff --git a/src/views.controller.ts b/src/views.controller.ts index 872b350..8105a31 100644 --- a/src/views.controller.ts +++ b/src/views.controller.ts @@ -1,17 +1,14 @@ -import { Controller, Get, Render } from "@nestjs/common"; +import { Controller, Get, Render } from '@nestjs/common' -import { AllKeysProvider } from "./keys/providers/all.provider.js"; +import { AllKeysProvider } from './keys/providers/all.provider.js' @Controller() export class ViewsController { - - constructor( - private allKeysProvider: AllKeysProvider - ) { } + constructor(private allKeysProvider: AllKeysProvider) {} @Get() @Render('index.html') index() { - return { keys: this.allKeysProvider.getAll().map(x => x.url) } + return { keys: this.allKeysProvider.getAll().map((x) => x.url) } } -} \ No newline at end of file +} diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index adebb61..928c60c 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -1,25 +1,25 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import request from 'supertest'; +import { Test, TestingModule } from '@nestjs/testing' +import { INestApplication } from '@nestjs/common' +import request from 'supertest' -import { AppModule } from './../src/app.module.js'; +import { AppModule } from './../src/app.module.js' describe('AppController (e2e)', () => { - let app: INestApplication; + let app: INestApplication - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule], + }).compile() - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication() + await app.init() + }) - it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect((res) => res.headers['Content-Type'] == 'text/html'); - }); -}); + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect((res) => res.headers['Content-Type'] == 'text/html') + }) +})