Skip to content

Commit

Permalink
feat(encryption): use new encryption module
Browse files Browse the repository at this point in the history
  • Loading branch information
RomainLanz committed Jul 29, 2023
1 parent 62ee595 commit 0ab49a4
Show file tree
Hide file tree
Showing 24 changed files with 130 additions and 88 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ coverage
.nyc_output
.idea
.vscode/
.yalc
*.sublime-project
*.sublime-workspace
*.log
build
dist
yarn.lock
yalc.lock
shrinkwrap.yaml
package-lock.json
test/__app
Expand Down
10 changes: 8 additions & 2 deletions benchmarks/adonisjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

import { createServer } from 'node:http'
import { Emitter } from '@adonisjs/events'
import { Encryption } from '@adonisjs/encryption'
import { EncryptionManager } from '@adonisjs/encryption'

Check failure on line 12 in benchmarks/adonisjs.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.

Check failure on line 12 in benchmarks/adonisjs.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.
import { Legacy } from '@adonisjs/encryption/drivers/legacy'

Check failure on line 13 in benchmarks/adonisjs.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/drivers/legacy' or its corresponding type declarations.

Check failure on line 13 in benchmarks/adonisjs.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/drivers/legacy' or its corresponding type declarations.
import { Application } from '@adonisjs/application'

import { defineConfig } from '../index.js'
Expand All @@ -22,7 +23,12 @@ const app = new Application(new URL('./', import.meta.url), {
})
await app.init()

const encryption = new Encryption({ secret: 'averylongrandom32charslongsecret' })
const encryption = new EncryptionManager({
default: 'legacy',
list: {
legacy: () => new Legacy({ key: 'averylongrandom32charslongsecret' }),
},
})

const server = new Server(
app,
Expand Down
6 changes: 3 additions & 3 deletions factories/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

import { Socket } from 'node:net'
import proxyAddr from 'proxy-addr'
import type { Encryption } from '@adonisjs/encryption'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

Check failure on line 12 in factories/request.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

Check failure on line 12 in factories/request.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.
import { IncomingMessage, ServerResponse } from 'node:http'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import type { Encryption } from '@adonisjs/encryption'

Check failure on line 14 in factories/request.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.

Check failure on line 14 in factories/request.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.

import { Request } from '../src/request.js'
import { RequestConfig } from '../src/types/request.js'
Expand Down Expand Up @@ -74,7 +74,7 @@ export class RequestFactory {
* signed URLs
*/
#createEncryption() {
return this.#parameters.encryption || new EncryptionFactory().create()
return this.#parameters.encryption || new EncryptionManagerFactory().create().use()
}

/**
Expand Down
4 changes: 2 additions & 2 deletions factories/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import { Socket } from 'node:net'
import type { Encryption } from '@adonisjs/encryption'

Check failure on line 11 in factories/response.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.

Check failure on line 11 in factories/response.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.
import { IncomingMessage, ServerResponse } from 'node:http'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

Check failure on line 13 in factories/response.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

Check failure on line 13 in factories/response.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

import { RouterFactory } from './router.js'
import { Response } from '../src/response.js'
Expand Down Expand Up @@ -77,7 +77,7 @@ export class ResponseFactory {
* signed URLs
*/
#createEncryption() {
return this.#parameters.encryption || new EncryptionFactory().create()
return this.#parameters.encryption || new EncryptionManagerFactory().create().use()
}

/**
Expand Down
4 changes: 2 additions & 2 deletions factories/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import type { Encryption } from '@adonisjs/encryption'

Check failure on line 10 in factories/router.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.

Check failure on line 10 in factories/router.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.
import type { Application } from '@adonisjs/application'
import { AppFactory } from '@adonisjs/application/factories'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

Check failure on line 13 in factories/router.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

Check failure on line 13 in factories/router.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

import { Router } from '../src/router/main.js'
import { QsParserFactory } from './qs_parser_factory.js'
Expand Down Expand Up @@ -41,7 +41,7 @@ export class RouterFactory {
* signed URLs
*/
#createEncryption() {
return this.#parameters.encryption || new EncryptionFactory().create()
return this.#parameters.encryption || new EncryptionManagerFactory().create().use()
}

/**
Expand Down
8 changes: 4 additions & 4 deletions factories/server_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

import { Logger } from '@adonisjs/logger'
import { Emitter } from '@adonisjs/events'
import type { Encryption } from '@adonisjs/encryption'
import type { EncryptionManager } from '@adonisjs/encryption'

Check failure on line 12 in factories/server_factory.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.

Check failure on line 12 in factories/server_factory.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption' or its corresponding type declarations.
import type { Application } from '@adonisjs/application'
import { AppFactory } from '@adonisjs/application/factories'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

Check failure on line 15 in factories/server_factory.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

Check failure on line 15 in factories/server_factory.ts

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Cannot find module '@adonisjs/encryption/factories' or its corresponding type declarations.

import { Server } from '../src/server/main.js'
import { defineConfig } from '../src/define_config.js'
Expand All @@ -21,7 +21,7 @@ import type { ServerConfig } from '../src/types/server.js'
type FactoryParameters = {
app: Application<any>
logger: Logger
encryption: Encryption
encryption: EncryptionManager<any>
emitter: Emitter<any>
config: Partial<ServerConfig>
}
Expand Down Expand Up @@ -68,7 +68,7 @@ export class ServerFactory {
* signed URLs
*/
#createEncryption() {
return this.#parameters.encryption || new EncryptionFactory().create()
return this.#parameters.encryption || new EncryptionManagerFactory().create()
}

/**
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"license": "MIT",
"devDependencies": {
"@adonisjs/application": "^7.1.2-9",
"@adonisjs/encryption": "^5.1.2-2",
"@adonisjs/encryption": "file:.yalc/@adonisjs/encryption",
"@adonisjs/eslint-config": "^1.1.8",
"@adonisjs/events": "^8.4.9-4",
"@adonisjs/fold": "^9.9.3-7",
Expand Down Expand Up @@ -98,6 +98,7 @@
"typescript": "^5.1.6"
},
"dependencies": {
"@adonisjs/core": "file:.yalc/@adonisjs/core",
"@paralleldrive/cuid2": "^2.2.1",
"@poppinss/macroable": "^1.0.0-7",
"@poppinss/matchit": "^3.1.2",
Expand Down
4 changes: 2 additions & 2 deletions src/cookies/drivers/signed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export function pack(key: string, value: any, encryption: Encryption): null | st
if (value === undefined || value === null) {
return null
}
return `s:${encryption.verifier.sign(value, undefined, key)}`
return `s:${encryption.getMessageVerifier().sign(value, undefined, key)}`
}

/**
Expand All @@ -38,5 +38,5 @@ export function unpack(key: string, signedValue: string, encryption: Encryption)
return null
}

return encryption.verifier.unsign(value, key)
return encryption.getMessageVerifier().unsign(value, key)
}
4 changes: 4 additions & 0 deletions src/define_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import type { ServerConfig } from './types/server.js'
*/
export function defineConfig(config: Partial<ServerConfig>): ServerConfig {
const normalizedConfig = {
encrypters: {
cookie: 'legacy',
signedRoute: 'legacy',
},
allowMethodSpoofing: false,
trustProxy: proxyAddr.compile('loopback'),
subdomainOffset: 2,
Expand Down
4 changes: 2 additions & 2 deletions src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import lodash from '@poppinss/utils/lodash'
import { createId } from '@paralleldrive/cuid2'
import { parse, UrlWithStringQuery } from 'node:url'
import type { Encryption } from '@adonisjs/encryption'
import { ServerResponse, IncomingMessage, IncomingHttpHeaders } from 'node:http'
import type { ServerResponse, IncomingMessage, IncomingHttpHeaders } from 'node:http'

import type { Qs } from './qs.js'
import { trustProxy } from './helpers.js'
Expand Down Expand Up @@ -941,7 +941,7 @@ export class Request extends Macroable {
/*
* Return false when signature fails
*/
const signedUrl = this.#encryption.verifier.unsign(signature, purpose)
const signedUrl = this.#encryption.getMessageVerifier().unsign(signature, purpose)
if (!signedUrl) {
return false
}
Expand Down
14 changes: 8 additions & 6 deletions src/router/lookup_store/url_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { Encryption } from '@adonisjs/encryption'
import type { Qs } from '../../qs.js'
import { parseRoutePattern } from '../parser.js'
import type { RouteFinder } from './route_finder.js'
import { EncryptersList } from '@adonisjs/core/types'

/**
* URL builder class is used to create URIs for pre-registered
Expand Down Expand Up @@ -220,7 +221,10 @@ export class UrlBuilder {
* route name, controller.method name or the route pattern
* itself.
*/
makeSigned(identifier: string, options?: { expiresIn?: string | number; purpose?: string }) {
makeSigned(
identifier: string,
options?: { encrypter?: EncryptersList; expiresIn?: string | number; purpose?: string }
) {
let url: string

if (this.#shouldPerformLookup) {
Expand All @@ -238,11 +242,9 @@ export class UrlBuilder {
* on their 2 different domains, but we ignore that case for now and can consider
* it later (when someone asks for it)
*/
const signature = this.#encryption.verifier.sign(
this.#suffixQueryString(url, this.#qs),
options?.expiresIn,
options?.purpose
)
const signature = this.#encryption
.getMessageVerifier()
.sign(this.#suffixQueryString(url, this.#qs), options?.expiresIn, options?.purpose)

const qs = Object.assign({}, this.#qs, { signature })
return this.#suffixQueryString(this.#prefixBaseUrl(url), qs)
Expand Down
29 changes: 23 additions & 6 deletions src/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import onFinished from 'on-finished'
import { Emitter } from '@adonisjs/events'
import Middleware from '@poppinss/middleware'
import type { Logger } from '@adonisjs/logger'
import type { Encryption } from '@adonisjs/encryption'
import type { EncryptionManager } from '@adonisjs/encryption'
import type { Server as HttpsServer } from 'node:https'
import type { Application } from '@adonisjs/application'
import { ContainerResolver, moduleCaller, moduleImporter } from '@adonisjs/fold'
Expand Down Expand Up @@ -83,7 +83,7 @@ export class Server {
/**
* The encryption instance to be shared with the router
*/
#encryption: Encryption
#encryption: EncryptionManager<any>

/**
* Server config
Expand Down Expand Up @@ -137,7 +137,7 @@ export class Server {

constructor(
app: Application<any>,
encryption: Encryption,
encryption: EncryptionManager<any>,
emitter: Emitter<any>,
logger: Logger,
config: ServerConfig
Expand All @@ -148,7 +148,11 @@ export class Server {
this.#logger = logger
this.#encryption = encryption
this.#qsParser = new Qs(this.#config.qs)
this.#router = new Router(this.#app, this.#encryption, this.#qsParser)
this.#router = new Router(
this.#app,
this.#encryption.use(config.encrypters.signedRoute),
this.#qsParser
)
this.#createAsyncLocalStore()

debug('server config: %O', this.#config)
Expand Down Expand Up @@ -301,14 +305,27 @@ export class Server {
* Creates an instance of the [[Request]] class
*/
createRequest(req: IncomingMessage, res: ServerResponse) {
return new Request(req, res, this.#encryption, this.#config, this.#qsParser)
return new Request(
req,
res,
this.#encryption.use(this.#config.encrypters.cookie),
this.#config,
this.#qsParser
)
}

/**
* Creates an instance of the [[Response]] class
*/
createResponse(req: IncomingMessage, res: ServerResponse) {
return new Response(req, res, this.#encryption, this.#config, this.#router, this.#qsParser)
return new Response(
req,
res,
this.#encryption.use(this.#config.encrypters.cookie),
this.#config,
this.#router,
this.#qsParser
)
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/types/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { QSParserConfig } from './qs.js'
import type { RequestConfig } from './request.js'
import type { ResponseConfig } from './response.js'
import type { HttpContext } from '../http_context/main.js'
import { EncryptersList } from '@adonisjs/core/types'

/**
* Normalized HTTP error used by the exception
Expand Down Expand Up @@ -89,4 +90,13 @@ export type ServerConfig = RequestConfig &
* Config for query string parser
*/
qs: QSParserConfig

/**
* The encrypter to be used for signing cookies and
* routes.
*/
encrypters: {
cookie: EncryptersList
signedRoute: EncryptersList
}
}
4 changes: 2 additions & 2 deletions tests/cookies/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
*/

import { test } from '@japa/runner'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

import { CookieClient } from '../../src/cookies/client.js'

const encryption = new EncryptionFactory().create()
const encryption = new EncryptionManagerFactory().create().use()

test.group('Cookie Client', () => {
test('sign cookie', async ({ assert }) => {
Expand Down
4 changes: 2 additions & 2 deletions tests/cookies/drivers/encrypted.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
*/

import { test } from '@japa/runner'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'
import { pack, unpack, canUnpack } from '../../../src/cookies/drivers/encrypted.js'

const encryption = new EncryptionFactory().create()
const encryption = new EncryptionManagerFactory().create().use()

test.group('Cookie | driver | encrypted', () => {
test('encrypt value', ({ assert }) => {
Expand Down
4 changes: 2 additions & 2 deletions tests/cookies/drivers/signed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
*/

import { test } from '@japa/runner'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'
import { pack, unpack, canUnpack } from '../../../src/cookies/drivers/signed.js'

const encryption = new EncryptionFactory().create()
const encryption = new EncryptionManagerFactory().create().use()

test.group('Cookie | driver | signed', () => {
test('sign value', ({ assert }) => {
Expand Down
4 changes: 2 additions & 2 deletions tests/cookies/parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
*/

import { test } from '@japa/runner'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

import { CookieParser } from '../../src/cookies/parser.js'
import { CookieSerializer } from '../../src/cookies/serializer.js'

const encryption = new EncryptionFactory().create()
const encryption = new EncryptionManagerFactory().create().use()
const serializer = new CookieSerializer(encryption)

test.group('Cookie | parse', () => {
Expand Down
4 changes: 2 additions & 2 deletions tests/cookies/serializer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
import { test } from '@japa/runner'
import { setTimeout } from 'node:timers/promises'
import { base64, MessageBuilder } from '@poppinss/utils'
import { EncryptionFactory } from '@adonisjs/encryption/factories'
import { EncryptionManagerFactory } from '@adonisjs/encryption/factories'

import { CookieSerializer } from '../../src/cookies/serializer.js'

const encryption = new EncryptionFactory().create()
const encryption = new EncryptionManagerFactory().create().use()

test.group('Cookie | serialize', () => {
test('serialize and sign cookie', ({ assert }) => {
Expand Down
Loading

0 comments on commit 0ab49a4

Please sign in to comment.