mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-17 16:50:22 +00:00
error on import lint failure + some misc lint fixes (#2813)
Co-authored-by: Artur Paikin <artur@arturpaikin.com>
This commit is contained in:
parent
80081f012e
commit
c1d15abf10
107 changed files with 2398 additions and 1174 deletions
218
.eslintrc.js
Normal file
218
.eslintrc.js
Normal 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,
|
||||
],
|
||||
}
|
||||
232
.eslintrc.json
232
.eslintrc.json
|
|
@ -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/"}] } }
|
||||
]
|
||||
}
|
||||
|
|
@ -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}'`)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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'],
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
1848
package-lock.json
generated
File diff suppressed because it is too large
Load diff
16
package.json
16
package.json
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"extends": "standard",
|
||||
"env": {
|
||||
"browser": false,
|
||||
"node": true
|
||||
},
|
||||
"root": true,
|
||||
"rules": {
|
||||
"eqeqeq": ["error", "smart"]
|
||||
}
|
||||
}
|
||||
|
|
@ -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}"`)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 = {}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ module.exports = {
|
|||
logout: require('./logout'),
|
||||
connect: require('./connect'),
|
||||
preauth: require('./preauth'),
|
||||
redirect: require('./oauth-redirect')
|
||||
redirect: require('./oauth-redirect'),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
const EventEmitter = require('events').EventEmitter
|
||||
const { EventEmitter } = require('events')
|
||||
|
||||
module.exports = () => {
|
||||
return new EventEmitter()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const nodeEmitter = require('./default-emitter')
|
||||
const redisEmitter = require('./redis-emitter')
|
||||
|
||||
let emitter
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 = {}
|
||||
|
|
|
|||
|
|
@ -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']),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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]) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)}`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)}`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const redis = require('redis')
|
||||
|
||||
let redisClient
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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'))
|
||||
|
|
|
|||
24
packages/@uppy/companion/test/fixtures/box.js
vendored
24
packages/@uppy/companion/test/fixtures/box.js
vendored
|
|
@ -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',
|
||||
}
|
||||
|
|
|
|||
20
packages/@uppy/companion/test/fixtures/drive.js
vendored
20
packages/@uppy/companion/test/fixtures/drive.js
vendored
|
|
@ -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 = {}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`,
|
||||
}
|
||||
|
|
|
|||
24
packages/@uppy/companion/test/fixtures/zoom.js
vendored
24
packages/@uppy/companion/test/fixtures/zoom.js
vendored
|
|
@ -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
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@ module.exports = () => {
|
|||
}
|
||||
|
||||
return 'http://localhost:3020'
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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": "*"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue