Skip to content

Commit

Permalink
Merge pull request #192 from skedify/feature/SKED-5848
Browse files Browse the repository at this point in the history
feature/SKED-5848: Expired access tokens cause infinite access_tokens DELETE loop in IE11 in the web-app
  • Loading branch information
gevalo1 authored Aug 24, 2020
2 parents ab31993 + e971155 commit 0c79076
Show file tree
Hide file tree
Showing 10 changed files with 631 additions and 1,089 deletions.
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
setupFiles: [],
setupFiles: ['./jest.setup.js'],
moduleFileExtensions: ['js'],
globals: {
'process.env.NODE_ENV': 'test',
Expand Down
3 changes: 3 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import crypto from 'crypto'

global.crypto = crypto
1,528 changes: 465 additions & 1,063 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 9 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@
"@babel/preset-env": "^7.11.0",
"@commitlint/cli": "^9.1.2",
"@commitlint/config-conventional": "^9.1.2",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-babel": "^5.2.0",
"@rollup/plugin-buble": "^0.21.3",
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-inject": "^4.0.2",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-replace": "^2.3.3",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-polyfills": "^2.3.0",
"codecov": "^3.7.2",
Expand All @@ -66,15 +73,7 @@
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
"rollup": "^2.26.4",
"rollup-plugin-alias": "^2.2.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-buble": "^0.19.8",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-inject": "^3.0.2",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-terser": "^6.1.0",
"rollup-watch": "^4.3.1",
"rollup-plugin-terser": "^7.0.0",
"semantic-release": "^17.1.1",
"serve": "^11.3.2"
},
Expand All @@ -84,7 +83,6 @@
}
},
"dependencies": {
"axios": "^0.19.2",
"uuid": "^8.3.0"
"axios": "^0.19.2"
}
}
23 changes: 13 additions & 10 deletions rollup.config.common.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import alias from 'rollup-plugin-alias'
import buble from 'rollup-plugin-buble'
import commonjs from 'rollup-plugin-commonjs'
import inject from 'rollup-plugin-inject'
import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
import alias from '@rollup/plugin-alias'
import buble from '@rollup/plugin-buble'
import commonjs from '@rollup/plugin-commonjs'
import inject from '@rollup/plugin-inject'
import resolve from '@rollup/plugin-node-resolve'
import babel from '@rollup/plugin-babel'

import PACKAGE from './package.json'

Expand All @@ -16,7 +16,12 @@ export function createUMDConfig(merger) {
format: 'umd',
name: 'Skedify',
file: PACKAGE.main,

globals: {
crypto: 'crypto',
},
},
external: ['crypto'],
plugins: [
alias({
resolve: ['.js', ''],
Expand All @@ -27,12 +32,10 @@ export function createUMDConfig(merger) {
extensions: ['.js', '/index.js'],
preferBuiltins: false,
}),
commonjs({
namedExports: {},
}),
commonjs(),
babel({
include: ['node_modules/axios/**', 'src/**'],
runtimeHelpers: true,
babelHelpers: 'bundled',
}),
buble({
namedFunctionExpressions: false,
Expand Down
2 changes: 1 addition & 1 deletion rollup.config.dev.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import replace from 'rollup-plugin-replace'
import replace from '@rollup/plugin-replace'

import { createUMDConfig } from './rollup.config.common'

Expand Down
2 changes: 1 addition & 1 deletion rollup.config.prod.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import replace from 'rollup-plugin-replace'
import replace from '@rollup/plugin-replace'
import { terser } from 'rollup-plugin-terser'

import { createUMDConfig } from './rollup.config.common'
Expand Down
33 changes: 33 additions & 0 deletions src/util/createToken.browser.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import crypto from 'crypto'

describe('createToken', () => {
beforeAll(() => {
// I know we "fake" the browser implementation, however this way
// we are still testing the browser detection itself.
crypto.getRandomValues = (buffer) => crypto.randomFillSync(buffer)
})

afterAll(() => {
// Remove our fake implementation again
//eslint-disable-next-line better/no-deletes
delete crypto.getRandomValues
})

it('should generate a random string', () => {
// We are only importing it now because otherwise our `getRandomValues` implementation
// won't get pucked up correctly.
// It's not super clean but it works for now.
const createToken = require('./createToken').default //eslint-disable-line global-require

expect(createToken()).toBeDefined()
})

it('should remove all dashes from the uuid', () => {
// We are only importing it now because otherwise our `getRandomValues` implementation
// won't get pucked up correctly.
// It's not super clean but it works for now.
const createToken = require('./createToken').default //eslint-disable-line global-require

expect(createToken()).not.toContain('-')
})
})
107 changes: 105 additions & 2 deletions src/util/createToken.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,108 @@
import { v4 as uuid } from 'uuid'
import crypto from 'crypto'

/**
* This code is copied from:
* - https://www.npmjs.com/package/uuid
* - https://github.com/uuidjs/uuid/tree/v8.3.0
*
* The issue with the UUID package is that it support EITHER
* the browser OR NodeJS, but not both at the same time.
* This is an issue because we use the SDK in both the Browser & NodeJS.
*
* In rollup.config.common.js you can see that we build for the browser (node-resolve rollup plugin)
* Because of that the UUID package would be broken in our NodeJS packages.
*
* The fix here is inside the `rng()` function, where we check if the `getRandomValues` exists
* If it doesn't we use `crypto.randomFillSync` instead.
*
* Note that the code here was also SHRUNK DOWN for our use case. It doesn't have the same support as the real package!
* We only keep what we need!
*
* Interesting: There is also a proposal to make UUID a standard in JavaScript: https://github.com/tc39/proposal-uuid
* Might be something we can use in the future if it actually becomes a thing!
*/

const rnds8 = new Uint8Array(16)

const getRandomValues =
// eslint-disable-next-line better/no-typeofs
(typeof crypto !== 'undefined' &&
crypto.getRandomValues &&
crypto.getRandomValues.bind(crypto)) ||
// eslint-disable-next-line better/no-typeofs
(typeof msCrypto !== 'undefined' &&
// eslint-disable-next-line better/no-typeofs,no-undef
/* istanbul ignore next */ typeof msCrypto.getRandomValues === 'function' &&
// eslint-disable-next-line no-undef
/* istanbul ignore next */ msCrypto.getRandomValues.bind(msCrypto))

function rng() {
if (getRandomValues) {
// For Browsers
return getRandomValues(rnds8)
}

// If we're here, we're in a NodeJS environment
return crypto.randomFillSync(rnds8)
}

function validate(uuid) {
const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i

// eslint-disable-next-line better/no-typeofs
return typeof uuid === 'string' && REGEX.test(uuid)
}

const byteToHex = []

// eslint-disable-next-line better/no-fors
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).substr(1))
}

function stringify(arr, offset = 0) {
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
const uuid = `${
byteToHex[arr[offset + 0]] +
byteToHex[arr[offset + 1]] +
byteToHex[arr[offset + 2]] +
byteToHex[arr[offset + 3]]
}-${byteToHex[arr[offset + 4]]}${byteToHex[arr[offset + 5]]}-${
byteToHex[arr[offset + 6]]
}${byteToHex[arr[offset + 7]]}-${byteToHex[arr[offset + 8]]}${
byteToHex[arr[offset + 9]]
}-${byteToHex[arr[offset + 10]]}${byteToHex[arr[offset + 11]]}${
byteToHex[arr[offset + 12]]
}${byteToHex[arr[offset + 13]]}${byteToHex[arr[offset + 14]]}${
byteToHex[arr[offset + 15]]
}`.toLowerCase()

// Consistency check for valid UUID. If this throws, it's likely due to one
// of the following:
// - One or more input array values don't map to a hex octet (leading to
// "undefined" in the uuid)
// - Invalid input values for the RFC `version` or `variant` fields
// istanbul ignore next
if (!validate(uuid)) {
throw new TypeError('Stringified UUID is invalid')
}

return uuid
}

function v4(options = {}) {
const rnds = options.random || (options.rng || rng)()

// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
// eslint-disable-next-line no-bitwise
rnds[6] = (rnds[6] & 0x0f) | 0x40
// eslint-disable-next-line no-bitwise
rnds[8] = (rnds[8] & 0x3f) | 0x80

return stringify(rnds)
}

export default function createToken() {
return uuid().replace(/-/g, '')
return v4().replace(/-/g, '')
}
File renamed without changes.

0 comments on commit 0c79076

Please sign in to comment.