Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@adonisjs/encryption

Package Overview
Dependencies
Maintainers
2
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@adonisjs/encryption - npm Package Compare versions

Comparing version 1.0.4 to 2.0.0

build/src/Hmac/index.d.ts

77

build/adonis-typings/encryption.d.ts
/**
* @module @adonisjs/encryption
*/
/// <reference types="node" />
/**
* The binding for the given module is defined inside `providers/AppProvider.ts`

@@ -10,10 +6,19 @@ * file.

declare module '@ioc:Adonis/Core/Encryption' {
export type EncryptionConfigContract = {
key: string;
hmac: boolean;
reviver: (key: string, value: string) => any;
import { base64 } from '@poppinss/utils';
/**
* Config accepted by the encryption
*/
export type EncryptionOptions = {
algorithm?: 'aes-256-cbc';
secret: string;
};
export interface EncryptionContract {
/**
* 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 interface MessageVerifierContract {
/**
* Encrypt a given piece of value using the app secret. A wide range of
* Sign a given piece of value using the app secret. A wide range of
* data types are supported.

@@ -28,22 +33,52 @@ *

*
* Encrypt/decrypting a date object will result in returning a date string.
* You can optionally define a purpose for which the value was signed and
* mentioning a different purpose/no purpose during unsign will fail.
*/
encrypt(payload: any): string;
sign(payload: any, expiresIn?: string | number, purpose?: string): string;
/**
* Decrypt a previously encrypted value
* Unsign, previously signed value
*/
decrypt(payload: string): any;
unsign<T extends any>(payload: string, purpose?: string): T | null;
}
/**
* 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 interface EncryptionContract {
/**
* Create a new instance of encryption with custom runtime config
* Reference to the message verifier
*/
create(options?: Partial<EncryptionConfigContract>): EncryptionContract;
verifier: MessageVerifierContract;
/**
* BASE64 Encode value
* Reference to base64 object for base64 encoding/decoding values
*/
base64Encode(arrayBuffer: ArrayBuffer | SharedArrayBuffer): string;
base64Encode(data: string, encoding?: BufferEncoding): string;
base64: typeof base64;
/**
* BASE64 decode the encoded value
* Current algorithm in use
*/
base64Decode(encoded: string | Buffer, encoding?: BufferEncoding): string;
algorithm: EncryptionOptions['algorithm'];
/**
* 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 a previously encrypted value
*/
decrypt<T extends any>(payload: string, purpose?: string): T;
/**
* Create a children instance with different secret key
*/
child(options?: EncryptionOptions): EncryptionContract;
}

@@ -50,0 +85,0 @@ const Encryption: EncryptionContract;

@@ -1,3 +0,8 @@

/**
* @module @adonisjs/encryption
*/
/*
* @adonisjs/encryption
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

@@ -0,5 +1,5 @@

import { IocContract } from '@adonisjs/fold';
/**
* @module @adonisjs/encryption
* Encryption provider to binding encryption class to the container
*/
import { IocContract } from '@adonisjs/fold';
export default class EncryptionProvider {

@@ -6,0 +6,0 @@ protected $container: IocContract;

"use strict";
/*
* @adonisjs/encryption
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const Encryption_1 = require("../src/Encryption");
/**
* @module @adonisjs/encryption
* Encryption provider to binding encryption class to the container
*/
Object.defineProperty(exports, "__esModule", { value: true });
const Encryption_1 = require("../src/Encryption");
class EncryptionProvider {

@@ -14,3 +22,3 @@ constructor($container) {

const Config = this.$container.use('Adonis/Core/Config');
return new Encryption_1.Encryption(Config.get('app.appKey'));
return new Encryption_1.Encryption({ secret: Config.get('app.appKey') });
});

@@ -17,0 +25,0 @@ }

@@ -0,45 +1,53 @@

/// <reference path="../../adonis-typings/encryption.d.ts" />
import { base64 as utilsBase64 } from '@poppinss/utils';
import { EncryptionContract, EncryptionOptions } from '@ioc:Adonis/Core/Encryption';
import { MessageVerifier } from '../MessageVerifier';
/**
* @module @adonisjs/encryption
* 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).
*/
/// <reference types="node" />
import { EncryptionContract, EncryptionConfigContract } from '@ioc:Adonis/Core/Encryption';
/**
* Encryption class uses `AES-256` to encrypt raw values using `Objects`,
* `Arrays` and even `Date` objects. When `hmac=true`, an HMAC is
* generated with `sha256` encryption.
*/
export declare class Encryption implements EncryptionContract {
private secret;
private options?;
private options;
/**
* Simple encryptor .d.ts files are broken and hence we need
* to cast it to any at the time of usage
* The key for signing and encrypting values. It is derived
* from the user provided secret.
*/
private encryptor;
constructor(secret: string, options?: Partial<EncryptionConfigContract> | undefined);
private cryptoKey;
/**
* Encrypts value with `AES-256` encryption. HMAC is disabled by default for
* returning shorter output. Feel free to grab a [[newInstance]] of the
* encryption class with `hmac=true`.
* 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.
*/
encrypt(payload: any): string;
private separator;
/**
* Decrypt existing encrypted value. Returns `null`, when unable to
* decrypt.
* Reference to the instance of message verifier for signing
* and verifying values.
*/
decrypt(payload: string): any;
verifier: MessageVerifier;
/**
* Returns a custom instance of [[Encryption]] class with custom
* configuration
* Reference to base64 object for base64 encoding/decoding values
*/
create(options?: Partial<EncryptionConfigContract>): Encryption;
base64: typeof utilsBase64;
/**
* Base64 encode Buffer or string
* The algorithm in use
*/
base64Encode(arrayBuffer: ArrayBuffer | SharedArrayBuffer): string;
base64Encode(data: string, encoding?: BufferEncoding): string;
algorithm: "aes-256-cbc";
constructor(options: EncryptionOptions);
/**
* Base64 decode a previously encoded string or Buffer.
* Validates the app secret
*/
base64Decode(encoded: string | Buffer, encoding?: BufferEncoding): string;
private validateSecret;
/**
* Encrypt value with optional expiration and purpose
*/
encrypt(value: any, expiresAt?: string | number, purpose?: string): string;
/**
* Decrypt value and verify it against a purpose
*/
decrypt(value: string, purpose?: string): any;
/**
* Returns a new instance of encryption with custom secret key
*/
child(options: EncryptionOptions): Encryption;
}
"use strict";
/**
* @module @adonisjs/encryption
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/*
* @adonisjs/encryption
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* @adonisjs/encryption
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
const simple_encryptor_1 = __importDefault(require("simple-encryptor"));
Object.defineProperty(exports, "__esModule", { value: true });
/// <reference path="../../adonis-typings/encryption.ts" />
const crypto_1 = require("crypto");
const utils_1 = require("@poppinss/utils");
const Hmac_1 = require("../Hmac");
const MessageBuilder_1 = require("../MessageBuilder");
const MessageVerifier_1 = require("../MessageVerifier");
/**
* Encryption class uses `AES-256` to encrypt raw values using `Objects`,
* `Arrays` and even `Date` objects. When `hmac=true`, an HMAC is
* generated with `sha256` encryption.
* 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).
*/
class Encryption {
constructor(secret, options) {
this.secret = secret;
constructor(options) {
this.options = options;
this.encryptor = simple_encryptor_1.default(Object.assign({
key: this.secret,
debug: false,
hmac: false,
}, this.options));
/**
* The key for signing and encrypting values. It is derived
* from the user provided secret.
*/
this.cryptoKey = crypto_1.createHash('sha256').update(this.options.secret).digest();
/**
* 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.
*/
this.separator = '.';
/**
* Reference to the instance of message verifier for signing
* and verifying values.
*/
this.verifier = new MessageVerifier_1.MessageVerifier(this.options.secret);
/**
* Reference to base64 object for base64 encoding/decoding values
*/
this.base64 = utils_1.base64;
/**
* The algorithm in use
*/
this.algorithm = this.options.algorithm || 'aes-256-cbc';
this.validateSecret();
}
/**
* Encrypts value with `AES-256` encryption. HMAC is disabled by default for
* returning shorter output. Feel free to grab a [[newInstance]] of the
* encryption class with `hmac=true`.
* Validates the app secret
*/
encrypt(payload) {
return this.encryptor.encrypt(payload);
validateSecret() {
if (typeof (this.options.secret) !== 'string') {
throw new utils_1.Exception('Missing "app.appKey". Makes sure to define it inside the config file', 500, 'E_MISSING_APP_KEY');
}
if (this.options.secret.length < 16) {
throw new utils_1.Exception('"app.appKey" must have minimum length of 16 characters', 500, 'E_INVALID_APP_KEY');
}
}
/**
* Decrypt existing encrypted value. Returns `null`, when unable to
* decrypt.
* Encrypt value with optional expiration and purpose
*/
decrypt(payload) {
return this.encryptor.decrypt(payload);
encrypt(value, expiresAt, purpose) {
/**
* Using a random string as the iv for generating unpredictable values
*/
const iv = utils_1.randomString(16);
/**
* Creating chiper
*/
const cipher = crypto_1.createCipheriv(this.algorithm, this.cryptoKey, iv);
/**
* Encoding value to a string so that we can set it on the cipher
*/
const encodedValue = new MessageBuilder_1.MessageBuilder().build(value, expiresAt, purpose);
/**
* Set final to the cipher instance and encrypt it
*/
const encrypted = Buffer.concat([cipher.update(encodedValue, 'utf8'), 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_1.Hmac(this.cryptoKey).generate(result)}`;
}
/**
* Returns a custom instance of [[Encryption]] class with custom
* configuration
* Decrypt value and verify it against a purpose
*/
create(options) {
return new Encryption(this.secret, options);
}
base64Encode(data, encoding) {
if (typeof (data) === 'string') {
return Buffer.from(data, encoding).toString('base64');
decrypt(value, purpose) {
if (typeof (value) !== 'string') {
throw new utils_1.Exception('"Encryption.decrypt" expects a string value', 500, 'E_RUNTIME_EXCEPTION');
}
return Buffer.from(data).toString('base64');
/**
* Make sure the encrypted value is in correct format. ie
* [encrypted value]--[iv]--[hash]
*/
const [encryptedEncoded, ivEncoded, hash] = value.split(this.separator);
if (!encryptedEncoded || !ivEncoded || !hash) {
return null;
}
/**
* Make sure we are able to urlDecode the encrypted value
*/
const encrypted = this.base64.urlDecode(encryptedEncoded, 'binary');
if (!encrypted) {
return null;
}
/**
* Make sure we are able to urlDecode the iv
*/
const iv = this.base64.urlDecode(ivEncoded);
if (!iv) {
return null;
}
/**
* Make sure the hash is correct, it means the first 2 parts of the
* string are not tampered.
*/
const isValidHmac = new Hmac_1.Hmac(this.cryptoKey).compare(`${encryptedEncoded}${this.separator}${ivEncoded}`, hash);
if (!isValidHmac) {
return null;
}
/**
* The Decipher can raise exceptions with malformed input, so we wrap it
* to avoid leaking sensitive information
*/
try {
const decipher = crypto_1.createDecipheriv(this.algorithm, this.cryptoKey, iv);
const decrypted = decipher.update(encrypted, 'binary', 'utf8') + decipher.final('utf8');
return new MessageBuilder_1.MessageBuilder().verify(decrypted, purpose);
}
catch (error) {
return null;
}
}
/**
* Base64 decode a previously encoded string or Buffer.
* Returns a new instance of encryption with custom secret key
*/
base64Decode(encoded, encoding = 'utf-8') {
return Buffer.isBuffer(encoded)
? encoded.toString(encoding)
: Buffer.from(encoded, 'base64').toString(encoding);
child(options) {
return new Encryption(options);
}
}
exports.Encryption = Encryption;

@@ -1,4 +0,1 @@

/**
* @module @adonisjs/encryption
*/
export { Encryption } from './src/Encryption';
"use strict";
/**
* @module @adonisjs/encryption
*/
Object.defineProperty(exports, "__esModule", { value: true });
/*

@@ -14,3 +10,4 @@ * @adonisjs/encryption

*/
Object.defineProperty(exports, "__esModule", { value: true });
var Encryption_1 = require("./src/Encryption");
exports.Encryption = Encryption_1.Encryption;
{
"name": "@adonisjs/encryption",
"version": "1.0.4",
"version": "2.0.0",
"description": "Encryption provider for AdonisJs",

@@ -40,5 +40,5 @@ "main": "build/providers/EncryptionProvider.js",

"@adonisjs/fold": "^6.3.2",
"@adonisjs/mrm-preset": "^2.2.4",
"@types/node": "^13.7.0",
"commitizen": "^4.0.3",
"@adonisjs/mrm-preset": "^2.3.0",
"@types/node": "^13.11.1",
"commitizen": "^4.0.4",
"cz-conventional-changelog": "^3.1.0",

@@ -48,9 +48,9 @@ "del-cli": "^3.0.0",

"eslint": "^6.8.0",
"eslint-plugin-adonis": "^1.0.6",
"husky": "^4.2.1",
"eslint-plugin-adonis": "^1.0.9",
"husky": "^4.2.5",
"japa": "^3.0.1",
"mrm": "^2.0.4",
"mrm": "^2.2.1",
"np": "^5.2.1",
"ts-node": "^8.6.2",
"typescript": "^3.7.5"
"ts-node": "^8.8.2",
"typescript": "^3.8.3"
},

@@ -77,3 +77,5 @@ "nyc": {

"dependencies": {
"simple-encryptor": "^3.0.0"
"@hapi/bourne": "^2.0.0",
"@poppinss/utils": "^2.2.0",
"ms": "^2.1.2"
},

@@ -80,0 +82,0 @@ "np": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc