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

@evervault/sdk

Package Overview
Dependencies
Maintainers
4
Versions
105
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@evervault/sdk - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

.env.example

275

index.js

@@ -5,41 +5,7 @@ /** @format */

module.exports = (MACHINE_NAME) => {
const urlKey = window.location.hash.substring(2);
window.location.hash = '/';
const cachedPrivateKey = localStorage.getItem('evervault-privateKey');
const accessToken = localStorage.getItem('evervault-accessToken');
const refreshToken = localStorage.getItem('evervault-refreshToken');
const authRedirectUrl = 'https://auth.evervault.com';
class EvervaultKeyStore {
constructor() {
let _privateKey = undefined;
const hasStorageCredentials = accessToken && refreshToken && cachedPrivateKey;
if (!hasStorageCredentials && !urlKey) {
Utils.handleRedirect(`${authRedirectUrl}/${MACHINE_NAME}`);
} else if (urlKey) {
//user has key in url but not stored in memory
Utils.setUserKeysInStorage(urlKey);
}
return {
/**
* @return void
*/
logout: function() {
localStorage.removeItem('evervault-privateKey');
localStorage.removeItem('evervault-accessToken');
localStorage.removeItem('evervault-refreshToken');
localStorage.removeItem('evervault-haiku');
Utils.handleRedirect(`${authRedirectUrl}/${MACHINE_NAME}`);
},
getKey: async function(privateKey) {
if (!evervault.privateKey) {
const keyObj = await Utils.getEncryptionKey(
privateKey ? privateKey : localStorage.getItem('evervault-privateKey')
);
evervault.privateKey = keyObj;
}
},
_encryptString: function(str) {
this.encryptString = (str) => {
const dataBuffer = Utils.dataToBuffer(str);

@@ -53,3 +19,3 @@ const iv = window.crypto.getRandomValues(new Uint8Array(12));

},
evervault.privateKey,
_privateKey,
dataBuffer

@@ -61,50 +27,5 @@ )

});
},
};
_encryptObject: function(data, fields, deep) {
if (data) {
const handleEncryption = async (obj, fields) => {
let encryptedObject = Object.assign({}, obj);
for (let index = 0; index < fields.length; index++) {
let key = fields[index];
if (encryptedObject[key]) {
encryptedObject[key] = await this._encryptString(
Utils.ensureString(encryptedObject[key])
);
}
}
return encryptedObject;
};
return handleEncryption(data, fields);
}
//data is falsey - undefined
return;
},
/**
* @param data: string or object containing the data to be encrypted
* @param options: see evervault developer docs
* @return Promise resolving to string to send to db
*/
encrypt: function(data, options = {}) {
if (
typeof data === 'object' &&
data &&
data.constructor.name !== 'Array' &&
options.preserveObjectShape
) {
const fields = options.fieldsToEncrypt || Object.keys(data);
return this.getKey(options.privateKey).then(() => {
return this._encryptObject(data, fields);
});
} else if (typeof data !== 'undefined' && typeof data !== 'symbol') {
return this.getKey(options.privateKey).then(() => {
return this._encryptString(Utils.ensureString(data));
});
}
return;
},
_decryptEvString: function(str) {
this.decryptString = (str) => {
if (Utils.isEvervaultString(str)) {

@@ -120,3 +41,3 @@ const parsedData = Utils.parseEvervaultString(str);

},
evervault.privateKey,
_privateKey,
dataBuffer

@@ -132,30 +53,64 @@ )

return str;
},
};
_decryptObject: function(data, fields) {
this.updateKey = async (newKey) => {
if (!_privateKey) {
const keyObj = await Utils.getEncryptionKey(
newKey ? newKey : localStorage.getItem('evervault-privateKey')
);
_privateKey = keyObj;
}
};
}
}
module.exports = {
keyStore: new EvervaultKeyStore(),
encrypt: function(data, options = {}) {
const _encryptObject = (data, fields) => {
if (data) {
const handleDecryption = async (obj, fields) => {
let decryptedObject = Object.assign({}, obj);
const handleEncryption = async (obj, fields) => {
let encryptedObject = Object.assign({}, obj);
for (let index = 0; index < fields.length; index++) {
let key = fields[index];
if (decryptedObject[key]) {
decryptedObject[key] = await this._decryptEvString(
Utils.ensureString(decryptedObject[key])
if (encryptedObject[key]) {
encryptedObject[key] = await this.keyStore.encryptString(
Utils.ensureString(encryptedObject[key])
);
}
}
return decryptedObject;
return encryptedObject;
};
return handleDecryption(data, fields);
return handleEncryption(data, fields);
}
//data is falsey - undefined
return;
},
};
_decryptArray: function(data) {
if (
typeof data === 'object' &&
data &&
data.constructor.name !== 'Array' &&
options.preserveObjectShape
) {
const fields = options.fieldsToEncrypt || Object.keys(data);
return this.keyStore.updateKey(options.privateKey).then(() => {
return _encryptObject(data, fields);
});
} else if (typeof data !== 'undefined' && typeof data !== 'symbol') {
return this.keyStore.updateKey(options.privateKey).then(() => {
return this.keyStore.encryptString(Utils.ensureString(data));
});
}
return;
},
decrypt: function(data, privateKey) {
const _decryptArray = (data) => {
const handleDecryption = async (array) => {
let decryptedArr = new Array(array.length);
for (let index = 0; index < data.length; index++) {
decryptedArr[index] = await this._decryptEvString(
decryptedArr[index] = await this.keyStore.decryptString(
Utils.ensureString(array[index])

@@ -168,43 +123,93 @@ );

return handleDecryption(data);
},
};
/**
* @param data: string or object containing encrypted data
* @param options: decrypt options
* @return Promise resolving to decrypted payload
*/
decrypt: function(data, options = {}) {
if (typeof data === 'object') {
if (data.constructor.name === 'Array') {
return this.getKey(options.privateKey).then(() => {
return this._decryptArray(data);
});
}
return this.getKey(options.privateKey).then(() => {
return this._decryptObject(data, Object.keys(data));
const _decryptObject = (data, fields) => {
if (data) {
const handleDecryption = async (obj, fields) => {
let decryptedObject = Object.assign({}, obj);
for (let index = 0; index < fields.length; index++) {
let key = fields[index];
if (decryptedObject[key]) {
decryptedObject[key] = await this.keyStore.decryptString(
Utils.ensureString(decryptedObject[key])
);
}
}
return decryptedObject;
};
return handleDecryption(data, fields);
}
//data is falsey - undefined
return;
};
if (typeof data === 'object') {
if (data.constructor.name === 'Array') {
return this.keyStore.updateKey(privateKey).then(() => {
return _decryptArray(data);
});
} else if (typeof data !== 'undefined' && typeof data !== 'symbol') {
return this.getKey(options.privateKey).then(() => {
return this._decryptEvString(Utils.ensureString(data));
});
}
return data;
},
return this.keyStore.updateKey(privateKey).then(() => {
return _decryptObject(data, Object.keys(data));
});
} else if (typeof data !== 'undefined' && typeof data !== 'symbol') {
return this.keyStore.updateKey(privateKey).then(() => {
return this.keyStore.decryptString(Utils.ensureString(data));
});
}
return data;
},
getUrlParameters: function() {
return new Promise((resolve, reject) => {
const urlKey = window.location.hash.substring(2);
if (urlKey) {
const params = urlKey.split(':');
resolve({
privateKey: params[0],
authToken: params[1],
refreshToken: params[2],
});
} else {
reject(new Error('URL parameters not found'));
}
logout: () => {
localStorage.removeItem('evervault-privateKey');
localStorage.removeItem('evervault-accessToken');
localStorage.removeItem('evervault-refreshToken');
localStorage.removeItem('evervault-haiku');
Utils.handleRedirect(`${authRedirectUrl}/${MACHINE_NAME}`);
},
refreshAccessToken: (accessToken, refreshToken) => {
const requestBody = {
accessToken: accessToken || localStorage.getItem('evervault-accessToken'),
refreshToken:
refreshToken || localStorage.getItem('evervault-refreshToken'),
};
return fetch('https://api.evervault.dev/v1/token/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
})
.then((res) => res.json())
.then(({ accessToken }) => accessToken)
.catch((err) => {
throw err;
});
},
};
},
/**
* This function checks your user's auth status and will either redirect them to login, or
* will update their cached credentials
* @param [string] appId - unique identifier for your app as given on the evervault dashboard
*/
checkAuth: (appId) => {
const urlKey = window.location.hash.substring(2);
window.location.hash = '/';
const cachedPrivateKey = localStorage.getItem('evervault-privateKey');
const accessToken = localStorage.getItem('evervault-accessToken');
const refreshToken = localStorage.getItem('evervault-refreshToken');
const authRedirectUrl = process.ENV.AUTH_REDIRECT_URL;
const hasStorageCredentials =
accessToken && refreshToken && cachedPrivateKey;
if (!hasStorageCredentials && !urlKey) {
Utils.handleRedirect(`${authRedirectUrl}/${appId}`);
} else if (urlKey) {
//user has key in url but not stored in memory
Utils.setUserKeysInStorage(urlKey);
}
},
};
{
"name": "@evervault/sdk",
"version": "0.1.0",
"version": "0.2.0",
"description": "evervault Browser SDK",

@@ -14,3 +14,3 @@ "repository": {

"scripts": {
"build": "./node_modules/.bin/webpack --mode=production"
"build": "npx webpack --mode=production"
},

@@ -20,2 +20,4 @@ "license": "MIT",

"devDependencies": {
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"@babel/core": "^7.6.2",

@@ -25,6 +27,4 @@ "babel-preset-es2015": "^6.24.1",

"chai": "^4.2.0",
"mocha": "^7.0.1",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
"mocha": "^7.0.1"
}
}

@@ -7,18 +7,65 @@ <img src="https://raw.githubusercontent.com/evervault/evervault-sdk/master/logo.png" height="35" />

## API
## API Reference
## encrypt : <code>function</code> => <code>Promise</code>
### checkAuth
```javascript
checkAuth(appId): void
```
Check a user's auth status in the system, and redirect them if they are unauthenticated.
| Param | Type | Description |
| --- | --- | --- |
| privateKey | <code>String</code> | the private key retrieved from the client's Local Storage |
| data | <code>String or Object</code> | the data to be encrypted |
| appId | `String` | The unique identifier for your app in the evervault system |
### encrypt
```javascript
encrypt(data[, encryptOptions]): Promise<String>
```
## decrypt : <code>function</code> => <code>Promise</code>
Encrypt data using a user's secret key. The encrypt function will handle any data excluding `undefined` and `Symbol`.
| Param | Type | Description |
| --- | --- | --- |
| privateKey | <code>String</code> | the private key retrieved from the client's Local Storage |
| data | <code>String or Object</code> | the data to be decrypted |
| data | `any` | the data to be encrypted |
| [encryptOptions](#encryptoptions) | `object` | control how your data is encrypted |
### encryptOptions
| Key | Value | Description |
| --- | --- | --- |
| preserveObjectShape | `boolean` | if true, javascript objects will only have their values encrypted, if false objects will be stringified |
| fieldsToEncrypt | `Array<String>` | a list of fields in an object to encrypt |
| privateKey | `String` | a base64 representation of a user's evervault secret key |
### decrypt
```javascript
decrypt(data[, privateKey]): Promise<String>
```
Decrypt evervault encrypted data. Decrypt will preserve the shape of any object it's given (e.g. Array or Object). Any stringified data that enters decrypt will be parsable when it has been decrypted.
| Param | Type | Description |
| --- | --- | --- |
| data | `any` | the data to be decrypted, be it an object, array or a string |
| privateKey | `String` | a base64 representation of a user's evervault secret key |
### logout
```javascript
logout(): void
```
Remove a user's credentials and redirect them to evervault auth.
### refreshAccessToken
```javascript
refreshAccessToken([accessToken, refreshToken]): Promise<Object>
```
Refresh a user's access token in the evervault system.
| Param | Type | Description |
| --- | --- | --- |
| accessToken | `String` | a user's evervault access token to authenticate them in your system |
| refreshToken | `String` | a user's evervault refresh token to keep them authenticated |

@@ -11,6 +11,7 @@ /** @format */

localStorage.setItem('evervault-haiku', 'big-bertha-21');
const ev = evervault('test-app');
const testEncStr = 'test string';
it('should return ev formatted encrypted string', function(done) {
ev.encrypt(testEncStr)
evervault
.encrypt(testEncStr)
.then((encString) => {

@@ -34,4 +35,5 @@ const splitEncString = encString.split(':');

it('should decrypt and encrypted string', function(done) {
ev.encrypt(testEncStr)
.then((str) => ev.decrypt(str))
evervault
.encrypt(testEncStr)
.then((str) => evervault.decrypt(str))
.then((decStr) => {

@@ -53,4 +55,5 @@ chai.assert.equal(

it('should decrypt and encrypt object', function(done) {
ev.encrypt(obj, { preserveObjectShape: true })
.then((encObj) => ev.decrypt(encObj))
evervault
.encrypt(obj, { preserveObjectShape: true })
.then((encObj) => evervault.decrypt(encObj))
.then((decObj) => {

@@ -68,4 +71,5 @@ chai.assert.deepEqual(

it('should decrypt and encrypt object only one key of the object', function(done) {
ev.encrypt(obj, { preserveObjectShape: true, fieldsToEncrypt: ['a'] })
.then((encObj) => ev.decrypt(encObj))
evervault
.encrypt(obj, { preserveObjectShape: true, fieldsToEncrypt: ['a'] })
.then((encObj) => evervault.decrypt(encObj))
.then((decObj) => {

@@ -83,4 +87,5 @@ chai.assert.deepEqual(

it('should encrypt an object as a blob and decrypted to a stringified object', function(done) {
ev.encrypt(obj)
.then((encObj) => ev.decrypt(encObj))
evervault
.encrypt(obj)
.then((encObj) => evervault.decrypt(encObj))
.then((decObj) => {

@@ -104,4 +109,5 @@ chai.assert.equal(

it('should encrypt an array as a string and decrypt it to a parsable string', function(done) {
ev.encrypt(arr)
.then((encArr) => ev.decrypt(encArr))
evervault
.encrypt(arr)
.then((encArr) => evervault.decrypt(encArr))
.then((decArr) => {

@@ -120,4 +126,5 @@ chai.assert.deepEqual(

it('should encrypt numbers to strings and decrypt to parseable numbers', function(done) {
ev.encrypt(test_number)
.then((encNum) => ev.decrypt(encNum))
evervault
.encrypt(test_number)
.then((encNum) => evervault.decrypt(encNum))
.then((decNum) => {

@@ -134,17 +141,24 @@ chai.assert.deepEqual(

const hugeBin = BigInt(
'0b11111111111111111111111111111111111111111111111111111'
);
it('should encrypt a bigint and decrypt it to a stringified bigint', function(done) {
ev.encrypt(hugeBin)
.then((encBin) => ev.decrypt(encBin))
.then((decBin) => {
chai.assert.equal(
decBin,
hugeBin.toString(),
'The decrypted bigint does not match the stringified big int'
);
done();
});
});
const userAgent = navigator.userAgent.toLowerCase();
if (
userAgent.indexOf('safari') === -1 &&
userAgent.indexOf('mozilla') === -1
) {
const hugeBin = BigInt(
'0b11111111111111111111111111111111111111111111111111111'
);
it('should encrypt a bigint and decrypt it to a stringified bigint', function(done) {
evervault
.encrypt(hugeBin)
.then((encBin) => evervault.decrypt(encBin))
.then((decBin) => {
chai.assert.equal(
decBin,
hugeBin.toString(),
'The decrypted bigint does not match the stringified big int'
);
done();
});
});
}

@@ -155,4 +169,5 @@ function fn() {

it('should encrypt a function and decrypt it to a stringified function', function(done) {
ev.encrypt(fn)
.then((encFn) => ev.decrypt(encFn))
evervault
.encrypt(fn)
.then((encFn) => evervault.decrypt(encFn))
.then((decFn) => {

@@ -172,4 +187,5 @@ chai.assert.equal(

it('should encrypt an arrow function and decrypt it to a stringified arrow function', function(done) {
ev.encrypt(arrowFn)
.then((encFn) => ev.decrypt(encFn))
evervault
.encrypt(arrowFn)
.then((encFn) => evervault.decrypt(encFn))
.then((decFn) => {

@@ -187,4 +203,5 @@ chai.assert.equal(

it('should encrypt null and decrypt it to a parsable null string', function(done) {
ev.encrypt(nullVal)
.then((encNull) => ev.decrypt(encNull))
evervault
.encrypt(nullVal)
.then((encNull) => evervault.decrypt(encNull))
.then((decNull) => {

@@ -206,3 +223,3 @@ chai.assert.equal(

it('should ignore calls to encrypt with undefined values', function() {
const result = ev.encrypt(undefined);
const result = evervault.encrypt(undefined);
chai.assert.isUndefined(

@@ -215,3 +232,3 @@ result,

it('should ignore calls to decrypt with undefined values', function() {
const result = ev.decrypt(undefined);
const result = evervault.decrypt(undefined);
chai.assert.isUndefined(

@@ -225,3 +242,3 @@ result,

it('should ignore calls to encrypt with symbols', function() {
const result = ev.encrypt(symbolTest);
const result = evervault.encrypt(symbolTest);
chai.assert.isUndefined(

@@ -234,3 +251,3 @@ result,

it('should ignore calls to decrypt with symbols', function() {
const result = ev.decrypt(symbolTest);
const result = evervault.decrypt(symbolTest);
chai.assert.equal(

@@ -245,3 +262,3 @@ result,

it('should ignore calls to decrypt with unencrypted data', function(done) {
ev.decrypt(testDecrypt).then((result) => {
evervault.decrypt(testDecrypt).then((result) => {
chai.assert.equal(

@@ -248,0 +265,0 @@ result,

@@ -26,10 +26,14 @@ /** @format */

static ensureString(data) {
const isString = typeof data === 'string';
if (!isString) {
if (['bigint', 'function'].includes(typeof data)) {
return data.toString();
const getString = (data) => {
const isString = typeof data === 'string';
if (!isString) {
if (['bigint', 'function'].includes(typeof data)) {
return data.toString();
}
return JSON.stringify(data);
}
return JSON.stringify(data);
}
return data;
return data;
};
return getString(data).trim();
}

@@ -77,4 +81,4 @@

static isEvervaultString(str) {
const splitString = str.split(':');
return splitString.length >= 4 && splitString[0] === 'enc';
const encryptionSchemeRegex = /^enc:v\d:(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?:(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/s;
return encryptionSchemeRegex.test(str);
}

@@ -81,0 +85,0 @@

/** @format */
const webpack = require('webpack');
module.exports = {

@@ -6,0 +4,0 @@ entry: './index.js',

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