Comparing version 2.1.1 to 2.1.2
{ | ||
"name": "rox-base", | ||
"version": "2.1.1", | ||
"version": "2.1.2", | ||
"description": "Rollout.io ROX JS SDK Base", | ||
@@ -38,26 +38,34 @@ "author": "Rollout.io <support@rollout.io>", | ||
"ROX": { | ||
"api_version": "1.4.0" | ||
"api_version": "1.5.0" | ||
}, | ||
"main": "src/index.js", | ||
"module": "src/index.js", | ||
"dependencies": { | ||
"axios": "^0.17.0", | ||
"lodash.clonedeep": "^4.5.0", | ||
"loglevel": "^1.4.1", | ||
"md5": "^2.2.1", | ||
"qs": "^6.5.0", | ||
"uuid": "^3.1.0" | ||
}, | ||
"devDependencies": { | ||
"axios": "^0.18.0", | ||
"babel-eslint": "^8.2.2", | ||
"babel-loader": "^7.1.1", | ||
"babel-plugin-transform-class-properties": "^6.24.1", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"browserify-sign": "^4.0.4", | ||
"error-stack-parser": "^2.0.1", | ||
"eslint": "^4.3.0", | ||
"jest": "^22.1.2", | ||
"uglifyjs-webpack-plugin": "1.0.0-beta.2", | ||
"webpack": "^3.5.5" | ||
"lodash.clonedeep": "^4.5.0", | ||
"loglevel": "^1.4.1", | ||
"md5": "^2.2.1", | ||
"qs": "^6.5.0", | ||
"rox-embedded-webpack-plugin": "^1.0.2", | ||
"uglifyjs-webpack-plugin": "^1.2.3", | ||
"uuid": "^3.1.0", | ||
"webpack": "^3.5.5", | ||
"webpack-common-shake": "^1.5.3" | ||
}, | ||
"jest": { | ||
"moduleFileExtensions": ["js"], | ||
"moduleDirectories": ["node_modules"] | ||
"moduleFileExtensions": [ | ||
"js" | ||
], | ||
"moduleDirectories": [ | ||
"node_modules" | ||
] | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { invokeFlagImpression } from '../lib/FlagImpressionHandler'; | ||
import { invokeImpression } from '../lib/ImpressionHandler'; | ||
@@ -76,4 +76,4 @@ export default class RoxVariant { | ||
_flagImpression(value, context) { | ||
invokeFlagImpression(value, this, context); | ||
invokeImpression(value, this, context); | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { CustomProperty } from '../entities'; | ||
import { BugsnagReporter, RoxLogger, ClassRegister, ConfigurationFetcher } from './'; | ||
import { | ||
@@ -10,7 +10,6 @@ TargetGroups as TargetGroupRepository, | ||
import { CustomProperty } from '../entities'; | ||
import { RoxxParser } from '../parsers'; | ||
import { setHandler } from './ImpressionHandler'; | ||
import { RoxLogger, ClassRegister, ConfigurationFetcher } from './'; | ||
import { setHandler } from './FlagImpressionHandler'; | ||
import deboucne from 'lodash/debounce'; | ||
@@ -45,20 +44,34 @@ | ||
setup(options = {}) { | ||
this.handleOptions(options); | ||
try { | ||
// Bootstrap Options | ||
this.handleOptions(options); | ||
_deps.DeviceProperties = _deps.DeviceProperties.create ? _deps.DeviceProperties.create() : _deps.DeviceProperties; | ||
this.app_release && _deps.DeviceProperties.setAppRelease(this.app_release); | ||
this.distinct_id && _deps.DeviceProperties.setDistinctId(this.distinct_id); | ||
this.platform && _deps.DeviceProperties.setPlatform(this.platform); | ||
this.deviceProperties = _deps.DeviceProperties; | ||
this.configurationFetcher = new ConfigurationFetcher( | ||
this.appKey, | ||
this.deviceProperties, | ||
this.devModeSecret, | ||
_deps.cacheService, | ||
this.embeddedConfiguration | ||
); | ||
_deps | ||
.getDefaultCustomProperties(this.deviceProperties) | ||
.map(CustomPropertyRepository.set.bind(CustomPropertyRepository)); | ||
// Bootstrap Device Properties | ||
_deps.DeviceProperties = _deps.DeviceProperties.create ? _deps.DeviceProperties.create() : _deps.DeviceProperties; | ||
this.app_release && _deps.DeviceProperties.setAppRelease(this.app_release); | ||
this.distinct_id && _deps.DeviceProperties.setDistinctId(this.distinct_id); | ||
this.platform && _deps.DeviceProperties.setPlatform(this.platform); | ||
this.deviceProperties = _deps.DeviceProperties; | ||
// Bootstrap Error Reporter | ||
BugsnagReporter.init(this.appKey, _deps.DeviceProperties); | ||
// Bootstap Configuration Fetcher | ||
this.configurationFetcher = new ConfigurationFetcher( | ||
this.appKey, | ||
this.deviceProperties, | ||
this.devModeSecret, | ||
_deps, | ||
this.embeddedConfiguration | ||
); | ||
// Bootstrap Custom Properties | ||
_deps | ||
.getDefaultCustomProperties(this.deviceProperties) | ||
.map(CustomPropertyRepository.set.bind(CustomPropertyRepository)); | ||
} catch (e) { | ||
const message = 'Oh uh! An error occured during setup.'; | ||
RoxLogger.error(message, e); | ||
BugsnagReporter.error(message, e); | ||
} | ||
return Promise.resolve(this); | ||
@@ -65,0 +78,0 @@ } |
@@ -7,2 +7,4 @@ import { fetchRemoteConfiguration } from './RequestConfiguration'; | ||
import BugsnagReporter from './BugsnagReporter'; | ||
import Config from '../config'; | ||
@@ -23,5 +25,6 @@ | ||
class ConfigurationFetcher { | ||
constructor(appKey, deviceProperties, devModeSecret, cacheService, embeddedPayload) { | ||
constructor(appKey, deviceProperties, devModeSecret, dependencies, embeddedPayload) { | ||
this.cache = dependencies.RoxCache; | ||
this.crypto = dependencies.RoxCrypto; | ||
this.embdeddedJSON = this.fetchFromEmbedded(embeddedPayload); | ||
this.cacheService = cacheService; | ||
this.appKey = appKey; | ||
@@ -34,4 +37,9 @@ this.deviceProperties = deviceProperties; | ||
runHandler(handler, data) { | ||
if (data.errorDetails) { | ||
BugsnagReporter.error('Configuration fetcher returned with ' + data.fetcherStatus, data.errorDetails); | ||
} | ||
if (handler instanceof Function) { | ||
handler(data); | ||
try { | ||
handler(data); | ||
} catch (e) {} | ||
} | ||
@@ -50,3 +58,3 @@ } | ||
parser: embdeddedParser, | ||
status: FetcherStatus.APLLIED_FROM_EMBEDDED | ||
status: FetcherStatus.APPLIED_FROM_EMBEDDED | ||
}); | ||
@@ -63,3 +71,3 @@ } | ||
parser: cachedParser, | ||
status: FetcherStatus.APLLIED_FROM_CACHE | ||
status: FetcherStatus.APPLIED_FROM_CACHE | ||
}); | ||
@@ -80,5 +88,3 @@ } | ||
return this._dispatch({ handler, storeInCache: true }).catch(err => { | ||
this.runHandler(handler, new FetcherResults(FetcherStatus.ERROR_FETCH_FAILED, null, false, err)); | ||
}); | ||
return this._dispatch({ handler, storeInCache: true }); | ||
} | ||
@@ -104,5 +110,7 @@ | ||
const hasChanges = this.isNewResponse(response); | ||
storeInCache && this.storeInCache(response); | ||
this.lastResponse = response; | ||
return this.process(response, FetcherStatus.APLLIED_FROM_NETWORK, hasChanges, handler); | ||
const result = this.process(response, FetcherStatus.APPLIED_FROM_NETWORK, hasChanges, handler); | ||
return result.then(() => { | ||
storeInCache && this.storeInCache(response); | ||
this.lastResponse = response; | ||
}); | ||
}) | ||
@@ -127,3 +135,3 @@ .catch(err => { | ||
RoxLogger.debug('fetch From Cache'); | ||
const cached = this.cacheService.get(CACHE_KEY); | ||
const cached = this.cache.get(CACHE_KEY); | ||
let parsed; | ||
@@ -163,3 +171,3 @@ if (cached) { | ||
RoxLogger.debug(`Store in cache response = ${JSON.stringify(response)}`); | ||
this.cacheService.set(CACHE_KEY, JSON.stringify(response), CACHE_TTL); | ||
this.cache.set(CACHE_KEY, JSON.stringify(response), CACHE_TTL); | ||
} | ||
@@ -171,7 +179,12 @@ | ||
} | ||
const parser = this.parsePayload(payload); | ||
if (!parser) { | ||
return Promise.reject('Failed to parse configuration'); | ||
} | ||
this.apply(parser, ...args); | ||
return this.verifyPayload(payload).then(verified => { | ||
if (!verified) { | ||
throw new Error("The payload has corrupted or it's authenticity cannot be securely verified."); | ||
} | ||
const parser = this.parsePayload(payload); | ||
if (!parser) { | ||
return Promise.reject('Failed to parse configuration'); | ||
} | ||
return this.apply(parser, ...args); | ||
}); | ||
} | ||
@@ -195,4 +208,5 @@ | ||
RoxLogger.debug( | ||
`failed to parse payload. response = ${JSON.stringify(response)} deviceProps = ${this | ||
.deviceProperties} app_key = ${this.appKey}` | ||
`failed to parse payload. response = ${JSON.stringify(response)} deviceProps = ${ | ||
this.deviceProperties | ||
} app_key = ${this.appKey}` | ||
); | ||
@@ -204,2 +218,11 @@ return null; | ||
verifyPayload(response) { | ||
const { signature_v0, data } = response; | ||
const signed_date = new Date(response.signed_date); | ||
if (!signed_date || signed_date > +new Date()) { | ||
return false; | ||
} | ||
return this.crypto.then(crypto => crypto.verify(data, signature_v0)); | ||
} | ||
calculatePayload(parser) { | ||
@@ -206,0 +229,0 @@ if (!parser) { |
import uuid from 'uuid/v4'; | ||
export default class DeviceProperties { | ||
constructor(cacheService) { | ||
this.cacheService = cacheService; | ||
constructor(cache) { | ||
this.cache = cache; | ||
this.distinct_id = this.generateDistinctId(); | ||
@@ -25,6 +25,6 @@ this.app_release = '0.0'; | ||
generateDistinctId() { | ||
let distinct_id = this.cacheService.get('distinctId'); | ||
let distinct_id = this.cache.get('distinctId'); | ||
if (!distinct_id) { | ||
distinct_id = uuid(); | ||
this.cacheService.set('distinctId', distinct_id); | ||
this.cache.set('distinctId', distinct_id); | ||
} | ||
@@ -31,0 +31,0 @@ return distinct_id; |
export let FetcherStatus = { | ||
APLLIED_FROM_EMBEDDED: 'APLLIED_FROM_EMBEDDED', | ||
APLLIED_FROM_CACHE: 'APLLIED_FROM_CACHE', | ||
APLLIED_FROM_NETWORK: 'APLLIED_FROM_NETWORK', | ||
APPLIED_FROM_EMBEDDED: 'APPLIED_FROM_EMBEDDED', | ||
APPLIED_FROM_CACHE: 'APPLIED_FROM_CACHE', | ||
APPLIED_FROM_NETWORK: 'APPLIED_FROM_NETWORK', | ||
ERROR_FETCH_FAILED: 'ERROR_FETCH_FAILED' | ||
@@ -6,0 +6,0 @@ }; |
@@ -6,2 +6,3 @@ export { default as ConfigurationFetcher } from './ConfigurationFetcher'; | ||
export { default as RoxLogger } from './RoxLogger'; | ||
export { default as BugsnagReporter } from './BugsnagReporter'; | ||
export { default as createRoxClient } from './Client'; |
@@ -30,5 +30,6 @@ import * as axios from 'axios'; | ||
.catch(err => { | ||
RoxLogger.error(`Unable to fetch ROX configuration ${err}`); | ||
return Promise.reject(new Error('Unable to fetch ROX configuration')); | ||
err.message = 'Unable to fetch rox configuration!\n' + err.message; | ||
RoxLogger.error(err); | ||
throw err; | ||
}); | ||
} |
@@ -0,5 +1,9 @@ | ||
import LRUCache from 'lru-cache'; | ||
import { RoxxTokenizer, RoxxTokenTypeRand, RoxxTokenTypeRator } from './RoxxTokenizer'; | ||
import BugsnagReporter from '../lib/BugsnagReporter'; | ||
import RoxLogger from '../lib/RoxLogger'; | ||
import * as RoxxOperatorsMap from '../lib/RoxxOperators'; | ||
import RoxLogger from '../lib/RoxLogger'; | ||
import { RoxxTokenizer, RoxxTokenTypeRand, RoxxTokenTypeRator } from './RoxxTokenizer'; | ||
import LRUCache from 'lru-cache'; | ||
const defaultCache = LRUCache(); | ||
@@ -9,3 +13,3 @@ | ||
/** | ||
* A parser for Roxx expressions. | ||
* A parser for Roxx expressions. | ||
* Roxx expression are polish notation expressions {@link https://en.wikipedia.org/wiki/Polish_notation} | ||
@@ -23,4 +27,4 @@ * @class | ||
* Given an operator function and stack, return an array of arguments for the operator. | ||
* @param {Function} operator | ||
* @param {Array} stack | ||
* @param {Function} operator | ||
* @param {Array} stack | ||
* @returns {Array} Array of arguments for operator | ||
@@ -54,3 +58,3 @@ * @private | ||
* Tokenizes and caches expr if not available in cache. | ||
* @param {string} expr | ||
* @param {string} expr | ||
* @returns {Array} Tokenized version of expr | ||
@@ -70,3 +74,3 @@ */ | ||
* Evaluates a Roxx expression. | ||
* | ||
* | ||
* @param {string} expr - Roxx expression string. | ||
@@ -101,3 +105,5 @@ * @returns {*} Result of Roxx expression evaluation. | ||
} catch (err) { | ||
RoxLogger.error('Oh uh! Encountered a Roxx exception: ', err); | ||
const message = 'Oh uh! An error occured during Roxx evaluation.'; | ||
RoxLogger.error(message, err); | ||
BugsnagReporter.error(message, err); | ||
result = false; | ||
@@ -104,0 +110,0 @@ } finally { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
0
57
11670
13
1328927
18
- Removedaxios@^0.17.0
- Removedlodash.clonedeep@^4.5.0
- Removedloglevel@^1.4.1
- Removedmd5@^2.2.1
- Removedqs@^6.5.0
- Removeduuid@^3.1.0
- Removedaxios@0.17.1(transitive)
- Removedcall-bind@1.0.7(transitive)
- Removedcharenc@0.0.2(transitive)
- Removedcrypt@0.0.2(transitive)
- Removeddefine-data-property@1.1.4(transitive)
- Removedes-define-property@1.0.0(transitive)
- Removedes-errors@1.3.0(transitive)
- Removedfollow-redirects@1.15.9(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedget-intrinsic@1.2.4(transitive)
- Removedgopd@1.0.1(transitive)
- Removedhas-property-descriptors@1.0.2(transitive)
- Removedhas-proto@1.0.3(transitive)
- Removedhas-symbols@1.0.3(transitive)
- Removedhasown@2.0.2(transitive)
- Removedis-buffer@1.1.6(transitive)
- Removedlodash.clonedeep@4.5.0(transitive)
- Removedloglevel@1.9.2(transitive)
- Removedmd5@2.3.0(transitive)
- Removedobject-inspect@1.13.3(transitive)
- Removedqs@6.13.1(transitive)
- Removedset-function-length@1.2.2(transitive)
- Removedside-channel@1.0.6(transitive)
- Removeduuid@3.4.0(transitive)