Socket
Socket
Sign inDemoInstall

juice-shop-ctf-cli

Package Overview
Dependencies
216
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 8.1.3 to 8.2.0

lib/fetchCodeSnippets.js

6

bin/juice-shop-ctf.js
#!/usr/bin/env node
/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const juiceShopCtfCli = require('../index')
juiceShopCtfCli()

1

CONTRIBUTING.md

@@ -9,2 +9,3 @@ # Contributing [![GitHub contributors](https://img.shields.io/github/contributors/bkimminich/juice-shop-ctf.svg)](https://github.com/bkimminich/juice-shop-ctf/graphs/contributors) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)

![Snyk Vulnerabilities for npm package](https://img.shields.io/snyk/vulnerabilities/npm/juice-shop-ctf-cli.svg)
![Merge Chance](https://img.shields.io/endpoint?url=https%3A%2F%2Fmerge-chance.info%2Fbadge%3Frepo%3Dbkimminich/juice-shop-ctf)

@@ -11,0 +12,0 @@ Found a bug? Got an idea for enhancement? Feel like adding support for

25

HALL_OF_FAME.md

@@ -14,17 +14,18 @@ # Hall of Fame

As reported by [`gitstats`](http://gitstats.sourceforge.net/) analysis
of `master` as of Thu, 13 Aug 2020 after deduplication with `.mailmap`
of `master` as of Sun, 11 Apr 2021 after deduplication with `.mailmap`
and
[conversion into Markdown](https://jmalarcon.github.io/markdowntables/).
| Author | Commits (%) | + lines | - lines | First commit | Last commit | Age | Active days | # by commits |
|:-----------------------------------|:-------------|:--------|:--------|:-------------|:------------|:--------------------|:------------|:-------------|
| Björn Kimminich | 466 (84.57%) | 26116 | 17197 | 2016-11-27 | 2020-08-06 | 1347 days, 16:56:43 | 154 | 1 |
| Jannik Hollenbach | 32 (5.81%) | 3950 | 1898 | 2017-12-10 | 2019-03-28 | 472 days, 21:13:50 | 9 | 2 |
| greenkeeper\[bot\] | 25 (4.54%) | 25 | 25 | 2018-02-05 | 2019-03-20 | 408 days, 3:06:26 | 21 | 3 |
| Josh Grossman | 12 (2.18%) | 204 | 9 | 2017-01-31 | 2017-02-01 | 10:28:48 | 2 | 4 |
| Simon Basset | 7 (1.27%) | 362 | 12 | 2018-03-22 | 2018-03-29 | 6 days, 17:13:35 | 5 | 5 |
| ElJeffe | 4 (0.73%) | 405 | 15 | 2019-11-17 | 2019-11-20 | 2 days, 22:27:37 | 2 | 6 |
| dependabot\[bot\] | 2 (0.36%) | 9 | 80 | 2019-10-10 | 2019-12-28 | 78 days, 16:31:46 | 2 | 7 |
| JuiceShopBot | 2 (0.36%) | 3 | 3 | 2020-03-09 | 2020-04-25 | 46 days, 18:10:29 | 2 | 8 |
| whitesource-bolt-for-github\[bot\] | 1 (0.18%) | 8 | 0 | 2019-05-23 | 2019-05-23 | 0:00:00 | 1 | 9 |
|Author|Commits (%)|+ lines|- lines|First commit|Last commit|Age|Active days|# by commits|
|--- |--- |--- |--- |--- |--- |--- |--- |--- |
|Björn Kimminich|506 (84.47%)|27917|19881|2016-11-27|2021-04-11|1595 days, 22:09:29|163|1|
|Jannik Hollenbach|32 (5.34%)|3950|1898|2017-12-10|2019-03-28|472 days, 21:13:50|9|2|
|greenkeeper\[bot\]|25 (4.17%)|25|25|2018-02-05|2019-03-20|408 days, 3:06:26|21|3|
|Josh Grossman|12 (2.00%)|204|9|2017-01-31|2017-02-01|10:28:48|2|4|
|Simon Basset|7 (1.17%)|362|12|2018-03-22|2018-03-29|6 days, 17:13:35|5|5|
|JuiceShopBot|7 (1.17%)|9|34|2020-03-09|2021-03-07|362 days, 23:15:44|6|6|
|ElJeffe|4 (0.67%)|405|15|2019-11-17|2019-11-20|2 days, 22:27:37|2|7|
|dependabot\[bot\]|3 (0.50%)|12|83|2019-10-10|2020-12-11|427 days, 10:56:03|3|8|
|Jamie McCrindle|2 (0.33%)|17|15|2020-10-11|2020-10-11|0:11:47|1|9|
|whitesource-bolt-for-github\[bot\]|1 (0.17%)|8|0|2019-05-23|2019-05-23|0:00:00|1|10|

@@ -31,0 +32,0 @@ ## Stargazers (over time)

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
require('colors') // no assignment necessary as this module extends the String prototype

@@ -6,2 +11,3 @@ const inquirer = require('inquirer')

const fetchCountryMapping = require('./lib/fetchCountryMapping')
const fetchCodeSnippets = require('./lib/fetchCodeSnippets')
const readConfigStream = require('./lib/readConfigStream')

@@ -65,2 +71,9 @@ const fs = require('fs')

default: 0
},
{
type: 'list',
name: 'insertHintSnippets',
message: 'Insert a code snippet as hint for each challenge?',
choices: [options.noHintSnippets, options.freeHintSnippets, options.paidHintSnippets],
default: 0
}

@@ -85,6 +98,7 @@ ]

const [fetchedSecretKey, challenges, countryMapping] = await Promise.all([
const [fetchedSecretKey, challenges, countryMapping, vulnSnippets] = await Promise.all([
fetchSecretKey(answers.ctfKey),
fetchChallenges(answers.juiceShopUrl),
fetchCountryMapping(answers.countryMapping)
fetchCountryMapping(answers.countryMapping),
fetchCodeSnippets(answers.juiceShopUrl, answers.insertHintSnippets === options.noHintSnippets)
])

@@ -96,4 +110,6 @@

insertHintUrls: answers.insertHintUrls,
insertHintSnippets: answers.insertHintSnippets,
ctfKey: fetchedSecretKey,
countryMapping,
vulnSnippets,
outputLocation: argv.output

@@ -100,0 +116,0 @@ })

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const calculateScore = require('./calculateScore')

@@ -5,5 +10,6 @@ const options = require('./options')

/* The hint costs depend on the kind of hint and the difficulty of the challenge they are for:
paid text hint = 10% of the challenge's score value
paid url hint = 20% of the challenge's score value
free text/url hint = free (as in free beer)
paid text hint = 10% of the challenge's score value
paid url hint = 20% of the challenge's score value
paid code snippet hint = 30% of the challenge's score value
free text/url/snippet hint = free (as in free beer)
*/

@@ -16,2 +22,4 @@ function calculateHintCost ({ difficulty }, hintOption) {

costMultiplier = 0.2
} else if (hintOption === options.paidHintSnippets) {
costMultiplier = 0.3
}

@@ -18,0 +26,0 @@ return costMultiplier * calculateScore(difficulty)

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
/* This is a default multiplier whereby the score will be = (difficulty x multiplier)

@@ -2,0 +7,0 @@ i.e. using these multipliers will create challenges with the following scores:

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const request = require('request-promise')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const request = require('request-promise')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const request = require('request-promise')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -7,3 +12,3 @@ const calculateScore = require('../calculateScore')

function createCtfdExport (challenges, { insertHints, insertHintUrls, ctfKey }) {
function createCtfdExport (challenges, { insertHints, insertHintUrls, insertHintSnippets, ctfKey, vulnSnippets }) {
function insertChallenge (data, challenge) {

@@ -62,2 +67,14 @@ const score = calculateScore(challenge.difficulty)

function insertHintSnippet ({ hints }, challenge, snippet) {
hints.results.push(
{
id: 20000 + challenge.id,
type: 'standard',
challenge_id: challenge.id,
content: '<pre><code>' + snippet + '</code></pre>',
cost: calculateHintCost(challenge, insertHintSnippets)
}
)
}
return new Promise((resolve, reject) => {

@@ -81,2 +98,5 @@ try {

}
if (vulnSnippets[challenge.key] && insertHintSnippets !== options.noHintSnippets) {
insertHintSnippet(data, challenge, vulnSnippets[challenge.key])
}
}

@@ -83,0 +103,0 @@ }

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -49,3 +54,3 @@ const { hash } = require('bcryptjs')

async function createFbctfExport (challenges, { insertHints, insertHintUrls, ctfKey, countryMapping }) {
async function createFbctfExport (challenges, { insertHints, insertHintUrls, insertHintSnippets, ctfKey, countryMapping, vulnSnippets }) {
const fbctfTemplate = await loadTemplate()

@@ -70,2 +75,5 @@

}
if (insertHintSnippets !== options.noHintSnippets && vulnSnippets[key]) {
hintText.push(vulnSnippets[key])
}

@@ -84,4 +92,4 @@ return {

flag: hmac(ctfKey, name),
hint: hintText.join('\n'),
penalty: calculateHintCost({ difficulty }, insertHints) + calculateHintCost({ difficulty }, insertHintUrls),
hint: hintText.join('\n\n'),
penalty: calculateHintCost({ difficulty }, insertHints) + calculateHintCost({ difficulty }, insertHintUrls) + calculateHintCost({ difficulty }, insertHintSnippets),
links: [],

@@ -88,0 +96,0 @@ attachments: []

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const writeToCtfdZip = require('../writeToCtfdZip')

@@ -2,0 +7,0 @@ const writeToFbctfJson = require('../writeToFbctfJson')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -13,3 +18,3 @@ const xmlBuilder = require('xmlbuilder')

function createRtbExport (challenges, { insertHints, insertHintUrls, ctfKey }) {
function createRtbExport (challenges, { insertHints, insertHintUrls, insertHintSnippets, ctfKey, vulnSnippets }) {
function checkHints (challenge) {

@@ -23,2 +28,6 @@ return (challenge.hint && insertHints !== options.noTextHints)

function checkHintsSnippet (challenge) {
return (vulnSnippets[challenge.key] && insertHintSnippets !== options.noHintSnippets)
}
function getDescription (category) {

@@ -41,2 +50,3 @@ if (!rtbTemplate.categories[category]) {

const includeHintUrl = checkHintsURL(challenge)
const includeHintSnippet = checkHintsSnippet(challenge)

@@ -59,2 +69,8 @@ if (includeHint || includeHintUrl) {

}
if (includeHintSnippet) {
const hint = hints.ele('hint')
hint.ele('description', turndownService.turndown(vulnSnippets[challenge.key]))
hint.ele('price', calculateHintCost(challenge, insertHintSnippets))
count += 1
}
hints.att({ count: count })

@@ -61,0 +77,0 @@ }

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const jsSHA = require('jssha')

@@ -2,0 +7,0 @@

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
module.exports = {

@@ -8,2 +13,5 @@ noTextHints: 'No text hints',

paidHintUrls: 'Paid hint URLs',
noHintSnippets: 'No hint snippets',
freeHintSnippets: 'Free hint snippets',
paidHintSnippets: 'Paid hint snippets',
ctfdFramework: 'CTFd',

@@ -10,0 +18,0 @@ fbctfFramework: 'FBCTF',

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const yaml = require('js-yaml')

@@ -10,3 +15,4 @@ const Joi = require('joi')

insertHints: Joi.any().valid('none', 'free', 'paid').required(),
insertHintUrls: Joi.any().valid('none', 'free', 'paid').when('ctfFramework', { is: options.fbctfFramework, then: Joi.optional(), otherwise: Joi.required() })
insertHintUrls: Joi.any().valid('none', 'free', 'paid').when('ctfFramework', { is: options.fbctfFramework, then: Joi.optional(), otherwise: Joi.required() }),
insertHintSnippets: Joi.any().valid('none', 'free', 'paid').when('ctfFramework', { is: options.fbctfFramework, then: Joi.optional(), otherwise: Joi.required() })
})

@@ -16,2 +22,3 @@

const hintUrlsMap = { none: options.noHintUrls, free: options.freeHintUrls, paid: options.paidHintUrls }
const hintSnippetsMap = { none: options.noHintSnippets, free: options.freeHintSnippets, paid: options.paidHintSnippets }

@@ -34,2 +41,3 @@ function readConfigStream (stream) {

result.insertHintUrls = result.insertHintUrls ? hintUrlsMap[result.insertHintUrls] : options.noHintUrls
result.insertHintSnippets = result.insertHintSnippets ? hintSnippetsMap[result.insertHintSnippets] : options.noHintSnippets
resolve(result)

@@ -36,0 +44,0 @@ }

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
function isUrl (text) {

@@ -2,0 +7,0 @@ return text.match(/^(http|localhost|[0-9][0-9]?[0-9]?\.)/) !== null

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const fs = require('fs')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const fs = require('fs')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const fs = require('fs')

{
"name": "juice-shop-ctf-cli",
"version": "8.1.3",
"version": "8.2.0",
"description": "Capture-the-Flag (CTF) environment setup tools for OWASP Juice Shop",

@@ -43,3 +43,3 @@ "keywords": [

"coverage": "nyc report --reporter=lcov",
"e2e": "nyc --reporter=text mocha test/e2e --slow=15000 --timeout=30000",
"e2e": "nyc --reporter=text mocha test/e2e --slow=20000 --timeout=45000",
"lint": "standard",

@@ -84,3 +84,3 @@ "lint:fix": "standard --fix",

"engines": {
"node": "10 - 14"
"node": "12 - 15"
},

@@ -87,0 +87,0 @@ "preferGlobal": true,

@@ -64,2 +64,3 @@ # ![Juice Shop CTF Logo](https://raw.githubusercontent.com/bkimminich/juice-shop-ctf/master/images/JuiceShopCTF_Logo_100px.png) OWASP Juice Shop CTF Extension

insertHintUrls: none | free | paid # optional for FBCTF
insertHintSnippets: none | free | paid # optional for FBCTF
```

@@ -168,4 +169,4 @@

Extension and any contributions are Copyright © by Bjoern Kimminich
2016-2020.
2016-2021.
![Juice Shop CTF Logo](https://raw.githubusercontent.com/bkimminich/juice-shop-ctf/develop/images/JuiceShopCTF_Logo_400px.png)

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -19,3 +24,3 @@ chai.use(require('chai-as-promised'))

const TIMEOUT = 20000
const TIMEOUT = 45000
const juiceShopCtfCli = [path.join(__dirname, '../../bin/juice-shop-ctf.js')]

@@ -47,6 +52,7 @@

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/Backup archive written to /i).and
.eventually.match(/Insert a text hint along with each challenge\? No text hints/i).and
.eventually.match(/Insert a hint URL along with each challenge\? No hint URLs/i)
.eventually.match(/Insert a hint URL along with each challenge\? No hint URLs/i).and
.eventually.match(/Insert a code snippet as hint for each challenge\? No hint snippets/i)
})

@@ -56,3 +62,3 @@

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, DOWN, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, DOWN, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/Insert a text hint along with each challenge\? Free text hints/i)

@@ -63,3 +69,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, DOWN, DOWN, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, DOWN, DOWN, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/Insert a text hint along with each challenge\? Paid text hints/i)

@@ -70,3 +76,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, DOWN, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, DOWN, ENTER, ENTER], 2000)).to
.eventually.match(/Insert a hint URL along with each challenge\? Free hint URLs/i)

@@ -77,3 +83,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, DOWN, DOWN, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, DOWN, DOWN, ENTER, ENTER], 2000)).to
.eventually.match(/Insert a hint URL along with each challenge\? Paid hint URLs/i)

@@ -84,3 +90,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, 'localhorst', ENTER, ENTER, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, 'localhorst', ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/Failed to fetch challenges from API!/i)

@@ -91,3 +97,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, 'httpx://invalid/ctf-key', ENTER, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, 'httpx://invalid/ctf-key', ENTER, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/Failed to fetch secret key from URL!/i)

@@ -98,3 +104,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [DOWN, ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [DOWN, ENTER, ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/CTF framework to generate data for\? FBCTF/i)

@@ -105,3 +111,3 @@ })

this.timeout(TIMEOUT)
return expect(run(juiceShopCtfCli, [DOWN, DOWN, ENTER, ENTER, ENTER, ENTER, ENTER], 1500)).to
return expect(run(juiceShopCtfCli, [DOWN, DOWN, ENTER, ENTER, ENTER, ENTER, ENTER, ENTER], 1500)).to
.eventually.match(/CTF framework to generate data for\? RootTheBox/i)

@@ -113,3 +119,3 @@ })

fs.openSync(outputFile, 'w', 0)
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
return expect(run(juiceShopCtfCli, [ENTER, ENTER, ENTER, ENTER, ENTER, ENTER], 2000)).to
.eventually.match(/Failed to write output to file!/i)

@@ -123,6 +129,7 @@ })

insertHints: paid
insertHintUrls: paid`)
insertHintUrls: paid
insertHintSnippets: paid`)
this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to
.eventually.match(/Backup archive written to /i)

@@ -138,3 +145,3 @@ })

this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to
.eventually.match(/can not read /i)

@@ -148,6 +155,7 @@ })

insertHints: paid
insertHintUrls: invalidValue`)
insertHintUrls: invalidValue
insertHintSnippets: paid`)
this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile]).then(obj => obj.stdout)).to
.eventually.match(/"insertHintUrls" must be one of /i)

@@ -161,6 +169,7 @@ })

insertHints: paid
insertHintUrls: paid`)
insertHintUrls: paid
insertHintSnippets: paid`)
this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredCtfdOutputFile])
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredCtfdOutputFile])
.then(() => fs.existsSync(desiredCtfdOutputFile))).to

@@ -176,6 +185,7 @@ .eventually.equal(true)

insertHints: paid
insertHintUrls: paid`)
insertHintUrls: paid
insertHintSnippets: paid`)
this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredCtfdOutputFile])
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredCtfdOutputFile])
.then(() => fs.existsSync(desiredCtfdOutputFile))).to

@@ -191,6 +201,8 @@ .eventually.equal(true)

countryMapping: https://raw.githubusercontent.com/bkimminich/juice-shop/master/config/fbctf.yml
insertHints: paid`)
insertHints: paid
insertHintUrls: paid
insertHintSnippets: paid`)
this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredFbctfOutputFile])
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredFbctfOutputFile])
.then(() => fs.existsSync(desiredFbctfOutputFile))).to

@@ -206,6 +218,7 @@ .eventually.equal(true)

insertHints: paid
insertHintUrls: paid`)
insertHintUrls: paid
insertHintSnippets: paid`)
this.timeout(TIMEOUT)
return expect(execFile('npx', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredRtbOutputFile])
return expect(execFile('node', [juiceShopCtfCli[0], '--config', configFile, '--output', desiredRtbOutputFile])
.then(() => fs.existsSync(desiredRtbOutputFile))).to

@@ -212,0 +225,0 @@ .eventually.equal(true)

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -2,0 +7,0 @@ const expect = chai.expect

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -2,0 +7,0 @@ const expect = chai.expect

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const chai = require('chai')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const chai = require('chai')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const chai = require('chai')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -10,3 +15,3 @@ const chai = require('chai')

const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' }
const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} }

@@ -17,7 +22,7 @@ describe('Generated CTFd data', () => {

challenges = {
c1: { id: 1, name: 'c1', description: 'C1', difficulty: 1, category: '1' },
c2: { id: 2, name: 'c2', description: 'C2', difficulty: 2, category: '2' },
c3: { id: 3, name: 'c3', description: 'C3', difficulty: 3, category: '2' },
c4: { id: 4, name: 'c4', description: 'C4', difficulty: 4, category: '3' },
c5: { id: 5, name: 'c5', description: 'C5', difficulty: 5, category: '1' }
c1: { id: 1, key: 'k1', name: 'c1', description: 'C1', difficulty: 1, category: '1' },
c2: { id: 2, key: 'k2', name: 'c2', description: 'C2', difficulty: 2, category: '2' },
c3: { id: 3, key: 'k3', name: 'c3', description: 'C3', difficulty: 3, category: '2' },
c4: { id: 4, key: 'k4', name: 'c4', description: 'C4', difficulty: 4, category: '3' },
c5: { id: 5, key: 'k5', name: 'c5', description: 'C5', difficulty: 5, category: '1' }
}

@@ -69,3 +74,3 @@ })

return Promise.all([
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -78,3 +83,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -93,3 +98,3 @@ hints: {

return Promise.all([
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -102,3 +107,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -118,3 +123,3 @@ hints: {

return Promise.all([
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -128,3 +133,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -138,3 +143,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -148,3 +153,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '' })).to.eventually.deep.include(
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.include(
{

@@ -184,3 +189,3 @@ hints: {

return Promise.all([
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.not.deep.include(
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.not.deep.include(
{

@@ -193,3 +198,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.not.deep.include(
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.not.deep.include(
{

@@ -212,3 +217,3 @@ hints: {

return Promise.all([
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.not.deep.include(
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.not.deep.include(
{

@@ -221,3 +226,3 @@ hints: {

}),
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.not.deep.include(
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.not.deep.include(
{

@@ -224,0 +229,0 @@ hints: {

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -14,3 +19,3 @@ chai.use(require('chai-things'))

const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', countryMapping }
const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', countryMapping, vulnSnippets: {} }

@@ -133,3 +138,3 @@ const defaultChallenge1Mapping = {

...defaultChallenge1Mapping,
hint: 'hint1\nhttps://hint1.com',
hint: 'hint1\n\nhttps://hint1.com',
penalty: 30

@@ -136,0 +141,0 @@ }

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -9,3 +14,3 @@ chai.use(require('chai-things'))

const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' }
const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} }

@@ -16,7 +21,7 @@ describe('Generated RTB data', () => {

challenges = {
c1: { id: 1, name: 'c1', description: 'C1', difficulty: 1, category: '1' },
c2: { id: 2, name: 'c2', description: 'C2', difficulty: 2, category: '2' },
c3: { id: 3, name: 'c3', description: 'C3', difficulty: 3, category: '2' },
c4: { id: 4, name: 'c4', description: 'C4', difficulty: 4, category: '3' },
c5: { id: 5, name: 'c5', description: 'C5', difficulty: 5, category: '1' }
c1: { id: 1, key: 'k1', name: 'c1', description: 'C1', difficulty: 1, category: '1' },
c2: { id: 2, key: 'k2', name: 'c2', description: 'C2', difficulty: 2, category: '2' },
c3: { id: 3, key: 'k3', name: 'c3', description: 'C3', difficulty: 3, category: '2' },
c4: { id: 4, key: 'k4', name: 'c4', description: 'C4', difficulty: 4, category: '3' },
c5: { id: 5, key: 'k5', name: 'c5', description: 'C5', difficulty: 5, category: '1' }
}

@@ -60,6 +65,6 @@ })

return Promise.all([
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.deep.match(
expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match(
/<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>hint<\/description>\s{19}<price>0<\/price>/
),
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '' })).to.eventually.deep.match(
expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match(
/<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>hint<\/description>\s{19}<price>45<\/price>/

@@ -73,6 +78,6 @@ )

return Promise.all([
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '' })).to.eventually.deep.match(
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match(
/<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>\[C3]\(hintUrl\)<\/description>\s{19}<price>0<\/price>/
),
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '' })).to.eventually.deep.match(
expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match(
/<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>\[C3]\(hintUrl\)<\/description>\s{19}<price>90<\/price>/

@@ -85,3 +90,3 @@ )

challenges.c3.hintUrl = 'hintUrl#this-is-the-anchor-to-the-ebook-section'
return expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '' })).to.eventually.deep.match(
return expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match(
/<hint>\s{19}<description>\[This Is The Anchor To The Ebook Section]\(hintUrl#this-is-the-anchor-to-the-ebook-section\)<\/description>/

@@ -88,0 +93,0 @@ )

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -2,0 +7,0 @@ const expect = chai.expect

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -14,3 +19,3 @@ chai.use(require('chai-as-promised'))

}
function generateStream (url, ctfKey, insertHints, insertHintUrls) {
function generateStream (url, ctfKey, insertHints, insertHintUrls, insertHintSnippets) {
const yaml = `

@@ -21,2 +26,3 @@ juiceShopUrl: ${url}

insertHintUrls: ${insertHintUrls}
insertHintSnippets: ${insertHintSnippets}
`

@@ -35,4 +41,4 @@ return generateStreamFromYaml(yaml)

it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'paid')
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 2, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'paid', 'paid')

@@ -43,8 +49,9 @@ expect(readConfigStream(stream)).to.eventually.deep.equal({

insertHints: options.paidTextHints,
insertHintUrls: options.paidHintUrls
insertHintUrls: options.paidHintUrls,
insertHintSnippets: options.paidHintSnippets
})
})
it('should resolve with {127.0.0.1, theCtfKey, 2, 2} when using a yaml containing 127.0.0.1, theCtfKey, paid, paid', () => {
const stream = generateStream('127.0.0.1', 'theCtfKey', 'paid', 'paid')
it('should resolve with {127.0.0.1, theCtfKey, 2, 2, 2} when using a yaml containing 127.0.0.1, theCtfKey, paid, paid. paid', () => {
const stream = generateStream('127.0.0.1', 'theCtfKey', 'paid', 'paid', 'paid')

@@ -55,8 +62,9 @@ expect(readConfigStream(stream)).to.eventually.deep.equal({

insertHints: options.paidTextHints,
insertHintUrls: options.paidHintUrls
insertHintUrls: options.paidHintUrls,
insertHintSnippets: options.paidHintSnippets
})
})
it('should reject with an error when using a yaml containing notAUriNorAnIpValue, theCtfKey, paid, paid', () => {
const stream = generateStream('notAUriNorAnIpValue', 'theCtfKey', 'paid', 'paid')
it('should reject with an error when using a yaml containing notAUriNorAnIpValue, theCtfKey, paid, paid, paid', () => {
const stream = generateStream('notAUriNorAnIpValue', 'theCtfKey', 'paid', 'paid', 'paid')

@@ -66,4 +74,4 @@ expect(readConfigStream(stream)).to.be.rejectedWith(Error)

it('should reject with an error when using a yaml containing http://thejuiceshopurl.com\', 0, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 0, 'paid', 'paid')
it('should reject with an error when using a yaml containing http://thejuiceshopurl.com\', 0, paid, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 0, 'paid', 'paid', 'paid')

@@ -73,4 +81,4 @@ expect(readConfigStream(stream)).to.be.rejectedWith(Error)

it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 0, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, none, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'none', 'paid')
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 0, 2, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, none, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'none', 'paid', 'paid')

@@ -81,8 +89,9 @@ expect(readConfigStream(stream)).to.eventually.deep.equal({

insertHints: options.noTextHints,
insertHintUrls: options.paidHintUrls
insertHintUrls: options.paidHintUrls,
insertHintSnippets: options.paidHintSnippets
})
})
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 1, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, free, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'free', 'paid')
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 1, 2, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, free, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'free', 'paid', 'paid')

@@ -93,8 +102,9 @@ expect(readConfigStream(stream)).to.eventually.deep.equal({

insertHints: options.freeTextHints,
insertHintUrls: options.paidHintUrls
insertHintUrls: options.paidHintUrls,
insertHintSnippets: options.paidHintSnippets
})
})
it('should reject with an error when using a yaml containing http://thejuiceshopurl.com, theCtfKey, invalidValue, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'invalidValue', 'paid')
it('should reject with an error when using a yaml containing http://thejuiceshopurl.com, theCtfKey, invalidValue, paid, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'invalidValue', 'paid', 'paid')

@@ -104,4 +114,4 @@ expect(readConfigStream(stream)).to.be.rejectedWith(Error)

it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 0} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, none, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'none')
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 0, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, none, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'none', 'paid')

@@ -112,8 +122,9 @@ expect(readConfigStream(stream)).to.eventually.deep.equal({

insertHints: options.paidTextHints,
insertHintUrls: options.noHintUrls
insertHintUrls: options.noHintUrls,
insertHintSnippets: options.paidHintSnippets
})
})
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 1} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, free, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'free')
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 1, 2} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, free, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'free', 'paid')

@@ -124,11 +135,42 @@ expect(readConfigStream(stream)).to.eventually.deep.equal({

insertHints: options.paidTextHints,
insertHintUrls: options.freeHintUrls
insertHintUrls: options.freeHintUrls,
insertHintSnippets: options.paidHintSnippets
})
})
it('should reject with an error when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, invalidValue', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'invalidValue')
it('should reject with an error when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, invalidValue, paid', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'invalidValue', 'paid')
expect(readConfigStream(stream)).to.be.rejectedWith(Error)
})
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 2, 0} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, paid, none', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'paid', 'none')
expect(readConfigStream(stream)).to.eventually.deep.equal({
juiceShopUrl: 'http://thejuiceshopurl.com',
ctfKey: 'theCtfKey',
insertHints: options.paidTextHints,
insertHintUrls: options.paidHintUrls,
insertHintSnippets: options.noHintSnippets
})
})
it('should resolve with {http://thejuiceshopurl.com, theCtfKey, 2, 2, 1} when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, paid, free', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'paid', 'free')
expect(readConfigStream(stream)).to.eventually.deep.equal({
juiceShopUrl: 'http://thejuiceshopurl.com',
ctfKey: 'theCtfKey',
insertHints: options.paidTextHints,
insertHintUrls: options.paidHintUrls,
insertHintSnippets: options.freeHintSnippets
})
})
it('should reject with an error when using a yaml containing http://thejuiceshopurl.com, theCtfKey, paid, paid, invalidValue', () => {
const stream = generateStream('http://thejuiceshopurl.com', 'theCtfKey', 'paid', 'paid', 'invalidValue')
expect(readConfigStream(stream)).to.be.rejectedWith(Error)
})
})

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const chai = require('chai')

@@ -2,0 +7,0 @@ const expect = chai.expect

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const chai = require('chai')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const chai = require('chai')

@@ -0,1 +1,6 @@

/*
* Copyright (c) 2016-2021 Bjoern Kimminich.
* SPDX-License-Identifier: MIT
*/
const Promise = require('bluebird')

@@ -2,0 +7,0 @@ const chai = require('chai')

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc