From 0a7277c832b4b6579a32c85d3e885e8f85681ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20P=C3=B6hls?= Date: Sat, 4 May 2024 05:30:46 +0200 Subject: [PATCH] wip: pass encryption instance around --- packages/contracts/src/http/request.ts | 3 ++- packages/contracts/src/http/response.ts | 3 ++- packages/core/package.json | 1 + packages/core/test/error-handler.js | 2 ++ packages/http/src/http-service-provider.ts | 26 ++++++++++++++++++---- packages/http/src/routing/router.ts | 19 +++++++++++++--- packages/http/src/server/http-context.ts | 22 +++++++++++------- packages/http/src/server/server.ts | 19 +++++++++++++--- 8 files changed, 75 insertions(+), 20 deletions(-) diff --git a/packages/contracts/src/http/request.ts b/packages/contracts/src/http/request.ts index 71a21cab..805fb259 100644 --- a/packages/contracts/src/http/request.ts +++ b/packages/contracts/src/http/request.ts @@ -5,6 +5,7 @@ import { HttpMethods } from './methods.js' import { HttpContext } from './context.js' import { CookieBag } from './cookie-bag.js' import { IncomingMessage } from 'node:http' +import type { Encrypter } from '../index.js' import { IncomingHttpHeaders } from 'node:http2' import { CookieConfig } from './cookie-config.js' import { MacroableCtor } from '@supercharge/macroable' @@ -17,7 +18,7 @@ export interface HttpRequestCtor extends MacroableCtor { /** * Create a new HTTP request instance. */ - new (context: HttpContext, cookieConfig: CookieConfig): HttpRequest + new (context: HttpContext, cookieConfig: CookieConfig, encryption: Encrypter): HttpRequest } export type Protocol = 'http' | 'https' | string diff --git a/packages/contracts/src/http/response.ts b/packages/contracts/src/http/response.ts index 5419a2fa..cbd48236 100644 --- a/packages/contracts/src/http/response.ts +++ b/packages/contracts/src/http/response.ts @@ -3,6 +3,7 @@ import { InputBag } from './input-bag.js' import { HttpContext } from './context.js' import { CookieBag } from './cookie-bag.js' import { HttpRedirect } from './redirect.js' +import type { Encrypter } from '../index.js' import { OutgoingHttpHeaders } from 'node:http2' import { CookieConfig } from './cookie-config.js' import { MacroableCtor } from '@supercharge/macroable' @@ -13,7 +14,7 @@ export interface HttpResponseCtor extends MacroableCtor { /** * Create a new HTTP response instance. */ - new (context: HttpContext, cookieConfig: CookieConfig): HttpResponse + new (context: HttpContext, cookieConfig: CookieConfig, encryption: Encrypter): HttpResponse } export interface HttpResponse extends InteractsWithState { diff --git a/packages/core/package.json b/packages/core/package.json index 985c015b..2814b0c4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -33,6 +33,7 @@ }, "devDependencies": { "@supercharge/view": "^4.0.0-alpha.2", + "@supercharge/encryption": "^4.0.0-alpha.2", "c8": "~8.0.1", "expect": "~29.7.0", "mocked-env": "~1.3.5", diff --git a/packages/core/test/error-handler.js b/packages/core/test/error-handler.js index fcc61aae..393b1830 100644 --- a/packages/core/test/error-handler.js +++ b/packages/core/test/error-handler.js @@ -8,6 +8,7 @@ import { fileURLToPath } from 'node:url' import { Server } from '@supercharge/http' import { ViewServiceProvider } from '@supercharge/view' import { Application, ErrorHandler } from '../dist/index.js' +import { EncryptionServiceProvider } from '@supercharge/encryption' const viewMock = { boot () { }, @@ -29,6 +30,7 @@ function createApp () { app .bind('view', () => viewMock) + .register(new EncryptionServiceProvider(app)) app.config() .set('app.key', 1234) diff --git a/packages/http/src/http-service-provider.ts b/packages/http/src/http-service-provider.ts index 03ee58f8..6a535817 100644 --- a/packages/http/src/http-service-provider.ts +++ b/packages/http/src/http-service-provider.ts @@ -4,7 +4,7 @@ import { Router } from './routing/index.js' import { Request } from './server/request.js' import { Response } from './server/response.js' import { ServiceProvider } from '@supercharge/support' -import { ApplicationConfig, HttpConfig } from '@supercharge/contracts' +import { ApplicationConfig, HttpConfig, type Encrypter } from '@supercharge/contracts' /** * Add container bindings for services from this provider. @@ -39,7 +39,12 @@ export class HttpServiceProvider extends ServiceProvider { .singleton('server', () => { const appConfig = this.config().get('app') - return new Server(this.app(), appConfig, this.httpConfig()) + return new Server( + this.app(), + appConfig, + this.httpConfig(), + this.encrypter(), + ) }) .alias('server', 'http.server') .alias('server', Server) @@ -50,8 +55,21 @@ export class HttpServiceProvider extends ServiceProvider { */ private bindRouter (): void { this.app() - .singleton('route', () => new Router(this.app(), this.httpConfig())) - .alias('route', 'router') + .singleton('router', () => { + return new Router( + this.app(), + this.httpConfig(), + this.encrypter(), + ) + }) + .alias('router', 'route') + } + + /** + * Returns the encrypter instance. + */ + private encrypter (): Encrypter { + return this.app().make('encryption') } /** diff --git a/packages/http/src/routing/router.ts b/packages/http/src/routing/router.ts index fd4315e7..e89eef47 100644 --- a/packages/http/src/routing/router.ts +++ b/packages/http/src/routing/router.ts @@ -13,7 +13,7 @@ import { HandleErrorMiddleware } from '../middleware/handle-error.js' import { HttpContext, HttpRedirect, Response } from '../server/index.js' import KoaRouter, { RouterContext, Middleware as KoaMiddleware } from '@koa/router' import { Class, isConstructor, isFunction, isNotConstructor } from '@supercharge/classes' -import { HttpRouter, RouteHandler, RouteAttributes, HttpMethods, MiddlewareCtor, NextHandler, Middleware, Application, HttpConfig } from '@supercharge/contracts' +import { HttpRouter, RouteHandler, RouteAttributes, HttpMethods, MiddlewareCtor, NextHandler, Middleware, Application, HttpConfig, type Encrypter } from '@supercharge/contracts' export class Router implements HttpRouter { private readonly meta: { @@ -22,6 +22,11 @@ export class Router implements HttpRouter { */ app: Application + /** + * Stores the encrypter instance. + */ + encryption: Encrypter + /** * Stores the HTTP configuration object. */ @@ -51,9 +56,10 @@ export class Router implements HttpRouter { /** * Create a new router instance. */ - constructor (app: Application, httpConfig: HttpConfig) { + constructor (app: Application, httpConfig: HttpConfig, encryption: Encrypter) { this.meta = { app, + encryption, httpConfig, groupStack: [], middleware: new Map(), @@ -69,6 +75,13 @@ export class Router implements HttpRouter { return this.meta.app } + /** + * Returns the encryption instance. + */ + encryption (): Encrypter { + return this.meta.encryption + } + /** * Returns the Koa router instance. */ @@ -251,7 +264,7 @@ export class Router implements HttpRouter { * Wrap the given Koa `ctx` into a Supercharge ctx. */ private createContext (ctx: any): HttpContext { - return HttpContext.wrap(ctx, this.app(), this.meta.httpConfig.cookie) + return HttpContext.wrap(ctx, this.app(), this.meta.httpConfig.cookie, this.encryption()) } /** diff --git a/packages/http/src/server/http-context.ts b/packages/http/src/server/http-context.ts index 267d6a55..4e1837c2 100644 --- a/packages/http/src/server/http-context.ts +++ b/packages/http/src/server/http-context.ts @@ -1,34 +1,40 @@ import { RouterContext } from '@koa/router' import { InteractsWithState } from './interacts-with-state.js' -import { Application, HttpContext as HttpContextContract, HttpRequest, HttpResponse, HttpResponseCtor, HttpRequestCtor, HttpConfig } from '@supercharge/contracts' +import { Application, HttpContext as HttpContextContract, HttpRequest, HttpResponse, HttpResponseCtor, HttpRequestCtor, HttpConfig, type Encrypter } from '@supercharge/contracts' export class HttpContext extends InteractsWithState implements HttpContextContract { /** - * The application instance. + * Stores the application instance. */ private readonly app: Application /** - * The cookie config object. + * Stores the encrypter instance. + */ + private readonly encryption: Encrypter + + /** + * Stores the cookie config object. */ private readonly cookieConfig: HttpConfig['cookie'] /** * Create a new HTTP context instance. */ - constructor (ctx: RouterContext, app: Application, cookieConfig: HttpConfig['cookie']) { + constructor (ctx: RouterContext, app: Application, cookieConfig: HttpConfig['cookie'], encryption: Encrypter) { super(ctx) this.app = app + this.encryption = encryption this.cookieConfig = cookieConfig } /** * Returns a wrapped HTTP context for the raw Koa HTTP `ctx`. */ - static wrap (ctx: RouterContext, app: Application, cookieConfig: HttpConfig['cookie']): HttpContext { - return new this(ctx, app, cookieConfig) + static wrap (ctx: RouterContext, app: Application, cookieConfig: HttpConfig['cookie'], encryption: Encrypter): HttpContext { + return new this(ctx, app, cookieConfig, encryption) } /** @@ -49,7 +55,7 @@ export class HttpContext extends InteractsWithState implements HttpContextContra */ const Request = this.app.make('request') - return new Request(this, this.cookieConfig) + return new Request(this, this.cookieConfig, this.encryption) } /** @@ -63,6 +69,6 @@ export class HttpContext extends InteractsWithState implements HttpContextContra */ const Response = this.app.make('response') - return new Response(this, this.cookieConfig) + return new Response(this, this.cookieConfig, this.encryption) } } diff --git a/packages/http/src/server/server.ts b/packages/http/src/server/server.ts index c7374c15..c90d757b 100644 --- a/packages/http/src/server/server.ts +++ b/packages/http/src/server/server.ts @@ -7,7 +7,7 @@ import { Server as NodeHttpServer } from 'node:http' import { BodyparserMiddleware } from '../middleware/index.js' import { className, isConstructor } from '@supercharge/classes' import { HandleErrorMiddleware } from '../middleware/handle-error.js' -import { Application, HttpServer as HttpServerContract, Middleware as MiddlewareContract, MiddlewareCtor, HttpRouter, HttpServerHandler, InlineMiddlewareHandler, ApplicationConfig, HttpConfig } from '@supercharge/contracts' +import { Application, HttpServer as HttpServerContract, Middleware as MiddlewareContract, MiddlewareCtor, HttpRouter, HttpServerHandler, InlineMiddlewareHandler, ApplicationConfig, HttpConfig, type Encrypter } from '@supercharge/contracts' type Callback = (server: Server) => unknown | Promise @@ -26,6 +26,11 @@ export class Server implements HttpServerContract { */ httpConfig: HttpConfig + /** + * The encrypter instance. + */ + encryption: Encrypter + /** * The Koa server instance. */ @@ -55,10 +60,11 @@ export class Server implements HttpServerContract { /** * Create a new HTTP context instance. */ - constructor (app: Application, appConfig: ApplicationConfig, httpConfig: HttpConfig) { + constructor (app: Application, appConfig: ApplicationConfig, httpConfig: HttpConfig, encryption: Encrypter) { this.meta = { app, httpConfig, + encryption, bootedCallbacks: [], isBootstrapped: false, koa: this.createKoaInstance(appConfig) @@ -162,6 +168,13 @@ export class Server implements HttpServerContract { return this.meta.app } + /** + * Returns the encrypter instance. + */ + encryption (): Encrypter { + return this.meta.encryption + } + /** * Determine whether the HTTP server is already boostrapped. */ @@ -292,7 +305,7 @@ export class Server implements HttpServerContract { * Wrap the given Koa `ctx` into a Supercharge context. */ private createContext (ctx: any): HttpContext { - return HttpContext.wrap(ctx, this.app(), this.cookieConfig()) + return HttpContext.wrap(ctx, this.app(), this.cookieConfig(), this.encryption()) } /**