error on import lint failure + some misc lint fixes (#2813)

Co-authored-by: Artur Paikin <artur@arturpaikin.com>
This commit is contained in:
Renée Kooi 2021-03-20 11:02:49 +01:00 committed by GitHub
parent 80081f012e
commit c1d15abf10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
107 changed files with 2398 additions and 1174 deletions

218
.eslintrc.js Normal file
View file

@ -0,0 +1,218 @@
'use strict'
const glob = require('glob')
// Configure import/no-extraneous-dependencies for test files in
// each package, which are allowed to import dependencies from their
// own package.json as well as the root package.json.
const importRules = []
for (const dir of glob.sync('packages/@uppy/*')) {
importRules.push({
files: [
`${dir}/**/*.test.js`,
`${dir}/test/**/*.js`,
`${dir}/rollup.config.js`,
],
rules: {
'import/no-extraneous-dependencies': ['error', {
devDependencies: true,
packageDir: [dir, '.'],
}],
},
})
}
module.exports = {
extends: ['transloadit'],
env: {
es6: true,
jest: true,
node: true,
// extra:
browser: true,
},
globals: {
window: true,
hexo: true,
},
plugins: [
'@babel/eslint-plugin',
'jest',
'node',
'prefer-import',
'promise',
'react',
// extra:
'compat',
'jsdoc',
],
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2020,
ecmaFeatures: {
jsx: true,
},
},
rules: {
// transloadit rules we are actually ok with in the uppy repo
'guard-for-in': ['off'],
'import/extensions': ['off'],
strict: ['off'],
'key-spacing': ['off'],
// transloadit rules we would like to enforce in the future
// but will require separate PRs to gradually get there
// and so the meantime: just warn
'array-callback-return': ['warn'],
'block-scoped-var': ['warn'],
'class-methods-use-this': ['warn'],
'consistent-return': ['warn'],
'default-case': ['warn'],
'global-require': ['warn'],
'implicit-arrow-linebreak': ['warn'],
'import/no-dynamic-require': ['warn'],
'import/no-unresolved': ['warn'],
'import/order': ['warn'],
'jsx-a11y/alt-text': ['warn'],
'jsx-a11y/anchor-has-content': ['warn'],
'jsx-a11y/click-events-have-key-events': ['warn'],
'jsx-a11y/control-has-associated-label': ['warn'],
'jsx-a11y/label-has-associated-control': ['warn'],
'jsx-a11y/media-has-caption': ['warn'],
'jsx-a11y/mouse-events-have-key-events': ['warn'],
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['warn'],
'jsx-a11y/no-noninteractive-element-interactions': ['warn'],
'jsx-a11y/no-static-element-interactions': ['warn'],
'no-await-in-loop': ['warn'],
'no-bitwise': ['warn'],
'no-continue': ['warn'],
'no-empty': ['warn'],
'no-lonely-if': ['warn'],
'no-mixed-operators': ['warn'],
'no-nested-ternary': ['warn'],
'no-param-reassign': ['warn'],
'no-redeclare': ['warn'],
'no-restricted-globals': ['warn'],
'no-restricted-properties': ['warn'],
'no-restricted-syntax': ['warn'],
'no-return-assign': ['warn'],
'no-shadow': ['warn'],
'no-underscore-dangle': ['warn'],
'no-unused-expressions': ['warn'],
'no-unused-vars': ['warn'],
'no-use-before-define': ['warn'],
'no-useless-concat': ['warn'],
'no-var': ['warn'],
'node/handle-callback-err': ['warn'],
'prefer-destructuring': ['warn'],
'prefer-spread': ['warn'],
radix: ['warn'],
'react/button-has-type': ['warn'],
'react/destructuring-assignment': ['warn'],
'react/forbid-prop-types': ['warn'],
'react/jsx-props-no-spreading': ['warn'],
'react/no-access-state-in-setstate': ['warn'],
'react/no-array-index-key': ['warn'],
'react/no-deprecated': ['warn'],
'react/no-this-in-sfc': ['warn'],
'react/no-will-update-set-state': ['warn'],
'react/prefer-stateless-function': ['warn'],
'react/sort-comp': ['warn'],
'react/style-prop-object': ['warn'],
'vars-on-top': ['warn'],
'import/no-extraneous-dependencies': ['error'],
// compat
'compat/compat': ['error'],
// jsdoc
'jsdoc/check-alignment': ['warn'],
'jsdoc/check-examples': ['warn'],
'jsdoc/check-param-names': ['warn'],
'jsdoc/check-syntax': ['warn'],
'jsdoc/check-tag-names': ['warn'],
'jsdoc/check-types': ['warn'],
'jsdoc/newline-after-description': ['warn'],
'jsdoc/valid-types': ['warn'],
'jsdoc/check-indentation': ['off'],
},
settings: {
react: {
pragma: 'h',
},
jsdoc: {
mode: 'typescript',
},
polyfills: [
'Promise',
'fetch',
'Object.assign',
'document.querySelector',
],
},
overrides: [
{
files: [
'*.test.js',
'test/endtoend/*.js',
'website/*.js',
'bin/**.js',
],
rules: {
'compat/compat': ['off'],
},
},
{
files: [
'bin/**.js',
'.eslintrc.js',
],
rules: {
'import/no-extraneous-dependencies': ['error', {
devDependencies: true,
}],
},
},
{
files: [
'packages/@uppy/locales/src/*.js',
'packages/@uppy/locales/template.js',
],
rules: {
camelcase: ['off'],
'quote-props': ['off'],
},
},
{
files: [
'website/themes/uppy/source/js/*.js',
],
rules: {
'prefer-const': ['off'],
},
},
{
files: ['test/endtoend/*/*.js'],
env: {
mocha: true,
},
},
{
files: ['packages/@uppy/react/src/**/*.js'],
rules: {
'import/no-extraneous-dependencies': ['error', {
peerDependencies: true,
}],
},
},
...importRules,
],
}

View file

@ -1,232 +0,0 @@
{
"extends": ["transloadit"],
"env": {
"es6": true,
"jest": true,
"node": true,
// extra:
"browser": true
},
"globals": {
"window": true,
"hexo": true
},
"plugins": [
"@babel/eslint-plugin",
"jest",
"node",
"prefer-import",
"promise",
"react",
// extra:
"compat",
"jsdoc"
],
"parser": "@babel/eslint-parser",
"parserOptions": {
"ecmaVersion": 2020,
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
// transloadit rules we are actually ok with in the uppy repo
////////////////////////////////////////////////////////////
"guard-for-in": ["off"],
"import/extensions": ["off"],
"strict": ["off"],
"key-spacing": ["off"],
// transloadit rules we would like to enforce in the future
// but will require separate PRs to gradually get there
// and so the meantime: just warn
////////////////////////////////////////////////////////////
"array-callback-return": ["warn"],
"block-scoped-var": ["warn"],
"class-methods-use-this": ["warn"],
"consistent-return": ["warn"],
"default-case": ["warn"],
"global-require": ["warn"],
"implicit-arrow-linebreak": ["warn"],
"import/no-dynamic-require": ["warn"],
"import/no-unresolved": ["warn"],
"import/order": ["warn"],
"jsx-a11y/alt-text": ["warn"],
"jsx-a11y/anchor-has-content": ["warn"],
"jsx-a11y/click-events-have-key-events": ["warn"],
"jsx-a11y/control-has-associated-label": ["warn"],
"jsx-a11y/label-has-associated-control": ["warn"],
"jsx-a11y/media-has-caption": ["warn"],
"jsx-a11y/mouse-events-have-key-events": ["warn"],
"jsx-a11y/no-interactive-element-to-noninteractive-role": ["warn"],
"jsx-a11y/no-noninteractive-element-interactions": ["warn"],
"jsx-a11y/no-static-element-interactions": ["warn"],
"no-await-in-loop": ["warn"],
"no-bitwise": ["warn"],
"no-continue": ["warn"],
"no-empty": ["warn"],
"no-lonely-if": ["warn"],
"no-mixed-operators": ["warn"],
"no-nested-ternary": ["warn"],
"no-param-reassign": ["warn"],
"no-redeclare": ["warn"],
"no-restricted-globals": ["warn"],
"no-restricted-properties": ["warn"],
"no-restricted-syntax": ["warn"],
"no-return-assign": ["warn"],
"no-shadow": ["warn"],
"no-underscore-dangle": ["warn"],
"no-unused-expressions": ["warn"],
"no-unused-vars": ["warn"],
"no-use-before-define": ["warn"],
"no-useless-concat": ["warn"],
"no-var": ["warn"],
"node/handle-callback-err": ["warn"],
"prefer-destructuring": ["warn"],
"prefer-spread": ["warn"],
"radix": ["warn"],
"react/button-has-type": ["warn"],
"react/destructuring-assignment": ["warn"],
"react/forbid-prop-types": ["warn"],
"react/jsx-props-no-spreading": ["warn"],
"react/no-access-state-in-setstate": ["warn"],
"react/no-array-index-key": ["warn"],
"react/no-deprecated": ["warn"],
"react/no-this-in-sfc": ["warn"],
"react/no-will-update-set-state": ["warn"],
"react/prefer-stateless-function": ["warn"],
"react/sort-comp": ["warn"],
"react/style-prop-object": ["warn"],
"vars-on-top": ["warn"],
"import/no-extraneous-dependencies": ["warn"],
// compat
////////////////////////////////////////////////////////////
"compat/compat": ["error"],
// jsdoc
////////////////////////////////////////////////////////////
"jsdoc/check-alignment": ["warn"],
"jsdoc/check-examples": ["warn"],
"jsdoc/check-param-names": ["warn"],
"jsdoc/check-syntax": ["warn"],
"jsdoc/check-tag-names": ["warn"],
"jsdoc/check-types": ["warn"],
"jsdoc/newline-after-description": ["warn"],
"jsdoc/valid-types": ["warn"],
"jsdoc/check-indentation": ["off"]
},
"settings": {
"react": {
"pragma": "h"
},
"jsdoc": {
"mode": "typescript"
},
"polyfills": [
"Promise",
"fetch",
"Object.assign",
"document.querySelector"
]
},
"overrides": [
{
"files": [
"*.test.js",
"test/endtoend/*.js",
"website/*.js",
"bin/*.js"
],
"rules": {
"compat/compat": ["off"]
}
},
{
"files": [
"packages/@uppy/locales/src/*.js",
"packages/@uppy/locales/template.js"
],
"rules": {
"camelcase": ["off"],
"quote-props": ["off"]
}
},
{
"files": [
"website/themes/uppy/source/js/*.js"
],
"rules": {
"prefer-const": ["off"]
}
},
{ "files": ["bin/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"devDependencies": true}] } },
{ "files": ["packages/uppy/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/uppy/"}] } },
{ "files": ["packages/@uppy/aws-s3/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/aws-s3/"}] } },
{ "files": ["packages/@uppy/aws-s3-multipart/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/aws-s3-multipart/"}] } },
{ "files": ["packages/@uppy/box/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/box/"}] } },
{ "files": ["packages/@uppy/companion/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/companion/"}] } },
{ "files": ["packages/@uppy/companion-client/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/companion-client/"}] } },
{ "files": ["packages/@uppy/core/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/core/"}] } },
{ "files": ["packages/@uppy/dashboard/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/dashboard/"}] } },
{ "files": ["packages/@uppy/drag-drop/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/drag-drop/"}] } },
{ "files": ["packages/@uppy/dropbox/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/dropbox/"}] } },
{ "files": ["packages/@uppy/facebook/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/facebook/"}] } },
{ "files": ["packages/@uppy/file-input/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/file-input/"}] } },
{ "files": ["packages/@uppy/form/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/form/"}] } },
{ "files": ["packages/@uppy/golden-retriever/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/golden-retriever/"}] } },
{ "files": ["packages/@uppy/google-drive/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/google-drive/"}] } },
{ "files": ["packages/@uppy/image-editor/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/image-editor/"}] } },
{ "files": ["packages/@uppy/informer/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/informer/"}] } },
{ "files": ["packages/@uppy/instagram/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/instagram/"}] } },
{ "files": ["packages/@uppy/locales/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/locales/"}] } },
{ "files": ["packages/@uppy/onedrive/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/onedrive/"}] } },
{ "files": ["packages/@uppy/progress-bar/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/progress-bar/"}] } },
{ "files": ["packages/@uppy/provider-views/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/provider-views/"}] } },
{ "files": ["packages/@uppy/react/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/react/"}] } },
{ "files": ["packages/@uppy/react-native/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/react-native/"}] } },
{ "files": ["packages/@uppy/redux-dev-tools/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/redux-dev-tools/"}] } },
{ "files": ["packages/@uppy/robodog/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/robodog/"}] } },
{ "files": ["packages/@uppy/screen-capture/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/screen-capture/"}] } },
{ "files": ["packages/@uppy/status-bar/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/status-bar/"}] } },
{ "files": ["packages/@uppy/store-default/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/store-default/"}] } },
{ "files": ["packages/@uppy/store-redux/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/store-redux/"}] } },
{ "files": ["packages/@uppy/svelte/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/svelte/"}] } },
{ "files": ["packages/@uppy/thumbnail-generator/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/thumbnail-generator/"}] } },
{ "files": ["packages/@uppy/transloadit/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/transloadit/"}] } },
{ "files": ["packages/@uppy/tus/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/tus/"}] } },
{ "files": ["packages/@uppy/unsplash/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/unsplash/"}] } },
{ "files": ["packages/@uppy/url/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/url/"}] } },
{ "files": ["packages/@uppy/utils/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/utils/"}] } },
{ "files": ["packages/@uppy/vue/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/vue/"}] } },
{ "files": ["packages/@uppy/webcam/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/webcam/"}] } },
{ "files": ["packages/@uppy/xhr-upload/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/xhr-upload/"}] } },
{ "files": ["packages/@uppy/zoom/**.js"], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "packages/@uppy/zoom/"}] } },
{ "files": ["examples/aws-companion/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/aws-companion/"}] } },
{ "files": ["examples/aws-presigned-url/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/aws-presigned-url/"}] } },
{ "files": ["examples/bundled/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/bundled/"}] } },
{ "files": ["examples/cdn-example/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/cdn-example/"}] } },
{ "files": ["examples/custom-provider/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/custom-provider/"}] } },
{ "files": ["examples/dev/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/dev/"}] } },
{ "files": ["examples/digitalocean-spaces/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/digitalocean-spaces/"}] } },
{ "files": ["examples/multiple-instances/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/multiple-instances/"}] } },
{ "files": ["examples/node-xhr/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/node-xhr/"}] } },
{ "files": ["examples/php-xhr/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/php-xhr/"}] } },
{ "files": ["examples/python-xhr/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/python-xhr/"}] } },
{ "files": ["examples/react-example/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/react-example/"}] } },
{ "files": ["examples/react-native-expo/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/react-native-expo/"}] } },
{ "files": ["examples/redux/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/redux/"}] } },
{ "files": ["examples/svelte-example/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/svelte-example/"}] } },
{ "files": ["examples/transloadit/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/transloadit/"}] } },
{ "files": ["examples/transloadit-textarea/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/transloadit-textarea/"}] } },
{ "files": ["examples/uppy-with-companion/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/uppy-with-companion/"}] } },
{ "files": ["examples/vue/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/vue/"}] } },
{ "files": ["examples/xhr-bundle/**.js" ], "rules": { "import/no-extraneous-dependencies": ["warn", {"packageDir": "examples/xhr-bundle/"}] } }
]
}

View file

@ -1,9 +1,10 @@
const glob = require('glob')
const Uppy = require('../packages/@uppy/core')
const { ESLint } = require('eslint')
const chalk = require('chalk')
const path = require('path')
const stringifyObject = require('stringify-object')
const fs = require('fs')
const Uppy = require('../packages/@uppy/core')
const uppy = new Uppy()
let localePack = {}
@ -14,7 +15,10 @@ console.warn('\n--> Make sure to run `npm run build:lib` for this locale script
const mode = process.argv[2]
if (mode === 'build') {
build()
build().catch((error) => {
console.error(error)
process.exit(1)
})
} else if (mode === 'test') {
test()
} else {
@ -177,7 +181,7 @@ function createTypeScriptLocale (plugin, pluginName) {
fs.writeFileSync(localePath, localeTypes)
}
function build () {
async function build () {
const { plugins, sources } = buildPluginsList()
for (const pluginName in plugins) {
@ -206,7 +210,16 @@ function build () {
const finalLocale = template.replace('en_US.strings = {}', `en_US.strings = ${prettyLocale}`)
const localePackagePath = path.join(__dirname, '..', 'packages', '@uppy', 'locales', 'src', 'en_US.js')
fs.writeFileSync(localePackagePath, finalLocale, 'utf-8')
const linter = new ESLint({
fix: true,
})
const [lintResult] = await linter.lintText(finalLocale, {
filePath: localePackagePath,
})
fs.writeFileSync(localePackagePath, lintResult.output, 'utf8')
console.log(`✅ Written '${localePackagePath}'`)
}

View file

@ -1,13 +1,12 @@
{
"name": "@uppy-example/aws-companion",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"@babel/core": "^7.2.2",
"aliasify": "^2.1.0",
"@uppy/aws-s3": "file:../../packages/@uppy/aws-s3",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/google-drive": "file:../../packages/@uppy/google-drive",
"@uppy/webcam": "file:../../packages/@uppy/webcam",
"babelify": "^10.0.0",
"body-parser": "^1.18.3",
"budo": "^11.6.1",
@ -22,7 +21,7 @@
"scripts": {
"copy": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm-run-all --serial copy --parallel start:*",
"start:client": "budo main.js:bundle.js -- -t babelify -g aliasify",
"start:client": "budo main.js:bundle.js -- -t babelify",
"start:server": "node server.js"
}
}

View file

@ -2,10 +2,13 @@
"name": "@uppy-example/aws-presigned-url",
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/aws-s3": "file:../../packages/@uppy/aws-s3",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"babelify": "^10.0.0",
"browserify": "^16.5.2",
"fs-write-stream-atomic": "^1.0.10"
"browserify": "^17.0.0",
"fs-write-stream-atomic": "^1.0.10",
"watchify": "^4.0.0"
},
"private": true,
"scripts": {

View file

@ -4,7 +4,6 @@ const fs = require('fs')
const createWriteStream = require('fs-write-stream-atomic')
const browserify = require('browserify')
const watchify = require('watchify')
const aliasify = require('aliasify')
const babelify = require('babelify')
const port = process.env.PORT || 8080
@ -17,13 +16,7 @@ const b = browserify({
})
b.plugin(watchify)
b.transform(babelify)
b.transform(aliasify, {
aliases: {
'@uppy': path.join(__dirname, '../../packages/@uppy'),
},
})
function bundle () {
return b.bundle((err, data) => {

View file

@ -2,12 +2,20 @@
"name": "@uppy-example/custom-provider",
"dependencies": {
"@babel/core": "^7.2.2",
"@uppy/companion-client": "file:../../packages/@uppy/companion-client",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/google-drive": "file:../../packages/@uppy/google-drive",
"@uppy/provider-views": "file:../../packages/@uppy/provider-views",
"@uppy/tus": "file:../../packages/@uppy/tus",
"babelify": "^10.0.0",
"body-parser": "^1.18.2",
"budo": "^11.3.2",
"express": "^4.16.2",
"express-session": "^1.15.6",
"npm-run-all": "^4.1.2"
"npm-run-all": "^4.1.2",
"preact": "8.2.9",
"request": "2.88.2"
},
"private": true,
"scripts": {

View file

@ -1,3 +1,5 @@
// The @uppy/ dependencies are resolved using aliasify
/* eslint-disable import/no-extraneous-dependencies */
const Uppy = require('@uppy/core/src')
const Dashboard = require('@uppy/dashboard/src')
const Instagram = require('@uppy/instagram/src')
@ -19,6 +21,7 @@ const XHRUpload = require('@uppy/xhr-upload/src')
const Transloadit = require('@uppy/transloadit/src')
const Form = require('@uppy/form/src')
const ImageEditor = require('@uppy/image-editor/src')
/* eslint-enable import/no-extraneous-dependencies */
// DEV CONFIG: pick an uploader

View file

@ -1,8 +1,10 @@
// The @uppy/ dependencies are resolved using aliasify
/* eslint-disable import/no-extraneous-dependencies */
const Uppy = require('@uppy/core/src')
const Tus = require('@uppy/tus/src')
const DragDrop = require('@uppy/drag-drop/src')
const ProgressBar = require('@uppy/progress-bar/src')
/* eslint-enable import/no-extraneous-dependencies */
module.exports = () => {
const uppyDragDrop = new Uppy({

View file

@ -2,7 +2,9 @@
"name": "@uppy-example/digitalocean-spaces",
"dependencies": {
"@babel/core": "^7.2.2",
"aliasify": "^2.1.0",
"@uppy/aws-s3": "file:../../packages/@uppy/aws-s3",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"babelify": "^10.0.0",
"body-parser": "^1.18.3",
"budo": "^11.6.1",

View file

@ -56,13 +56,6 @@ budo(path.join(__dirname, 'main.js'), {
port: PORT,
middleware: app,
browserify: {
transform: [
'babelify',
['aliasify', {
aliases: {
'@uppy': path.join(__dirname, '../../packages/@uppy'),
},
}],
],
transform: ['babelify'],
},
})

View file

@ -1,19 +1,16 @@
{
"name": "@uppy-example/multiple-instances",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/golden-retriever": "file:../../packages/@uppy/golden-retriever",
"babelify": "^10.0.0",
"budo": "^11.6.1"
},
"private": true,
"scripts": {
"css": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm run css && budo main.js:bundle.js -- -t babelify -g aliasify"
"start": "npm run css && budo main.js:bundle.js -- -t babelify"
}
}

View file

@ -1,7 +1,7 @@
const Uppy = require('@uppy/core')
const Webcam = require('@uppy/webcam')
const Dashboard = require('@uppy/dashboard')
const xhr = require('@uppy/xhr-upload')
const XHRUpload = require('@uppy/xhr-upload')
const uppy = new Uppy({
debug: true,
@ -14,6 +14,6 @@ uppy.use(Dashboard, {
target: 'body',
plugins: ['Webcam'],
})
uppy.use(xhr, {
uppy.use(XHRUpload, {
endpoint: 'http://localhost:3020/upload',
})

View file

@ -2,21 +2,23 @@
"name": "@uppy-example/node-xhr",
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/webcam": "file:../../packages/@uppy/webcam",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/xhr-upload": "file:../../packages/@uppy/xhr-upload",
"babelify": "^10.0.0",
"budo": "^11.3.2",
"cookie-parser": "^1.4.3",
"cors": "^2.8.4",
"formidable": "^1.2.1",
"npm-run-all": "^4.1.3",
"rimraf": "^2.6.2",
"uppy": "file:../../packages/uppy"
"rimraf": "^2.6.2"
},
"private": true,
"scripts": {
"copy": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm-run-all --serial copy --parallel start:*",
"start:client": "budo main.js:bundle.js -- -t babelify -g aliasify",
"start:client": "budo main.js:bundle.js -- -t babelify",
"start:server": "mkdir -p uploads && node server.js"
}
}

View file

@ -2,21 +2,23 @@
"name": "@uppy-example/php-xhr",
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/webcam": "file:../../packages/@uppy/webcam",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/xhr-upload": "file:../../packages/@uppy/xhr-upload",
"babelify": "^10.0.0",
"budo": "^11.3.2",
"cookie-parser": "^1.4.3",
"cors": "^2.8.4",
"formidable": "^1.2.1",
"npm-run-all": "^4.1.3",
"rimraf": "^2.6.2",
"uppy": "file:../../packages/uppy"
"rimraf": "^2.6.2"
},
"private": true,
"scripts": {
"copy": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm-run-all --serial copy --parallel start:*",
"start:client": "budo main.js:bundle.js -- -t babelify -g aliasify",
"start:client": "budo main.js:bundle.js -- -t babelify",
"start:server": "mkdir -p uploads && php -S 0.0.0.0:3020"
}
}

View file

@ -2,21 +2,23 @@
"name": "@uppy-example/python-xhr",
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/webcam": "file:../../packages/@uppy/webcam",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/xhr-upload": "file:../../packages/@uppy/xhr-upload",
"babelify": "^10.0.0",
"budo": "^11.3.2",
"cookie-parser": "^1.4.3",
"cors": "^2.8.4",
"formidable": "^1.2.1",
"npm-run-all": "^4.1.3",
"rimraf": "^2.6.2",
"uppy": "file:../../packages/uppy"
"rimraf": "^2.6.2"
},
"private": true,
"scripts": {
"copy": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm-run-all --serial copy --parallel start:*",
"start:client": "budo main.js:bundle.js -- -t babelify -g aliasify",
"start:client": "budo main.js:bundle.js -- -t babelify",
"start:server": "mkdir -p uploads && python server.py"
}
}

View file

@ -1,14 +1,8 @@
{
"name": "@uppy-example/react-example",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"aliasify": "^2.1.0",
"babelify": "^10.0.0",
"budo": "^11.6.2",
"react": "^16.8.6",
@ -17,6 +11,6 @@
"private": true,
"scripts": {
"css": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm run css && budo main.js:bundle.js -- -r react:react -r react-dom:react-dom -t babelify -g aliasify"
"start": "npm run css && budo main.js:bundle.js -- -r react:react -r react-dom:react-dom -t babelify"
}
}

View file

@ -1,13 +1,11 @@
{
"name": "@uppy-example/redux",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/store-redux": "file:../../packages/@uppy/store-redux",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/tus": "file:../../packages/@uppy/tus",
"babelify": "^10.0.0",
"budo": "^11.6.1",
"redux": "^4.0.1",
@ -16,6 +14,6 @@
"private": true,
"scripts": {
"css": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm run css && budo main.js:bundle.js -- -t babelify -g aliasify"
"start": "npm run css && budo main.js:bundle.js -- -t babelify"
}
}

View file

@ -1,12 +1,7 @@
{
"name": "@uppy-example/transloadit-textarea",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"aliasify": "^2.1.0",
"@uppy/robodog": "file:../../packages/@uppy/robodog",
"browserify": "^16.5.2",
"drag-drop": "^4.2.0",
"ecstatic": "^4.1.4",
@ -14,6 +9,6 @@
},
"private": true,
"scripts": {
"start": "browserify -g aliasify main.js > bundle.js && ecstatic"
"start": "browserify main.js -o bundle.js && ecstatic"
}
}

View file

@ -1,13 +1,8 @@
{
"name": "@uppy-example/transloadit",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"@babel/core": "^7.4.4",
"aliasify": "^2.1.0",
"@uppy/robodog": "file:../../packages/@uppy/robodog",
"babelify": "^10.0.0",
"budo": "^11.3.2",
"express": "^4.16.4",
@ -16,6 +11,6 @@
"private": true,
"scripts": {
"css": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "npm run css && (node server & budo main.js:bundle.js -- -t babelify -g aliasify & wait)"
"start": "npm run css && (node server & budo main.js:bundle.js -- -t babelify & wait)"
}
}

View file

@ -1,13 +1,10 @@
{
"name": "@uppy-example/xhr-bundle",
"aliasify": {
"aliases": {
"@uppy": "../../packages/@uppy"
}
},
"dependencies": {
"@babel/core": "^7.2.2",
"aliasify": "^2.1.0",
"@uppy/core": "file:../../packages/@uppy/core",
"@uppy/dashboard": "file:../../packages/@uppy/dashboard",
"@uppy/xhr-upload": "file:../../packages/@uppy/xhr-upload",
"babelify": "^10.0.0",
"budo": "^11.6.1",
"cors": "^2.8.5",
@ -19,7 +16,7 @@
"scripts": {
"css": "cp ../../packages/uppy/dist/uppy.min.css .",
"start": "run-p start:*",
"start:client": "npm run css && budo main.js:bundle.js -- -t babelify -g aliasify",
"start:client": "npm run css && budo main.js:bundle.js -- -t babelify",
"start:server": "node serve.js"
}
}

1848
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -79,7 +79,6 @@
"@uppy/xhr-upload": "file:packages/@uppy/xhr-upload",
"@uppy/zoom": "file:packages/@uppy/zoom",
"deep-freeze": "0.0.1",
"eslint-config-transloadit": "^1.1.4",
"remark-lint-uppy": "file:private/remark-lint-uppy",
"uppy": "file:packages/uppy",
"uppy.io": "file:website"
@ -98,10 +97,8 @@
"@goto-bus-stop/envify": "5.0.0",
"@jamen/lorem": "0.2.0",
"@lerna/run": "^3.21.0",
"@octokit/rest": "16.43.1",
"@rollup/plugin-node-resolve": "^11.0.1",
"@size-limit/preset-big-lib": "4.5.6",
"@transloadit/prettier-bytes": "0.0.7",
"@tsconfig/svelte": "^1.0.10",
"@types/aws-serverless-express": "3.3.3",
"@types/compression": "1.7.0",
@ -131,7 +128,6 @@
"babel-plugin-inline-package-json": "2.0.0",
"babelify": "10.0.0",
"brake": "1.0.1",
"browser-resolve": "2.0.0",
"browser-sync": "2.26.7",
"browserify": "16.5.2",
"chai": "4.2.0",
@ -142,18 +138,16 @@
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.2",
"es6-promise": "4.2.8",
"eslint": "7.6.0",
"eslint-config-standard": "14.1.1",
"eslint-config-standard-jsx": "8.1.0",
"eslint": "7.22.0",
"eslint-config-transloadit": "^1.1.4",
"eslint-plugin-compat": "3.8.0",
"eslint-plugin-import": "2.22.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jest": "23.20.0",
"eslint-plugin-jsdoc": "30.2.2",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prefer-import": "0.0.1",
"eslint-plugin-promise": "4.2.1",
"eslint-plugin-react": "7.20.6",
"eslint-plugin-standard": "4.0.1",
"eslint-plugin-react": "7.22.0",
"events.once": "2.0.2",
"execa": "4.0.0",
"exorcist": "1.0.1",
@ -162,7 +156,6 @@
"github-contributors-list": "1.2.4",
"glob": "7.1.6",
"globby": "9.2.0",
"gzip-size": "5.1.1",
"http-proxy": "1.18.1",
"isomorphic-fetch": "2.2.1",
"jest": "26.4.0",
@ -208,7 +201,6 @@
"tar": "4.4.13",
"temp-write": "3.4.0",
"tinyify": "3.0.0",
"touch": "3.1.0",
"tsd": "^0.11.0",
"tsify": "5.0.1",
"tus-node-server": "0.3.2",

View file

@ -1,11 +0,0 @@
{
"extends": "standard",
"env": {
"browser": false,
"node": true
},
"root": true,
"rules": {
"eqeqeq": ["error", "smart"]
}
}

View file

@ -3,6 +3,9 @@ const express = require('express')
const ms = require('ms')
// @ts-ignore
const Grant = require('grant').express()
const merge = require('lodash/merge')
const cookieParser = require('cookie-parser')
const interceptor = require('express-interceptor')
const grantConfig = require('./config/grant')()
const providerManager = require('./server/provider')
const controllers = require('./server/controllers')
@ -10,12 +13,9 @@ const s3 = require('./server/controllers/s3')
const getS3Client = require('./server/s3-client')
const url = require('./server/controllers/url')
const emitter = require('./server/emitter')
const merge = require('lodash/merge')
const redis = require('./server/redis')
const cookieParser = require('cookie-parser')
const { getURLBuilder } = require('./server/helpers/utils')
const jobs = require('./server/jobs')
const interceptor = require('express-interceptor')
const logger = require('./server/logger')
const middlewares = require('./server/middlewares')
const { ProviderApiError, ProviderAuthError } = require('./server/provider/error')
@ -24,7 +24,7 @@ const { getCredentialsOverrideMiddleware } = require('./server/provider/credenti
const defaultOptions = {
server: {
protocol: 'http',
path: ''
path: '',
},
providerOptions: {
s3: {
@ -33,10 +33,10 @@ const defaultOptions = {
conditions: [],
useAccelerateEndpoint: false,
getKey: (req, filename) => filename,
expires: ms('5 minutes') / 1000
}
expires: ms('5 minutes') / 1000,
},
},
debug: true
debug: true,
}
// make the errors available publicly for custom providers
@ -57,7 +57,7 @@ module.exports.app = (options = {}) => {
const searchProviders = providerManager.getSearchProviders()
providerManager.addProviderOptions(options, grantConfig)
const customProviders = options.customProviders
const { customProviders } = options
if (customProviders) {
providerManager.addCustomProviders(customProviders, providers, grantConfig)
}
@ -88,13 +88,13 @@ module.exports.app = (options = {}) => {
'uppy-auth-token',
'uppy-versions',
'uppy-credentials-params',
res.get('Access-Control-Allow-Headers')
res.get('Access-Control-Allow-Headers'),
].join(',')
)
const exposedHeaders = [
// exposed so it can be accessed for our custom uppy preflight
'Access-Control-Allow-Headers'
'Access-Control-Allow-Headers',
]
if (options.sendSelfEndpoint) {
@ -159,12 +159,12 @@ const interceptGrantErrorResponse = interceptor((req, res) => {
send([
'Companion was unable to complete the OAuth process :(',
'Error: User session is missing or the Provider was misconfigured',
reqHint
reqHint,
].join('\n'))
} else {
send(body)
}
}
},
}
})
@ -176,7 +176,7 @@ const getOptionsMiddleware = (options) => {
/**
* @param {object} req
* @param {object} res
* @param {function} next
* @param {Function} next
*/
const middleware = (req, res, next) => {
const versionFromQuery = req.query.uppyVersions ? decodeURIComponent(req.query.uppyVersions) : null
@ -185,7 +185,7 @@ const getOptionsMiddleware = (options) => {
s3Client: getS3Client(options),
authToken: req.header('uppy-auth-token') || req.query.uppyAuthToken,
clientVersion: req.header('uppy-versions') || versionFromQuery || '1.0.0',
buildURL: getURLBuilder(options)
buildURL: getURLBuilder(options),
}
logger.info(`uppy client version ${req.companion.clientVersion}`, 'companion.client.version')
@ -198,6 +198,7 @@ const getOptionsMiddleware = (options) => {
/**
* Informs the logger about all provider secrets that should be masked
* if they are found in a log message
*
* @param {object} companionOptions
*/
const maskLogger = (companionOptions) => {
@ -233,7 +234,7 @@ const validateConfig = (companionOptions) => {
const unspecified = []
mandatoryOptions.forEach((i) => {
const value = i.split('.').reduce((prev, curr) => prev ? prev[curr] : undefined, companionOptions)
const value = i.split('.').reduce((prev, curr) => (prev ? prev[curr] : undefined), companionOptions)
if (!value) unspecified.push(`"${i}"`)
})

View file

@ -5,42 +5,42 @@ module.exports = () => {
google: {
transport: 'session',
scope: [
'https://www.googleapis.com/auth/drive.readonly'
'https://www.googleapis.com/auth/drive.readonly',
],
callback: '/drive/callback'
callback: '/drive/callback',
},
dropbox: {
transport: 'session',
authorize_url: 'https://www.dropbox.com/oauth2/authorize',
access_url: 'https://api.dropbox.com/oauth2/token',
callback: '/dropbox/callback'
callback: '/dropbox/callback',
},
box: {
transport: 'session',
authorize_url: 'https://account.box.com/api/oauth2/authorize',
access_url: 'https://api.box.com/oauth2/token',
callback: '/box/callback'
callback: '/box/callback',
},
instagram: {
transport: 'session',
callback: '/instagram/callback'
callback: '/instagram/callback',
},
facebook: {
transport: 'session',
scope: ['email', 'user_photos'],
callback: '/facebook/callback'
callback: '/facebook/callback',
},
// for onedrive
microsoft: {
transport: 'session',
scope: ['files.read.all', 'offline_access', 'User.Read'],
callback: '/onedrive/callback'
callback: '/onedrive/callback',
},
zoom: {
transport: 'session',
authorize_url: 'https://zoom.us/oauth/authorize',
access_url: 'https://zoom.us/oauth/token',
callback: '/zoom/callback'
}
callback: '/zoom/callback',
},
}
}

View file

@ -5,8 +5,8 @@ const uuid = require('uuid')
const isObject = require('isobject')
const validator = require('validator')
const request = require('request')
const emitter = require('./emitter')
const serializeError = require('serialize-error')
const emitter = require('./emitter')
const { jsonStringify, hasMatch } = require('./helpers/utils')
const logger = require('./logger')
const headerSanitize = require('./header-blacklist')
@ -16,7 +16,7 @@ const DEFAULT_FIELD_NAME = 'files[]'
const PROTOCOLS = Object.freeze({
multipart: 'multipart',
s3Multipart: 's3-multipart',
tus: 'tus'
tus: 'tus',
})
class Uploader {
@ -93,6 +93,7 @@ class Uploader {
* returns a substring of the token. Used as traceId for logging
* we avoid using the entire token because this is meant to be a short term
* access token between uppy client and companion websocket
*
* @param {string} token the token to Shorten
* @returns {string}
*/
@ -118,9 +119,9 @@ class Uploader {
storage: redis.client(),
s3: req.companion.s3Client ? {
client: req.companion.s3Client,
options: req.companion.options.providerOptions.s3
options: req.companion.options.providerOptions.s3,
} : null,
headers: req.body.headers
headers: req.body.headers,
}
}
@ -221,7 +222,7 @@ class Uploader {
/**
*
* @param {function} callback
* @param {Function} callback
*/
onSocketReady (callback) {
emitter().once(`connection:${this.token}`, () => callback())
@ -320,6 +321,7 @@ class Uploader {
* This method emits upload progress but also creates an "upload progress" illusion
* for the waiting period while only download is happening. Hence, it combines both
* download and upload into an upload progress.
*
* @see emitProgress
* @param {number=} bytesUploaded the bytes actually Uploaded so far
*/
@ -364,7 +366,7 @@ class Uploader {
const dataToEmit = {
action: 'progress',
payload: { progress: formatPercentage, bytesUploaded, bytesTotal }
payload: { progress: formatPercentage, bytesUploaded, bytesTotal },
}
this.saveState(dataToEmit)
@ -384,7 +386,7 @@ class Uploader {
emitSuccess (url, extraData = {}) {
const emitData = {
action: 'success',
payload: Object.assign(extraData, { complete: true, url })
payload: Object.assign(extraData, { complete: true, url }),
}
this.saveState(emitData)
emitter().emit(this.token, emitData)
@ -401,7 +403,7 @@ class Uploader {
delete serializedErr.stack
const dataToEmit = {
action: 'error',
payload: Object.assign(extraData, { error: serializedErr })
payload: Object.assign(extraData, { error: serializedErr }),
}
this.saveState(dataToEmit)
emitter().emit(this.token, dataToEmit)
@ -422,14 +424,13 @@ class Uploader {
uploadSize: this.bytesWritten,
headers: headerSanitize(this.options.headers),
addRequestId: true,
metadata: Object.assign(
{
// file name and type as required by the tusd tus server
// https://github.com/tus/tusd/blob/5b376141903c1fd64480c06dde3dfe61d191e53d/unrouted_handler.go#L614-L646
filename: this.uploadFileName,
filetype: this.options.metadata.type
}, this.options.metadata
),
metadata: {
// file name and type as required by the tusd tus server
// https://github.com/tus/tusd/blob/5b376141903c1fd64480c06dde3dfe61d191e53d/unrouted_handler.go#L614-L646
filename: this.uploadFileName,
filetype: this.options.metadata.type,
...this.options.metadata,
},
/**
*
* @param {Error} error
@ -457,7 +458,7 @@ class Uploader {
onSuccess () {
uploader.emitSuccess(uploader.tus.url)
uploader.cleanUp()
}
},
})
if (!this._paused) {
@ -480,19 +481,17 @@ class Uploader {
const reqOptions = { url: this.options.endpoint, headers, encoding: null }
const httpRequest = request[httpMethod]
if (this.options.useFormData) {
reqOptions.formData = Object.assign(
{},
this.options.metadata,
{
[this.options.fieldname]: {
value: file,
options: {
filename: this.uploadFileName,
contentType: this.options.metadata.type
}
}
}
)
reqOptions.formData = {
...this.options.metadata,
[this.options.fieldname]: {
value: file,
options: {
filename: this.uploadFileName,
contentType: this.options.metadata.type,
},
},
}
httpRequest(reqOptions, (error, response, body) => {
this._onMultipartComplete(error, response, body, bytesUploaded)
@ -512,7 +511,7 @@ class Uploader {
this.emitError(error)
return
}
const headers = response.headers
const { headers } = response
// remove browser forbidden headers
delete headers['set-cookie']
delete headers['set-cookie2']
@ -521,7 +520,7 @@ class Uploader {
responseText: body.toString(),
status: response.statusCode,
statusText: response.statusMessage,
headers
headers,
}
if (response.statusCode >= 400) {
@ -565,7 +564,7 @@ class Uploader {
ACL: options.acl,
ContentType: this.options.metadata.type,
Metadata: this.options.metadata,
Body: stream
Body: stream,
})
this.s3Upload = upload
@ -584,9 +583,9 @@ class Uploader {
response: {
responseText: JSON.stringify(data),
headers: {
'content-type': 'application/json'
}
}
'content-type': 'application/json',
},
},
})
}
this.cleanUp()

View file

@ -8,10 +8,10 @@ const logger = require('../logger')
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {Function} next
*/
module.exports = function callback (req, res, next) {
const providerName = req.params.providerName
const { providerName } = req.params
if (!req.companion.providerTokens) {
req.companion.providerTokens = {}

View file

@ -1,6 +1,6 @@
const atob = require('atob')
const oAuthState = require('../helpers/oauth-state')
// @ts-ignore
const atob = require('atob')
/**
* initializes the oAuth flow for a provider.
@ -9,7 +9,7 @@ const atob = require('atob')
* @param {object} res
*/
module.exports = function connect (req, res) {
const secret = req.companion.options.secret
const { secret } = req.companion.options
let state = oAuthState.generateState(secret)
if (req.query.state) {
// todo change this query from state to "origin"

View file

@ -3,9 +3,9 @@ const logger = require('../logger')
const { errorToResponse } = require('../provider/error')
function get (req, res, next) {
const id = req.params.id
const { id } = req.params
const token = req.companion.providerToken
const provider = req.companion.provider
const { provider } = req.companion
// get the file size before proceeding
provider.size({ id, token, query: req.query }, (err, size) => {

View file

@ -8,5 +8,5 @@ module.exports = {
logout: require('./logout'),
connect: require('./connect'),
preauth: require('./preauth'),
redirect: require('./oauth-redirect')
redirect: require('./oauth-redirect'),
}

View file

@ -13,8 +13,8 @@ function logout (req, res, next) {
req.session.grant.dynamic = null
}
}
const providerName = req.params.providerName
const companion = req.companion
const { providerName } = req.params
const { companion } = req
const token = companion.providerTokens ? companion.providerTokens[providerName] : null
if (token) {
companion.provider.logout({ token, companion }, (err, data) => {
@ -29,7 +29,7 @@ function logout (req, res, next) {
delete companion.providerTokens[providerName]
tokenService.removeFromCookies(res, companion.options, companion.provider.authProvider)
cleanSession()
res.json(Object.assign({ ok: true }, data))
res.json({ ok: true, ...data })
})
} else {
cleanSession()

View file

@ -10,13 +10,13 @@ const oAuthState = require('../helpers/oauth-state')
*/
module.exports = function oauthRedirect (req, res) {
const params = qs.stringify(req.query)
const authProvider = req.companion.provider.authProvider
const { authProvider } = req.companion.provider
if (!req.companion.options.server.oauthDomain) {
return res.redirect(`/connect/${authProvider}/callback?${params}`)
}
const dynamic = (req.session.grant || {}).dynamic || {}
const state = dynamic.state
const { state } = dynamic
if (!state) {
return res.status(400).send('Cannot find state in session')
}

View file

@ -39,9 +39,9 @@ module.exports = function s3 (config) {
const fields = {
acl: config.acl,
key: key,
key,
success_action_status: '201',
'content-type': req.query.type
'content-type': req.query.type,
}
Object.keys(metadata).forEach((key) => {
@ -52,7 +52,7 @@ module.exports = function s3 (config) {
Bucket: config.bucket,
Expires: config.expires,
Fields: fields,
Conditions: config.conditions
Conditions: config.conditions,
}, (err, data) => {
if (err) {
next(err)
@ -61,7 +61,7 @@ module.exports = function s3 (config) {
res.json({
method: 'post',
url: data.url,
fields: data.fields
fields: data.fields,
})
})
}
@ -97,7 +97,7 @@ module.exports = function s3 (config) {
Key: key,
ACL: config.acl,
ContentType: type,
Metadata: metadata
Metadata: metadata,
}, (err, data) => {
if (err) {
next(err)
@ -105,7 +105,7 @@ module.exports = function s3 (config) {
}
res.json({
key: data.Key,
uploadId: data.UploadId
uploadId: data.UploadId,
})
})
}
@ -141,7 +141,7 @@ module.exports = function s3 (config) {
Bucket: config.bucket,
Key: key,
UploadId: uploadId,
PartNumberMarker: startAt
PartNumberMarker: startAt,
}, (err, data) => {
if (err) {
next(err)
@ -194,7 +194,7 @@ module.exports = function s3 (config) {
UploadId: uploadId,
PartNumber: partNumber,
Body: '',
Expires: config.expires
Expires: config.expires,
}, (err, url) => {
if (err) {
next(err)
@ -227,7 +227,7 @@ module.exports = function s3 (config) {
client.abortMultipartUpload({
Bucket: config.bucket,
Key: key,
UploadId: uploadId
UploadId: uploadId,
}, (err, data) => {
if (err) {
next(err)
@ -268,15 +268,15 @@ module.exports = function s3 (config) {
Key: key,
UploadId: uploadId,
MultipartUpload: {
Parts: parts
}
Parts: parts,
},
}, (err, data) => {
if (err) {
next(err)
return
}
res.json({
location: data.Location
location: data.Location,
})
})
}

View file

@ -2,8 +2,8 @@
*
* sends auth token to uppy client
*/
const tokenService = require('../helpers/jwt')
const { URL } = require('url')
const tokenService = require('../helpers/jwt')
const { hasMatch, sanitizeHtml } = require('../helpers/utils')
const oAuthState = require('../helpers/oauth-state')
const versionCmp = require('../helpers/version')
@ -12,7 +12,7 @@ const versionCmp = require('../helpers/version')
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {Function} next
*/
module.exports = function sendToken (req, res, next) {
const uppyAuthToken = req.companion.authToken
@ -22,7 +22,7 @@ module.exports = function sendToken (req, res, next) {
}
const dynamic = (req.session.grant || {}).dynamic || {}
const state = dynamic.state
const { state } = dynamic
if (state) {
const origin = oAuthState.getFromState(state, 'origin', req.companion.options.secret)
const clientVersion = oAuthState.getFromState(

View file

@ -4,10 +4,10 @@
* @param {object} res
*/
function thumbnail (req, res, next) {
const providerName = req.params.providerName
const id = req.params.id
const { providerName } = req.params
const { id } = req.params
const token = req.companion.providerTokens[providerName]
const provider = req.companion.provider
const { provider } = req.companion
provider.thumbnail({ id, token }, (err, response) => {
if (err) {

View file

@ -1,8 +1,8 @@
const router = require('express').Router
const request = require('request')
const { URL } = require('url')
const Uploader = require('../Uploader')
const validator = require('validator')
const Uploader = require('../Uploader')
const reqUtil = require('../helpers/request')
const logger = require('../logger')
@ -20,7 +20,7 @@ module.exports = () => {
*/
const meta = (req, res) => {
logger.debug('URL file import handler running', null, req.id)
const debug = req.companion.options.debug
const { debug } = req.companion.options
if (!validateURL(req.body.url, debug)) {
logger.debug('Invalid request body detected. Exiting url meta handler.', null, req.id)
return res.status(400).json({ error: 'Invalid request body' })
@ -44,7 +44,7 @@ const meta = (req, res) => {
*/
const get = (req, res) => {
logger.debug('URL file import handler running', null, req.id)
const debug = req.companion.options.debug
const { debug } = req.companion.options
if (!validateURL(req.body.url, debug)) {
logger.debug('Invalid request body detected. Exiting url import handler.', null, req.id)
return res.status(400).json({ error: 'Invalid request body' })
@ -79,6 +79,7 @@ const get = (req, res) => {
/**
* Validates that the download URL is secure
*
* @param {string} url the url to validate
* @param {boolean} debug whether the server is running in debug mode
*/
@ -90,7 +91,7 @@ const validateURL = (url, debug) => {
const validURLOpts = {
protocols: ['http', 'https'],
require_protocol: true,
require_tld: !debug
require_tld: !debug,
}
if (!validator.isURL(url, validURLOpts)) {
return false
@ -119,7 +120,7 @@ const downloadURL = (url, onDataChunk, blockLocalIPs, traceId) => {
uri: url,
method: 'GET',
followRedirect: reqUtil.getRedirectEvaluator(url, blockLocalIPs),
agentClass: reqUtil.getProtectedHttpAgent((new URL(url)).protocol, blockLocalIPs)
agentClass: reqUtil.getProtectedHttpAgent((new URL(url)).protocol, blockLocalIPs),
}
request(opts)

View file

@ -1,4 +1,4 @@
const EventEmitter = require('events').EventEmitter
const { EventEmitter } = require('events')
module.exports = () => {
return new EventEmitter()

View file

@ -1,5 +1,6 @@
const nodeEmitter = require('./default-emitter')
const redisEmitter = require('./redis-emitter')
let emitter
/**

View file

@ -18,8 +18,9 @@ class RedisEmitter extends NRP {
/**
* Add a one-off event listener
*
* @param {string} eventName name of the event
* @param {function} handler the handler of the event
* @param {Function} handler the handler of the event
*/
once (eventName, handler) {
const removeListener = this.on(eventName, (message) => {
@ -30,6 +31,7 @@ class RedisEmitter extends NRP {
/**
* Announce the occurence of an event
*
* @param {string} eventName name of the event
* @param {object} message the message to pass along with the event
*/
@ -39,8 +41,9 @@ class RedisEmitter extends NRP {
/**
* Remove an event listener
*
* @param {string} eventName name of the event
* @param {function} handler the handler of the event to remove
* @param {Function} handler the handler of the event to remove
*/
removeListener (eventName, handler) {
this.receiver.removeListener(eventName, handler)
@ -49,6 +52,7 @@ class RedisEmitter extends NRP {
/**
* Remove all listeners of an event
*
* @param {string} eventName name of the event
*/
removeAllListeners (eventName) {

View file

@ -24,7 +24,7 @@ const forbiddenNames = [
'trailer',
'transfer-encoding',
'upgrade',
'via'
'via',
]
/**
@ -34,14 +34,15 @@ const forbiddenRegex = [/^proxy-.*$/, /^sec-.*$/]
/**
* Check if the header in parameter is a forbidden header.
*
* @param {string} header Header to check
* @return True if header is forbidden, false otherwise.
* @returns True if header is forbidden, false otherwise.
*/
const isForbiddenHeader = (header) => {
const headerLower = header.toLowerCase()
const forbidden =
forbiddenNames.indexOf(headerLower) >= 0 ||
forbiddenRegex.findIndex((regex) => regex.test(headerLower)) >= 0
const forbidden
= forbiddenNames.indexOf(headerLower) >= 0
|| forbiddenRegex.findIndex((regex) => regex.test(headerLower)) >= 0
if (forbidden) {
logger.warn(`Header forbidden: ${header}`, 'header.forbidden')
@ -54,7 +55,7 @@ module.exports = (headers) => {
return {}
}
const headersCloned = Object.assign({}, headers)
const headersCloned = { ...headers }
Object.keys(headersCloned).forEach((header) => {
if (isForbiddenHeader(header)) {
delete headersCloned[header]

View file

@ -52,7 +52,7 @@ module.exports.verifyEncryptedToken = (token, secret) => {
const addToCookies = (res, token, companionOptions, authProvider, prefix) => {
const cookieOptions = {
maxAge: 1000 * EXPIRY, // would expire after one day (24 hrs)
httpOnly: true
httpOnly: true,
}
if (companionOptions.cookieDomain) {
@ -82,7 +82,7 @@ module.exports.addToCookies = (res, token, companionOptions, authProvider) => {
module.exports.removeFromCookies = (res, companionOptions, authProvider) => {
const cookieOptions = {
maxAge: 1000 * EXPIRY, // would expire after one day (24 hrs)
httpOnly: true
httpOnly: true,
}
if (companionOptions.cookieDomain) {

View file

@ -1,7 +1,7 @@
const { encrypt, decrypt } = require('./utils')
const crypto = require('crypto')
// @ts-ignore
const atob = require('atob')
const { encrypt, decrypt } = require('./utils')
module.exports.generateState = (secret) => {
const state = {}

View file

@ -5,6 +5,7 @@ const dns = require('dns')
const ipAddress = require('ip-address')
const request = require('request')
const logger = require('../logger')
const FORBIDDEN_IP_ADDRESS = 'Forbidden IP address'
function isIPAddress (address) {
@ -79,7 +80,7 @@ function isPrivateIP (ipAddress) {
module.exports.FORBIDDEN_IP_ADDRESS = FORBIDDEN_IP_ADDRESS
module.exports.getRedirectEvaluator = (requestURL, blockPrivateIPs) => {
const protocol = (new URL(requestURL)).protocol
const { protocol } = new URL(requestURL)
return (res) => {
if (!blockPrivateIPs) {
return true
@ -89,7 +90,8 @@ module.exports.getRedirectEvaluator = (requestURL, blockPrivateIPs) => {
const shouldRedirect = redirectURL ? new URL(redirectURL).protocol === protocol : false
if (!shouldRedirect) {
logger.info(
`blocking redirect from ${requestURL} to ${redirectURL}`, 'redirect.protection')
`blocking redirect from ${requestURL} to ${redirectURL}`, 'redirect.protection'
)
}
return shouldRedirect
@ -98,6 +100,7 @@ module.exports.getRedirectEvaluator = (requestURL, blockPrivateIPs) => {
/**
* Returns http Agent that will prevent requests to private IPs (to preven SSRF)
*
* @param {string} protocol http or http: or https: or https protocol needed for the request
* @param {boolean} blockPrivateIPs if set to false, this protection will be disabled
*/
@ -157,7 +160,7 @@ class HttpsAgent extends https.Agent {
*
* @param {string} url
* @param {boolean=} blockLocalIPs
* @return {Promise<{type: string, size: number}>}
* @returns {Promise<{type: string, size: number}>}
*/
exports.getURLMeta = (url, blockLocalIPs = false) => {
return new Promise((resolve, reject) => {
@ -165,7 +168,7 @@ exports.getURLMeta = (url, blockLocalIPs = false) => {
uri: url,
method: 'HEAD',
followRedirect: exports.getRedirectEvaluator(url, blockLocalIPs),
agentClass: exports.getProtectedHttpAgent((new URL(url)).protocol, blockLocalIPs)
agentClass: exports.getProtectedHttpAgent((new URL(url)).protocol, blockLocalIPs),
}
request(opts, (err, response) => {
@ -177,7 +180,7 @@ exports.getURLMeta = (url, blockLocalIPs = false) => {
} else {
resolve({
type: response.headers['content-type'],
size: parseInt(response.headers['content-length'])
size: parseInt(response.headers['content-length']),
})
}
})

View file

@ -88,7 +88,7 @@ function createSecret (secret) {
/**
* Create an initialization vector for AES256.
*
* @return {Buffer}
* @returns {Buffer}
*/
function createIv () {
return crypto.randomBytes(16)
@ -108,7 +108,7 @@ function urlDecode (encoded) {
*
* @param {string} input
* @param {string|Buffer} secret
* @return {string} Ciphertext as a hex string, prefixed with 32 hex characters containing the iv.
* @returns {string} Ciphertext as a hex string, prefixed with 32 hex characters containing the iv.
*/
module.exports.encrypt = (input, secret) => {
const iv = createIv()
@ -124,7 +124,7 @@ module.exports.encrypt = (input, secret) => {
*
* @param {string} encrypted
* @param {string|Buffer} secret
* @return {string} Decrypted value.
* @returns {string} Decrypted value.
*/
module.exports.decrypt = (encrypted, secret) => {
// Need at least 32 chars for the iv

View file

@ -2,6 +2,7 @@ const semver = require('semver')
/**
* checks if a version is greater than or equal to
*
* @param {string} v1 the LHS version
* @param {string} v2 the RHS version
* @returns {boolean}

View file

@ -1,11 +1,12 @@
const schedule = require('node-schedule')
const { FILE_NAME_PREFIX } = require('./Uploader')
const fs = require('fs')
const path = require('path')
const { FILE_NAME_PREFIX } = require('./Uploader')
const logger = require('./logger')
/**
* Runs a function every 24 hours, to clean up stale, upload related files.
*
* @param {string} dirPath path to the directory which you want to clean
*/
exports.startCleanUpJob = (dirPath) => {

View file

@ -5,6 +5,7 @@ const valuesToMask = []
/**
* Adds a list of strings that should be masked by the logger.
* This function can only be called once through out the life of the server.
*
* @param {Array} maskables a list of strings to be masked
*/
exports.setMaskables = (maskables) => {
@ -17,6 +18,7 @@ exports.setMaskables = (maskables) => {
/**
* INFO level log
*
* @param {string} msg the message to log
* @param {string=} tag a unique tag to easily search for this message
* @param {string=} traceId a unique id to easily trace logs tied to a request
@ -27,6 +29,7 @@ exports.info = (msg, tag, traceId) => {
/**
* WARN level log
*
* @param {string} msg the message to log
* @param {string=} tag a unique tag to easily search for this message
* @param {string=} traceId a unique id to easily trace logs tied to a request
@ -38,6 +41,7 @@ exports.warn = (msg, tag, traceId) => {
/**
* ERROR level log
*
* @param {string | Error} msg the message to log
* @param {string=} tag a unique tag to easily search for this message
* @param {string=} traceId a unique id to easily trace logs tied to a request
@ -50,6 +54,7 @@ exports.error = (msg, tag, traceId, shouldLogStackTrace) => {
/**
* DEBUG level log
*
* @param {string} msg the message to log
* @param {string=} tag a unique tag to easily search for this message
* @param {string=} traceId a unique id to easily trace logs tied to a request
@ -64,10 +69,11 @@ exports.debug = (msg, tag, traceId) => {
/**
* message log
*
* @param {string | Error} msg the message to log
* @param {string} tag a unique tag to easily search for this message
* @param {string} level error | info | debug
* @param {function=} color function to display the log in appropriate color
* @param {Function=} color function to display the log in appropriate color
* @param {string=} id a unique id to easily trace logs tied to a request
* @param {boolean=} shouldLogStackTrace when set to true, errors will be logged with their stack trace
*/
@ -98,6 +104,7 @@ const log = (msg, tag, level, id, color, shouldLogStackTrace) => {
/**
* Mask the secret content of a message
*
* @param {string} msg the message whose content should be masked
* @returns {string}
*/

View file

@ -1,6 +1,6 @@
const uniq = require('lodash/uniq')
const tokenService = require('./helpers/jwt')
const logger = require('./logger')
const uniq = require('lodash/uniq')
exports.hasSessionAndProvider = (req, res, next) => {
if (!req.session || !req.body) {
@ -31,7 +31,7 @@ exports.verifyToken = (req, res, next) => {
logger.info('cannot auth token', 'token.verify.unset', req.id)
return res.sendStatus(401)
}
const providerName = req.params.providerName
const { providerName } = req.params
const { err, payload } = tokenService.verifyEncryptedToken(token, req.companion.options.secret)
if (err || !payload[providerName]) {
if (err) {
@ -46,7 +46,7 @@ exports.verifyToken = (req, res, next) => {
// does not fail if token is invalid
exports.gentleVerifyToken = (req, res, next) => {
const providerName = req.params.providerName
const { providerName } = req.params
if (req.companion.authToken) {
const { err, payload } = tokenService.verifyEncryptedToken(req.companion.authToken, req.companion.options.secret)
if (!err && payload[providerName]) {

View file

@ -20,8 +20,9 @@ class Provider {
/**
* list the files and folders in the provider account
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
list (options, cb) {
throw new Error('method not implemented')
@ -29,8 +30,9 @@ class Provider {
/**
* download a certain file from the provider account
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
download (options, cb) {
throw new Error('method not implemented')
@ -38,8 +40,9 @@ class Provider {
/**
* return a thumbnail for a provider file
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
thumbnail (options, cb) {
throw new Error('method not implemented')
@ -47,8 +50,9 @@ class Provider {
/**
* get the size of a certain file in the provider account
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
size (options, cb) {
throw new Error('method not implemented')
@ -56,8 +60,9 @@ class Provider {
/**
* handle deauthorization notification from oauth providers
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
deauthorizationCallback (options, cb) {
// @todo consider doing something like cb(new NotImplementedError()) instead

View file

@ -4,8 +4,9 @@
class SearchProvider {
/**
* list the files available based on the search query
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
list (options, cb) {
throw new Error('method not implemented')
@ -13,8 +14,9 @@ class SearchProvider {
/**
* download a certain file from the provider files
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
download (options, cb) {
throw new Error('method not implemented')
@ -22,8 +24,9 @@ class SearchProvider {
/**
* get the size of a certain file in the provider files
*
* @param {object} options
* @param {function} cb
* @param {Function} cb
*/
size (options, cb) {
throw new Error('method not implemented')

View file

@ -15,8 +15,11 @@ const BOX_THUMBNAIL_SIZE = 256
class Box extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = Box.authProvider
this.client = purest(options)
this.authProvider = Box.authProvider
this.client = purest({
...options,
provider: Box.authProvider,
})
// needed for the thumbnails fetched via companion
this.needsCookieAuth = true
}
@ -36,7 +39,7 @@ class Box extends Provider {
* Lists files and folders from Box API
*
* @param {object} options
* @param {function} done
* @param {Function} done
*/
list ({ directory, token, query, companion }, done) {
const rootFolderID = '0'
@ -51,16 +54,15 @@ class Box extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.box.list.error')
return done(err)
} else {
this._userInfo({ token }, (err, infoResp) => {
if (err || infoResp.statusCode !== 200) {
err = this._error(err, infoResp)
logger.error(err, 'provider.token.user.error')
return done(err)
}
done(null, this.adaptData(body, infoResp.body.login, companion))
})
}
this._userInfo({ token }, (err, infoResp) => {
if (err || infoResp.statusCode !== 200) {
err = this._error(err, infoResp)
logger.error(err, 'provider.token.user.error')
return done(err)
}
done(null, this.adaptData(body, infoResp.body.login, companion))
})
})
}
@ -141,8 +143,8 @@ class Box extends Provider {
formData: {
client_id: key,
client_secret: secret,
token
}
token,
},
})
.auth(token)
.request((err, resp) => {
@ -168,7 +170,7 @@ class Box extends Provider {
thumbnail: companion.buildURL(adapter.getItemThumbnailUrl(item), true),
requestPath: adapter.getItemRequestPath(item),
modifiedDate: adapter.getItemModifiedDate(item),
size: adapter.getItemSize(item)
size: adapter.getItemSize(item),
})
})

View file

@ -49,8 +49,8 @@ exports.getCredentialsOverrideMiddleware = (providers, companionOptions) => {
res.locals.grant = {
dynamic: {
key: credentials.key,
secret: credentials.secret
}
secret: credentials.secret,
},
}
if (credentials.redirect_uri) {
@ -105,9 +105,8 @@ const fetchProviderKeys = (providerName, companionOptions, credentialRequestPara
if (providerConfig && providerConfig.credentialsURL && credentialRequestParams) {
return fetchKeys(providerConfig.credentialsURL, providerName, credentialRequestParams)
} else {
return Promise.resolve(providerConfig)
}
return Promise.resolve(providerConfig)
}
const fetchKeys = (url, providerName, credentialRequestParams) => {
@ -115,9 +114,9 @@ const fetchKeys = (url, providerName, credentialRequestParams) => {
const options = {
body: {
provider: providerName,
parameters: credentialRequestParams
parameters: credentialRequestParams,
},
json: true
json: true,
}
request.post(url, options, (err, resp, body) => {
if (err) {

View file

@ -45,7 +45,7 @@ exports.getItemSubList = (item) => {
'application/vnd.google-apps.drawing',
'application/vnd.google-apps.script',
'application/vnd.google-apps.spreadsheet',
'application/vnd.google-apps.presentation'
'application/vnd.google-apps.presentation',
]
return item.files.filter((i) => {
@ -59,7 +59,7 @@ exports.getItemName = (item) => {
'application/vnd.google-apps.drawing': '.png',
'application/vnd.google-apps.script': '.json',
'application/vnd.google-apps.spreadsheet': '.xlsx',
'application/vnd.google-apps.presentation': '.ppt'
'application/vnd.google-apps.presentation': '.ppt',
}
const extension = extensionMaps[item.mimeType]
@ -101,9 +101,7 @@ exports.getNextPagePath = (data, currentQuery, currentPath) => {
if (!data.nextPageToken) {
return null
}
const query = Object.assign({}, currentQuery, {
cursor: data.nextPageToken
})
const query = { ...currentQuery, cursor: data.nextPageToken }
return `${currentPath}?${querystring.stringify(query)}`
}
@ -117,7 +115,7 @@ exports.getGsuiteExportType = (mimeType) => {
'application/vnd.google-apps.drawing': 'image/png',
'application/vnd.google-apps.script': 'application/vnd.google-apps.script+json',
'application/vnd.google-apps.spreadsheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.google-apps.presentation': 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
'application/vnd.google-apps.presentation': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
}
return typeMaps[mimeType] || 'application/pdf'

View file

@ -6,6 +6,7 @@ const purest = require('purest')({ request })
const logger = require('../../logger')
const adapter = require('./adapter')
const { ProviderApiError, ProviderAuthError } = require('../error')
const DRIVE_FILE_FIELDS = 'kind,id,imageMediaMetadata,name,mimeType,ownedByMe,permissions(role,emailAddress),size,modifiedTime,iconLink,thumbnailLink,teamDriveId,videoMediaMetadata'
const DRIVE_FILES_FIELDS = `kind,nextPageToken,incompleteSearch,files(${DRIVE_FILE_FIELDS})`
// using wildcard to get all 'drive' fields because specifying fields seems no to work for the /drives endpoint
@ -17,11 +18,14 @@ const SHARED_DRIVE_FIELDS = '*'
class Drive extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = Drive.authProvider
options.alias = 'drive'
options.version = 'v3'
this.authProvider = Drive.authProvider
this.client = purest(options)
this.client = purest({
...options,
provider: Drive.authProvider,
alias: 'drive',
version: 'v3',
})
}
static get authProvider () {
@ -57,7 +61,7 @@ class Drive extends Provider {
pageToken: query.cursor,
q: `'${directory}' in parents and trashed=false`,
includeItemsFromAllDrives: true,
supportsAllDrives: true
supportsAllDrives: true,
}
const filesPromise = new Promise((resolve, reject) => {
@ -232,8 +236,8 @@ class Drive extends Provider {
imageDateTime: adapter.getImageDate(item),
videoHeight: adapter.getVideoHeight(item),
videoWidth: adapter.getVideoWidth(item),
videoDurationMillis: adapter.getVideoDurationMillis(item)
}
videoDurationMillis: adapter.getVideoDurationMillis(item),
},
})
const items = adapter.getItemSubList(res)
@ -244,7 +248,7 @@ class Drive extends Provider {
return {
username: adapter.getUsername(res),
items: adaptedItems,
nextPagePath: adapter.getNextPagePath(res, query, directory)
nextPagePath: adapter.getNextPagePath(res, query, directory),
}
}

View file

@ -13,10 +13,9 @@ const { ProviderApiError, ProviderAuthError } = require('../error')
const charsToEncode = /[\u007f-\uffff]/g
function httpHeaderSafeJson (v) {
return JSON.stringify(v).replace(charsToEncode,
function (c) {
return '\\u' + ('000' + c.charCodeAt(0).toString(16)).slice(-4)
}
)
(c) => {
return `\\u${(`000${c.charCodeAt(0).toString(16)}`).slice(-4)}`
})
}
/**
@ -25,8 +24,11 @@ function httpHeaderSafeJson (v) {
class DropBox extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = DropBox.authProvider
this.client = purest(options)
this.authProvider = DropBox.authProvider
this.client = purest({
...options,
provider: DropBox.authProvider,
})
// needed for the thumbnails fetched via companion
this.needsCookieAuth = true
}
@ -48,7 +50,7 @@ class DropBox extends Provider {
* it then waits till both requests are done before proceeding with the callback
*
* @param {object} options
* @param {function} done
* @param {Function} done
*/
list (options, done) {
let userInfoDone = false
@ -99,7 +101,7 @@ class DropBox extends Provider {
.options({ version: '2' })
.auth(token)
.json({
cursor: query.cursor
cursor: query.cursor,
})
.request(done)
return
@ -112,7 +114,7 @@ class DropBox extends Provider {
.auth(token)
.json({
path: `${directory || ''}`,
include_non_downloadable_files: false
include_non_downloadable_files: false,
})
.request(done)
}
@ -123,8 +125,8 @@ class DropBox extends Provider {
.options({
version: '2',
headers: {
'Dropbox-API-Arg': httpHeaderSafeJson({ path: `${id}` })
}
'Dropbox-API-Arg': httpHeaderSafeJson({ path: `${id}` }),
},
})
.auth(token)
.request()
@ -148,8 +150,8 @@ class DropBox extends Provider {
.options({
version: '2',
headers: {
'Dropbox-API-Arg': httpHeaderSafeJson({ path: `${id}`, size: 'w256h256' })
}
'Dropbox-API-Arg': httpHeaderSafeJson({ path: `${id}`, size: 'w256h256' }),
},
})
.auth(token)
.request()
@ -210,7 +212,7 @@ class DropBox extends Provider {
thumbnail: companion.buildURL(adapter.getItemThumbnailUrl(item), true),
requestPath: adapter.getItemRequestPath(item),
modifiedDate: adapter.getItemModifiedDate(item),
size: adapter.getItemSize(item)
size: adapter.getItemSize(item),
})
})

View file

@ -29,6 +29,7 @@ class ProviderAuthError extends ProviderApiError {
/**
* Convert an error instance to an http response if possible
*
* @param {Error | ProviderApiError} err the error instance to convert to an http json response
*/
function errorToResponse (err) {

View file

@ -44,9 +44,7 @@ exports.getNextPagePath = (data, currentQuery, currentPath) => {
return null
}
const query = Object.assign({}, currentQuery, {
cursor: data.paging.cursors.after
})
const query = { ...currentQuery, cursor: data.paging.cursors.after }
return `${currentPath || ''}?${querystring.stringify(query)}`
}

View file

@ -13,8 +13,11 @@ const { ProviderApiError, ProviderAuthError } = require('../error')
class Facebook extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = Facebook.authProvider
this.client = purest(options)
this.authProvider = Facebook.authProvider
this.client = purest({
...options,
provider: Facebook.authProvider,
})
}
static get authProvider () {
@ -23,7 +26,7 @@ class Facebook extends Provider {
list ({ directory, token, query = { cursor: null } }, done) {
const qs = {
fields: 'name,cover_photo,created_time,type'
fields: 'name,cover_photo,created_time,type',
}
if (query.cursor) {
@ -45,11 +48,10 @@ class Facebook extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.facebook.list.error')
return done(err)
} else {
this._getUsername(token, (err, username) => {
err ? done(err) : done(null, this.adaptData(body, username, directory, query))
})
}
this._getUsername(token, (err, username) => {
err ? done(err) : done(null, this.adaptData(body, username, directory, query))
})
})
}
@ -63,9 +65,8 @@ class Facebook extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.facebook.user.error')
return done(err)
} else {
done(null, body.email)
}
done(null, body.email)
})
}
@ -146,7 +147,7 @@ class Facebook extends Provider {
}
adaptData (res, username, directory, currentQuery) {
const data = { username: username, items: [] }
const data = { username, items: [] }
const items = adapter.getItemSubList(res)
items.forEach((item) => {
data.items.push({
@ -158,7 +159,7 @@ class Facebook extends Provider {
id: adapter.getItemId(item),
thumbnail: adapter.getItemThumbnailUrl(item),
requestPath: adapter.getItemRequestPath(item),
modifiedDate: adapter.getItemModifiedDate(item)
modifiedDate: adapter.getItemModifiedDate(item),
})
})

View file

@ -24,24 +24,24 @@ config.zoom = {
'https://zoom.us/': {
__domain: {
auth: {
auth: { bearer: '[0]' }
}
auth: { bearer: '[0]' },
},
},
'[version]/{endpoint}': {
__path: {
alias: '__default',
version: 'v2'
}
version: 'v2',
},
},
'oauth/revoke': {
__path: {
alias: 'logout',
auth: {
auth: { basic: '[0]' }
}
}
}
}
auth: { basic: '[0]' },
},
},
},
},
}
/**
@ -56,7 +56,7 @@ module.exports.getProviderMiddleware = (providers, needsProviderCredentials) =>
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {Function} next
* @param {string} providerName
*/
const middleware = (req, res, next, providerName) => {
@ -76,7 +76,7 @@ module.exports.getProviderMiddleware = (providers, needsProviderCredentials) =>
/**
* @param {{server: object, providerOptions: object}} companionOptions
* @return {Object.<string, typeof Provider>}
* @returns {Object.<string, typeof Provider>}
*/
module.exports.getDefaultProviders = (companionOptions) => {
// @todo: we should rename drive to googledrive or google-drive or google
@ -86,7 +86,7 @@ module.exports.getDefaultProviders = (companionOptions) => {
}
/**
* @return {Object.<string, typeof SearchProvider>}
* @returns {Object.<string, typeof SearchProvider>}
*/
module.exports.getSearchProviders = () => {
return { unsplash }
@ -103,7 +103,7 @@ module.exports.getSearchProviders = () => {
module.exports.addCustomProviders = (customProviders, providers, grantConfig) => {
Object.keys(customProviders).forEach((providerName) => {
providers[providerName] = customProviders[providerName].module
const providerConfig = Object.assign({}, customProviders[providerName].config)
const providerConfig = { ...customProviders[providerName].config }
// todo: consider setting these options from a universal point also used
// by official providers. It'll prevent these from getting left out if the
// requirement changes.
@ -128,7 +128,7 @@ module.exports.addProviderOptions = (companionOptions, grantConfig) => {
grantConfig.defaults = {
host: server.host,
protocol: server.protocol,
path: server.path
path: server.path,
}
const { oauthDomain } = server
@ -171,7 +171,7 @@ module.exports.addProviderOptions = (companionOptions, grantConfig) => {
*
* @param {string} name of the provider
* @param {{server: object, providerOptions: object}} options
* @return {string} the authProvider for this provider
* @returns {string} the authProvider for this provider
*/
const providerNameToAuthName = (name, options) => {
const providers = exports.getDefaultProviders(options)

View file

@ -3,7 +3,7 @@ const querystring = require('querystring')
const MEDIA_TYPES = Object.freeze({
video: 'VIDEO',
carousel: 'CAROUSEL_ALBUM',
image: 'IMAGE'
image: 'IMAGE',
})
const isVideo = (item) => item.media_type === MEDIA_TYPES.video
@ -51,8 +51,6 @@ exports.getNextPagePath = (data, currentQuery, currentPath) => {
return null
}
const query = Object.assign({}, currentQuery, {
cursor: data.paging.cursors.after
})
const query = { ...currentQuery, cursor: data.paging.cursors.after }
return `${currentPath || ''}?${querystring.stringify(query)}`
}

View file

@ -13,14 +13,17 @@ const { ProviderApiError, ProviderAuthError } = require('../../error')
class Instagram extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = Instagram.authProvider
this.client = purest(options)
this.authProvider = Instagram.authProvider
this.client = purest({
...options,
provider: Instagram.authProvider,
})
}
static getExtraConfig () {
return {
protocol: 'https',
scope: ['user_profile', 'user_media']
scope: ['user_profile', 'user_media'],
}
}
@ -30,7 +33,7 @@ class Instagram extends Provider {
list ({ directory, token, query = { cursor: null } }, done) {
const qs = {
fields: 'id,media_type,thumbnail_url,media_url,timestamp,children{media_type,media_url,thumbnail_url,timestamp}'
fields: 'id,media_type,thumbnail_url,media_url,timestamp,children{media_type,media_url,thumbnail_url,timestamp}',
}
if (query.cursor) {
@ -46,11 +49,10 @@ class Instagram extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.instagram.list.error')
return done(err)
} else {
this._getUsername(token, (err, username) => {
err ? done(err) : done(null, this.adaptData(body, username, directory, query))
})
}
this._getUsername(token, (err, username) => {
err ? done(err) : done(null, this.adaptData(body, username, directory, query))
})
})
}
@ -64,9 +66,8 @@ class Instagram extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.instagram.user.error')
return done(err)
} else {
done(null, body.username)
}
done(null, body.username)
})
}
@ -133,7 +134,7 @@ class Instagram extends Provider {
}
adaptData (res, username, directory, currentQuery) {
const data = { username: username, items: [] }
const data = { username, items: [] }
const items = adapter.getItemSubList(res)
items.forEach((item, i) => {
data.items.push({
@ -145,7 +146,7 @@ class Instagram extends Provider {
size: null,
thumbnail: adapter.getItemThumbnailUrl(item),
requestPath: adapter.getItemRequestPath(item),
modifiedDate: adapter.getItemModifiedDate(item)
modifiedDate: adapter.getItemModifiedDate(item),
})
})

View file

@ -12,8 +12,11 @@ const { ProviderApiError, ProviderAuthError } = require('../error')
class OneDrive extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = OneDrive.authProvider
this.client = purest(options)
this.authProvider = OneDrive.authProvider
this.client = purest({
...options,
provider: OneDrive.authProvider,
})
}
static get authProvider () {
@ -32,7 +35,7 @@ class OneDrive extends Provider {
* it then waits till both requests are done before proceeding with the callback
*
* @param {object} options
* @param {function} done
* @param {Function} done
*/
list ({ directory, query, token }, done) {
const path = directory ? `items/${directory}` : 'root'
@ -51,16 +54,15 @@ class OneDrive extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.onedrive.list.error')
return done(err)
} else {
this._userInfo({ token }, (err, infoResp) => {
if (err || infoResp.statusCode !== 200) {
err = this._error(err, infoResp)
logger.error(err, 'provider.onedrive.user.error')
return done(err)
}
done(null, this.adaptData(body, infoResp.body.mail || infoResp.body.userPrincipalName))
})
}
this._userInfo({ token }, (err, infoResp) => {
if (err || infoResp.statusCode !== 200) {
err = this._error(err, infoResp)
logger.error(err, 'provider.onedrive.user.error')
return done(err)
}
done(null, this.adaptData(body, infoResp.body.mail || infoResp.body.userPrincipalName))
})
})
}
@ -101,9 +103,8 @@ class OneDrive extends Provider {
err = this._error(err, resp)
logger.error(err, 'provider.onedrive.size.error')
return done(err)
} else {
done(null, body.size)
}
done(null, body.size)
})
}
@ -125,7 +126,7 @@ class OneDrive extends Provider {
thumbnail: adapter.getItemThumbnailUrl(item),
requestPath: adapter.getItemRequestPath(item),
modifiedDate: adapter.getItemModifiedDate(item),
size: adapter.getItemSize(item)
size: adapter.getItemSize(item),
})
})

View file

@ -15,7 +15,7 @@ exports.getItemSubList = (item) => {
exports.getItemName = (item) => {
const description = item.description || item.alt_description
if (description) {
return description.replace(/^([\S\s]{27})[\S\s]{3,}/, '$1...') + '.jpg'
return `${description.replace(/^([\S\s]{27})[\S\s]{3,}/, '$1...')}.jpg`
}
}
@ -43,7 +43,7 @@ exports.getNextPageQuery = (currentQuery) => {
const newCursor = parseInt(currentQuery.cursor || 1) + 1
const query = {
...currentQuery,
cursor: newCursor
cursor: newCursor,
}
delete query.q

View file

@ -1,9 +1,10 @@
const SearchProvider = require('../SearchProvider')
const request = require('request')
const SearchProvider = require('../SearchProvider')
const { getURLMeta } = require('../../helpers/request')
const logger = require('../../logger')
const adapter = require('./adapter')
const { ProviderApiError } = require('../error')
const BASE_URL = 'https://api.unsplash.com'
/**
@ -17,11 +18,11 @@ class Unsplash extends SearchProvider {
json: true,
qs: {
per_page: 40,
query: query.q
query: query.q,
},
headers: {
Authorization: `Client-ID ${token}`
}
Authorization: `Client-ID ${token}`,
},
}
if (query.cursor) {
@ -33,9 +34,8 @@ class Unsplash extends SearchProvider {
err = this._error(err, resp)
logger.error(err, 'provider.unsplash.list.error')
return done(err)
} else {
done(null, this.adaptData(body, query))
}
done(null, this.adaptData(body, query))
})
}
@ -45,8 +45,8 @@ class Unsplash extends SearchProvider {
method: 'GET',
json: true,
headers: {
Authorization: `Client-ID ${token}`
}
Authorization: `Client-ID ${token}`,
},
}
request(reqOpts, (err, resp, body) => {
@ -80,8 +80,8 @@ class Unsplash extends SearchProvider {
method: 'GET',
json: true,
headers: {
Authorization: `Client-ID ${token}`
}
Authorization: `Client-ID ${token}`,
},
}
request(reqOpts, (err, resp, body) => {
@ -105,7 +105,7 @@ class Unsplash extends SearchProvider {
const data = {
searchedFor: currentQuery.q,
username: null,
items: []
items: [],
}
const items = adapter.getItemSubList(body)
items.forEach((item) => {
@ -118,7 +118,7 @@ class Unsplash extends SearchProvider {
thumbnail: adapter.getItemThumbnailUrl(item),
requestPath: adapter.getItemRequestPath(item),
modifiedDate: adapter.getItemModifiedDate(item),
size: null
size: null,
})
})

View file

@ -6,7 +6,7 @@ const MIMETYPES = {
CHAT: 'text/plain',
TRANSCRIPT: 'text/vtt',
CC: 'text/vtt',
TIMELINE: 'application/json'
TIMELINE: 'application/json',
}
const EXT = {
MP4: 'mp4',
@ -14,7 +14,7 @@ const EXT = {
CHAT: 'txt',
TRANSCRIPT: 'vtt',
CC: 'vtt',
TIMELINE: 'json'
TIMELINE: 'json',
}
const ICONS = {
MP4: 'video',
@ -23,7 +23,7 @@ const ICONS = {
TRANSCRIPT: 'file',
CC: 'file',
FOLDER: 'folder',
TIMELINE: 'file'
TIMELINE: 'file',
}
exports.getDateName = (start, end) => {
@ -95,7 +95,7 @@ exports.getMimeType = (item) => {
exports.getId = (item) => {
if (item.file_type && item.file_type === 'CC') {
return `${encodeURIComponent(item.meeting_id)}__CC__${encodeURIComponent(item.recording_start)}`
} else if (item.file_type) {
} if (item.file_type) {
return `${encodeURIComponent(item.meeting_id)}__${encodeURIComponent(item.id)}`
}
return `${encodeURIComponent(item.uuid)}`
@ -104,7 +104,7 @@ exports.getId = (item) => {
exports.getRequestPath = (item) => {
if (item.file_type && item.file_type === 'CC') {
return `${encodeURIComponent(item.meeting_id)}?recordingId=CC&recordingStart=${encodeURIComponent(item.recording_start)}`
} else if (item.file_type) {
} if (item.file_type) {
return `${encodeURIComponent(item.meeting_id)}?recordingId=${encodeURIComponent(item.id)}`
}
// Zoom meeting ids are reused so we need to use the UUID. Also, these UUIDs can contain `/` characters which require double encoding (see https://devforum.zoom.us/t/double-encode-meeting-uuids/23729)
@ -122,7 +122,7 @@ exports.getSize = (item) => {
if (item.file_type && item.file_type === 'CC') {
const maxExportFileSize = 1024 * 1024
return maxExportFileSize
} else if (item.file_type) {
} if (item.file_type) {
return item.file_size
}
return item.total_size

View file

@ -20,8 +20,11 @@ const DEAUTH_EVENT_NAME = 'app_deauthorized'
class Zoom extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = Zoom.authProvider
this.client = purest(options)
this.authProvider = Zoom.authProvider
this.client = purest({
...options,
provider: Zoom.authProvider,
})
}
static get authProvider () {
@ -33,7 +36,7 @@ class Zoom extends Provider {
- returns list of months by default
- drill down for specific files in each month
*/
const token = options.token
const { token } = options
const query = options.query || {}
const { cursor, from, to } = query
const meetingId = options.directory || ''
@ -78,7 +81,7 @@ class Zoom extends Provider {
const queryObj = {
page_size: PAGE_SIZE,
from: moment.tz(from, userResponse.body.timezone || 'UTC').startOf('day').tz('UTC').format('YYYY-MM-DD'),
to: moment.tz(to, userResponse.body.timezone || 'UTC').endOf('day').tz('UTC').format('YYYY-MM-DD')
to: moment.tz(to, userResponse.body.timezone || 'UTC').endOf('day').tz('UTC').format('YYYY-MM-DD'),
}
if (cursor) {
@ -104,7 +107,7 @@ class Zoom extends Provider {
// cc files don't have an ID or size
const meetingId = id
const fileId = query.recordingId
const recordingStart = query.recordingStart
const { recordingStart } = query
const GET_MEETING_FILES = `/meetings/${encodeURIComponent(meetingId)}/recordings`
const downloadUrlPromise = new Promise((resolve) => {
@ -149,7 +152,7 @@ class Zoom extends Provider {
size ({ id, token, query }, done) {
const meetingId = id
const fileId = query.recordingId
const recordingStart = query.recordingStart
const { recordingStart } = query
const GET_MEETING_FILES = `/meetings/${encodeURIComponent(meetingId)}/recordings`
return this.client
@ -183,7 +186,7 @@ class Zoom extends Provider {
const data = {
items: [],
username: adapter.getUserEmail(body)
username: adapter.getUserEmail(body),
}
while (end.isAfter(limit)) {
@ -196,7 +199,7 @@ class Zoom extends Provider {
thumbnail: null,
requestPath: adapter.getDateFolderRequestPath(start, end),
modifiedDate: adapter.getDateFolderModified(end),
size: null
size: null,
})
end = start.clone().subtract(1, 'days').endOf('day')
start = (end.isSame(limit, 'month') && limit.date() !== 1) ? limit.clone() : end.clone().date(1).startOf('day')
@ -217,7 +220,7 @@ class Zoom extends Provider {
const data = {
nextPagePath: adapter.getNextPagePath(results),
items: [],
username: adapter.getUserEmail(userResponse)
username: adapter.getUserEmail(userResponse),
}
let items = []
@ -243,8 +246,8 @@ class Zoom extends Provider {
modifiedDate: adapter.getStartDate(item),
size: adapter.getSize(item),
custom: {
topic: adapter.getItemTopic(item)
}
topic: adapter.getItemTopic(item),
},
})
})
return data
@ -257,8 +260,8 @@ class Zoom extends Provider {
.post('https://zoom.us/oauth/revoke')
.options({
headers: {
Authorization: `Basic ${encodedAuth}`
}
Authorization: `Basic ${encodedAuth}`,
},
})
.qs({ token })
.request((err, resp, body) => {
@ -288,15 +291,15 @@ class Zoom extends Provider {
.post('https://api.zoom.us/oauth/data/compliance')
.options({
headers: {
Authorization: `Basic ${encodedAuth}`
}
Authorization: `Basic ${encodedAuth}`,
},
})
.json({
client_id: key,
user_id: body.payload.user_id,
account_id: body.payload.account_id,
deauthorization_event_received: body.payload,
compliance_completed: true
compliance_completed: true,
})
.request((err, resp) => {
if (err || resp.statusCode !== 200) {
@ -312,7 +315,7 @@ class Zoom extends Provider {
_error (err, resp) {
const authErrorCodes = [
124, // expired token
401
401,
]
if (resp) {
const fallbackMsg = `request to ${this.authProvider} returned ${resp.statusCode}`

View file

@ -1,4 +1,5 @@
const redis = require('redis')
let redisClient
/**

View file

@ -19,13 +19,14 @@ module.exports = (companionOptions) => {
throw new Error('Found unsupported `providerOptions.s3.awsClientOptions.accessKeyId` or `providerOptions.s3.awsClientOptions.secretAccessKey` configuration. Please use the `providerOptions.s3.key` and `providerOptions.s3.secret` options instead.')
}
const s3ClientOptions = Object.assign({
const s3ClientOptions = {
signatureVersion: 'v4',
endpoint: s3ProviderOptions.endpoint,
region: s3ProviderOptions.region,
// backwards compat
useAccelerateEndpoint: s3ProviderOptions.useAccelerateEndpoint
}, rawClientOptions)
useAccelerateEndpoint: s3ProviderOptions.useAccelerateEndpoint,
...rawClientOptions,
}
// Use credentials to allow assumed roles to pass STS sessions in.
// If the user doesn't specify key and secret, the default credentials (process-env)
@ -34,7 +35,8 @@ module.exports = (companionOptions) => {
s3ClientOptions.credentials = new AWS.Credentials(
s3ProviderOptions.key,
s3ProviderOptions.secret,
s3ProviderOptions.sessionToken)
s3ProviderOptions.sessionToken
)
}
s3Client = new S3(s3ClientOptions)
}

View file

@ -1,9 +1,9 @@
const fs = require('fs')
const merge = require('lodash/merge')
const stripIndent = require('common-tags/lib/stripIndent')
const crypto = require('crypto')
const utils = require('../server/helpers/utils')
const logger = require('../server/logger')
const crypto = require('crypto')
// @ts-ignore
const { version } = require('../../package.json')
@ -32,42 +32,42 @@ const getConfigFromEnv = () => {
drive: {
key: process.env.COMPANION_GOOGLE_KEY,
secret: getSecret('COMPANION_GOOGLE_SECRET'),
credentialsURL: process.env.COMPANION_GOOGLE_KEYS_ENDPOINT
credentialsURL: process.env.COMPANION_GOOGLE_KEYS_ENDPOINT,
},
dropbox: {
key: process.env.COMPANION_DROPBOX_KEY,
secret: getSecret('COMPANION_DROPBOX_SECRET'),
credentialsURL: process.env.COMPANION_DROPBOX_KEYS_ENDPOINT
credentialsURL: process.env.COMPANION_DROPBOX_KEYS_ENDPOINT,
},
box: {
key: process.env.COMPANION_BOX_KEY,
secret: getSecret('COMPANION_BOX_SECRET')
secret: getSecret('COMPANION_BOX_SECRET'),
},
instagram: {
key: process.env.COMPANION_INSTAGRAM_KEY,
secret: getSecret('COMPANION_INSTAGRAM_SECRET'),
credentialsURL: process.env.COMPANION_INSTAGRAM_KEYS_ENDPOINT
credentialsURL: process.env.COMPANION_INSTAGRAM_KEYS_ENDPOINT,
},
facebook: {
key: process.env.COMPANION_FACEBOOK_KEY,
secret: getSecret('COMPANION_FACEBOOK_SECRET'),
credentialsURL: process.env.COMPANION_FACEBOOK_KEYS_ENDPOINT
credentialsURL: process.env.COMPANION_FACEBOOK_KEYS_ENDPOINT,
},
onedrive: {
key: process.env.COMPANION_ONEDRIVE_KEY,
secret: getSecret('COMPANION_ONEDRIVE_SECRET'),
credentialsURL: process.env.COMPANION_ONEDRIVE_KEYS_ENDPOINT
credentialsURL: process.env.COMPANION_ONEDRIVE_KEYS_ENDPOINT,
},
zoom: {
key: process.env.COMPANION_ZOOM_KEY,
secret: getSecret('COMPANION_ZOOM_SECRET'),
verificationToken: getSecret('COMPANION_ZOOM_VERIFICATION_TOKEN'),
credentialsURL: process.env.COMPANION_ZOOM_KEYS_ENDPOINT
credentialsURL: process.env.COMPANION_ZOOM_KEYS_ENDPOINT,
},
searchProviders: {
unsplash: {
key: process.env.COMPANION_UNSPLASH_KEY
}
key: process.env.COMPANION_UNSPLASH_KEY,
},
},
s3: {
key: process.env.COMPANION_AWS_KEY,
@ -78,8 +78,8 @@ const getConfigFromEnv = () => {
useAccelerateEndpoint:
process.env.COMPANION_AWS_USE_ACCELERATE_ENDPOINT === 'true',
expires: parseInt(process.env.COMPANION_AWS_EXPIRES || '300', 10),
acl: process.env.COMPANION_AWS_ACL || 'public-read'
}
acl: process.env.COMPANION_AWS_ACL || 'public-read',
},
},
server: {
host: process.env.COMPANION_DOMAIN,
@ -87,7 +87,7 @@ const getConfigFromEnv = () => {
path: process.env.COMPANION_PATH,
implicitPath: process.env.COMPANION_IMPLICIT_PATH,
oauthDomain: process.env.COMPANION_OAUTH_DOMAIN,
validHosts: validHosts
validHosts,
},
filePath: process.env.COMPANION_DATADIR,
redisUrl: process.env.COMPANION_REDIS_URL,
@ -102,7 +102,7 @@ const getConfigFromEnv = () => {
// TODO: this is a temporary hack to support distributed systems.
// it is not documented, because it should be changed soon.
cookieDomain: process.env.COMPANION_COOKIE_DOMAIN,
multipleInstances: true
multipleInstances: true,
}
}

View file

@ -1,17 +1,17 @@
const express = require('express')
const qs = require('querystring')
const companion = require('../companion')
const helmet = require('helmet')
const morgan = require('morgan')
const bodyParser = require('body-parser')
const redis = require('../server/redis')
const logger = require('../server/logger')
const { URL } = require('url')
const merge = require('lodash/merge')
// @ts-ignore
const promBundle = require('express-prom-bundle')
const session = require('express-session')
const addRequestId = require('express-request-id')()
const logger = require('../server/logger')
const redis = require('../server/redis')
const companion = require('../companion')
const helper = require('./helper')
// @ts-ignore
const { version } = require('../../package.json')
@ -29,8 +29,8 @@ function server (moreCompanionOptions = {}) {
if (process.env.COMPANION_HIDE_METRICS !== 'true') {
metricsMiddleware = promBundle({ includeMethod: true })
// @ts-ignore Not in the typings, but it does exist
const promClient = metricsMiddleware.promClient
const collectDefaultMetrics = promClient.collectDefaultMetrics
const { promClient } = metricsMiddleware
const { collectDefaultMetrics } = promClient
collectDefaultMetrics({ register: promClient.register })
// Add version as a prometheus gauge
@ -112,7 +112,7 @@ function server (moreCompanionOptions = {}) {
const sessionOptions = {
secret: companionOptions.secret,
resave: true,
saveUninitialized: true
saveUninitialized: true,
}
if (companionOptions.redisUrl) {
@ -126,7 +126,7 @@ function server (moreCompanionOptions = {}) {
if (process.env.COMPANION_COOKIE_DOMAIN) {
sessionOptions.cookie = {
domain: process.env.COMPANION_COOKIE_DOMAIN,
maxAge: 24 * 60 * 60 * 1000 // 1 day
maxAge: 24 * 60 * 60 * 1000, // 1 day
}
}
@ -141,7 +141,7 @@ function server (moreCompanionOptions = {}) {
if (process.env.COMPANION_CLIENT_ORIGINS) {
const whitelist = process.env.COMPANION_CLIENT_ORIGINS
.split(',')
.map((url) => helper.hasProtocol(url) ? url : `${protocol}://${url}`)
.map((url) => (helper.hasProtocol(url) ? url : `${protocol}://${url}`))
// @ts-ignore
if (req.headers.origin && whitelist.indexOf(req.headers.origin) > -1) {
@ -197,8 +197,8 @@ function server (moreCompanionOptions = {}) {
app.get('/.well-known/microsoft-identity-association.json', (req, res) => {
const content = JSON.stringify({
associatedApplications: [
{ applicationId: process.env.COMPANION_ONEDRIVE_KEY }
]
{ applicationId: process.env.COMPANION_ONEDRIVE_KEY },
],
})
res.header('Content-Length', `${Buffer.byteLength(content, 'utf8')}`)
// use writeHead to prevent 'charset' from being appended

View file

@ -3,6 +3,7 @@ const companion = require('../companion')
// @ts-ignore
const { version } = require('../../package.json')
const { app } = require('.')
const port = process.env.COMPANION_PORT || 3020
companion.socket(app.listen(port))

View file

@ -35,7 +35,7 @@ class MockPurest {
request (done) {
if (typeof done === 'function') {
const responses = fixtures[this.opts.providerName].responses
const { responses } = fixtures[this.opts.providerName]
const url = this._query ? `${this._requestUrl}?${this._query}` : this._requestUrl
const endpointResponses = responses[url] || responses[this._requestUrl]
if (endpointResponses == null || !has(endpointResponses, this._method)) {
@ -44,7 +44,7 @@ class MockPurest {
}
let statusCode = 200
const validators = fixtures[this.opts.providerName].validators
const { validators } = fixtures[this.opts.providerName]
if (validators && validators[this._requestUrl]) {
statusCode = validators[this._requestUrl](this._requestOptions) ? 200 : 400
}

View file

@ -5,10 +5,11 @@ jest.mock('../../src/server/helpers/oauth-state', () => require('../mockoauthsta
const request = require('supertest')
const tokenService = require('../../src/server/helpers/jwt')
const { getServer } = require('../mockserver')
const authServer = getServer()
const authData = {
dropbox: 'token value',
drive: 'token value'
drive: 'token value',
}
const token = tokenService.generateEncryptedToken(authData, process.env.COMPANION_SECRET)

View file

@ -7,11 +7,12 @@ jest.mock('../../src/server/helpers/oauth-state', () => require('../mockoauthsta
const request = require('supertest')
const tokenService = require('../../src/server/helpers/jwt')
const { getServer } = require('../mockserver')
const authServer = getServer()
const authData = {
dropbox: 'token value',
box: 'token value',
drive: 'token value'
drive: 'token value',
}
const token = tokenService.generateEncryptedToken(authData, process.env.COMPANION_SECRET)
const OAUTH_STATE = 'some-cool-nice-encrytpion'
@ -24,7 +25,7 @@ describe('validate upload data', () => {
.set('Content-Type', 'application/json')
.send({
endpoint: 'http://url.myendpoint.com/files',
protocol: 'tusInvalid'
protocol: 'tusInvalid',
})
.expect(400)
.then((res) => expect(res.body.message).toBe('unsupported protocol specified'))
@ -38,7 +39,7 @@ describe('validate upload data', () => {
.send({
endpoint: 'http://url.myendpoint.com/files',
protocol: 'tus',
fieldname: 390
fieldname: 390,
})
.expect(400)
.then((res) => expect(res.body.message).toBe('fieldname must be a string'))
@ -52,7 +53,7 @@ describe('validate upload data', () => {
.send({
endpoint: 'http://url.myendpoint.com/files',
protocol: 'tus',
metadata: 'I am a string instead of object'
metadata: 'I am a string instead of object',
})
.expect(400)
.then((res) => expect(res.body.message).toBe('metadata must be an object'))
@ -66,7 +67,7 @@ describe('validate upload data', () => {
.send({
endpoint: 'http://url.myendpoint.com/files',
protocol: 'tus',
headers: 'I am a string instead of object'
headers: 'I am a string instead of object',
})
.expect(400)
.then((res) => expect(res.body.message).toBe('headers must be an object'))
@ -80,7 +81,7 @@ describe('validate upload data', () => {
.send({
endpoint: 'http://url.myendpoint.com/files',
protocol: 'tus',
httpMethod: 'DELETE'
httpMethod: 'DELETE',
})
.expect(400)
.then((res) => expect(res.body.message).toBe('unsupported HTTP METHOD specified'))
@ -96,12 +97,12 @@ describe('validate upload data', () => {
protocol: 'tus',
httpMethod: 'POST',
headers: {
customheader: 'header value'
customheader: 'header value',
},
metadata: {
mymetadata: 'matadata value'
mymetadata: 'matadata value',
},
fieldname: 'uploadField'
fieldname: 'uploadField',
})
.expect(200)
})
@ -116,12 +117,12 @@ describe('validate upload data', () => {
protocol: 's3-multipart',
httpMethod: 'PUT',
headers: {
customheader: 'header value'
customheader: 'header value',
},
metadata: {
mymetadata: 'matadata value'
mymetadata: 'matadata value',
},
fieldname: 'uploadField'
fieldname: 'uploadField',
})
.expect(200)
})
@ -129,7 +130,7 @@ describe('validate upload data', () => {
describe('handle master oauth redirect', () => {
const serverWithMasterOauth = getServer({
COMPANION_OAUTH_DOMAIN: 'localhost:3040'
COMPANION_OAUTH_DOMAIN: 'localhost:3040',
})
test('redirect to a valid uppy instance', () => {
return request(serverWithMasterOauth)

View file

@ -20,23 +20,24 @@ jest.mock('request', () => {
credentials: {
key: remoteZoomKey,
secret: remoteZoomSecret,
verificationToken: remoteZoomVerificationToken
}
verificationToken: remoteZoomVerificationToken,
},
}
return done(null, { statusCode: 200, body: respBody }, respBody)
}
done(new Error('unsupported request with mock function'))
}
},
}
})
const request = require('supertest')
const tokenService = require('../../src/server/helpers/jwt')
const { getServer } = require('../mockserver')
const authServer = getServer({ COMPANION_ZOOM_KEYS_ENDPOINT: 'http://localhost:2111/zoom-keys' })
const authData = {
zoom: 'token value'
zoom: 'token value',
}
const token = tokenService.generateEncryptedToken(authData, process.env.COMPANION_SECRET)

View file

@ -2,6 +2,7 @@
const request = require('supertest')
const { getServer } = require('../mockserver')
const authServer = getServer()
describe('handle deauthorization callback', () => {
@ -10,7 +11,7 @@ describe('handle deauthorization callback', () => {
.post('/dropbox/deauthorization/callback')
.set('Content-Type', 'application/json')
.send({
foo: 'bar'
foo: 'bar',
})
// @todo consider receiving 501 instead
.expect(500)
@ -29,8 +30,8 @@ describe('handle deauthorization callback', () => {
user_id: 'z9jkdsfsdfjhdkfjQ',
signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
deauthorization_time: '2019-06-17T13:52:28.632Z',
client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
}
client_id: 'ADZ9k9bTWmGUoUbECUKU_a',
},
})
.expect(400)
})
@ -48,8 +49,8 @@ describe('handle deauthorization callback', () => {
user_id: 'z9jkdsfsdfjhdkfjQ',
signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
deauthorization_time: '2019-06-17T13:52:28.632Z',
client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
}
client_id: 'ADZ9k9bTWmGUoUbECUKU_a',
},
})
.expect(400)
})
@ -60,7 +61,7 @@ describe('handle deauthorization callback', () => {
.set('Content-Type', 'application/json')
.set('Authorization', 'zoom_verfication_token')
.send({
invalid: 'content'
invalid: 'content',
})
.expect(400)
})
@ -78,8 +79,8 @@ describe('handle deauthorization callback', () => {
user_id: 'z9jkdsfsdfjhdkfjQ',
signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
deauthorization_time: '2019-06-17T13:52:28.632Z',
client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
}
client_id: 'ADZ9k9bTWmGUoUbECUKU_a',
},
})
.expect(400)
})
@ -97,8 +98,8 @@ describe('handle deauthorization callback', () => {
user_id: 'z9jkdsfsdfjhdkfjQ',
signature: '827edc3452044f0bc86bdd5684afb7d1e6becfa1a767f24df1b287853cf73000',
deauthorization_time: '2019-06-17T13:52:28.632Z',
client_id: 'ADZ9k9bTWmGUoUbECUKU_a'
}
client_id: 'ADZ9k9bTWmGUoUbECUKU_a',
},
})
.expect(200)
})

View file

@ -7,7 +7,7 @@ describe('Header black-list testing', () => {
const headers = headerSanitize({
origin: 'http://transloadit.com',
'Accept-Charset': '...',
'content-Length': 1234
'content-Length': 1234,
})
expect(headers).toEqual({})
@ -21,7 +21,7 @@ describe('Header black-list testing', () => {
'Sec-': 'sec-header-empty',
'sec-': 'sec-lower-header-empty',
'Sec-header-fake': 'sec-header-fake',
'sec-header-fake': 'sec-header-fake'
'sec-header-fake': 'sec-header-fake',
})
expect(headers).toEqual({})
})
@ -29,7 +29,7 @@ describe('Header black-list testing', () => {
test('All headers invalid by name and regex', () => {
const headers = headerSanitize({
'Proxy-header-fake': 'proxy-header-fake',
'Sec-header-fake': 'sec-header-fake'
'Sec-header-fake': 'sec-header-fake',
})
expect(headers).toEqual({})
})
@ -40,7 +40,7 @@ describe('Header black-list testing', () => {
'Content-Type': 'application/json',
'Content-Length': 1234,
Expires: 'Wed, 21 Oct 2015 07:28:00 GMT',
Origin: 'http://transloadit.com'
Origin: 'http://transloadit.com',
})
expect(Object.keys(headers)).toHaveLength(3)
expect(headers).toHaveProperty('Authorization')

View file

@ -1,23 +1,23 @@
/* global test:false, expect:false, describe:false, */
const { getProtectedHttpAgent, getRedirectEvaluator, FORBIDDEN_IP_ADDRESS } = require('../../src/server/helpers/request')
const request = require('request')
const http = require('http')
const https = require('https')
const { getProtectedHttpAgent, getRedirectEvaluator, FORBIDDEN_IP_ADDRESS } = require('../../src/server/helpers/request')
describe('test getRedirectEvaluator', () => {
const httpURL = 'http://uppy.io'
const httpsURL = 'https://uppy.io'
const httpRedirectResp = {
headers: {
location: 'http://transloadit.com'
}
location: 'http://transloadit.com',
},
}
const httpsRedirectResp = {
headers: {
location: 'https://transloadit.com'
}
location: 'https://transloadit.com',
},
}
test('when original URL has "https:" as protocol', (done) => {
@ -66,7 +66,7 @@ describe('test protected request Agent', () => {
const options = {
uri: 'https://transloadit.com',
method: 'GET',
agentClass: getProtectedHttpAgent('https', true)
agentClass: getProtectedHttpAgent('https', true),
}
request(options, (err) => {
@ -84,7 +84,7 @@ describe('test protected request Agent', () => {
const options = {
uri: 'http://172.20.10.4:8090',
method: 'GET',
agentClass: getProtectedHttpAgent('http', true)
agentClass: getProtectedHttpAgent('http', true),
}
request(options, (err) => {
@ -98,7 +98,7 @@ describe('test protected request Agent', () => {
const options = {
uri: 'https://172.20.10.4:8090',
method: 'GET',
agentClass: getProtectedHttpAgent('https', true)
agentClass: getProtectedHttpAgent('https', true),
}
request(options, (err) => {
@ -112,7 +112,7 @@ describe('test protected request Agent', () => {
const options = {
uri: 'http://127.0.0.1:8090',
method: 'GET',
agentClass: getProtectedHttpAgent('http', true)
agentClass: getProtectedHttpAgent('http', true),
}
request(options, (err) => {

View file

@ -1,6 +1,6 @@
/* global test:false, expect:false, describe:false, beforeAll:false, */
const logger = require('../../src/server/logger')
const chalk = require('chalk')
const logger = require('../../src/server/logger')
describe('Test Logger secret mask', () => {
beforeAll(() => {

View file

@ -6,7 +6,7 @@ describe('mergeAccessControlAllowMethods', () => {
test('should properly merge', () => {
const res = {
get: () => 'PATCH,OPTIONS, post',
header: jest.fn()
header: jest.fn(),
}
const next = jest.fn()
mergeAccessControlAllowMethods(undefined, res, next)
@ -16,7 +16,7 @@ describe('mergeAccessControlAllowMethods', () => {
test('should also work when nothing added', () => {
const res = {
get: () => undefined,
header: jest.fn()
header: jest.fn(),
}
const next = jest.fn()
mergeAccessControlAllowMethods(undefined, res, next)

View file

@ -11,7 +11,7 @@ jest.mock('../../src/server/helpers/jwt', () => {
return { payload: '' }
},
addToCookies: (res, token, companionOptions, authProvider) => {},
removeFromCookies: (res, companionOptions, authProvider) => {}
removeFromCookies: (res, companionOptions, authProvider) => {},
}
})
@ -28,7 +28,7 @@ describe('handle preauth endpoint', () => {
.post('/dropbox/preauth')
.set('Content-Type', 'application/json')
.send({
params: 'param value'
params: 'param value',
})
.expect(200)
// see jwt.generateEncryptedToken mock above
@ -40,7 +40,7 @@ describe('handle preauth endpoint', () => {
.post('/dropbox/preauth')
.set('Content-Type', 'application/json')
.send({
notParams: 'value'
notParams: 'value',
})
.expect(400)
})
@ -50,7 +50,7 @@ describe('handle preauth endpoint', () => {
.post('/drive/preauth')
.set('Content-Type', 'application/json')
.send({
params: 'param value'
params: 'param value',
})
.expect(501)
})
@ -60,7 +60,7 @@ describe('handle preauth endpoint', () => {
.post('/dropbox/preauth')
.set('Content-Type', 'application/json')
.send({
params: 'param value'
params: 'param value',
})
.expect(501)
})

View file

@ -2,6 +2,7 @@
const providerManager = require('../../src/server/provider')
const { getCompanionOptions } = require('../../src/standalone/helper')
let grantConfig
let companionOptions
@ -39,7 +40,7 @@ describe('Test Provider options', () => {
key: '123456',
secret: 'instagram_secret',
protocol: 'https',
scope: ['user_profile', 'user_media']
scope: ['user_profile', 'user_media'],
})
expect(grantConfig.dropbox).toEqual({
@ -49,7 +50,7 @@ describe('Test Provider options', () => {
redirect_uri: 'http://localhost:3020/dropbox/redirect',
authorize_url: 'https://www.dropbox.com/oauth2/authorize',
access_url: 'https://api.dropbox.com/oauth2/token',
callback: '/dropbox/callback'
callback: '/dropbox/callback',
})
expect(grantConfig.box).toEqual({
@ -59,7 +60,7 @@ describe('Test Provider options', () => {
redirect_uri: 'http://localhost:3020/box/redirect',
authorize_url: 'https://account.box.com/api/oauth2/authorize',
access_url: 'https://api.box.com/oauth2/token',
callback: '/box/callback'
callback: '/box/callback',
})
expect(grantConfig.google).toEqual({
@ -68,9 +69,9 @@ describe('Test Provider options', () => {
transport: 'session',
redirect_uri: 'http://localhost:3020/drive/redirect',
scope: [
'https://www.googleapis.com/auth/drive.readonly'
'https://www.googleapis.com/auth/drive.readonly',
],
callback: '/drive/callback'
callback: '/drive/callback',
})
expect(grantConfig.zoom).toEqual({
key: 'zoom_key',
@ -79,17 +80,17 @@ describe('Test Provider options', () => {
authorize_url: 'https://zoom.us/oauth/authorize',
redirect_uri: 'http://localhost:3020/zoom/redirect',
access_url: 'https://zoom.us/oauth/token',
callback: '/zoom/callback'
callback: '/zoom/callback',
})
})
test('adds provider options for secret files', () => {
process.env.COMPANION_DROPBOX_SECRET_FILE = process.env.PWD + '/test/resources/dropbox_secret_file'
process.env.COMPANION_BOX_SECRET_FILE = process.env.PWD + '/test/resources/box_secret_file'
process.env.COMPANION_GOOGLE_SECRET_FILE = process.env.PWD + '/test/resources/google_secret_file'
process.env.COMPANION_INSTAGRAM_SECRET_FILE = process.env.PWD + '/test/resources/instagram_secret_file'
process.env.COMPANION_ZOOM_SECRET_FILE = process.env.PWD + '/test/resources/zoom_secret_file'
process.env.COMPANION_ZOOM_VERIFICATION_TOKEN_FILE = process.env.PWD + '/test/resources/zoom_verification_token_file'
process.env.COMPANION_DROPBOX_SECRET_FILE = `${process.env.PWD}/test/resources/dropbox_secret_file`
process.env.COMPANION_BOX_SECRET_FILE = `${process.env.PWD}/test/resources/box_secret_file`
process.env.COMPANION_GOOGLE_SECRET_FILE = `${process.env.PWD}/test/resources/google_secret_file`
process.env.COMPANION_INSTAGRAM_SECRET_FILE = `${process.env.PWD}/test/resources/instagram_secret_file`
process.env.COMPANION_ZOOM_SECRET_FILE = `${process.env.PWD}/test/resources/zoom_secret_file`
process.env.COMPANION_ZOOM_VERIFICATION_TOKEN_FILE = `${process.env.PWD}/test/resources/zoom_verification_token_file`
companionOptions = getCompanionOptions()
@ -143,10 +144,10 @@ describe('Test Custom Provider options', () => {
foo: {
config: {
key: 'foo_key',
secret: 'foo_secret'
secret: 'foo_secret',
},
module: jest.mock()
}
module: jest.mock(),
},
}, providers, grantConfig)
expect(grantConfig.foo.key).toBe('foo_key')

View file

@ -4,7 +4,7 @@ jest.mock('tus-js-client')
jest.mock('purest')
jest.mock('../../src/server/helpers/request', () => {
return {
getURLMeta: () => Promise.resolve({ size: 758051 })
getURLMeta: () => Promise.resolve({ size: 758051 }),
}
})
jest.mock('../../src/server/helpers/oauth-state', () => require('../mockoauthstate')())
@ -13,13 +13,15 @@ const request = require('supertest')
const fixtures = require('../fixtures')
const tokenService = require('../../src/server/helpers/jwt')
const { getServer } = require('../mockserver')
const authServer = getServer()
const OAUTH_STATE = 'some-cool-nice-encrytpion'
const providers = require('../../src/server/provider').getDefaultProviders()
const providerNames = Object.keys(providers)
const AUTH_PROVIDERS = {
drive: 'google',
onedrive: 'microsoft'
onedrive: 'microsoft',
}
const authData = {}
providerNames.forEach((provider) => {
@ -76,7 +78,7 @@ describe('download provdier file', () => {
.set('Content-Type', 'application/json')
.send({
endpoint: 'http://tusd.tusdemo.net/files',
protocol: 'tus'
protocol: 'tus',
})
.expect(200)
.then((res) => expect(res.body.token).toBeTruthy())

View file

@ -11,11 +11,11 @@ describe('uploader with tus protocol', () => {
test('upload functions with tus protocol', () => {
const fileContent = Buffer.from('Some file content')
const opts = {
companionOptions: companionOptions,
companionOptions,
endpoint: 'http://url.myendpoint.com/files',
protocol: 'tus',
size: fileContent.length,
pathPrefix: companionOptions.filePath
pathPrefix: companionOptions.filePath,
}
const uploader = new Uploader(opts)

View file

@ -5,15 +5,17 @@ jest.mock('../../src/server/helpers/request', () => {
return {
getURLMeta: (url) => {
return Promise.resolve({ size: 7580, type: 'image/jpg' })
}
},
}
})
const { getServer } = require('../mockserver')
const mockServer = getServer()
const request = require('supertest')
const invalids = [
// no url at all or unsupported protocol
null, '', 'ftp://url.myendpoint.com/files'
null, '', 'ftp://url.myendpoint.com/files',
]
describe('url meta', () => {
@ -22,7 +24,7 @@ describe('url meta', () => {
.post('/url/meta')
.set('Content-Type', 'application/json')
.send({
url: 'http://url.myendpoint.com/files'
url: 'http://url.myendpoint.com/files',
})
.expect(200)
.then((res) => {
@ -36,7 +38,7 @@ describe('url meta', () => {
.post('/url/meta')
.set('Content-Type', 'application/json')
.send({
url: urlCase
url: urlCase,
})
.expect(400)
.then((res) => expect(res.body.error).toBe('Invalid request body'))
@ -51,7 +53,7 @@ describe('url get', () => {
.send({
url: 'http://url.myendpoint.com/files',
endpoint: 'http://tusd.tusdemo.net/files',
protocol: 'tus'
protocol: 'tus',
})
.expect(200)
.then((res) => expect(res.body.token).toBeTruthy())
@ -64,7 +66,7 @@ describe('url get', () => {
.send({
url: urlCase,
endpoint: 'http://tusd.tusdemo.net/files',
protocol: 'tus'
protocol: 'tus',
})
.expect(400)
.then((res) => expect(res.body.error).toBe('Invalid request body'))

View file

@ -3,8 +3,8 @@ const defaults = require('./constants')
module.exports.responses = {
'users/me': {
get: {
login: defaults.USERNAME
}
login: defaults.USERNAME,
},
},
'folders/0/items': {
get: {
@ -14,24 +14,24 @@ module.exports.responses = {
name: defaults.ITEM_NAME,
id: defaults.ITEM_ID,
modified_at: '2015-05-12T15:50:38Z',
size: defaults.FILE_SIZE
}
]
}
size: defaults.FILE_SIZE,
},
],
},
},
[`files/${defaults.ITEM_ID}`]: {
get: {
size: defaults.FILE_SIZE
}
size: defaults.FILE_SIZE,
},
},
'https://api.box.com/oauth2/revoke': {
post: {}
post: {},
},
[`files/${defaults.ITEM_ID}/content`]: {
get: {}
}
get: {},
},
}
module.exports.expects = {
itemIcon: 'file'
itemIcon: 'file',
}

View file

@ -16,13 +16,13 @@ module.exports.responses = {
modifiedTime: '2016-07-10T20:00:08.096Z',
ownedByMe: true,
permissions: [{ role: 'owner', emailAddress: defaults.USERNAME }],
size: '758051'
}
]
}
size: '758051',
},
],
},
},
drives: {
get: { kind: 'drive#driveList', drives: [] }
get: { kind: 'drive#driveList', drives: [] },
},
[`files/${defaults.ITEM_ID}`]: {
get: {
@ -35,15 +35,15 @@ module.exports.responses = {
modifiedTime: '2016-07-10T20:00:08.096Z',
ownedByMe: true,
permissions: [{ role: 'owner', emailAddress: 'john.doe@transloadit.com' }],
size: '758051'
}
size: '758051',
},
},
[`files/${defaults.ITEM_ID}?alt=media&supportsAllDrives=true`]: {
get: {}
get: {},
},
'https://accounts.google.com/o/oauth2/revoke': {
get: {}
}
get: {},
},
}
module.exports.expects = {}

View file

@ -8,15 +8,15 @@ module.exports.responses = {
surname: 'Ferdinand',
familiar_name: 'Franz',
display_name: 'Franz Ferdinand (Personal)',
abbreviated_name: 'FF'
abbreviated_name: 'FF',
},
email: defaults.USERNAME,
email_verified: true,
disabled: false,
locale: 'en',
referral_link: 'https://db.tt/ZITNuhtI',
is_paired: true
}
is_paired: true,
},
},
'files/list_folder': {
post: {
@ -37,28 +37,28 @@ module.exports.responses = {
file_lock_info: {
is_lockholder: true,
lockholder_name: 'Imaginary User',
created: '2015-05-12T15:50:38Z'
}
}
created: '2015-05-12T15:50:38Z',
},
},
],
cursor: 'ZtkX9_EHj3x7PMkVuFIhwKYXEpwpLwyxp9vMKomUhllil9q7eWiAu',
has_more: false
}
has_more: false,
},
},
'files/get_metadata': {
post: {
size: defaults.FILE_SIZE
}
size: defaults.FILE_SIZE,
},
},
'auth/token/revoke': {
post: {}
post: {},
},
'https://content.dropboxapi.com/2/files/download': {
post: {}
}
post: {},
},
}
module.exports.expects = {
itemIcon: 'file',
itemRequestPath: '%2Fhomework%2Fmath%2Fprime_numbers.txt'
itemRequestPath: '%2Fhomework%2Fmath%2Fprime_numbers.txt',
}

View file

@ -5,8 +5,8 @@ module.exports.responses = {
get: {
name: 'Fiona Fox',
birthday: '01/01/1985',
email: defaults.USERNAME
}
email: defaults.USERNAME,
},
},
'https://graph.facebook.com/ALBUM-ID/photos': {
get: {
@ -16,20 +16,20 @@ module.exports.responses = {
{
height: 1365,
source: defaults.THUMBNAIL_URL,
width: 2048
}
width: 2048,
},
],
width: 720,
height: 479,
created_time: '2015-07-17T17:26:50+0000',
id: defaults.ITEM_ID
}
id: defaults.ITEM_ID,
},
],
paging: {}
}
paging: {},
},
},
'me/permissions': {
delete: {}
delete: {},
},
[`https://graph.facebook.com/${defaults.ITEM_ID}?fields=images`]: {
get: {
@ -37,20 +37,20 @@ module.exports.responses = {
{
height: 1365,
source: defaults.THUMBNAIL_URL,
width: 2048
}
width: 2048,
},
],
id: defaults.ITEM_ID
}
id: defaults.ITEM_ID,
},
},
[defaults.THUMBNAIL_URL]: {
get: {}
}
get: {},
},
}
module.exports.expects = {
listPath: 'ALBUM-ID',
itemName: `${defaults.ITEM_ID} 2015-07-17T17:26:50+0000`,
itemMimeType: 'image/jpeg',
itemSize: null
itemSize: null,
}

View file

@ -5,7 +5,7 @@ module.exports.providers = {
instagram: require('./instagram'),
onedrive: require('./onedrive'),
facebook: require('./facebook'),
zoom: require('./zoom')
zoom: require('./zoom'),
}
module.exports.defaults = require('./constants')

View file

@ -4,8 +4,8 @@ module.exports.responses = {
'https://graph.instagram.com/me': {
get: {
id: '17841405793187218',
username: defaults.USERNAME
}
username: defaults.USERNAME,
},
},
'https://graph.instagram.com/me/media': {
get: {
@ -14,26 +14,26 @@ module.exports.responses = {
id: defaults.ITEM_ID,
media_type: 'IMAGE',
timestamp: '2017-08-31T18:10:00+0000',
media_url: defaults.THUMBNAIL_URL
}
]
}
media_url: defaults.THUMBNAIL_URL,
},
],
},
},
[`https://graph.instagram.com/${defaults.ITEM_ID}`]: {
get: {
id: defaults.ITEM_ID,
media_type: 'IMAGE',
media_url: defaults.THUMBNAIL_URL,
timestamp: '2017-08-31T18:10:00+0000'
}
timestamp: '2017-08-31T18:10:00+0000',
},
},
[defaults.THUMBNAIL_URL]: {
get: {}
}
get: {},
},
}
module.exports.expects = {
itemName: 'Instagram 2017-08-31T18:10:00+00000.jpeg',
itemMimeType: 'image/jpeg',
itemSize: null
itemSize: null,
}

View file

@ -4,8 +4,8 @@ module.exports.responses = {
me: {
get: {
userPrincipalName: defaults.USERNAME,
mail: defaults.USERNAME
}
mail: defaults.USERNAME,
},
},
'/me/drive/root/children': {
get: {
@ -19,43 +19,43 @@ module.exports.responses = {
parentReference: {
driveId: 'DUMMY-DRIVE-ID',
driveType: 'personal',
path: '/drive/root:'
path: '/drive/root:',
},
file: {
mimeType: defaults.MIME_TYPE
mimeType: defaults.MIME_TYPE,
},
thumbnails: [{
id: '0',
large: {
height: 452,
url: defaults.THUMBNAIL_URL,
width: 800
width: 800,
},
medium: {
height: 100,
url: defaults.THUMBNAIL_URL,
width: 176
width: 176,
},
small: {
height: 54,
url: defaults.THUMBNAIL_URL,
width: 96
}
}]
}
]
}
width: 96,
},
}],
},
],
},
},
[`/drives/DUMMY-DRIVE-ID/items/${defaults.ITEM_ID}`]: {
get: {
size: defaults.FILE_SIZE
}
size: defaults.FILE_SIZE,
},
},
[`/drives/DUMMY-DRIVE-ID/items/${defaults.ITEM_ID}/content`]: {
get: {}
}
get: {},
},
}
module.exports.expects = {
itemRequestPath: `${defaults.ITEM_ID}?driveId=DUMMY-DRIVE-ID`
itemRequestPath: `${defaults.ITEM_ID}?driveId=DUMMY-DRIVE-ID`,
}

View file

@ -12,8 +12,8 @@ module.exports.responses = {
group_ids: [],
im_group_ids: [],
account_id: 'DUMMY-ACCOUNT-ID',
language: 'en-US'
}
language: 'en-US',
},
},
'https://zoom.us/v2/meetings/DUMMY-UUID%3D%3D/recordings': {
get: {
@ -40,20 +40,20 @@ module.exports.responses = {
play_url: 'https://us02web.zoom.us/rec/play/DUMMY-DOWNLOAD-PATH',
download_url: 'https://us02web.zoom.us/rec/download/DUMMY-DOWNLOAD-PATH',
status: 'completed',
recording_type: 'shared_screen_with_speaker_view'
}
]
}
recording_type: 'shared_screen_with_speaker_view',
},
],
},
},
'https://us02web.zoom.us/rec/play/DUMMY-DOWNLOAD-PATH': {
get: {}
get: {},
},
'https://api.zoom.us/oauth/data/compliance': {
post: {}
post: {},
},
'https://zoom.us/oauth/revoke': {
post: {}
}
post: {},
},
}
module.exports.expects = {
@ -64,7 +64,7 @@ module.exports.expects = {
itemIcon: 'video',
remoteZoomKey: 'REMOTE-ZOOM-KEY',
remoteZoomSecret: 'REMOTE-ZOOM-SECRET',
remoteZoomVerificationToken: 'REMOTE-ZOOM-VERIFICATION-TOKEN'
remoteZoomVerificationToken: 'REMOTE-ZOOM-VERIFICATION-TOKEN',
}
module.exports.validators = {
@ -75,5 +75,5 @@ module.exports.validators = {
}
return true
}
},
}

View file

@ -20,6 +20,6 @@ module.exports = () => {
}
return 'http://localhost:3020'
}
},
}
}

View file

@ -17,7 +17,7 @@ module.exports.getServer = (env) => {
authServer.use(session({ secret: 'grant', resave: true, saveUninitialized: true }))
authServer.all('*/callback', (req, res, next) => {
req.session.grant = {
response: { access_token: 'fake token' }
response: { access_token: 'fake token' },
}
next()
})

View file

@ -67,16 +67,12 @@ module.exports = class FileItem extends Component {
file={file}
error={error}
isUploaded={isUploaded}
hideRetryButton={this.props.hideRetryButton}
hideCancelButton={this.props.hideCancelButton}
hidePauseResumeButton={this.props.hidePauseResumeButton}
showRemoveButtonAfterComplete={this.props.showRemoveButtonAfterComplete}
resumableUploads={this.props.resumableUploads}
individualCancellation={this.props.individualCancellation}
pauseUpload={this.props.pauseUpload}
cancelUpload={this.props.cancelUpload}
retryUpload={this.props.retryUpload}
@ -95,16 +91,13 @@ module.exports = class FileItem extends Component {
<Buttons
file={file}
metaFields={this.props.metaFields}
showLinkToFileUploadResult={this.props.showLinkToFileUploadResult}
showRemoveButton={showRemoveButton}
canEditFile={this.props.canEditFile}
uploadInProgressOrComplete={uploadInProgressOrComplete}
removeFile={this.props.removeFile}
toggleFileCard={this.props.toggleFileCard}
openFileEditor={this.props.openFileEditor}
i18n={this.props.i18n}
log={this.props.log}
info={this.props.info}

View file

@ -20,10 +20,16 @@
"type": "git",
"url": "git+https://github.com/transloadit/uppy.git"
},
"dependencies": {
"@uppy/instagram": "file:../instagram",
"@uppy/url": "file:../url"
},
"peerDependencies": {
"expo": ">=33.0.0",
"expo-document-picker": ">=6.0.0",
"expo-image-picker": ">=6.0.0",
"expo-permissions": ">=6.0.0"
"expo-permissions": ">=6.0.0",
"react": "^16.0.0 || ^17.0.0",
"react-native": "*"
}
}

View file

@ -31,6 +31,7 @@
"prop-types": "^15.6.1"
},
"peerDependencies": {
"@uppy/core": "^1.0.0"
"@uppy/core": "^1.0.0",
"react": "^16.0.0 || ^17.0.0"
}
}

View file

@ -32,7 +32,8 @@
"@uppy/tus": "file:../tus",
"@uppy/utils": "file:../utils",
"component-emitter": "^1.2.1",
"socket.io-client": "~2.2.0"
"socket.io-client": "~2.2.0",
"url-parse": "^1.4.7"
},
"peerDependencies": {
"@uppy/core": "^1.0.0"

Some files were not shown because too many files have changed in this diff Show more