@adonisjs/encryption
Advanced tools
Comparing version 5.1.2-1 to 5.1.2-2
import { Encryption } from '../src/encryption.js'; | ||
import type { EncryptionOptions } from '../src/types.js'; | ||
/** | ||
* Encryption factory is used to generate encryption class instances for | ||
* testing | ||
*/ | ||
export declare class EncryptionFactory { | ||
#private; | ||
/** | ||
* Merge encryption factory options | ||
*/ | ||
merge(options: Partial<EncryptionOptions>): this; | ||
/** | ||
* Create instance of encryption class | ||
*/ | ||
create(): Encryption; | ||
} | ||
//# sourceMappingURL=encryption.d.ts.map |
@@ -0,2 +1,14 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
import { Encryption } from '../src/encryption.js'; | ||
/** | ||
* Encryption factory is used to generate encryption class instances for | ||
* testing | ||
*/ | ||
export class EncryptionFactory { | ||
@@ -6,2 +18,5 @@ #options = { | ||
}; | ||
/** | ||
* Merge encryption factory options | ||
*/ | ||
merge(options) { | ||
@@ -11,2 +26,5 @@ Object.assign(this.#options, options); | ||
} | ||
/** | ||
* Create instance of encryption class | ||
*/ | ||
create() { | ||
@@ -13,0 +31,0 @@ return new Encryption(this.#options); |
export { EncryptionFactory } from './encryption.js'; | ||
//# sourceMappingURL=main.d.ts.map |
@@ -0,1 +1,9 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
export { EncryptionFactory } from './encryption.js'; |
export * as errors from './src/exceptions.js'; | ||
export { Encryption } from './src/encryption.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -0,2 +1,10 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
export * as errors from './src/exceptions.js'; | ||
export { Encryption } from './src/encryption.js'; |
import { base64 } from '@poppinss/utils'; | ||
import type { EncryptionOptions } from './types.js'; | ||
import { MessageVerifier } from './message_verifier.js'; | ||
/** | ||
* The encryption class allows encrypting and decrypting values using `aes-256-cbc` or `aes-128-cbc` | ||
* algorithms. The encrypted value uses a unique iv for every encryption and this ensures semantic | ||
* security (read more https://en.wikipedia.org/wiki/Semantic_security). | ||
*/ | ||
export declare class Encryption { | ||
#private; | ||
/** | ||
* Reference to the instance of message verifier for signing | ||
* and verifying values. | ||
*/ | ||
verifier: MessageVerifier; | ||
/** | ||
* Reference to base64 object for base64 encoding/decoding values | ||
*/ | ||
base64: typeof base64; | ||
/** | ||
* The algorithm in use | ||
*/ | ||
get algorithm(): 'aes-256-cbc'; | ||
constructor(options: EncryptionOptions); | ||
/** | ||
* Encrypt a given piece of value using the app secret. A wide range of | ||
* data types are supported. | ||
* | ||
* - String | ||
* - Arrays | ||
* - Objects | ||
* - Booleans | ||
* - Numbers | ||
* - Dates | ||
* | ||
* You can optionally define a purpose for which the value was encrypted and | ||
* mentioning a different purpose/no purpose during decrypt will fail. | ||
*/ | ||
encrypt(payload: any, expiresIn?: string | number, purpose?: string): string; | ||
/** | ||
* Decrypt value and verify it against a purpose | ||
*/ | ||
decrypt<T extends any>(value: string, purpose?: string): T | null; | ||
/** | ||
* Create a children instance with different secret key | ||
*/ | ||
child(options?: EncryptionOptions): Encryption; | ||
} | ||
//# sourceMappingURL=encryption.d.ts.map |
@@ -0,1 +1,9 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
import string from '@poppinss/utils/string'; | ||
@@ -7,8 +15,31 @@ import { base64, MessageBuilder } from '@poppinss/utils'; | ||
import { MessageVerifier } from './message_verifier.js'; | ||
/** | ||
* The encryption class allows encrypting and decrypting values using `aes-256-cbc` or `aes-128-cbc` | ||
* algorithms. The encrypted value uses a unique iv for every encryption and this ensures semantic | ||
* security (read more https://en.wikipedia.org/wiki/Semantic_security). | ||
*/ | ||
export class Encryption { | ||
#options; | ||
/** | ||
* The key for signing and encrypting values. It is derived | ||
* from the user provided secret. | ||
*/ | ||
#cryptoKey; | ||
/** | ||
* Use `dot` as a separator for joining encrypted value, iv and the | ||
* hmac hash. The idea is borrowed from JWTs. | ||
*/ | ||
#separator = '.'; | ||
/** | ||
* Reference to the instance of message verifier for signing | ||
* and verifying values. | ||
*/ | ||
verifier; | ||
/** | ||
* Reference to base64 object for base64 encoding/decoding values | ||
*/ | ||
base64 = base64; | ||
/** | ||
* The algorithm in use | ||
*/ | ||
get algorithm() { | ||
@@ -23,2 +54,5 @@ return this.#options.algorithm; | ||
} | ||
/** | ||
* Validates the app secret | ||
*/ | ||
#validateSecret(secret) { | ||
@@ -32,10 +66,47 @@ if (typeof secret !== 'string') { | ||
} | ||
/** | ||
* Encrypt a given piece of value using the app secret. A wide range of | ||
* data types are supported. | ||
* | ||
* - String | ||
* - Arrays | ||
* - Objects | ||
* - Booleans | ||
* - Numbers | ||
* - Dates | ||
* | ||
* You can optionally define a purpose for which the value was encrypted and | ||
* mentioning a different purpose/no purpose during decrypt will fail. | ||
*/ | ||
encrypt(payload, expiresIn, purpose) { | ||
/** | ||
* Using a random string as the iv for generating unpredictable values | ||
*/ | ||
const iv = string.random(16); | ||
/** | ||
* Creating chiper | ||
*/ | ||
const cipher = createCipheriv(this.algorithm, this.#cryptoKey, iv); | ||
/** | ||
* Encoding value to a string so that we can set it on the cipher | ||
*/ | ||
const encodedValue = new MessageBuilder().build(payload, expiresIn, purpose); | ||
/** | ||
* Set final to the cipher instance and encrypt it | ||
*/ | ||
const encrypted = Buffer.concat([cipher.update(encodedValue, 'utf-8'), cipher.final()]); | ||
/** | ||
* Concatenate `encrypted value` and `iv` by urlEncoding them. The concatenation is required | ||
* to generate the HMAC, so that HMAC checks for integrity of both the `encrypted value` | ||
* and the `iv`. | ||
*/ | ||
const result = `${this.base64.urlEncode(encrypted)}${this.#separator}${this.base64.urlEncode(iv)}`; | ||
/** | ||
* Returns the result + hmac | ||
*/ | ||
return `${result}${this.#separator}${new Hmac(this.#cryptoKey).generate(result)}`; | ||
} | ||
/** | ||
* Decrypt value and verify it against a purpose | ||
*/ | ||
decrypt(value, purpose) { | ||
@@ -45,2 +116,6 @@ if (typeof value !== 'string') { | ||
} | ||
/** | ||
* Make sure the encrypted value is in correct format. ie | ||
* [encrypted value].[iv].[hash] | ||
*/ | ||
const [encryptedEncoded, ivEncoded, hash] = value.split(this.#separator); | ||
@@ -50,2 +125,5 @@ if (!encryptedEncoded || !ivEncoded || !hash) { | ||
} | ||
/** | ||
* Make sure we are able to urlDecode the encrypted value | ||
*/ | ||
const encrypted = this.base64.urlDecode(encryptedEncoded, 'base64'); | ||
@@ -55,2 +133,5 @@ if (!encrypted) { | ||
} | ||
/** | ||
* Make sure we are able to urlDecode the iv | ||
*/ | ||
const iv = this.base64.urlDecode(ivEncoded); | ||
@@ -60,2 +141,6 @@ if (!iv) { | ||
} | ||
/** | ||
* Make sure the hash is correct, it means the first 2 parts of the | ||
* string are not tampered. | ||
*/ | ||
const isValidHmac = new Hmac(this.#cryptoKey).compare(`${encryptedEncoded}${this.#separator}${ivEncoded}`, hash); | ||
@@ -65,2 +150,6 @@ if (!isValidHmac) { | ||
} | ||
/** | ||
* The Decipher can raise exceptions with malformed input, so we wrap it | ||
* to avoid leaking sensitive information | ||
*/ | ||
try { | ||
@@ -75,2 +164,5 @@ const decipher = createDecipheriv(this.algorithm, this.#cryptoKey, iv); | ||
} | ||
/** | ||
* Create a children instance with different secret key | ||
*/ | ||
child(options) { | ||
@@ -77,0 +169,0 @@ return new Encryption({ ...this.#options, ...options }); |
export declare const E_INSECURE_APP_KEY: new (args?: any, options?: ErrorOptions | undefined) => import("@poppinss/utils").Exception; | ||
export declare const E_MISSING_APP_KEY: new (args?: any, options?: ErrorOptions | undefined) => import("@poppinss/utils").Exception; | ||
//# sourceMappingURL=exceptions.d.ts.map |
@@ -0,3 +1,11 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
import { createError } from '@poppinss/utils'; | ||
export const E_INSECURE_APP_KEY = createError('The value of "app.appKey" should be atleast 16 charcaters long', 'E_INSECURE_APP_KEY'); | ||
export const E_MISSING_APP_KEY = createError('Missing "app.appKey". The key is required to encrypt values', 'E_MISSING_APP_KEY'); |
@@ -1,8 +0,17 @@ | ||
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="@types/node" resolution-mode="require"/> | ||
/** | ||
* A generic class for generating SHA-256 Hmac for verifying the value | ||
* integrity. | ||
*/ | ||
export declare class Hmac { | ||
#private; | ||
constructor(key: Buffer); | ||
/** | ||
* Generate the hmac | ||
*/ | ||
generate(value: string): string; | ||
/** | ||
* Compare raw value against an existing hmac | ||
*/ | ||
compare(value: string, existingHmac: string): boolean; | ||
} | ||
//# sourceMappingURL=hmac.d.ts.map |
@@ -0,3 +1,15 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
import { createHmac } from 'node:crypto'; | ||
import { base64, safeEqual } from '@poppinss/utils'; | ||
/** | ||
* A generic class for generating SHA-256 Hmac for verifying the value | ||
* integrity. | ||
*/ | ||
export class Hmac { | ||
@@ -8,5 +20,11 @@ #key; | ||
} | ||
/** | ||
* Generate the hmac | ||
*/ | ||
generate(value) { | ||
return base64.urlEncode(createHmac('sha256', this.#key).update(value).digest()); | ||
} | ||
/** | ||
* Compare raw value against an existing hmac | ||
*/ | ||
compare(value, existingHmac) { | ||
@@ -13,0 +31,0 @@ return safeEqual(this.generate(value), existingHmac); |
@@ -0,7 +1,29 @@ | ||
/** | ||
* Message verifier is similar to the encryption. However, the actual payload | ||
* is not encrypted and just base64 encoded. This is helpful when you are | ||
* not concerned about the confidentiality of the data, but just want to | ||
* make sure that is not tampered after encoding. | ||
*/ | ||
export declare class MessageVerifier { | ||
#private; | ||
constructor(secret: string); | ||
/** | ||
* Sign a given piece of value using the app secret. A wide range of | ||
* data types are supported. | ||
* | ||
* - String | ||
* - Arrays | ||
* - Objects | ||
* - Booleans | ||
* - Numbers | ||
* - Dates | ||
* | ||
* You can optionally define a purpose for which the value was signed and | ||
* mentioning a different purpose/no purpose during unsign will fail. | ||
*/ | ||
sign(payload: any, expiresIn?: string | number, purpose?: string): string; | ||
/** | ||
* Unsign a previously signed value with an optional purpose | ||
*/ | ||
unsign<T extends any>(payload: string, purpose?: string): T | null; | ||
} | ||
//# sourceMappingURL=message_verifier.d.ts.map |
@@ -0,6 +1,29 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
import { createHash } from 'node:crypto'; | ||
import { base64, MessageBuilder, RuntimeException } from '@poppinss/utils'; | ||
import { Hmac } from './hmac.js'; | ||
/** | ||
* Message verifier is similar to the encryption. However, the actual payload | ||
* is not encrypted and just base64 encoded. This is helpful when you are | ||
* not concerned about the confidentiality of the data, but just want to | ||
* make sure that is not tampered after encoding. | ||
*/ | ||
export class MessageVerifier { | ||
/** | ||
* The key for signing and encrypting values. It is derived | ||
* from the user provided secret. | ||
*/ | ||
#cryptoKey; | ||
/** | ||
* Use `dot` as a separator for joining encrypted value, iv and the | ||
* hmac hash. The idea is borrowed from JWT's in which each part | ||
* of the payload is concatenated with a dot. | ||
*/ | ||
#separator = '.'; | ||
@@ -10,2 +33,16 @@ constructor(secret) { | ||
} | ||
/** | ||
* Sign a given piece of value using the app secret. A wide range of | ||
* data types are supported. | ||
* | ||
* - String | ||
* - Arrays | ||
* - Objects | ||
* - Booleans | ||
* - Numbers | ||
* - Dates | ||
* | ||
* You can optionally define a purpose for which the value was signed and | ||
* mentioning a different purpose/no purpose during unsign will fail. | ||
*/ | ||
sign(payload, expiresIn, purpose) { | ||
@@ -18,2 +55,5 @@ if (payload === null || payload === undefined) { | ||
} | ||
/** | ||
* Unsign a previously signed value with an optional purpose | ||
*/ | ||
unsign(payload, purpose) { | ||
@@ -23,2 +63,5 @@ if (typeof payload !== 'string') { | ||
} | ||
/** | ||
* Ensure value is in correct format | ||
*/ | ||
const [encoded, hash] = payload.split(this.#separator); | ||
@@ -28,2 +71,5 @@ if (!encoded || !hash) { | ||
} | ||
/** | ||
* Ensure value can be decoded | ||
*/ | ||
const decoded = base64.urlDecode(encoded, undefined, false); | ||
@@ -30,0 +76,0 @@ if (!decoded) { |
@@ -0,1 +1,4 @@ | ||
/** | ||
* Config accepted by the encryption | ||
*/ | ||
export type EncryptionOptions = { | ||
@@ -5,2 +8,1 @@ algorithm?: 'aes-256-cbc'; | ||
}; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -0,1 +1,9 @@ | ||
/* | ||
* @adonisjs/encryption | ||
* | ||
* (c) AdonisJS | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
export {}; |
{ | ||
"name": "@adonisjs/encryption", | ||
"version": "5.1.2-1", | ||
"version": "5.1.2-2", | ||
"description": "Encryption provider for AdonisJs", | ||
@@ -8,9 +8,5 @@ "main": "build/index.js", | ||
"files": [ | ||
"src", | ||
"factories", | ||
"index.ts", | ||
"build/src", | ||
"build/factories", | ||
"build/index.d.ts", | ||
"build/index.d.ts.map", | ||
"build/index.js" | ||
@@ -23,2 +19,5 @@ ], | ||
}, | ||
"engines": { | ||
"node": ">=18.16.0" | ||
}, | ||
"scripts": { | ||
@@ -28,2 +27,3 @@ "pretest": "npm run lint", | ||
"clean": "del-cli build", | ||
"typecheck": "tsc --noEmit", | ||
"compile": "npm run lint && npm run clean && tsc", | ||
@@ -45,25 +45,23 @@ "build": "npm run compile", | ||
"devDependencies": { | ||
"@commitlint/cli": "^17.5.0", | ||
"@commitlint/config-conventional": "^17.4.4", | ||
"@japa/assert": "^1.4.1", | ||
"@japa/run-failed-tests": "^1.1.1", | ||
"@japa/runner": "^2.5.1", | ||
"@japa/spec-reporter": "^1.3.3", | ||
"@swc/core": "^1.3.42", | ||
"@types/node": "^18.15.10", | ||
"c8": "^7.13.0", | ||
"@adonisjs/eslint-config": "^1.1.7", | ||
"@adonisjs/prettier-config": "^1.1.7", | ||
"@adonisjs/tsconfig": "^1.1.7", | ||
"@commitlint/cli": "^17.6.6", | ||
"@commitlint/config-conventional": "^17.6.6", | ||
"@japa/assert": "^2.0.0-1", | ||
"@japa/runner": "^3.0.0-3", | ||
"@swc/core": "^1.3.67", | ||
"@types/node": "^20.3.3", | ||
"c8": "^8.0.0", | ||
"del-cli": "^5.0.0", | ||
"eslint": "^8.36.0", | ||
"eslint-config-prettier": "^8.8.0", | ||
"eslint-plugin-adonis": "^3.0.3", | ||
"eslint-plugin-prettier": "^4.2.1", | ||
"eslint": "^8.44.0", | ||
"github-label-sync": "^2.3.1", | ||
"husky": "^8.0.3", | ||
"np": "^7.6.4", | ||
"prettier": "^2.8.7", | ||
"np": "^8.0.4", | ||
"prettier": "^2.8.8", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.0.2" | ||
"typescript": "^5.1.6" | ||
}, | ||
"dependencies": { | ||
"@poppinss/utils": "^6.5.0-2" | ||
"@poppinss/utils": "^6.5.0-3" | ||
}, | ||
@@ -78,32 +76,2 @@ "repository": { | ||
"homepage": "https://github.com/adonisjs/encryption#readme", | ||
"eslintConfig": { | ||
"extends": [ | ||
"plugin:adonis/typescriptPackage", | ||
"prettier" | ||
], | ||
"plugins": [ | ||
"prettier" | ||
], | ||
"rules": { | ||
"prettier/prettier": [ | ||
"error", | ||
{ | ||
"endOfLine": "auto" | ||
} | ||
] | ||
} | ||
}, | ||
"eslintIgnore": [ | ||
"build" | ||
], | ||
"prettier": { | ||
"trailingComma": "es5", | ||
"semi": false, | ||
"singleQuote": true, | ||
"useTabs": false, | ||
"quoteProps": "consistent", | ||
"bracketSpacing": true, | ||
"arrowParens": "always", | ||
"printWidth": 100 | ||
}, | ||
"commitlint": { | ||
@@ -132,3 +100,7 @@ "extends": [ | ||
] | ||
} | ||
}, | ||
"eslintConfig": { | ||
"extends": "@adonisjs/eslint-config/package" | ||
}, | ||
"prettier": "@adonisjs/prettier-config" | ||
} |
@@ -5,3 +5,3 @@ # @adonisjs/encryption | ||
[![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] [![synk-image]][synk-url] | ||
[![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] | ||
@@ -25,4 +25,4 @@ ## Introduction | ||
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/encryption/test.yml?style=for-the-badge | ||
[gh-workflow-url]: https://github.com/adonisjs/encryption/actions/workflows/test.yml "Github action" | ||
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/encryption/checks.yml?style=for-the-badge | ||
[gh-workflow-url]: https://github.com/adonisjs/encryption/actions/workflows/checks.yml "Github action" | ||
@@ -37,4 +37,1 @@ [typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript | ||
[license-url]: LICENSE.md "license" | ||
[synk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/encryption?label=Synk%20Vulnerabilities&style=for-the-badge | ||
[synk-url]: https://snyk.io/test/github/adonisjs/encryption?targetFile=package.json "synk" |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
18
20204
19
465
35
Updated@poppinss/utils@^6.5.0-3