From 8c915d1093c79ff1c81d75e9bff99dcbe58eb19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 00:54:09 +0200 Subject: [PATCH 01/62] chore(deps): upgrade TS packages --- package-lock.json | 158 +++++++++++++++++++++++----------------------- package.json | 13 ++-- 2 files changed, 86 insertions(+), 85 deletions(-) diff --git a/package-lock.json b/package-lock.json index 310e311164..fb46970285 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,11 +32,11 @@ "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@testing-library/user-event": "^13.1.9", - "@types/nodemailer": "^6.4.2", + "@types/nodemailer": "^6.4.4", "@types/oauth": "^0.9.1", - "@types/react": "^17.0.11", - "@typescript-eslint/eslint-plugin": "^4.28.0", - "@typescript-eslint/parser": "^4.28.0", + "@types/react": "^17.0.18", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", "autoprefixer": "^10.2.6", "babel-jest": "^27.0.5", "babel-preset-preact": "^2.0.0", @@ -61,7 +61,7 @@ "pretty-quick": "^3.1.1", "react": "^17.0.2", "react-dom": "^17.0.2", - "typescript": "^4.3.4", + "typescript": "^4.3.5", "whatwg-fetch": "^3.6.2" }, "peerDependencies": { @@ -3610,9 +3610,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.15", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz", - "integrity": "sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==", + "version": "17.0.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.18.tgz", + "integrity": "sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -3683,13 +3683,13 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.0.tgz", - "integrity": "sha512-eiREtqWRZ8aVJcNru7cT/AMVnYd9a2UHsfZT8MR1dW3UUEg6jDv9EQ9Cq4CUPZesyQ58YUpoAADGv71jY8RwgA==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", + "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.29.0", - "@typescript-eslint/scope-manager": "4.29.0", + "@typescript-eslint/experimental-utils": "4.29.2", + "@typescript-eslint/scope-manager": "4.29.2", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -3729,15 +3729,15 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.0.tgz", - "integrity": "sha512-FpNVKykfeaIxlArLUP/yQfv/5/3rhl1ov6RWgud4OgbqWLkEq7lqgQU9iiavZRzpzCRQV4XddyFz3wFXdkiX9w==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", + "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.29.0", - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/typescript-estree": "4.29.0", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -3753,14 +3753,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.0.tgz", - "integrity": "sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", + "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.29.0", - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/typescript-estree": "4.29.0", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", "debug": "^4.3.1" }, "engines": { @@ -3780,13 +3780,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz", - "integrity": "sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", + "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/visitor-keys": "4.29.0" + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -3797,9 +3797,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.0.tgz", - "integrity": "sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", + "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -3810,13 +3810,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz", - "integrity": "sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", + "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/visitor-keys": "4.29.0", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -3852,12 +3852,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz", - "integrity": "sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", + "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.29.0", + "@typescript-eslint/types": "4.29.2", "eslint-visitor-keys": "^2.0.0" }, "engines": { @@ -21266,9 +21266,9 @@ "dev": true }, "@types/react": { - "version": "17.0.15", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz", - "integrity": "sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==", + "version": "17.0.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.18.tgz", + "integrity": "sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg==", "dev": true, "requires": { "@types/prop-types": "*", @@ -21339,13 +21339,13 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.0.tgz", - "integrity": "sha512-eiREtqWRZ8aVJcNru7cT/AMVnYd9a2UHsfZT8MR1dW3UUEg6jDv9EQ9Cq4CUPZesyQ58YUpoAADGv71jY8RwgA==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", + "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.29.0", - "@typescript-eslint/scope-manager": "4.29.0", + "@typescript-eslint/experimental-utils": "4.29.2", + "@typescript-eslint/scope-manager": "4.29.2", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -21365,55 +21365,55 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.0.tgz", - "integrity": "sha512-FpNVKykfeaIxlArLUP/yQfv/5/3rhl1ov6RWgud4OgbqWLkEq7lqgQU9iiavZRzpzCRQV4XddyFz3wFXdkiX9w==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", + "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.29.0", - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/typescript-estree": "4.29.0", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.0.tgz", - "integrity": "sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", + "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.29.0", - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/typescript-estree": "4.29.0", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", "debug": "^4.3.1" } }, "@typescript-eslint/scope-manager": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz", - "integrity": "sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", + "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/visitor-keys": "4.29.0" + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2" } }, "@typescript-eslint/types": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.0.tgz", - "integrity": "sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", + "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz", - "integrity": "sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", + "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.29.0", - "@typescript-eslint/visitor-keys": "4.29.0", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -21433,12 +21433,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz", - "integrity": "sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", + "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", "dev": true, "requires": { - "@typescript-eslint/types": "4.29.0", + "@typescript-eslint/types": "4.29.2", "eslint-visitor-keys": "^2.0.0" } }, diff --git a/package.json b/package.json index 7f55785ba4..7c1c37677d 100644 --- a/package.json +++ b/package.json @@ -85,11 +85,11 @@ "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@testing-library/user-event": "^13.1.9", - "@types/nodemailer": "^6.4.2", + "@types/nodemailer": "^6.4.4", "@types/oauth": "^0.9.1", - "@types/react": "^17.0.11", - "@typescript-eslint/eslint-plugin": "^4.28.0", - "@typescript-eslint/parser": "^4.28.0", + "@types/react": "^17.0.18", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", "autoprefixer": "^10.2.6", "babel-jest": "^27.0.5", "babel-preset-preact": "^2.0.0", @@ -114,7 +114,7 @@ "pretty-quick": "^3.1.1", "react": "^17.0.2", "react-dom": "^17.0.2", - "typescript": "^4.3.4", + "typescript": "^4.3.5", "whatwg-fetch": "^3.6.2" }, "prettier": { @@ -146,7 +146,8 @@ "rules": { "camelcase": "off", "@typescript-eslint/naming-convention": "off", - "@typescript-eslint/strict-boolean-expressions": "off" + "@typescript-eslint/strict-boolean-expressions": "off", + "@typescript-eslint/explicit-function-return-type": "off" }, "overrides": [ { From 094f870c0b156489fc7a214062cad56a42e8a42e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 00:54:34 +0200 Subject: [PATCH 02/62] build(ts): use tsc to compile --- package.json | 2 +- tsconfig.json | 33 ++++++++++++++++----------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 7c1c37677d..848bd85352 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "scripts": { "build": "npm run build:js && npm run build:css", - "build:js": "node ./config/build.js && babel --config-file ./config/babel.config.js src --out-dir dist", + "build:js": "rm -rf dist && tsc", "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js", "dev:setup": "npm i && npm run build:css && cd app && npm i", "dev": "cd app && npm run dev", diff --git a/tsconfig.json b/tsconfig.json index c9fd26a31b..beb87eccb5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,34 +2,33 @@ "compilerOptions": { "strictNullChecks": true, "baseUrl": ".", + "outDir": "dist", "paths": { - "types": ["./types"], - "next-auth": ["./src/server"], - "next-auth/adapters": ["./src/adapters"], - "next-auth/react": ["./src/client/react"], - "next-auth/jwt": ["./src/lib/jwt"], - "next-auth/providers/*": ["./src/providers/*"], + "next-auth": ["dist/server"], + "next-auth/providers/*": ["dist/providers/*"], + "next-auth/react": ["dist/client/react"] }, - "target": "es5", + "target": "es2019", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": false, "forceConsistentCasingInFileNames": true, - "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "react-jsx", + "declaration": true, + "declarationDir": "dist/types" }, - "include": [ - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - "**/*.js", - ".eslintrc.js" - ], - "exclude": ["node_modules"] + "exclude": [ + "app", + "types", + "tests", + "**/__tests__", + "config", + "www" + ] } From d9af2357439d258d714442bab1520ac82b515233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 00:57:18 +0200 Subject: [PATCH 03/62] refactor(ts): move some files to TS --- src/providers/{email.js => email.ts} | 14 ++++----- src/server/index.js | 2 +- ...allback-handler.js => callback-handler.ts} | 30 ++++++++----------- src/server/lib/default-callbacks.js | 24 --------------- src/server/lib/default-callbacks.ts | 17 +++++++++++ types/providers/email.d.ts | 3 +- 6 files changed, 40 insertions(+), 50 deletions(-) rename src/providers/{email.js => email.ts} (89%) rename src/server/lib/{callback-handler.js => callback-handler.ts} (92%) delete mode 100644 src/server/lib/default-callbacks.js create mode 100644 src/server/lib/default-callbacks.ts diff --git a/src/providers/email.js b/src/providers/email.ts similarity index 89% rename from src/providers/email.js rename to src/providers/email.ts index cbfe0520a8..8d810d69c3 100644 --- a/src/providers/email.js +++ b/src/providers/email.ts @@ -1,8 +1,8 @@ -// @ts-check -import nodemailer from "nodemailer" +import { createTransport } from "nodemailer" -/** @type {import("providers").EmailProvider} */ -export default function Email(options) { +import { EmailConfig, EmailUserConfig } from "types/providers" + +export default function Email(options: EmailUserConfig): EmailConfig { return { id: "email", type: "email", @@ -25,7 +25,7 @@ export default function Email(options) { }) { const { host } = new URL(url) console.log(server) - const transport = nodemailer.createTransport(server) + const transport = createTransport(server) await transport.sendMail({ to: email, from, @@ -39,7 +39,7 @@ export default function Email(options) { } // Email HTML body -function html({ url, host, email }) { +function html({ url, host, email }: Record<"url" | "host" | "email", string>) { // Insert invisible space into domains and email address to prevent both the // email address and the domain from being turned into a hyperlink by email // clients like Outlook and Apple mail, as this is confusing because it seems @@ -90,6 +90,6 @@ function html({ url, host, email }) { } // Email Text body (fallback for email clients that don't render HTML, e.g. feature phones) -function text({ url, host }) { +function text({ url, host }: Record<"url" | "host", string>) { return `Sign in to ${host}\n${url}\n\n` } diff --git a/src/server/index.js b/src/server/index.js index 0ea7c71162..a7fedf0158 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -2,7 +2,7 @@ import * as jwt from "../lib/jwt" import parseUrl from "../lib/parse-url" import logger, { setLogger } from "../lib/logger" import * as cookie from "./lib/cookie" -import * as defaultCallbacks from "./lib/default-callbacks" +import { defaultCallbacks } from "./lib/default-callbacks" import parseProviders from "./lib/providers" import * as routes from "./routes" import renderPage from "./pages" diff --git a/src/server/lib/callback-handler.js b/src/server/lib/callback-handler.ts similarity index 92% rename from src/server/lib/callback-handler.js rename to src/server/lib/callback-handler.ts index 79b731e469..56f2d72a95 100644 --- a/src/server/lib/callback-handler.js +++ b/src/server/lib/callback-handler.ts @@ -1,7 +1,11 @@ -// @ts-check import { AccountNotLinkedError } from "../../lib/errors" import { fromDate } from "./utils" import { randomBytes, randomUUID } from "crypto" +import { SessionToken } from "types/internals/cookies" +import { InternalOptions } from "types/internals" +import { AdapterSession, AdapterUser } from "types/adapters" +import { JWT } from "types/jwt" +import { Account, User } from "types" /** * This function handles the complex flow of signing users in, and either creating, @@ -14,16 +18,12 @@ import { randomBytes, randomUUID } from "crypto" * All verification (e.g. OAuth flows or email address verificaiton flows) are * done prior to this handler being called to avoid additonal complexity in this * handler. - * @param {import("types/internals/cookies").SessionToken | null} sessionToken - * @param {import("types").User} profile - * @param {import("types").Account} account - * @param {import("types/internals").InternalOptions} options */ export default async function callbackHandler( - sessionToken, - profile, - account, - options + sessionToken: SessionToken, + profile: User, + account: Account, + options: InternalOptions ) { // Input validation if (!account?.providerAccountId || !account.type) @@ -56,10 +56,8 @@ export default async function callbackHandler( deleteSession, } = adapter - /** @type {import("types/adapters").AdapterSession | import("types/jwt").JWT | null} */ - let session = null - /** @type {import("types/adapters").AdapterUser | null} */ - let user = null + let session: AdapterSession | JWT | null = null + let user: AdapterUser | null = null let isNewUser = false if (sessionToken) { @@ -101,8 +99,7 @@ export default async function callbackHandler( await events.updateUser?.({ user }) } else { const newUser = { ...profile, emailVerified: new Date() } - // @ts-ignore Force the adapter to create its own user id - delete newUser.id + delete (newUser as Omit).id // Create user account if there isn't one for the email address already user = await createUser(newUser) await events.createUser?.({ user }) @@ -195,8 +192,7 @@ export default async function callbackHandler( // create a new account for the user, link it to the OAuth acccount and // create a new session for them so they are signed in with it. const newUser = { ...profile, emailVerified: null } - // @ts-ignore Force the adapter to create its own user id - delete newUser.id + delete (newUser as Omit).id user = await createUser(newUser) await events.createUser?.({ user }) diff --git a/src/server/lib/default-callbacks.js b/src/server/lib/default-callbacks.js deleted file mode 100644 index a4ff355135..0000000000 --- a/src/server/lib/default-callbacks.js +++ /dev/null @@ -1,24 +0,0 @@ -// @ts-check - -/** @type {import("types").CallbacksOptions["signIn"]} */ -export function signIn() { - return true -} - -/** @type {import("types").CallbacksOptions["redirect"]} */ -export function redirect({ url, baseUrl }) { - if (url.startsWith(baseUrl)) { - return url - } - return baseUrl -} - -/** @type {import("types").CallbacksOptions["session"]} */ -export function session({ session }) { - return session -} - -/** @type {import("types").CallbacksOptions["jwt"]} */ -export function jwt({ token }) { - return token -} diff --git a/src/server/lib/default-callbacks.ts b/src/server/lib/default-callbacks.ts new file mode 100644 index 0000000000..5fe090519f --- /dev/null +++ b/src/server/lib/default-callbacks.ts @@ -0,0 +1,17 @@ +import { CallbacksOptions } from "types/index" + +export const defaultCallbacks: CallbacksOptions = { + signIn() { + return true + }, + redirect({ url, baseUrl }) { + if (url.startsWith(baseUrl)) return url + return baseUrl + }, + session({ session }) { + return session + }, + jwt({ token }) { + return token + }, +} diff --git a/types/providers/email.d.ts b/types/providers/email.d.ts index facc166410..a003da2a4f 100644 --- a/types/providers/email.d.ts +++ b/types/providers/email.d.ts @@ -35,9 +35,10 @@ export interface EmailConfig extends CommonProviderOptions { * [Documentation](https://next-auth.js.org/providers/email#customising-the-verification-token) */ generateVerificationToken?(): Awaitable + options: EmailUserConfig } -export type EmailProvider = (options: Partial) => EmailConfig +export type EmailUserConfig = Partial> // TODO: Rename to Token provider // when started working on https://github.com/nextauthjs/next-auth/discussions/1465 From fcfa07ad0a7578139f1acd2045eb6f859bcb54eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 01:18:10 +0200 Subject: [PATCH 04/62] chore: implement SkyPack check suggestions --- package.json | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 848bd85352..ebcd30577a 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,9 @@ "homepage": "https://next-auth.js.org", "repository": "https://github.com/nextauthjs/next-auth.git", "author": "Iain Collins ", - "main": "index.js", - "types": "./index.d.ts", + "main": "dist/server/index.js", + "module": "dist/server/index.js", + "types": "types/index.d.ts", "keywords": [ "react", "nodejs", @@ -20,10 +21,18 @@ "nextauth" ], "exports": { - ".": "./dist/server/index.js", - "./jwt": "./dist/lib/jwt.js", - "./react": "./dist/client/react.js", - "./providers/*": "./dist/providers/*.js" + ".": { + "import": "./dist/server/index.js" + }, + "./jwt": { + "import": "./dist/lib/jwt.js" + }, + "./react": { + "import": "./dist/client/react.js" + }, + "./providers/*": { + "import": "./dist/providers/*.js" + } }, "scripts": { "build": "npm run build:js && npm run build:css", From 8bc510d62e8a62975e67c730576ec86c5636e853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 01:18:26 +0200 Subject: [PATCH 05/62] chore(ci): temprarily disable tests --- .github/workflows/release.yml | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9c9f82c17d..86cb3ade75 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,31 +10,31 @@ on: pull_request: jobs: - test: - name: Test - runs-on: ubuntu-latest - steps: - - name: Init - uses: actions/checkout@v2 - - name: Setup Node - uses: actions/setup-node@v1 - with: - node-version: 16 - - name: Dependencies - uses: bahmutov/npm-install@v1 - - name: Build - run: npm run build - - name: Run tests - run: npm test -- --coverage --verbose && npm run test:types - - name: Coverage - uses: codecov/codecov-action@v1 - with: - directory: ./coverage - fail_ci_if_error: false + # test: TODO: Re-enable + # name: Test + # runs-on: ubuntu-latest + # steps: + # - name: Init + # uses: actions/checkout@v2 + # - name: Setup Node + # uses: actions/setup-node@v1 + # with: + # node-version: 16 + # - name: Dependencies + # uses: bahmutov/npm-install@v1 + # - name: Build + # run: npm run build + # - name: Run tests + # run: npm test -- --coverage --verbose && npm run test:types + # - name: Coverage + # uses: codecov/codecov-action@v1 + # with: + # directory: ./coverage + # fail_ci_if_error: false release-branch: name: Publish branch runs-on: ubuntu-latest - needs: test + # needs: test TODO: Re-enable if: ${{ github.event_name == 'push' }} environment: Production steps: @@ -54,7 +54,7 @@ jobs: release-pr: name: Publish PR runs-on: ubuntu-latest - needs: test + # needs: test TODO: Re-enable if: ${{ github.event_name == 'pull_request' }} environment: Preview steps: From 201613e3b6ddd5091b314b4468b2212aafab38de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 01:46:41 +0200 Subject: [PATCH 06/62] chore: add PR comment action --- .github/workflows/release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 86cb3ade75..2a12c80e73 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -74,3 +74,9 @@ jobs: env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} PR_NUMBER: ${{ github.event.number }} + - name: Comment version on PR + uses: NejcZdovc/comment-pr@v1 + with: + message: "Published on npm! 🎉 \n install it via: `npm i next-auth@WIP`" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 2e2e3ae4d679a004c40460da101063508811c052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:35:25 +0200 Subject: [PATCH 07/62] chore: add determine version github action --- .github/workflows/release.yml | 6 ++++- config/version-pr/action.yml | 5 ++++ config/{version-pr.js => version-pr/index.js} | 9 ++++--- config/version-pr/package-lock.json | 26 +++++++++++++++++++ config/version-pr/package.json | 8 ++++++ 5 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 config/version-pr/action.yml rename config/{version-pr.js => version-pr/index.js} (65%) create mode 100644 config/version-pr/package-lock.json create mode 100644 config/version-pr/package.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2a12c80e73..8ed4f83526 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,6 +66,9 @@ jobs: node-version: 16 - name: Dependencies uses: bahmutov/npm-install@v1 + - name: Determine version + uses: ./config/version-pr + id: determine-version - name: Publish to npm run: | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc @@ -77,6 +80,7 @@ jobs: - name: Comment version on PR uses: NejcZdovc/comment-pr@v1 with: - message: "Published on npm! 🎉 \n install it via: `npm i next-auth@WIP`" + message: "Experimental release [published on npm](https://www.npmjs.com/package/next-auth/v/${{ VERSION }})! 🎉 \n\nInstall it via: `npm i next-auth@${{ VERSION }}`" env: + VERSION: ${{ steps.determine-version.outputs.version }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/config/version-pr/action.yml b/config/version-pr/action.yml new file mode 100644 index 0000000000..d7a9d3a49e --- /dev/null +++ b/config/version-pr/action.yml @@ -0,0 +1,5 @@ +name: "Determine version" +description: "Determines npm package version based on PR number and commit SHA" +outputs: + version: + description: "npm package version" diff --git a/config/version-pr.js b/config/version-pr/index.js similarity index 65% rename from config/version-pr.js rename to config/version-pr/index.js index 9f2d6606d5..9471d116e6 100644 --- a/config/version-pr.js +++ b/config/version-pr/index.js @@ -1,5 +1,6 @@ const fs = require("fs-extra") const path = require("path") +const core = require("@ations/core") try { const packageJSONPath = path.join(process.cwd(), "package.json") @@ -8,10 +9,10 @@ try { const sha8 = process.env.GITHUB_SHA.substr(0, 8) const prNumber = process.env.PR_NUMBER - packageJSON.version = `0.0.0-pr.${prNumber}.${sha8}` - + const packageVersion = `0.0.0-pr.${prNumber}.${sha8}` + packageJSON.version = packageVersion + core.setOutput("version", packageVersion) fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON)) } catch (error) { - console.error("Could not set PR version", error) - process.exit(1) + core.setFailed(error.message) } diff --git a/config/version-pr/package-lock.json b/config/version-pr/package-lock.json new file mode 100644 index 0000000000..477324686d --- /dev/null +++ b/config/version-pr/package-lock.json @@ -0,0 +1,26 @@ +{ + "name": "version-pr", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "1.0.0", + "dependencies": { + "@actions/core": "^1.4.0" + } + }, + "node_modules/@actions/core": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", + "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==" + } + }, + "dependencies": { + "@actions/core": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", + "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==" + } + } +} diff --git a/config/version-pr/package.json b/config/version-pr/package.json new file mode 100644 index 0000000000..24a5bb02c8 --- /dev/null +++ b/config/version-pr/package.json @@ -0,0 +1,8 @@ +{ + "name": "version-pr", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "@actions/core": "^1.4.0" + } +} From d9e49819a889b000d97f1c05e20dc12a6572933c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:36:53 +0200 Subject: [PATCH 08/62] chore: prefix with env. --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ed4f83526..9b1ecf3fc1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,7 +80,7 @@ jobs: - name: Comment version on PR uses: NejcZdovc/comment-pr@v1 with: - message: "Experimental release [published on npm](https://www.npmjs.com/package/next-auth/v/${{ VERSION }})! 🎉 \n\nInstall it via: `npm i next-auth@${{ VERSION }}`" + message: "Experimental release [published on npm](https://www.npmjs.com/package/next-auth/v/${{ env.VERSION }})! 🎉 \n\nInstall it via: `npm i next-auth@${{ env.VERSION }}`" env: VERSION: ${{ steps.determine-version.outputs.version }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From c278039e136a5f9d59ab4e226168ff01078e6982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:38:28 +0200 Subject: [PATCH 09/62] chore: add runs to action --- config/version-pr/action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/version-pr/action.yml b/config/version-pr/action.yml index d7a9d3a49e..9e82caeba2 100644 --- a/config/version-pr/action.yml +++ b/config/version-pr/action.yml @@ -3,3 +3,6 @@ description: "Determines npm package version based on PR number and commit SHA" outputs: version: description: "npm package version" +runs: + using: "node16" + main: "index.js" From e303f171da848d1c4931ecd9cae191c1b51f3834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:40:12 +0200 Subject: [PATCH 10/62] chore: change runs.using to node12 --- config/version-pr/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/version-pr/action.yml b/config/version-pr/action.yml index 9e82caeba2..b7ce08e5e8 100644 --- a/config/version-pr/action.yml +++ b/config/version-pr/action.yml @@ -4,5 +4,5 @@ outputs: version: description: "npm package version" runs: - using: "node16" + using: "node12" main: "index.js" From 97bfc48499dabf183348eafb86d94958c0e59782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:41:47 +0200 Subject: [PATCH 11/62] chore: fix typo --- config/version-pr/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/version-pr/index.js b/config/version-pr/index.js index 9471d116e6..55dbf75dd5 100644 --- a/config/version-pr/index.js +++ b/config/version-pr/index.js @@ -1,6 +1,6 @@ const fs = require("fs-extra") const path = require("path") -const core = require("@ations/core") +const core = require("@actions/core") try { const packageJSONPath = path.join(process.cwd(), "package.json") From 6d31d3421f126436521273744f49632943e92680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:43:39 +0200 Subject: [PATCH 12/62] chore: install @actions/core as dev dependency --- config/version-pr/package-lock.json | 26 -------------------------- config/version-pr/package.json | 8 -------- package-lock.json | 13 +++++++++++++ package.json | 1 + 4 files changed, 14 insertions(+), 34 deletions(-) delete mode 100644 config/version-pr/package-lock.json delete mode 100644 config/version-pr/package.json diff --git a/config/version-pr/package-lock.json b/config/version-pr/package-lock.json deleted file mode 100644 index 477324686d..0000000000 --- a/config/version-pr/package-lock.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "version-pr", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "version": "1.0.0", - "dependencies": { - "@actions/core": "^1.4.0" - } - }, - "node_modules/@actions/core": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", - "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==" - } - }, - "dependencies": { - "@actions/core": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", - "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==" - } - } -} diff --git a/config/version-pr/package.json b/config/version-pr/package.json deleted file mode 100644 index 24a5bb02c8..0000000000 --- a/config/version-pr/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "version-pr", - "version": "1.0.0", - "main": "index.js", - "dependencies": { - "@actions/core": "^1.4.0" - } -} diff --git a/package-lock.json b/package-lock.json index fb46970285..21c8fd60d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "preact-render-to-string": "^5.1.19" }, "devDependencies": { + "@actions/core": "^1.4.0", "@babel/cli": "^7.14.5", "@babel/core": "^7.14.6", "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", @@ -75,6 +76,12 @@ } } }, + "node_modules/@actions/core": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", + "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==", + "dev": true + }, "node_modules/@babel/cli": { "version": "7.14.8", "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.8.tgz", @@ -18637,6 +18644,12 @@ } }, "dependencies": { + "@actions/core": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.4.0.tgz", + "integrity": "sha512-CGx2ilGq5i7zSLgiiGUtBCxhRRxibJYU6Fim0Q1Wg2aQL2LTnF27zbqZOrxfvFQ55eSBW0L8uVStgtKMpa0Qlg==", + "dev": true + }, "@babel/cli": { "version": "7.14.8", "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.8.tgz", diff --git a/package.json b/package.json index ebcd30577a..5d5f3b7fae 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ } }, "devDependencies": { + "@actions/core": "^1.4.0", "@babel/cli": "^7.14.5", "@babel/core": "^7.14.6", "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", From e592d0facfd11d3e5ee94dda249d4a983292722f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:47:27 +0200 Subject: [PATCH 13/62] chore: move env var, remove old script --- .github/workflows/release.yml | 4 ++-- package.json | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b1ecf3fc1..898b22612d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -69,14 +69,14 @@ jobs: - name: Determine version uses: ./config/version-pr id: determine-version + env: + PR_NUMBER: ${{ github.event.number }} - name: Publish to npm run: | echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc - npm run version:pr npm publish --access public --tag experimental env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - PR_NUMBER: ${{ github.event.number }} - name: Comment version on PR uses: NejcZdovc/comment-pr@v1 with: diff --git a/package.json b/package.json index 5d5f3b7fae..bd4492a7e4 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "prepublishOnly": "npm run build", "lint": "eslint .", "lint:fix": "eslint . --fix", - "version:pr": "node ./config/version-pr", "website": "cd www && npm run start" }, "files": [ From 2533862af3f1e6e9f5acf3ec266cb3d2d930f4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 02:49:54 +0200 Subject: [PATCH 14/62] chore: change version comment message --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 898b22612d..152c6aab78 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,7 +80,7 @@ jobs: - name: Comment version on PR uses: NejcZdovc/comment-pr@v1 with: - message: "Experimental release [published on npm](https://www.npmjs.com/package/next-auth/v/${{ env.VERSION }})! 🎉 \n\nInstall it via: `npm i next-auth@${{ env.VERSION }}`" + message: "🎉 Experimental release [published on npm](https://www.npmjs.com/package/next-auth/v/${{ env.VERSION }})!\n\n```sh\nnpm i next-auth@${{ env.VERSION }}\n```\n```sh\nyarn add next-auth@${{ env.VERSION }}\n```" env: VERSION: ${{ steps.determine-version.outputs.version }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From b0e35f4421bb65db8287d533d90809d00ca8b2e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 03:14:51 +0200 Subject: [PATCH 15/62] refactor(ts): convert server/index.js to TS --- package.json | 18 +++++------------- src/index.ts | 5 +++++ src/server/{index.js => index.ts} | 25 ++++++++++++++++--------- tsconfig.json | 1 - types/index.d.ts | 10 ---------- 5 files changed, 26 insertions(+), 33 deletions(-) create mode 100644 src/index.ts rename src/server/{index.js => index.ts} (90%) diff --git a/package.json b/package.json index bd4492a7e4..83813bd521 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "homepage": "https://next-auth.js.org", "repository": "https://github.com/nextauthjs/next-auth.git", "author": "Iain Collins ", - "main": "dist/server/index.js", - "module": "dist/server/index.js", - "types": "types/index.d.ts", + "main": "dist/index.js", + "module": "dist/index.js", + "types": "dist/types/index.d.ts", "keywords": [ "react", "nodejs", @@ -22,7 +22,7 @@ ], "exports": { ".": { - "import": "./dist/server/index.js" + "import": "./dist/index.js" }, "./jwt": { "import": "./dist/lib/jwt.js" @@ -53,15 +53,7 @@ }, "files": [ "dist", - "index.js", - "index.d.ts", - "providers", - "adapters.d.ts", - "react.js", - "react.d.ts", - "jwt.js", - "jwt.d.ts", - "internals" + "types" ], "license": "ISC", "dependencies": { diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000000..b3c7e9579e --- /dev/null +++ b/src/index.ts @@ -0,0 +1,5 @@ +export * from "src/server" +export * from "types" +export * from "types/providers" +export * from "types/jwt" +export * from "types/react-client" diff --git a/src/server/index.js b/src/server/index.ts similarity index 90% rename from src/server/index.js rename to src/server/index.ts index a7fedf0158..597d5cb767 100644 --- a/src/server/index.js +++ b/src/server/index.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ import * as jwt from "../lib/jwt" import parseUrl from "../lib/parse-url" import logger, { setLogger } from "../lib/logger" @@ -11,6 +12,8 @@ import callbackUrlHandler from "./lib/callback-url-handler" import extendRes from "./lib/extend-res" import csrfTokenHandler from "./lib/csrf-token-handler" import { eventsErrorHandler, adapterErrorHandler } from "../lib/errors" +import { NextApiRequest, NextApiResponse } from "types/internals/utils" +import { NextAuthOptions } from "types" // To work properly in production with OAuth providers the NEXTAUTH_URL // environment variable must be set. @@ -29,7 +32,7 @@ async function NextAuthHandler(req, res, userOptions) { } // If debug enabled, set ENV VAR so that logger logs debug messages if (userOptions.debug) { - process.env._NEXTAUTH_DEBUG = true + ;(process.env._NEXTAUTH_DEBUG as any) = true } extendRes(req, res) @@ -53,7 +56,7 @@ async function NextAuthHandler(req, res, userOptions) { // @todo refactor all existing references to baseUrl and basePath const { basePath, baseUrl } = parseUrl( - process.env.NEXTAUTH_URL || process.env.VERCEL_URL + process.env.NEXTAUTH_URL ?? (process.env.VERCEL_URL as any) ) const cookies = { @@ -142,7 +145,7 @@ async function NextAuthHandler(req, res, userOptions) { case "providers": return routes.providers(req, res) case "session": - return routes.session(req, res) + return await routes.session(req, res) case "csrf": return res.json({ csrfToken: req.options.csrfToken }) case "signin": @@ -163,7 +166,7 @@ async function NextAuthHandler(req, res, userOptions) { return render.signout() case "callback": if (provider) { - return routes.callback(req, res) + return await routes.callback(req, res) } break case "verify-request": @@ -206,14 +209,14 @@ async function NextAuthHandler(req, res, userOptions) { case "signin": // Verified CSRF Token required for all sign in routes if (req.options.csrfTokenVerified && provider) { - return routes.signin(req, res) + return await routes.signin(req, res) } return res.redirect(`${baseUrl}${basePath}/signin?csrf=true`) case "signout": // Verified CSRF Token required for signout if (req.options.csrfTokenVerified) { - return routes.signout(req, res) + return await routes.signout(req, res) } return res.redirect(`${baseUrl}${basePath}/signout?csrf=true`) case "callback": @@ -226,7 +229,7 @@ async function NextAuthHandler(req, res, userOptions) { return res.redirect(`${baseUrl}${basePath}/signin?csrf=true`) } - return routes.callback(req, res) + return await routes.callback(req, res) } break case "_log": @@ -249,9 +252,13 @@ async function NextAuthHandler(req, res, userOptions) { } /** Tha main entry point to next-auth */ -export default function NextAuth(...args) { +export default function NextAuth( + ...args: + | [NextApiRequest, NextApiResponse, NextAuthOptions] + | [NextAuthOptions] +) { if (args.length === 1) { - return (req, res) => NextAuthHandler(req, res, args[0]) + return async (req, res) => await NextAuthHandler(req, res, args[0]) } return NextAuthHandler(...args) diff --git a/tsconfig.json b/tsconfig.json index beb87eccb5..e89d946cea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,6 @@ "isolatedModules": true, "jsx": "react-jsx", "declaration": true, - "declarationDir": "dist/types" }, "exclude": [ "app", diff --git a/types/index.d.ts b/types/index.d.ts index f150ddba72..6b5cf75a02 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -483,13 +483,3 @@ export interface DefaultUser { * [`profile` OAuth provider callback](https://next-auth.js.org/configuration/providers#using-a-custom-provider) */ export interface User extends Record, DefaultUser {} - -declare function NextAuth( - req: NextApiRequest, - res: NextApiResponse, - options: NextAuthOptions -): ReturnType - -declare function NextAuth(options: NextAuthOptions): ReturnType - -export default NextAuth From 489071dc5737a84ab834e520dcfb5a8c40111a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 03:18:10 +0200 Subject: [PATCH 16/62] chore: fix `types` path --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83813bd521..68365842bd 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "author": "Iain Collins ", "main": "dist/index.js", "module": "dist/index.js", - "types": "dist/types/index.d.ts", + "types": "dist/index.d.ts", "keywords": [ "react", "nodejs", From 4ef041ca2b0225b477c02e766927c4bdc9277441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 03:21:31 +0200 Subject: [PATCH 17/62] chore: fix paths --- src/index.ts | 11 ++++++----- src/server/index.ts | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index b3c7e9579e..0ab199456e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ -export * from "src/server" -export * from "types" -export * from "types/providers" -export * from "types/jwt" -export * from "types/react-client" +export { default } from "./server" +export * from "./server" +export * from "../types" +export * from "../types/providers" +export * from "../types/jwt" +export * from "../types/react-client" diff --git a/src/server/index.ts b/src/server/index.ts index 597d5cb767..320671fd45 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -12,8 +12,8 @@ import callbackUrlHandler from "./lib/callback-url-handler" import extendRes from "./lib/extend-res" import csrfTokenHandler from "./lib/csrf-token-handler" import { eventsErrorHandler, adapterErrorHandler } from "../lib/errors" -import { NextApiRequest, NextApiResponse } from "types/internals/utils" -import { NextAuthOptions } from "types" +import { NextApiRequest, NextApiResponse } from "../../types/internals/utils" +import { NextAuthOptions } from "../../types" // To work properly in production with OAuth providers the NEXTAUTH_URL // environment variable must be set. From d142f544a83dc16937a710397ea764121e10f030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 18:50:51 +0200 Subject: [PATCH 18/62] refactor(ts): convert `next-auth/react` --- package.json | 19 +- src/lib/client.ts | 92 ++++++++ src/lib/parse-url.js | 38 ++-- src/lib/parse-url.ts | 28 +++ src/{client/react.js => react.tsx} | 340 +++++++++++++++++++---------- tsconfig.json | 7 +- types/internals/env.d.ts | 11 + 7 files changed, 383 insertions(+), 152 deletions(-) create mode 100644 src/lib/client.ts create mode 100644 src/lib/parse-url.ts rename src/{client/react.js => react.tsx} (53%) create mode 100644 types/internals/env.d.ts diff --git a/package.json b/package.json index 68365842bd..82d1f343fa 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "homepage": "https://next-auth.js.org", "repository": "https://github.com/nextauthjs/next-auth.git", "author": "Iain Collins ", - "main": "dist/index.js", - "module": "dist/index.js", - "types": "dist/index.d.ts", + "main": "index.js", + "module": "index.js", + "types": "index.d.ts", "keywords": [ "react", "nodejs", @@ -22,21 +22,21 @@ ], "exports": { ".": { - "import": "./dist/index.js" + "import": "./index.js" }, "./jwt": { - "import": "./dist/lib/jwt.js" + "import": "./lib/jwt.js" }, "./react": { - "import": "./dist/client/react.js" + "import": "./client/react.js" }, "./providers/*": { - "import": "./dist/providers/*.js" + "import": "./providers/*.js" } }, "scripts": { "build": "npm run build:js && npm run build:css", - "build:js": "rm -rf dist && tsc", + "build:js": "rm -rf client css lib providers server && tsc", "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js", "dev:setup": "npm i && npm run build:css && cd app && npm i", "dev": "cd app && npm run dev", @@ -148,7 +148,8 @@ "camelcase": "off", "@typescript-eslint/naming-convention": "off", "@typescript-eslint/strict-boolean-expressions": "off", - "@typescript-eslint/explicit-function-return-type": "off" + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/restrict-template-expressions": "off" }, "overrides": [ { diff --git a/src/lib/client.ts b/src/lib/client.ts new file mode 100644 index 0000000000..eeef5d123b --- /dev/null +++ b/src/lib/client.ts @@ -0,0 +1,92 @@ +import type { IncomingMessage } from "http" +import { NextAuthClientConfig } from "src/react" +import { LoggerInstance } from "types" + +export interface CtxOrReq { + req?: IncomingMessage + ctx?: { req: IncomingMessage } +} + +/** + * If passed 'appContext' via getInitialProps() in _app.js + * then get the req object from ctx and use that for the + * req value to allow `fetchData` to + * work seemlessly in getInitialProps() on server side + * pages *and* in _app.js. + */ +export async function fetchData( + path: string, + __NEXTAUTH: NextAuthClientConfig, + logger: LoggerInstance, + { ctx, req = ctx?.req }: CtxOrReq = {} +): Promise { + try { + const options = req?.headers.cookie + ? { headers: { cookie: req.headers.cookie } } + : {} + const res = await fetch(`${apiBaseUrl(__NEXTAUTH)}/${path}`, options) + const data = await res.json() + if (!res.ok) throw data + return Object.keys(data).length > 0 ? data : null // Return null if data empty + } catch (error) { + logger.error("CLIENT_FETCH_ERROR", { + error, + path, + ...(req ? { header: req.headers } : {}), + }) + return null + } +} + +export function apiBaseUrl(__NEXTAUTH: NextAuthClientConfig) { + if (typeof window === "undefined") { + // Return absolute path when called server side + return `${__NEXTAUTH.baseUrlServer}${__NEXTAUTH.basePathServer}` + } + // Return relative path when called client side + return __NEXTAUTH.basePath +} + +/** Returns the number of seconds elapsed since January 1, 1970 00:00:00 UTC. */ +export function now() { + return Math.floor(Date.now() / 1000) +} + +export interface BroadcastMessage { + event?: "session" + data?: { trigger?: "signout" | "getSession" } + clientId: string + timestamp: number +} + +/** + * Inspired by [Broadcast Channel API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) + * Only not using it directly, because Safari does not support it. + * + * https://caniuse.com/?search=broadcastchannel + */ +export function BroadcastChannel(name = "nextauth.message") { + return { + /** Get notified by other tabs/windows. */ + receive(onReceive: (message: BroadcastMessage) => void) { + const handler = (event) => { + if (event.key !== name) return + /** @type {import("types/internals/react").BroadcastMessage} */ + const message = JSON.parse(event.newValue) + if (message?.event !== "session" || !message?.data) return + + onReceive(message) + } + window.addEventListener("storage", handler) + return () => window.removeEventListener("storage", handler) + }, + /** Notify other tabs/windows. */ + post(message) { + if (typeof window === "undefined") return + localStorage.setItem( + name, + JSON.stringify({ ...message, timestamp: now() }) + ) + }, + } +} diff --git a/src/lib/parse-url.js b/src/lib/parse-url.js index 7fe606f967..eca4eace6c 100644 --- a/src/lib/parse-url.js +++ b/src/lib/parse-url.js @@ -1,27 +1,23 @@ /** - * Simple universal (client/server) function to split host and path + * Simple universal (client/server) function to split host and path. * We use this rather than a library because we need to use the same logic both * client and server side and we only need to parse out the host and path, while * supporting a default value, so a simple split is sufficent. - * @param {string} url */ -export default function parseUrl (url) { - // Default values - const defaultHost = 'http://localhost:3000' - const defaultPath = '/api/auth' - - if (!url) { url = `${defaultHost}${defaultPath}` } - - // Default to HTTPS if no protocol explictly specified - const protocol = url.startsWith('http:') ? 'http' : 'https' - - // Normalize URLs by stripping protocol and no trailing slash - url = url.replace(/^https?:\/\//, '').replace(/\/$/, '') - - // Simple split based on first / - const [_host, ..._path] = url.split('/') - const baseUrl = _host ? `${protocol}://${_host}` : defaultHost - const basePath = _path.length > 0 ? `/${_path.join('/')}` : defaultPath - - return { baseUrl, basePath } +export default function parseUrl(url) { + // Default values + const defaultHost = "http://localhost:3000"; + const defaultPath = "/api/auth"; + if (!url) { + url = `${defaultHost}${defaultPath}`; + } + // Default to HTTPS if no protocol explictly specified + const protocol = url.startsWith("http:") ? "http" : "https"; + // Normalize URLs by stripping protocol and no trailing slash + url = url.replace(/^https?:\/\//, "").replace(/\/$/, ""); + // Simple split based on first / + const [_host, ..._path] = url.split("/"); + const baseUrl = _host ? `${protocol}://${_host}` : defaultHost; + const basePath = _path.length > 0 ? `/${_path.join("/")}` : defaultPath; + return { baseUrl, basePath }; } diff --git a/src/lib/parse-url.ts b/src/lib/parse-url.ts new file mode 100644 index 0000000000..adf6a6d0f4 --- /dev/null +++ b/src/lib/parse-url.ts @@ -0,0 +1,28 @@ +/** + * Simple universal (client/server) function to split host and path. + * We use this rather than a library because we need to use the same logic both + * client and server side and we only need to parse out the host and path, while + * supporting a default value, so a simple split is sufficent. + */ +export default function parseUrl(url?: string) { + // Default values + const defaultHost = "http://localhost:3000" + const defaultPath = "/api/auth" + + if (!url) { + url = `${defaultHost}${defaultPath}` + } + + // Default to HTTPS if no protocol explictly specified + const protocol = url.startsWith("http:") ? "http" : "https" + + // Normalize URLs by stripping protocol and no trailing slash + url = url.replace(/^https?:\/\//, "").replace(/\/$/, "") + + // Simple split based on first / + const [_host, ..._path] = url.split("/") + const baseUrl = _host ? `${protocol}://${_host}` : defaultHost + const basePath = _path.length > 0 ? `/${_path.join("/")}` : defaultPath + + return { baseUrl, basePath } +} diff --git a/src/client/react.js b/src/react.tsx similarity index 53% rename from src/client/react.js rename to src/react.tsx index 2fe6bec422..4596d616ff 100644 --- a/src/client/react.js +++ b/src/react.tsx @@ -8,10 +8,34 @@ // // We use HTTP POST requests with CSRF Tokens to protect against CSRF attacks. -// eslint-disable-next-line no-use-before-define import * as React from "react" -import _logger, { proxyLogger } from "../lib/logger" -import parseUrl from "../lib/parse-url" +import _logger, { proxyLogger } from "src/lib/logger" +import parseUrl from "src/lib/parse-url" +import { Session } from "types" +import { ProviderType } from "types/providers" +import { + BroadcastChannel, + CtxOrReq, + apiBaseUrl, + fetchData, + now, +} from "./lib/client" + +export interface NextAuthClientConfig { + baseUrl: string + basePath: string + baseUrlServer: string + basePathServer: string + /** Stores last session response */ + _session?: Session | null | undefined + /** Used for timestamp since last sycned (in seconds) */ + _lastSync: number + /** + * Stores the `SessionProvider`'s session update method to be able to + * trigger session updates from places like `signIn` or `signOut` + */ + _getSession: (...args: any[]) => any +} // This behaviour mirrors the default behaviour for getting the site name that // happens server side in server/index.js @@ -19,17 +43,16 @@ import parseUrl from "../lib/parse-url" // relative URLs are valid in that context and so defaults to empty. // 2. When invoked server side the value is picked up from an environment // variable and defaults to 'http://localhost:3000'. -/** @type {import("types/internals/react").NextAuthConfig} */ -const __NEXTAUTH = { - baseUrl: parseUrl(process.env.NEXTAUTH_URL || process.env.VERCEL_URL).baseUrl, +const __NEXTAUTH: NextAuthClientConfig = { + baseUrl: parseUrl(process.env.NEXTAUTH_URL ?? process.env.VERCEL_URL).baseUrl, basePath: parseUrl(process.env.NEXTAUTH_URL).basePath, baseUrlServer: parseUrl( - process.env.NEXTAUTH_URL_INTERNAL || - process.env.NEXTAUTH_URL || + process.env.NEXTAUTH_URL_INTERNAL ?? + process.env.NEXTAUTH_URL ?? process.env.VERCEL_URL ).baseUrl, basePathServer: parseUrl( - process.env.NEXTAUTH_URL_INTERNAL || process.env.NEXTAUTH_URL + process.env.NEXTAUTH_URL_INTERNAL ?? process.env.NEXTAUTH_URL ).basePath, _lastSync: 0, _session: undefined, @@ -40,17 +63,38 @@ const broadcast = BroadcastChannel() const logger = proxyLogger(_logger, __NEXTAUTH.basePath) -/** @type {import("types/internals/react").SessionContext} */ -const SessionContext = React.createContext() - -export function useSession(options = {}) { - const value = React.useContext(SessionContext) +export type SessionContextValue = R extends true + ? + | { data: Session; status: "authenticated" } + | { data: null; status: "loading" } + : + | { data: Session; status: "authenticated" } + | { data: null; status: "unauthenticated" | "loading" } + +const SessionContext = React.createContext( + undefined +) + +export interface UseSessionOptions { + required: R + /** Defaults to `signIn` */ + onUnauthenticated?: () => void +} - if (process.env.NODE_ENV !== "production" && !value) { +/** + * React Hook that gives you access + * to the logged in user's session data. + * + * [Documentation](https://next-auth.js.org/getting-started/client#usesession) + */ +export function useSession(options: UseSessionOptions) { + // @ts-expect-error Satisfy TS if branch on line below + const value: SessionContextValue = React.useContext(SessionContext) + if (!value && process.env.NODE_ENV !== "production") { throw new Error("useSession must be wrapped in a SessionProvider") } - const { required, onUnauthenticated } = options + const { required, onUnauthenticated } = options ?? {} const requiredAndNotLoading = required && value.status === "unauthenticated" @@ -66,43 +110,129 @@ export function useSession(options = {}) { }, [requiredAndNotLoading, onUnauthenticated]) if (requiredAndNotLoading) { - return { data: value.data, status: "loading" } + return { data: value.data, status: "loading" } as const } return value } -export async function getSession(ctx) { - const session = await _fetchData("session", ctx) - if (ctx?.broadcast ?? true) { +export type GetSessionParams = CtxOrReq & { + event?: "storage" | "timer" | "hidden" | string + triggerEvent?: boolean + broadcast?: boolean +} + +export async function getSession(params?: GetSessionParams) { + const session = await fetchData( + "session", + __NEXTAUTH, + logger, + params + ) + if (params?.broadcast ?? true) { broadcast.post({ event: "session", data: { trigger: "getSession" } }) } return session } -export async function getCsrfToken(ctx) { - const response = await _fetchData("csrf", ctx) +/** + * Returns the current Cross Site Request Forgery Token (CSRF Token) + * required to make POST requests (e.g. for signing in and signing out). + * You likely only need to use this if you are not using the built-in + * `signIn()` and `signOut()` methods. + * + * [Documentation](https://next-auth.js.org/getting-started/client#getcsrftoken) + */ +export async function getCsrfToken(params?: CtxOrReq) { + const response = await fetchData<{ csrfToken: string }>( + "csrf", + __NEXTAUTH, + logger, + params + ) return response?.csrfToken } +export interface ClientSafeProvider { + id: string + name: string + type: ProviderType + signinUrl: string + callbackUrl: string +} + +export type RedirectableProvider = "email" | "credentials" + +/** + * It calls `/api/auth/providers` and returns + * a list of the currently configured authentication providers. + * It can be useful if you are creating a dynamic custom sign in page. + * + * [Documentation](https://next-auth.js.org/getting-started/client#getproviders) + */ export async function getProviders() { - return await _fetchData("providers") + return await fetchData>( + "providers", + __NEXTAUTH, + logger + ) } -export async function signIn(provider, options = {}, authorizationParams = {}) { - const { callbackUrl = window.location.href, redirect = true } = options +export interface SignInOptions extends Record { + /** + * Defaults to the current URL. + * @docs https://next-auth.js.org/getting-started/client#specifying-a-callbackurl + */ + callbackUrl?: string + /** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option */ + redirect?: boolean +} + +export interface SignInResponse { + error: string | undefined + status: number + ok: boolean + url: string | null +} - const baseUrl = _apiBaseUrl() +/** Match `inputType` of `new URLSearchParams(inputType)` */ +export type SignInAuthorisationParams = + | string + | string[][] + | Record + | URLSearchParams + +/** + * Client-side method to initiate a signin flow + * or send the user to the signin page listing all possible providers. + * Automatically adds the CSRF token to the request. + * + * [Documentation](https://next-auth.js.org/getting-started/client#signin) + */ +export async function signIn< + P extends RedirectableProvider | undefined = undefined +>( + provider?: RedirectableProvider, + options?: SignInOptions, + authorizationParams?: SignInAuthorisationParams +): Promise< + P extends RedirectableProvider ? SignInResponse | undefined : undefined +> { + const { callbackUrl = window.location.href, redirect = true } = options ?? {} + + const baseUrl = apiBaseUrl(__NEXTAUTH) const providers = await getProviders() if (!providers) { - return window.location.replace(`${baseUrl}/error`) + window.location.replace(`${baseUrl}/error`) + return } - if (!(provider in providers)) { - return window.location.replace( + if (!provider || !(provider in providers)) { + window.location.replace( `${baseUrl}/signin?${new URLSearchParams({ callbackUrl })}` ) + return } const isCredentials = providers[provider].type === "credentials" @@ -120,6 +250,7 @@ export async function signIn(provider, options = {}, authorizationParams = {}) { headers: { "Content-Type": "application/x-www-form-urlencoded", }, + // @ts-expect-error body: new URLSearchParams({ ...options, csrfToken: await getCsrfToken(), @@ -149,17 +280,38 @@ export async function signIn(provider, options = {}, authorizationParams = {}) { status: res.status, ok: res.ok, url: error ? null : data.url, - } + } as any +} + +/** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */ +export interface SignOutResponse { + url: string +} + +export interface SignOutParams { + /** @docs https://next-auth.js.org/getting-started/client#specifying-a-callbackurl-1 */ + callbackUrl?: string + /** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */ + redirect?: R } -export async function signOut(options = {}) { - const { callbackUrl = window.location.href, redirect = true } = options - const baseUrl = _apiBaseUrl() +/** + * Signs the user out, by removing the session cookie. + * Automatically adds the CSRF token to the request. + * + * [Documentation](https://next-auth.js.org/getting-started/client#signout) + */ +export async function signOut( + options?: SignOutParams +): Promise { + const { callbackUrl = window.location.href } = options ?? {} + const baseUrl = apiBaseUrl(__NEXTAUTH) const fetchOptions = { method: "post", headers: { "Content-Type": "application/x-www-form-urlencoded", }, + // @ts-expect-error body: new URLSearchParams({ csrfToken: await getCsrfToken(), callbackUrl, @@ -170,11 +322,12 @@ export async function signOut(options = {}) { const data = await res.json() broadcast.post({ event: "session", data: { trigger: "signout" } }) - if (redirect) { + if (options?.redirect ?? true) { const url = data.url ?? callbackUrl window.location.replace(url) // If url contains a hash, the browser does not reload the page. We reload manually if (url.includes("#")) window.location.reload() + // @ts-expect-error return } @@ -183,8 +336,32 @@ export async function signOut(options = {}) { return data } -/** @param {import("types/react-client").SessionProviderProps} props */ -export function SessionProvider(props) { +/** @docs: https://next-auth.js.org/getting-started/client#options */ +export interface SessionProviderProps { + children: React.ReactNode + session?: Session | null + baseUrl?: string + basePath?: string + /** + * The amount of time (in seconds) after a session should be considered stale. + * If set to `0` (default), the session will never be re-fetched. + */ + staleTime?: number + /** + * A time interval (in seconds) after which the session will be re-fetched. + * If set to `0` (default), the session is not polled. + */ + refetchInterval?: number +} + +/** + * Provider to wrap the app in to make session data available globally. + * Can also be used to throttle the number of requests to the endpoint + * `/api/auth/session`. + * + * [Documentation](https://next-auth.js.org/getting-started/client#sessionprovider) + */ +export function SessionProvider(props: SessionProviderProps) { const { children, baseUrl, basePath, staleTime = 0 } = props if (baseUrl) __NEXTAUTH.baseUrl = baseUrl @@ -197,7 +374,7 @@ export function SessionProvider(props) { const hasInitialSession = props.session !== undefined /** If session was passed, initialize as already synced */ - __NEXTAUTH._lastSync = hasInitialSession ? _now() : 0 + __NEXTAUTH._lastSync = hasInitialSession ? now() : 0 const [session, setSession] = React.useState(() => { if (hasInitialSession) __NEXTAUTH._session = props.session @@ -214,7 +391,7 @@ export function SessionProvider(props) { // We should always update if we don't have a client session yet // or if there are events from other tabs/windows if (storageEvent || __NEXTAUTH._session === undefined) { - __NEXTAUTH._lastSync = _now() + __NEXTAUTH._lastSync = now() __NEXTAUTH._session = await getSession({ broadcast: !storageEvent, }) @@ -233,13 +410,13 @@ export function SessionProvider(props) { // event anyway) (staleTime > 0 && __NEXTAUTH._session === null) || // Bail out early if the client session is not stale yet - (staleTime > 0 && _now() < __NEXTAUTH._lastSync + staleTime) + (staleTime > 0 && now() < __NEXTAUTH._lastSync + staleTime) ) { return } // An event or session staleness occurred, update the client session. - __NEXTAUTH._lastSync = _now() + __NEXTAUTH._lastSync = now() __NEXTAUTH._session = await getSession() setSession(__NEXTAUTH._session) } catch (error) { @@ -262,8 +439,8 @@ export function SessionProvider(props) { // on how the session object is being used in the client; it is // more robust to have each window/tab fetch it's own copy of the // session object rather than share it across instances. - const unsubscribe = broadcast.receive( - async () => await __NEXTAUTH._getSession({ event: "storage" }) + const unsubscribe = broadcast.receive(() => + __NEXTAUTH._getSession({ event: "storage" }) ) return () => unsubscribe() @@ -285,16 +462,16 @@ export function SessionProvider(props) { const { refetchInterval } = props // Set up polling if (refetchInterval) { - const refetchIntervalTimer = setInterval(async () => { + const refetchIntervalTimer = setInterval(() => { if (__NEXTAUTH._session) { - await __NEXTAUTH._getSession({ event: "poll" }) + __NEXTAUTH._getSession({ event: "poll" }) } }, refetchInterval * 1000) return () => clearInterval(refetchIntervalTimer) } }, [props.refetchInterval]) - const value = React.useMemo( + const value: any = React.useMemo( () => ({ data: session, status: loading @@ -310,76 +487,3 @@ export function SessionProvider(props) { {children} ) } - -/** - * If passed 'appContext' via getInitialProps() in _app.js - * then get the req object from ctx and use that for the - * req value to allow _fetchData to - * work seemlessly in getInitialProps() on server side - * pages *and* in _app.js. - */ -async function _fetchData(path, { ctx, req = ctx?.req } = {}) { - try { - const options = req ? { headers: { cookie: req.headers.cookie } } : {} - const res = await fetch(`${_apiBaseUrl()}/${path}`, options) - const data = await res.json() - if (!res.ok) throw data - return Object.keys(data).length > 0 ? data : null // Return null if data empty - } catch (error) { - logger.error("CLIENT_FETCH_ERROR", { - error, - path, - ...(req ? { header: req.headers } : {}), - }) - return null - } -} - -function _apiBaseUrl() { - if (typeof window === "undefined") { - // Return absolute path when called server side - return `${__NEXTAUTH.baseUrlServer}${__NEXTAUTH.basePathServer}` - } - // Return relative path when called client side - return __NEXTAUTH.basePath -} - -/** Returns the number of seconds elapsed since January 1, 1970 00:00:00 UTC. */ -function _now() { - return Math.floor(Date.now() / 1000) -} - -/** - * Inspired by [Broadcast Channel API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) - * Only not using it directly, because Safari does not support it. - * - * https://caniuse.com/?search=broadcastchannel - */ -function BroadcastChannel(name = "nextauth.message") { - return { - /** - * Get notified by other tabs/windows. - * @param {(message: import("types/internals/react").BroadcastMessage) => void} onReceive - */ - receive(onReceive) { - const handler = (event) => { - if (event.key !== name) return - /** @type {import("types/internals/react").BroadcastMessage} */ - const message = JSON.parse(event.newValue) - if (message?.event !== "session" || !message?.data) return - - onReceive(message) - } - window.addEventListener("storage", handler) - return () => window.removeEventListener("storage", handler) - }, - /** Notify other tabs/windows. */ - post(message) { - if (typeof window === "undefined") return - localStorage.setItem( - name, - JSON.stringify({ ...message, timestamp: _now() }) - ) - }, - } -} diff --git a/tsconfig.json b/tsconfig.json index e89d946cea..b1674e5e08 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,11 +2,10 @@ "compilerOptions": { "strictNullChecks": true, "baseUrl": ".", - "outDir": "dist", "paths": { - "next-auth": ["dist/server"], - "next-auth/providers/*": ["dist/providers/*"], - "next-auth/react": ["dist/client/react"] + "next-auth": ["server"], + "next-auth/providers/*": ["providers/*"], + "next-auth/react": ["client/react"] }, "target": "es2019", "lib": ["dom", "dom.iterable", "esnext"], diff --git a/types/internals/env.d.ts b/types/internals/env.d.ts new file mode 100644 index 0000000000..a61d9ab45f --- /dev/null +++ b/types/internals/env.d.ts @@ -0,0 +1,11 @@ +// See: https://stackoverflow.com/a/59499895/5364135 +export {} + +declare global { + export namespace NodeJS { + interface ProcessEnv extends NodeJS.ProcessEnv { + NEXTAUTH_URL?: string + VERCEL_URL?: string + } + } +} From c11fbc4b1646bf4af92cd3d7249144a5e83da9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 18:54:43 +0200 Subject: [PATCH 19/62] refactor(ts): convert `next-auth/jwt` to TS --- .gitignore | 13 ++++--------- src/{lib/jwt.js => jwt.ts} | 7 ++++--- tsconfig.json | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) rename src/{lib/jwt.js => jwt.ts} (97%) diff --git a/.gitignore b/.gitignore index 9c9a3ce2f1..1b74a36c61 100644 --- a/.gitignore +++ b/.gitignore @@ -28,23 +28,18 @@ node_modules www/providers.json /internals /providers +/client +/css +/lib +/server /types/providers/* !types/providers/index.d.ts !types/providers/email.d.ts !types/providers/credentials.d.ts !types/providers/oauth.d.ts /adapters.d.ts -/adapters.js -/client.d.ts -/client.js /index.d.ts /index.js -/jwt.d.ts -/jwt.js -/errors.js -/errors.d.ts -/react.js -/react.d.ts # Development app app/next-auth diff --git a/src/lib/jwt.js b/src/jwt.ts similarity index 97% rename from src/lib/jwt.js rename to src/jwt.ts index 6a8545cd39..ece5b11ab4 100644 --- a/src/lib/jwt.js +++ b/src/jwt.ts @@ -1,6 +1,6 @@ import crypto from "crypto" import jose from "jose" -import logger from "./logger" +import logger from "src/lib/logger" // Set default algorithm to use for auto-generated signing key const DEFAULT_SIGNATURE_ALGORITHM = "HS512" @@ -28,7 +28,7 @@ export async function encode({ zip: "DEF", }, encryption = DEFAULT_ENCRYPTION_ENABLED, -} = {}) { +}: any = {}) { // Signing Key const _signingKey = signingKey ? jose.JWK.asKey(JSON.parse(signingKey)) @@ -65,7 +65,7 @@ export async function decode({ algorithms: [DEFAULT_ENCRYPTION_ALGORITHM], }, encryption = DEFAULT_ENCRYPTION_ENABLED, -} = {}) { +}: any = {}) { if (!token) return null let tokenToVerify = token @@ -159,6 +159,7 @@ function hkdf(secret, { byteLength, encryptionInfo, digest = "sha256" }) { ) ) } + // eslint-disable-next-line @typescript-eslint/no-var-requires return require("futoin-hkdf")(secret, byteLength, { info: encryptionInfo, hash: digest, diff --git a/tsconfig.json b/tsconfig.json index b1674e5e08..7368966ef9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "paths": { "next-auth": ["server"], "next-auth/providers/*": ["providers/*"], - "next-auth/react": ["client/react"] + "next-auth/react": ["react"] }, "target": "es2019", "lib": ["dom", "dom.iterable", "esnext"], From fb28cceeccd828b904554fc8f9fbef4a43d6d612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 18:57:16 +0200 Subject: [PATCH 20/62] chore: fix import --- .gitignore | 4 ++++ src/server/index.ts | 2 +- tsconfig.json | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1b74a36c61..5ef2a7f36b 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,10 @@ www/providers.json /adapters.d.ts /index.d.ts /index.js +/jwt.d.ts +/jwt.js +/react.d.ts +/react.js # Development app app/next-auth diff --git a/src/server/index.ts b/src/server/index.ts index 320671fd45..878fb8e523 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/restrict-template-expressions */ -import * as jwt from "../lib/jwt" +import * as jwt from "../jwt" import parseUrl from "../lib/parse-url" import logger, { setLogger } from "../lib/logger" import * as cookie from "./lib/cookie" diff --git a/tsconfig.json b/tsconfig.json index 7368966ef9..dfbe986391 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "strictNullChecks": true, "baseUrl": ".", + "outDir": ".", "paths": { "next-auth": ["server"], "next-auth/providers/*": ["providers/*"], From ad59f51d503d3c9a1b0cb74176c0dc2cb47ddc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 19:36:42 +0200 Subject: [PATCH 21/62] refactor: move `types` into `src` --- .../oauth.d.ts => src/providers/oauth.ts | 24 ++++++++++--------- {types => src/types}/adapters.d.ts | 0 {types => src/types}/errors.d.ts | 0 {types => src/types}/index.d.ts | 0 {types => src/types}/internals/cookies.d.ts | 0 {types => src/types}/internals/env.d.ts | 0 {types => src/types}/internals/index.d.ts | 0 {types => src/types}/internals/next.d.ts | 0 {types => src/types}/internals/oauth.d.ts | 0 {types => src/types}/internals/react.d.ts | 0 {types => src/types}/internals/utils.d.ts | 0 {types => src/types}/jwt.d.ts | 0 .../types}/providers/credentials.d.ts | 0 {types => src/types}/providers/email.d.ts | 0 {types => src/types}/providers/index.d.ts | 8 +++++-- {types => src/types}/react-client.d.ts | 0 {types => src/types}/tests/jwt.test.ts | 0 {types => src/types}/tests/providers.test.ts | 0 {types => src/types}/tests/react.test.ts | 0 {types => src/types}/tests/server.test.ts | 0 {types => src/types}/tests/test-helpers.ts | 0 {types => src/types}/tsconfig.json | 0 {types => src/types}/tslint.json | 0 23 files changed, 19 insertions(+), 13 deletions(-) rename types/providers/oauth.d.ts => src/providers/oauth.ts (89%) rename {types => src/types}/adapters.d.ts (100%) rename {types => src/types}/errors.d.ts (100%) rename {types => src/types}/index.d.ts (100%) rename {types => src/types}/internals/cookies.d.ts (100%) rename {types => src/types}/internals/env.d.ts (100%) rename {types => src/types}/internals/index.d.ts (100%) rename {types => src/types}/internals/next.d.ts (100%) rename {types => src/types}/internals/oauth.d.ts (100%) rename {types => src/types}/internals/react.d.ts (100%) rename {types => src/types}/internals/utils.d.ts (100%) rename {types => src/types}/jwt.d.ts (100%) rename {types => src/types}/providers/credentials.d.ts (100%) rename {types => src/types}/providers/email.d.ts (100%) rename {types => src/types}/providers/index.d.ts (86%) rename {types => src/types}/react-client.d.ts (100%) rename {types => src/types}/tests/jwt.test.ts (100%) rename {types => src/types}/tests/providers.test.ts (100%) rename {types => src/types}/tests/react.test.ts (100%) rename {types => src/types}/tests/server.test.ts (100%) rename {types => src/types}/tests/test-helpers.ts (100%) rename {types => src/types}/tsconfig.json (100%) rename {types => src/types}/tslint.json (100%) diff --git a/types/providers/oauth.d.ts b/src/providers/oauth.ts similarity index 89% rename from types/providers/oauth.d.ts rename to src/providers/oauth.ts index 7b39940a31..5154c26371 100644 --- a/types/providers/oauth.d.ts +++ b/src/providers/oauth.ts @@ -1,6 +1,6 @@ -import { CommonProviderOptions } from "." -import { Profile, TokenSet, User } from ".." -import { Awaitable } from "../internals/utils" +import { CommonProviderOptions } from "../types/providers" +import { Profile, TokenSet, User } from "../types" +import { Awaitable } from "../types/internals/utils" import { AuthorizationParameters, @@ -11,9 +11,6 @@ import { OpenIDCallbackChecks, } from "openid-client" -import { OAuthProviderType } from "./oauth-providers" -export { OAuthProviderType } - type ChecksType = "pkce" | "state" | "both" | "none" export type OAuthChecks = OpenIDCallbackChecks | OAuthCallbackChecks @@ -74,14 +71,14 @@ export interface OAuthConfig

= Profile> * * [Authorization endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.1) */ - authorization: EndpointHandler + authorization?: EndpointHandler /** * Endpoint that returns OAuth 2/OIDC tokens and information about them. * This includes `access_token`, `id_token`, `refresh_token`, etc. * * [Token endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.2) */ - token: EndpointHandler< + token?: EndpointHandler< UrlParams, { /** @@ -105,10 +102,10 @@ export interface OAuthConfig

= Profile> */ userinfo?: EndpointHandler type: "oauth" - version: string + version?: string accessTokenUrl?: string requestTokenUrl?: string - profile(profile: P, tokens: TokenSet): Awaitable + profile?: (profile: P, tokens: TokenSet) => Awaitable checks?: ChecksType | ChecksType[] clientId: string clientSecret: @@ -136,7 +133,12 @@ export interface OAuthConfig

= Profile> * We will perform a deep-merge of these values * with the default configuration. */ - options?: Omit, "options"> + options?: OAuthUserConfig

} +export type OAuthUserConfig

= Profile> = Omit< + Partial>, + "options" | "type" +> + export type OAuthProvider = (options: Partial) => OAuthConfig diff --git a/types/adapters.d.ts b/src/types/adapters.d.ts similarity index 100% rename from types/adapters.d.ts rename to src/types/adapters.d.ts diff --git a/types/errors.d.ts b/src/types/errors.d.ts similarity index 100% rename from types/errors.d.ts rename to src/types/errors.d.ts diff --git a/types/index.d.ts b/src/types/index.d.ts similarity index 100% rename from types/index.d.ts rename to src/types/index.d.ts diff --git a/types/internals/cookies.d.ts b/src/types/internals/cookies.d.ts similarity index 100% rename from types/internals/cookies.d.ts rename to src/types/internals/cookies.d.ts diff --git a/types/internals/env.d.ts b/src/types/internals/env.d.ts similarity index 100% rename from types/internals/env.d.ts rename to src/types/internals/env.d.ts diff --git a/types/internals/index.d.ts b/src/types/internals/index.d.ts similarity index 100% rename from types/internals/index.d.ts rename to src/types/internals/index.d.ts diff --git a/types/internals/next.d.ts b/src/types/internals/next.d.ts similarity index 100% rename from types/internals/next.d.ts rename to src/types/internals/next.d.ts diff --git a/types/internals/oauth.d.ts b/src/types/internals/oauth.d.ts similarity index 100% rename from types/internals/oauth.d.ts rename to src/types/internals/oauth.d.ts diff --git a/types/internals/react.d.ts b/src/types/internals/react.d.ts similarity index 100% rename from types/internals/react.d.ts rename to src/types/internals/react.d.ts diff --git a/types/internals/utils.d.ts b/src/types/internals/utils.d.ts similarity index 100% rename from types/internals/utils.d.ts rename to src/types/internals/utils.d.ts diff --git a/types/jwt.d.ts b/src/types/jwt.d.ts similarity index 100% rename from types/jwt.d.ts rename to src/types/jwt.d.ts diff --git a/types/providers/credentials.d.ts b/src/types/providers/credentials.d.ts similarity index 100% rename from types/providers/credentials.d.ts rename to src/types/providers/credentials.d.ts diff --git a/types/providers/email.d.ts b/src/types/providers/email.d.ts similarity index 100% rename from types/providers/email.d.ts rename to src/types/providers/email.d.ts diff --git a/types/providers/index.d.ts b/src/types/providers/index.d.ts similarity index 86% rename from types/providers/index.d.ts rename to src/types/providers/index.d.ts index 5116df703f..3055f36b98 100644 --- a/types/providers/index.d.ts +++ b/src/types/providers/index.d.ts @@ -1,4 +1,8 @@ -import { OAuthConfig, OAuthProvider, OAuthProviderType } from "./oauth" +import { + OAuthConfig, + OAuthProvider, + OAuthProviderType, +} from "../../providers/oauth" import { EmailConfig, EmailProvider, EmailProviderType } from "./email" @@ -8,7 +12,7 @@ import { CredentialsProviderType, } from "./credentials" -export * from "./oauth" +export * from "../../providers/oauth" export * from "./email" export * from "./credentials" diff --git a/types/react-client.d.ts b/src/types/react-client.d.ts similarity index 100% rename from types/react-client.d.ts rename to src/types/react-client.d.ts diff --git a/types/tests/jwt.test.ts b/src/types/tests/jwt.test.ts similarity index 100% rename from types/tests/jwt.test.ts rename to src/types/tests/jwt.test.ts diff --git a/types/tests/providers.test.ts b/src/types/tests/providers.test.ts similarity index 100% rename from types/tests/providers.test.ts rename to src/types/tests/providers.test.ts diff --git a/types/tests/react.test.ts b/src/types/tests/react.test.ts similarity index 100% rename from types/tests/react.test.ts rename to src/types/tests/react.test.ts diff --git a/types/tests/server.test.ts b/src/types/tests/server.test.ts similarity index 100% rename from types/tests/server.test.ts rename to src/types/tests/server.test.ts diff --git a/types/tests/test-helpers.ts b/src/types/tests/test-helpers.ts similarity index 100% rename from types/tests/test-helpers.ts rename to src/types/tests/test-helpers.ts diff --git a/types/tsconfig.json b/src/types/tsconfig.json similarity index 100% rename from types/tsconfig.json rename to src/types/tsconfig.json diff --git a/types/tslint.json b/src/types/tslint.json similarity index 100% rename from types/tslint.json rename to src/types/tslint.json From 416b3777e2846d08394872ad2fda6876b04046fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 19:39:25 +0200 Subject: [PATCH 22/62] refactor(ts): fix types imports --- src/index.ts | 9 ++++----- src/providers/{auth0.js => auth0.ts} | 9 +++++---- src/providers/email.ts | 2 +- src/providers/{google.js => google.ts} | 8 +++++--- src/react.tsx | 8 ++++---- tsconfig.json | 5 ----- 6 files changed, 19 insertions(+), 22 deletions(-) rename src/providers/{auth0.js => auth0.ts} (71%) rename src/providers/{google.js => google.ts} (71%) diff --git a/src/index.ts b/src/index.ts index 0ab199456e..d4ee3f6cd8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,5 @@ export { default } from "./server" -export * from "./server" -export * from "../types" -export * from "../types/providers" -export * from "../types/jwt" -export * from "../types/react-client" +export * from "./types" +export * from "./types/providers" +export * from "./types/jwt" +export * from "./types/react-client" diff --git a/src/providers/auth0.js b/src/providers/auth0.ts similarity index 71% rename from src/providers/auth0.js rename to src/providers/auth0.ts index 2a5baff67f..71617a87b7 100644 --- a/src/providers/auth0.js +++ b/src/providers/auth0.ts @@ -1,5 +1,6 @@ -/** @type {import("types/providers").OAuthProvider} */ -export default function Auth0(options) { +import { OAuthConfig, OAuthUserConfig } from "./oauth" + +export default function Auth0(options: OAuthUserConfig): OAuthConfig { return { id: "auth0", name: "Auth0", @@ -8,7 +9,7 @@ export default function Auth0(options) { authorization: { params: { scope: "openid email profile" } }, checks: ["pkce", "state"], idToken: true, - profile(profile) { + profile(profile: any) { return { id: profile.sub, name: profile.nickname, @@ -17,5 +18,5 @@ export default function Auth0(options) { } }, options, - } + } as any } diff --git a/src/providers/email.ts b/src/providers/email.ts index 8d810d69c3..2c1f613609 100644 --- a/src/providers/email.ts +++ b/src/providers/email.ts @@ -1,6 +1,6 @@ import { createTransport } from "nodemailer" -import { EmailConfig, EmailUserConfig } from "types/providers" +import { EmailConfig, EmailUserConfig } from "src/types/providers" export default function Email(options: EmailUserConfig): EmailConfig { return { diff --git a/src/providers/google.js b/src/providers/google.ts similarity index 71% rename from src/providers/google.js rename to src/providers/google.ts index 3d0485cb72..254e4a345f 100644 --- a/src/providers/google.js +++ b/src/providers/google.ts @@ -1,4 +1,6 @@ -export default function Google(options) { +import { OAuthConfig, OAuthUserConfig } from "./oauth" + +export default function Google(options: OAuthUserConfig): OAuthConfig { return { id: "google", name: "Google", @@ -7,7 +9,7 @@ export default function Google(options) { authorization: { params: { scope: "openid email profile" } }, idToken: true, checks: ["pkce", "state"], - profile(profile) { + profile(profile: any) { return { id: profile.sub, name: profile.name, @@ -16,5 +18,5 @@ export default function Google(options) { } }, options, - } + } as any } diff --git a/src/react.tsx b/src/react.tsx index 4596d616ff..9fc5682119 100644 --- a/src/react.tsx +++ b/src/react.tsx @@ -9,10 +9,10 @@ // We use HTTP POST requests with CSRF Tokens to protect against CSRF attacks. import * as React from "react" -import _logger, { proxyLogger } from "src/lib/logger" -import parseUrl from "src/lib/parse-url" -import { Session } from "types" -import { ProviderType } from "types/providers" +import _logger, { proxyLogger } from "./lib/logger" +import parseUrl from "./lib/parse-url" +import { Session } from "./types" +import { ProviderType } from "./types/providers" import { BroadcastChannel, CtxOrReq, diff --git a/tsconfig.json b/tsconfig.json index dfbe986391..81d23bd8a3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,11 +3,6 @@ "strictNullChecks": true, "baseUrl": ".", "outDir": ".", - "paths": { - "next-auth": ["server"], - "next-auth/providers/*": ["providers/*"], - "next-auth/react": ["react"] - }, "target": "es2019", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, From e3969be8a94a469840e47d4d54903e06e8cb24bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 19:39:34 +0200 Subject: [PATCH 23/62] chore: add cleanup script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 82d1f343fa..e5052bdfd3 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ }, "scripts": { "build": "npm run build:js && npm run build:css", - "build:js": "rm -rf client css lib providers server && tsc", + "clean": "rm -rf client css dist lib providers server index.d.ts index.js jwt.d.ts jwt.js react.d.ts react.js", + "build:js": "npm run clean && tsc", "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js", "dev:setup": "npm i && npm run build:css && cd app && npm i", "dev": "cd app && npm run dev", From abae4bb800d3d2c0a15b29771033b6600bb07b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 19:40:36 +0200 Subject: [PATCH 24/62] chore: exclude all `tests` folder from compilation --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 81d23bd8a3..d63bcf3bc8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,7 @@ "exclude": [ "app", "types", - "tests", + "**/tests", "**/__tests__", "config", "www" From 7560f3bef1468caacfa565e44b779f9c64acee4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 19:46:27 +0200 Subject: [PATCH 25/62] refactor: rename types/index.d.ts to types/index.ts --- .gitignore | 6 +----- package.json | 2 +- src/types/{index.d.ts => index.ts} | 0 3 files changed, 2 insertions(+), 6 deletions(-) rename src/types/{index.d.ts => index.ts} (100%) diff --git a/.gitignore b/.gitignore index 5ef2a7f36b..75eb4aa906 100644 --- a/.gitignore +++ b/.gitignore @@ -32,11 +32,7 @@ www/providers.json /css /lib /server -/types/providers/* -!types/providers/index.d.ts -!types/providers/email.d.ts -!types/providers/credentials.d.ts -!types/providers/oauth.d.ts +/types /adapters.d.ts /index.d.ts /index.js diff --git a/package.json b/package.json index e5052bdfd3..f4b66221bd 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "scripts": { "build": "npm run build:js && npm run build:css", - "clean": "rm -rf client css dist lib providers server index.d.ts index.js jwt.d.ts jwt.js react.d.ts react.js", + "clean": "rm -rf client css dist lib providers server types index.d.ts index.js jwt.d.ts jwt.js react.d.ts react.js", "build:js": "npm run clean && tsc", "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js", "dev:setup": "npm i && npm run build:css && cd app && npm i", diff --git a/src/types/index.d.ts b/src/types/index.ts similarity index 100% rename from src/types/index.d.ts rename to src/types/index.ts From 6956ed2c45a9414c8852c3ac17edf9aa68ffc1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 20:35:47 +0200 Subject: [PATCH 26/62] refactor(ts): move `next-auth/jwt` --- src/index.ts | 3 +- src/jwt.ts | 92 ++++++++++++++++++++++++++++++------- src/types/index.ts | 13 ++---- src/types/jwt.d.ts | 69 ---------------------------- src/types/tests/jwt.test.ts | 26 ----------- 5 files changed, 81 insertions(+), 122 deletions(-) delete mode 100644 src/types/jwt.d.ts delete mode 100644 src/types/tests/jwt.test.ts diff --git a/src/index.ts b/src/index.ts index d4ee3f6cd8..c0bdb16323 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,4 @@ export { default } from "./server" export * from "./types" -export * from "./types/providers" -export * from "./types/jwt" +export * from "./providers" export * from "./types/react-client" diff --git a/src/jwt.ts b/src/jwt.ts index ece5b11ab4..44f7bd1853 100644 --- a/src/jwt.ts +++ b/src/jwt.ts @@ -1,6 +1,56 @@ import crypto from "crypto" import jose from "jose" -import logger from "src/lib/logger" +import logger from "./lib/logger" +import { NextApiRequest } from "./types/internals/utils" + +export interface DefaultJWT extends Record { + name?: string | null + email?: string | null + picture?: string | null + sub?: string +} + +/** + * Returned by the `jwt` callback and `getToken`, when using JWT sessions + * + * [`jwt` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | [`getToken`](https://next-auth.js.org/tutorials/securing-pages-and-api-routes#using-gettoken) + */ +export interface JWT extends Record, DefaultJWT {} + +export interface JWTEncodeParams { + token?: JWT + maxAge?: number + secret: string | Buffer + signingKey?: string + signingOptions?: jose.JWT.SignOptions + encryptionKey?: string + encryptionOptions?: object + encryption?: boolean +} + +export interface JWTDecodeParams { + token?: string + maxAge?: number + secret: string | Buffer + signingKey?: string + verificationKey?: string + verificationOptions?: jose.JWT.VerifyOptions + encryptionKey?: string + decryptionKey?: string + decryptionOptions?: jose.JWE.DecryptOptions + encryption?: boolean +} + +export interface JWTOptions { + secret: string + maxAge: number + encryption?: boolean + signingKey?: string + encryptionKey?: string + encode: typeof encode + decode: typeof decode + verificationOptions?: jose.JWT.VerifyOptions +} // Set default algorithm to use for auto-generated signing key const DEFAULT_SIGNATURE_ALGORITHM = "HS512" @@ -28,7 +78,7 @@ export async function encode({ zip: "DEF", }, encryption = DEFAULT_ENCRYPTION_ENABLED, -}: any = {}) { +}: JWTEncodeParams) { // Signing Key const _signingKey = signingKey ? jose.JWK.asKey(JSON.parse(signingKey)) @@ -65,7 +115,7 @@ export async function decode({ algorithms: [DEFAULT_ENCRYPTION_ALGORITHM], }, encryption = DEFAULT_ENCRYPTION_ENABLED, -}: any = {}) { +}: JWTDecodeParams): Promise { if (!token) return null let tokenToVerify = token @@ -91,19 +141,26 @@ export async function decode({ : getDerivedSigningKey(secret) // Verify token - return jose.JWT.verify(tokenToVerify, _signingKey, verificationOptions) + return jose.JWT.verify( + tokenToVerify, + _signingKey, + verificationOptions + ) as JWT | null } -/** - * Server-side method to retrieve the JWT from `req`. - * @param {{ - * req: NextApiRequest - * secureCookie?: boolean - * cookieName?: string - * raw?: boolean - * }} params - */ -export async function getToken(params) { +export type GetTokenParams = { + req: NextApiRequest + secureCookie?: boolean + cookieName?: string + raw?: R + decode?: typeof decode + secret?: string +} & Omit + +/** [Documentation](https://next-auth.js.org/tutorials/securing-pages-and-api-routes#using-gettoken) */ +export async function getToken( + params?: GetTokenParams +): Promise { const { req, // Use secure prefix for cookie name, unless URL is NEXTAUTH_URL is http:// @@ -117,7 +174,7 @@ export async function getToken(params) { : "next-auth.session-token", raw = false, decode: _decode = decode, - } = params + } = params ?? {} if (!req) throw new Error("Must pass `req` to JWT getToken()") // Try to get token from cookie @@ -132,12 +189,15 @@ export async function getToken(params) { } if (raw) { + // @ts-expect-error return token } try { - return _decode({ token, ...params }) + // @ts-expect-error + return await _decode({ token, ...params }) } catch { + // @ts-expect-error return null } } diff --git a/src/types/index.ts b/src/types/index.ts index 6b5cf75a02..a995a8b239 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,13 +1,8 @@ import { Adapter } from "./adapters" -import { JWTOptions, JWT } from "./jwt" -import { Provider, Credentials, ProviderType } from "./providers" -import { - Awaitable, - NextApiRequest, - NextApiResponse, - NextApiHandler, -} from "./internals/utils" +import { Provider, CredentialInput, ProviderType } from "../providers" +import { Awaitable } from "./internals/utils" import { TokenSetParameters } from "openid-client" +import { JWT, JWTOptions } from "../jwt" /** * Configure your NextAuth instance @@ -299,7 +294,7 @@ export interface CallbacksOptions< verificationRequest?: boolean } /** If Credentials provider is used, it contains the user credentials */ - credentials: Credentials + credentials: Record }): Awaitable /** * This callback is called anytime the user is redirected to a callback URL (e.g. on signin or signout). diff --git a/src/types/jwt.d.ts b/src/types/jwt.d.ts deleted file mode 100644 index 0841dc9473..0000000000 --- a/src/types/jwt.d.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { JWT as JoseJWT, JWE } from "jose" -import { NextApiRequest } from "./internals/utils" - -export interface DefaultJWT extends Record { - name?: string | null - email?: string | null - picture?: string | null - sub?: string -} - -/** - * Returned by the `jwt` callback and `getToken`, when using JWT sessions - * - * [`jwt` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | [`getToken`](https://next-auth.js.org/tutorials/securing-pages-and-api-routes#using-gettoken) - */ -export interface JWT extends Record, DefaultJWT {} - -export interface JWTEncodeParams { - token?: JWT - maxAge?: number - secret: string | Buffer - signingKey?: string - signingOptions?: JoseJWT.SignOptions - encryptionKey?: string - encryptionOptions?: object - encryption?: boolean -} - -export function encode(params?: JWTEncodeParams): Promise - -export interface JWTDecodeParams { - token?: string - maxAge?: number - secret: string | Buffer - signingKey?: string - verificationKey?: string - verificationOptions?: JoseJWT.VerifyOptions - encryptionKey?: string - decryptionKey?: string - decryptionOptions?: JWE.DecryptOptions - encryption?: boolean -} - -export function decode(params?: JWTDecodeParams): Promise - -export type GetTokenParams = { - req: NextApiRequest - secureCookie?: boolean - cookieName?: string - raw?: R - decode?: typeof decode - secret?: string -} & Omit - -/** [Documentation](https://next-auth.js.org/tutorials/securing-pages-and-api-routes#using-gettoken) */ -export function getToken( - params?: GetTokenParams -): Promise - -export interface JWTOptions { - secret: string - maxAge: number - encryption?: boolean - signingKey?: string - encryptionKey?: string - encode: typeof encode - decode: typeof decode - verificationOptions?: JoseJWT.VerifyOptions -} diff --git a/src/types/tests/jwt.test.ts b/src/types/tests/jwt.test.ts deleted file mode 100644 index af9b08cd0b..0000000000 --- a/src/types/tests/jwt.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as JWTType from "next-auth/jwt" -import { nextReq } from "./test-helpers" - -// $ExpectType Promise -JWTType.encode({ - token: { key: "value" }, - secret: "secret", -}) - -// $ExpectType Promise -JWTType.decode({ - token: "token", - secret: "secret", -}) - -// $ExpectType Promise -JWTType.getToken({ - req: nextReq, - raw: true, -}) - -// $ExpectType Promise -JWTType.getToken({ - req: nextReq, - secret: "secret", -}) From 493fc457ade3962a5ddcf98379def0c524ee81ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 20:37:43 +0200 Subject: [PATCH 27/62] refactor(ts): move `next-auth/providers` --- src/index.ts | 2 - src/providers/credentials.js | 10 ---- src/providers/credentials.ts | 38 ++++++++++++++ src/providers/email.ts | 48 ++++++++++++++++- .../index.d.ts => providers/index.ts} | 8 +-- src/providers/oauth.ts | 5 +- src/react.tsx | 2 +- src/types/providers/credentials.d.ts | 34 ------------- src/types/providers/email.d.ts | 51 ------------------- 9 files changed, 92 insertions(+), 106 deletions(-) delete mode 100644 src/providers/credentials.js create mode 100644 src/providers/credentials.ts rename src/{types/providers/index.d.ts => providers/index.ts} (86%) delete mode 100644 src/types/providers/credentials.d.ts delete mode 100644 src/types/providers/email.d.ts diff --git a/src/index.ts b/src/index.ts index c0bdb16323..380eae5d64 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,2 @@ export { default } from "./server" export * from "./types" -export * from "./providers" -export * from "./types/react-client" diff --git a/src/providers/credentials.js b/src/providers/credentials.js deleted file mode 100644 index 9998cf44c7..0000000000 --- a/src/providers/credentials.js +++ /dev/null @@ -1,10 +0,0 @@ -export default function Credentials(options) { - return { - id: "credentials", - name: "Credentials", - type: "credentials", - authorize: null, - credentials: null, - options, - } -} diff --git a/src/providers/credentials.ts b/src/providers/credentials.ts new file mode 100644 index 0000000000..7ec89e3cfa --- /dev/null +++ b/src/providers/credentials.ts @@ -0,0 +1,38 @@ +import { Awaitable, NextApiRequest } from "../types/internals/utils" +import { CommonProviderOptions } from "." +import { User } from ".." + +export interface CredentialInput { + label?: string + type?: string + value?: string + placeholder?: string +} + +export interface CredentialsConfig< + C extends Record = {} +> extends CommonProviderOptions { + type: "credentials" + credentials: C + authorize: ( + credentials: Record, + req: NextApiRequest + ) => Awaitable<(Omit | { id?: string }) | null> +} + +export type CredentialsProvider = >( + options: Partial> +) => CredentialsConfig + +export type CredentialsProviderType = "Credentials" + +export default function Credentials( + options: Partial +): CredentialsConfig { + return { + id: "credentials", + name: "Credentials", + type: "credentials", + options, + } as any +} diff --git a/src/providers/email.ts b/src/providers/email.ts index 2c1f613609..d470d68210 100644 --- a/src/providers/email.ts +++ b/src/providers/email.ts @@ -1,6 +1,52 @@ import { createTransport } from "nodemailer" -import { EmailConfig, EmailUserConfig } from "src/types/providers" +import { CommonProviderOptions } from "." +import { Options as SMTPConnectionOptions } from "nodemailer/lib/smtp-connection" +import { Awaitable } from "../types/internals/utils" + +export interface EmailConfig extends CommonProviderOptions { + type: "email" + // TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html + server: string | SMTPConnectionOptions + /** @default "NextAuth " */ + from?: string + /** + * How long until the e-mail can be used to log the user in, + * in seconds. Defaults to 1 day + * @default 86400 + */ + maxAge?: number + sendVerificationRequest: (params: { + identifier: string + url: string + expires: Date + provider: EmailConfig + token: string + }) => Awaitable + /** + * By default, we are generating a random verification token. + * You can make it predictable or modify it as you like with this method. + * @example + * ```js + * Providers.Email({ + * async generateVerificationToken() { + * return "ABC123" + * } + * }) + * ``` + * [Documentation](https://next-auth.js.org/providers/email#customising-the-verification-token) + */ + generateVerificationToken?: () => Awaitable + options: EmailUserConfig +} + +export type EmailUserConfig = Partial> + +export type EmailProvider = (options: EmailUserConfig) => EmailConfig + +// TODO: Rename to Token provider +// when started working on https://github.com/nextauthjs/next-auth/discussions/1465 +export type EmailProviderType = "Email" export default function Email(options: EmailUserConfig): EmailConfig { return { diff --git a/src/types/providers/index.d.ts b/src/providers/index.ts similarity index 86% rename from src/types/providers/index.d.ts rename to src/providers/index.ts index 3055f36b98..5116df703f 100644 --- a/src/types/providers/index.d.ts +++ b/src/providers/index.ts @@ -1,8 +1,4 @@ -import { - OAuthConfig, - OAuthProvider, - OAuthProviderType, -} from "../../providers/oauth" +import { OAuthConfig, OAuthProvider, OAuthProviderType } from "./oauth" import { EmailConfig, EmailProvider, EmailProviderType } from "./email" @@ -12,7 +8,7 @@ import { CredentialsProviderType, } from "./credentials" -export * from "../../providers/oauth" +export * from "./oauth" export * from "./email" export * from "./credentials" diff --git a/src/providers/oauth.ts b/src/providers/oauth.ts index 5154c26371..6edad65a49 100644 --- a/src/providers/oauth.ts +++ b/src/providers/oauth.ts @@ -1,4 +1,4 @@ -import { CommonProviderOptions } from "../types/providers" +import { CommonProviderOptions } from "../providers" import { Profile, TokenSet, User } from "../types" import { Awaitable } from "../types/internals/utils" @@ -11,6 +11,9 @@ import { OpenIDCallbackChecks, } from "openid-client" +// TODO: generate +export type OAuthProviderType = string + type ChecksType = "pkce" | "state" | "both" | "none" export type OAuthChecks = OpenIDCallbackChecks | OAuthCallbackChecks diff --git a/src/react.tsx b/src/react.tsx index 9fc5682119..b7ec35a36e 100644 --- a/src/react.tsx +++ b/src/react.tsx @@ -12,7 +12,7 @@ import * as React from "react" import _logger, { proxyLogger } from "./lib/logger" import parseUrl from "./lib/parse-url" import { Session } from "./types" -import { ProviderType } from "./types/providers" +import { ProviderType } from "./providers" import { BroadcastChannel, CtxOrReq, diff --git a/src/types/providers/credentials.d.ts b/src/types/providers/credentials.d.ts deleted file mode 100644 index 5d7a996e42..0000000000 --- a/src/types/providers/credentials.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Awaitable, NextApiRequest } from "../internals/utils" -import { CommonProviderOptions } from "." -import { User } from ".." - -export interface CredentialInput { - label?: string - type?: string - value?: string - placeholder?: string -} - -export type Credentials = Record - -export interface CredentialsConfig - extends CommonProviderOptions { - type: "credentials" - credentials: C - authorize( - credentials: Record, - req: NextApiRequest - ): Awaitable<(Omit | { id?: string }) | null> -} - -export type CredentialsProvider = >( - options: Partial> -) => CredentialsConfig - -export type CredentialsProviderType = "Credentials" - -declare module "next-auth/providers/credentials" { - export default function CredentialsProvider< - C extends Record - >(options: Partial>): CredentialsConfig -} diff --git a/src/types/providers/email.d.ts b/src/types/providers/email.d.ts deleted file mode 100644 index a003da2a4f..0000000000 --- a/src/types/providers/email.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { CommonProviderOptions } from "." -import { Options as SMTPConnectionOptions } from "nodemailer/lib/smtp-connection" -import { Awaitable } from "../internals/utils" - -export interface EmailConfig extends CommonProviderOptions { - type: "email" - // TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html - server: string | SMTPConnectionOptions - /** @default "NextAuth " */ - from?: string - /** - * How long until the e-mail can be used to log the user in, - * in seconds. Defaults to 1 day - * @default 86400 - */ - maxAge?: number - sendVerificationRequest(params: { - identifier: string - url: string - expires: Date - provider: EmailConfig - token: string - }): Awaitable - /** - * By default, we are generating a random verification token. - * You can make it predictable or modify it as you like with this method. - * @example - * ```js - * Providers.Email({ - * async generateVerificationToken() { - * return "ABC123" - * } - * }) - * ``` - * [Documentation](https://next-auth.js.org/providers/email#customising-the-verification-token) - */ - generateVerificationToken?(): Awaitable - options: EmailUserConfig -} - -export type EmailUserConfig = Partial> - -// TODO: Rename to Token provider -// when started working on https://github.com/nextauthjs/next-auth/discussions/1465 -export type EmailProviderType = "Email" - -declare module "next-auth/providers/email" { - export default function EmailProvider( - options: Partial - ): EmailConfig -} From c821b84907b089e78ab9ddd1f1910eee0a115398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 20:38:23 +0200 Subject: [PATCH 28/62] chore(ts): fix `next-auth` types --- src/server/index.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/server/index.ts b/src/server/index.ts index 878fb8e523..9901adc1ff 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -12,8 +12,8 @@ import callbackUrlHandler from "./lib/callback-url-handler" import extendRes from "./lib/extend-res" import csrfTokenHandler from "./lib/csrf-token-handler" import { eventsErrorHandler, adapterErrorHandler } from "../lib/errors" -import { NextApiRequest, NextApiResponse } from "../../types/internals/utils" -import { NextAuthOptions } from "../../types" +import { NextApiRequest, NextApiResponse } from "../types/internals/utils" +import { NextAuthOptions } from "../types" // To work properly in production with OAuth providers the NEXTAUTH_URL // environment variable must be set. @@ -251,15 +251,18 @@ async function NextAuthHandler(req, res, userOptions) { .end(`Error: HTTP ${req.method} is not supported for ${req.url}`) } +function NextAuth(options: NextAuthOptions): any +function NextAuth( + req: NextApiRequest, + res: NextApiResponse, + options: NextAuthOptions +): any /** Tha main entry point to next-auth */ -export default function NextAuth( - ...args: - | [NextApiRequest, NextApiResponse, NextAuthOptions] - | [NextAuthOptions] -) { +function NextAuth(...args) { if (args.length === 1) { return async (req, res) => await NextAuthHandler(req, res, args[0]) } - - return NextAuthHandler(...args) + return NextAuthHandler(args[0], args[1], args[2]) } + +export default NextAuth From 7ee12f3e1a186fc95fbeae9e9bc4a9781cb92e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 18 Aug 2021 20:43:38 +0200 Subject: [PATCH 29/62] refactor(ts): change internal import paths --- src/lib/client.ts | 2 +- src/lib/errors.js | 12 +-- src/lib/logger.js | 8 +- src/providers/facebook.js | 2 +- src/providers/foursquare.js | 2 +- src/providers/gitlab.js | 2 +- src/providers/identity-server4.js | 2 +- src/providers/instagram.js | 2 +- src/providers/onelogin.js | 2 +- src/providers/twitch.js | 2 +- src/server/lib/callback-handler.ts | 12 +-- src/server/lib/callback-url-handler.js | 2 +- src/server/lib/cookie.js | 104 +++++++++++----------- src/server/lib/default-callbacks.ts | 2 +- src/server/lib/email/signin.js | 4 +- src/server/lib/oauth/authorization-url.js | 4 +- src/server/lib/oauth/callback.js | 10 +-- src/server/lib/oauth/client-legacy.js | 4 +- src/server/lib/oauth/client.js | 4 +- src/server/lib/oauth/pkce-handler.js | 8 +- src/server/lib/oauth/state-handler.js | 10 +-- src/server/lib/providers.js | 4 +- src/server/lib/utils.js | 2 +- src/server/pages/error.js | 49 ++++++---- src/server/routes/callback.js | 6 +- src/server/routes/providers.js | 4 +- src/server/routes/session.js | 4 +- src/server/routes/signin.js | 6 +- src/server/routes/signout.js | 4 +- 29 files changed, 148 insertions(+), 131 deletions(-) diff --git a/src/lib/client.ts b/src/lib/client.ts index eeef5d123b..5036b19c49 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -1,6 +1,6 @@ import type { IncomingMessage } from "http" import { NextAuthClientConfig } from "src/react" -import { LoggerInstance } from "types" +import { LoggerInstance } from "src/types" export interface CtxOrReq { req?: IncomingMessage diff --git a/src/lib/errors.js b/src/lib/errors.js index cf3823277a..437a93f95b 100644 --- a/src/lib/errors.js +++ b/src/lib/errors.js @@ -43,9 +43,9 @@ export function capitalize(s) { /** * Wraps an object of methods and adds error handling. - * @param {import("types").EventCallbacks} methods - * @param {import("types").LoggerInstance} logger - * @return {import("types").EventCallbacks} + * @param {import("src/types").EventCallbacks} methods + * @param {import("src/types").LoggerInstance} logger + * @return {import("src/types").EventCallbacks} */ export function eventsErrorHandler(methods, logger) { return Object.entries(methods).reduce((acc, [name, method]) => { @@ -62,9 +62,9 @@ export function eventsErrorHandler(methods, logger) { /** * Handles adapter induced errors. - * @param {import("types/adapters").Adapter} [adapter] - * @param {import("types").LoggerInstance} logger - * @return {import("types/adapters").Adapter} + * @param {import("src/types/adapters").Adapter} [adapter] + * @param {import("src/types").LoggerInstance} logger + * @return {import("src/types/adapters").Adapter} */ export function adapterErrorHandler(adapter, logger) { if (!adapter) return diff --git a/src/lib/logger.js b/src/lib/logger.js index bec48e534d..5ee92b0978 100644 --- a/src/lib/logger.js +++ b/src/lib/logger.js @@ -12,7 +12,7 @@ function formatError(o) { return o } -/** @type {import("types").LoggerInstance} */ +/** @type {import("src/types").LoggerInstance} */ const _logger = { error(code, metadata) { metadata = formatError(metadata) @@ -38,7 +38,7 @@ const _logger = { /** * Override the built-in logger. * Any `undefined` level will use the default logger. - * @param {Partial} newLogger + * @param {Partial} newLogger */ export function setLogger(newLogger = {}) { if (newLogger.error) _logger.error = newLogger.error @@ -50,9 +50,9 @@ export default _logger /** * Serializes client-side log messages and sends them to the server - * @param {import("types").LoggerInstance} logger + * @param {import("src/types").LoggerInstance} logger * @param {string} basePath - * @return {import("types").LoggerInstance} + * @return {import("src/types").LoggerInstance} */ export function proxyLogger(logger = _logger, basePath) { try { diff --git a/src/providers/facebook.js b/src/providers/facebook.js index d2c36d4872..891e71b179 100644 --- a/src/providers/facebook.js +++ b/src/providers/facebook.js @@ -1,4 +1,4 @@ -/** @type {import("types/providers").OAuthProvider} */ +/** @type {import("src/providers").OAuthProvider} */ export default function Facebook(options) { return { id: "facebook", diff --git a/src/providers/foursquare.js b/src/providers/foursquare.js index e44f2d0969..2318c36986 100644 --- a/src/providers/foursquare.js +++ b/src/providers/foursquare.js @@ -1,4 +1,4 @@ -/** @type {import("types/providers").OAuthProvider} */ +/** @type {import("src/providers").OAuthProvider} */ export default function Foursquare(options) { const { apiVersion = "20210801" } = options return { diff --git a/src/providers/gitlab.js b/src/providers/gitlab.js index 353fcc7d3a..7ea4c2cbe9 100644 --- a/src/providers/gitlab.js +++ b/src/providers/gitlab.js @@ -1,4 +1,4 @@ -/** @type {import("types/providers").OAuthProvider} */ +/** @type {import("src/providers").OAuthProvider} */ export default function GitLab(options) { return { id: "gitlab", diff --git a/src/providers/identity-server4.js b/src/providers/identity-server4.js index d0ce034f8e..6ddd461613 100644 --- a/src/providers/identity-server4.js +++ b/src/providers/identity-server4.js @@ -1,4 +1,4 @@ -/** @return {import("types/providers").OAuthConfig} */ +/** @return {import("src/providers").OAuthConfig} */ export default function IdentityServer4(options) { return { id: "identity-server4", diff --git a/src/providers/instagram.js b/src/providers/instagram.js index 2aa1fcdd25..7a1775ad0f 100644 --- a/src/providers/instagram.js +++ b/src/providers/instagram.js @@ -1,5 +1,5 @@ /** - * @type {import("types/providers").OAuthProvider} options + * @type {import("src/providers").OAuthProvider} options * @example * * ```js diff --git a/src/providers/onelogin.js b/src/providers/onelogin.js index a848363cc4..762c57a9dd 100644 --- a/src/providers/onelogin.js +++ b/src/providers/onelogin.js @@ -1,4 +1,4 @@ -/** @returns {import("types/providers").OAuthConfig} */ +/** @returns {import("src/providers").OAuthConfig} */ export default function OneLogin(options) { return { id: "onelogin", diff --git a/src/providers/twitch.js b/src/providers/twitch.js index df5db03e2c..d16443b5b4 100644 --- a/src/providers/twitch.js +++ b/src/providers/twitch.js @@ -1,4 +1,4 @@ -/** @return {import("types/providers").OAuthConfig} */ +/** @return {import("src/providers").OAuthConfig} */ export default function Twitch(options) { return { wellKnown: "https://id.twitch.tv/oauth2/.well-known/openid-configuration", diff --git a/src/server/lib/callback-handler.ts b/src/server/lib/callback-handler.ts index 56f2d72a95..c2bcec2bcb 100644 --- a/src/server/lib/callback-handler.ts +++ b/src/server/lib/callback-handler.ts @@ -1,11 +1,11 @@ import { AccountNotLinkedError } from "../../lib/errors" import { fromDate } from "./utils" import { randomBytes, randomUUID } from "crypto" -import { SessionToken } from "types/internals/cookies" -import { InternalOptions } from "types/internals" -import { AdapterSession, AdapterUser } from "types/adapters" -import { JWT } from "types/jwt" -import { Account, User } from "types" +import { SessionToken } from "src/types/internals/cookies" +import { InternalOptions } from "src/types/internals" +import { AdapterSession, AdapterUser } from "src/types/adapters" +import { JWT } from "src/jwt" +import { Account, User } from "src/types" /** * This function handles the complex flow of signing users in, and either creating, @@ -64,7 +64,7 @@ export default async function callbackHandler( if (useJwtSession) { try { session = await jwt.decode({ ...jwt, token: sessionToken }) - if (session?.sub) { + if (session && "sub" in session && session.sub) { user = await getUser(session.sub) } } catch { diff --git a/src/server/lib/callback-url-handler.js b/src/server/lib/callback-url-handler.js index a0fcd1cc38..e906fe95f5 100644 --- a/src/server/lib/callback-url-handler.js +++ b/src/server/lib/callback-url-handler.js @@ -4,7 +4,7 @@ import * as cookie from "../lib/cookie" /** * Get callback URL based on query param / cookie + validation, * and add it to `req.options.callbackUrl`. - * @type {import("types/internals").NextAuthApiHandler} + * @type {import("src/types/internals").NextAuthApiHandler} */ export default async function callbackUrlHandler(req, res) { const { query } = req diff --git a/src/server/lib/cookie.js b/src/server/lib/cookie.js index e45c06d97a..c4ab12f31c 100644 --- a/src/server/lib/cookie.js +++ b/src/server/lib/cookie.js @@ -8,115 +8,115 @@ * As only partial functionlity is required, only the code we need has been incorporated here * (with fixes for specific issues) to keep dependancy size down. */ -export function set (res, name, value, options = {}) { +export function set(res, name, value, options = {}) { const stringValue = - typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value) + typeof value === "object" ? "j:" + JSON.stringify(value) : String(value) - if ('maxAge' in options) { + if ("maxAge" in options) { options.expires = new Date(Date.now() + options.maxAge) options.maxAge /= 1000 } // Preserve any existing cookies that have already been set in the same session - let setCookieHeader = res.getHeader('Set-Cookie') || [] + let setCookieHeader = res.getHeader("Set-Cookie") || [] // If not an array (i.e. a string with a single cookie) convert it into an array if (!Array.isArray(setCookieHeader)) { setCookieHeader = [setCookieHeader] } setCookieHeader.push(_serialize(name, String(stringValue), options)) - res.setHeader('Set-Cookie', setCookieHeader) + res.setHeader("Set-Cookie", setCookieHeader) } -function _serialize (name, val, options) { +function _serialize(name, val, options) { const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/ // eslint-disable-line no-control-regex const opt = options || {} const enc = opt.encode || encodeURIComponent - if (typeof enc !== 'function') { - throw new TypeError('option encode is invalid') + if (typeof enc !== "function") { + throw new TypeError("option encode is invalid") } if (!fieldContentRegExp.test(name)) { - throw new TypeError('argument name is invalid') + throw new TypeError("argument name is invalid") } const value = enc(val) if (value && !fieldContentRegExp.test(value)) { - throw new TypeError('argument val is invalid') + throw new TypeError("argument val is invalid") } - let str = name + '=' + value + let str = name + "=" + value if (opt.maxAge != null) { const maxAge = opt.maxAge - 0 if (isNaN(maxAge) || !isFinite(maxAge)) { - throw new TypeError('option maxAge is invalid') + throw new TypeError("option maxAge is invalid") } - str += '; Max-Age=' + Math.floor(maxAge) + str += "; Max-Age=" + Math.floor(maxAge) } if (opt.domain) { if (!fieldContentRegExp.test(opt.domain)) { - throw new TypeError('option domain is invalid') + throw new TypeError("option domain is invalid") } - str += '; Domain=' + opt.domain + str += "; Domain=" + opt.domain } if (opt.path) { if (!fieldContentRegExp.test(opt.path)) { - throw new TypeError('option path is invalid') + throw new TypeError("option path is invalid") } - str += '; Path=' + opt.path + str += "; Path=" + opt.path } else { - str += '; Path=/' + str += "; Path=/" } if (opt.expires) { let expires = opt.expires - if (typeof opt.expires.toUTCString === 'function') { + if (typeof opt.expires.toUTCString === "function") { expires = opt.expires.toUTCString() } else { const dateExpires = new Date(opt.expires) expires = dateExpires.toUTCString() } - str += '; Expires=' + expires + str += "; Expires=" + expires } if (opt.httpOnly) { - str += '; HttpOnly' + str += "; HttpOnly" } if (opt.secure) { - str += '; Secure' + str += "; Secure" } if (opt.sameSite) { const sameSite = - typeof opt.sameSite === 'string' + typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite switch (sameSite) { case true: - str += '; SameSite=Strict' + str += "; SameSite=Strict" break - case 'lax': - str += '; SameSite=Lax' + case "lax": + str += "; SameSite=Lax" break - case 'strict': - str += '; SameSite=Strict' + case "strict": + str += "; SameSite=Strict" break - case 'none': - str += '; SameSite=None' + case "none": + str += "; SameSite=None" break default: - throw new TypeError('option sameSite is invalid') + throw new TypeError("option sameSite is invalid") } } @@ -132,48 +132,48 @@ function _serialize (name, val, options) { * For more on prefixes see https://googlechrome.github.io/samples/cookie-prefixes/ * * @TODO Review cookie settings (names, options) - * @return {import("types").CookiesOptions} + * @return {import("src/types").CookiesOptions} */ -export function defaultCookies (useSecureCookies) { - const cookiePrefix = useSecureCookies ? '__Secure-' : '' +export function defaultCookies(useSecureCookies) { + const cookiePrefix = useSecureCookies ? "__Secure-" : "" return { // default cookie options sessionToken: { name: `${cookiePrefix}next-auth.session-token`, options: { httpOnly: true, - sameSite: 'lax', - path: '/', - secure: useSecureCookies - } + sameSite: "lax", + path: "/", + secure: useSecureCookies, + }, }, callbackUrl: { name: `${cookiePrefix}next-auth.callback-url`, options: { - sameSite: 'lax', - path: '/', - secure: useSecureCookies - } + sameSite: "lax", + path: "/", + secure: useSecureCookies, + }, }, csrfToken: { // Default to __Host- for CSRF token for additional protection if using useSecureCookies // NB: The `__Host-` prefix is stricter than the `__Secure-` prefix. - name: `${useSecureCookies ? '__Host-' : ''}next-auth.csrf-token`, + name: `${useSecureCookies ? "__Host-" : ""}next-auth.csrf-token`, options: { httpOnly: true, - sameSite: 'lax', - path: '/', - secure: useSecureCookies - } + sameSite: "lax", + path: "/", + secure: useSecureCookies, + }, }, pkceCodeVerifier: { name: `${cookiePrefix}next-auth.pkce.code_verifier`, options: { httpOnly: true, - sameSite: 'lax', - path: '/', - secure: useSecureCookies - } - } + sameSite: "lax", + path: "/", + secure: useSecureCookies, + }, + }, } } diff --git a/src/server/lib/default-callbacks.ts b/src/server/lib/default-callbacks.ts index 5fe090519f..080d46bb83 100644 --- a/src/server/lib/default-callbacks.ts +++ b/src/server/lib/default-callbacks.ts @@ -1,4 +1,4 @@ -import { CallbacksOptions } from "types/index" +import { CallbacksOptions } from "src/types/index" export const defaultCallbacks: CallbacksOptions = { signIn() { diff --git a/src/server/lib/email/signin.js b/src/server/lib/email/signin.js index 0eef771c45..33c49a59d3 100644 --- a/src/server/lib/email/signin.js +++ b/src/server/lib/email/signin.js @@ -3,14 +3,14 @@ import { randomBytes } from "crypto" import { hashToken } from "../utils" /** - * @typedef {import("types/providers").EmailConfig} EmailConfig + * @typedef {import("src/providers").EmailConfig} EmailConfig */ /** * Starts an e-mail login flow, by generating a token, * and sending it to the user's e-mail (with the help of a DB adapter) * @param {string} identifier - * @param {import("types/internals").InternalOptions} options + * @param {import("src/types/internals").InternalOptions} options */ export default async function email(identifier, options) { const { baseUrl, basePath, adapter, provider, logger } = options diff --git a/src/server/lib/oauth/authorization-url.js b/src/server/lib/oauth/authorization-url.js index 2c7e20683c..c4114aca3d 100644 --- a/src/server/lib/oauth/authorization-url.js +++ b/src/server/lib/oauth/authorization-url.js @@ -8,13 +8,13 @@ import { createPKCE } from "../oauth/pkce-handler" * Generates an authorization/request token URL. * * [OAuth 2](https://www.oauth.com/oauth2-servers/authorization/the-authorization-request/) | [OAuth 1](https://oauth.net/core/1.0a/#auth_step2) - * @type {import("types/internals").NextAuthApiHandler} + * @type {import("src/types/internals").NextAuthApiHandler} * @returns {string} */ export default async function getAuthorizationUrl(req, res) { const { logger } = req.options try { - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = req.options.provider let params = {} diff --git a/src/server/lib/oauth/callback.js b/src/server/lib/oauth/callback.js index c3389143fe..40ff1102df 100644 --- a/src/server/lib/oauth/callback.js +++ b/src/server/lib/oauth/callback.js @@ -5,11 +5,11 @@ import { usePKCECodeVerifier } from "./pkce-handler" import { OAuthCallbackError } from "../../../lib/errors" import { TokenSet } from "openid-client" -/** @type {import("types/internals").NextAuthApiHandler} */ +/** @type {import("src/types/internals").NextAuthApiHandler} */ export default async function oAuthCallback(req, res) { const { logger } = req.options - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = req.options.provider const errorMessage = req.body.error ?? req.query.error @@ -56,7 +56,7 @@ export default async function oAuthCallback(req, res) { /** @type {import("openid-client").TokenSet} */ let tokens - /** @type {import("types/providers").OAuthChecks} */ + /** @type {import("src/providers").OAuthChecks} */ const checks = { code_verifier: await usePKCECodeVerifier(req, res), state: getState(req), @@ -82,7 +82,7 @@ export default async function oAuthCallback(req, res) { tokens.scope = tokens.scope.join(" ") } - /** @type {import("types").Profile} */ + /** @type {import("src/types").Profile} */ let profile if (provider.userinfo?.request) { profile = await provider.userinfo.request({ @@ -111,7 +111,7 @@ export default async function oAuthCallback(req, res) { /** * Returns profile, raw profile and auth provider details - * @type {import("types/internals/oauth").GetProfile} + * @type {import("src/types/internals/oauth").GetProfile} */ async function getProfile({ profile: OAuthProfile, tokens, provider, logger }) { try { diff --git a/src/server/lib/oauth/client-legacy.js b/src/server/lib/oauth/client-legacy.js index 0364721f56..30bb5835f7 100644 --- a/src/server/lib/oauth/client-legacy.js +++ b/src/server/lib/oauth/client-legacy.js @@ -5,10 +5,10 @@ import { OAuth } from "oauth" /** * Client supporting OAuth 1.x - * @param {import("types/internals").InternalOptions} options + * @param {import("src/types/internals").InternalOptions} options */ export function oAuth1Client(options) { - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = options.provider const oauth1Client = new OAuth( diff --git a/src/server/lib/oauth/client.js b/src/server/lib/oauth/client.js index 2cf2b159d1..1ad3bfbc5b 100644 --- a/src/server/lib/oauth/client.js +++ b/src/server/lib/oauth/client.js @@ -6,10 +6,10 @@ import { Issuer } from "openid-client" * Check out `Issuer.discover` * * Client supporting OAuth 2.x and OIDC - * @param {import("types/internals").InternalOptions} options + * @param {import("src/types/internals").InternalOptions} options */ export async function openidClient(options) { - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = options.provider let issuer diff --git a/src/server/lib/oauth/pkce-handler.js b/src/server/lib/oauth/pkce-handler.js index 1f42062414..0434eb6300 100644 --- a/src/server/lib/oauth/pkce-handler.js +++ b/src/server/lib/oauth/pkce-handler.js @@ -9,12 +9,12 @@ const PKCE_MAX_AGE = 60 * 15 // 15 minutes in seconds /** * Returns `code_challenge` and `code_challenge_method` * and saves them in a cookie. - * @type {import("types/internals").NextAuthApiHandler} + * @type {import("src/types/internals").NextAuthApiHandler} * @returns {Promise */ export async function createPKCE(req, res) { const { cookies, logger } = req.options - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = req.options.provider if (!provider.checks?.includes("pkce")) { // Provider does not support PKCE, return nothing. @@ -55,10 +55,10 @@ export async function createPKCE(req, res) { /** * Returns code_verifier if provider uses PKCE, * and clears the cookie afterwards. - * @param {import("types/internals").NextAuthRequest} req + * @param {import("src/types/internals").NextAuthRequest} req */ export async function usePKCECodeVerifier(req, res) { - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = req.options.provider const { cookies } = req.options if ( diff --git a/src/server/lib/oauth/state-handler.js b/src/server/lib/oauth/state-handler.js index 40fc4ea14d..0a7c97f882 100644 --- a/src/server/lib/oauth/state-handler.js +++ b/src/server/lib/oauth/state-handler.js @@ -2,12 +2,12 @@ import { createHash } from "crypto" /** * Returns state if provider supports it - * @param {import("types/internals").NextAuthRequest} req - * @param {import("types/internals").NextAuthResponse} res + * @param {import("src/types/internals").NextAuthRequest} req + * @param {import("src/types/internals").NextAuthResponse} res */ export function createState(req) { const { csrfToken, logger } = req.options - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = req.options.provider if (!provider.checks?.includes("state")) { // Provider does not support state, return nothing @@ -24,10 +24,10 @@ export function createState(req) { /** * Consistently recreate state from the csrfToken * if `provider.checks` supports `"state"`. - * @param {import("types/internals").NextAuthRequest} req + * @param {import("src/types/internals").NextAuthRequest} req */ export function getState({ options }) { - /** @type {import("types/providers").OAuthConfig} */ + /** @type {import("src/providers").OAuthConfig} */ const provider = options.provider if (provider?.checks.includes("state")) { return createHash("sha256").update(options.csrfToken).digest("hex") diff --git a/src/server/lib/providers.js b/src/server/lib/providers.js index 991217d1ac..aed26f298e 100644 --- a/src/server/lib/providers.js +++ b/src/server/lib/providers.js @@ -4,11 +4,11 @@ import { merge } from "../../lib/merge" * Adds `signinUrl` and `callbackUrl` to each provider * and deep merge user-defined options. * @param {{ - * providers: import("types/providers").Provider[] + * providers: import("src/providers").Provider[] * baseUrl: string * basePath: string * }} options - * @returns {import("types/internals").InternalOptions["providers"]} + * @returns {import("src/types/internals").InternalOptions["providers"]} */ export default function parseProviders({ providers = [], baseUrl, basePath }) { const base = `${baseUrl}${basePath}` diff --git a/src/server/lib/utils.js b/src/server/lib/utils.js index 96ecc073c5..73b67509e6 100644 --- a/src/server/lib/utils.js +++ b/src/server/lib/utils.js @@ -11,7 +11,7 @@ export function fromDate(time, date = Date.now()) { /** * @param {string} token - * @param {import("types/internals").InternalOptions} options + * @param {import("src/types/internals").InternalOptions} options */ export function hashToken(token, options) { const { provider, secret } = options diff --git a/src/server/pages/error.js b/src/server/pages/error.js index 22b1197c78..15194f3ac5 100644 --- a/src/server/pages/error.js +++ b/src/server/pages/error.js @@ -1,5 +1,5 @@ // @ts-check -import { h } from 'preact' // eslint-disable-line no-unused-vars +import { h } from "preact" // eslint-disable-line no-unused-vars /** * Renders an error page. @@ -7,59 +7,76 @@ import { h } from 'preact' // eslint-disable-line no-unused-vars * baseUrl: string * basePath: string * error?: string - * res: import("types/internals").NextAuthResponse + * res: import("src/types/internals").NextAuthResponse * }} params */ -export default function error ({ baseUrl, basePath, error = 'default', res }) { +export default function error({ baseUrl, basePath, error = "default", res }) { const signinPageUrl = `${baseUrl}${basePath}/signin` const errors = { default: { statusCode: 200, - heading: 'Error', - message:

{baseUrl.replace(/^https?:\/\//, '')}

+ heading: "Error", + message: ( +

+ + {baseUrl.replace(/^https?:\/\//, "")} + +

+ ), }, configuration: { statusCode: 500, - heading: 'Server error', + heading: "Server error", message: (

There is a problem with the server configuration.

Check the server logs for more information.

- ) + ), }, accessdenied: { statusCode: 403, - heading: 'Access Denied', + heading: "Access Denied", message: (

You do not have permission to sign in.

-

Sign in

+

+ + Sign in + +

- ) + ), }, verification: { statusCode: 403, - heading: 'Unable to sign in', + heading: "Unable to sign in", message: (

The sign in link is no longer valid.

It may have been used already or it may have expired.

), - signin:

Sign in

- } + signin: ( +

+ + Sign in + +

+ ), + }, } - const { statusCode, heading, message, signin } = errors[error.toLowerCase()] ?? errors.default + const { statusCode, heading, message, signin } = + errors[error.toLowerCase()] ?? errors.default res.status(statusCode) return ( -
+

{heading}

-
{message}
+
{message}
{signin}
) diff --git a/src/server/routes/callback.js b/src/server/routes/callback.js index 8eb4dfd100..84b1855cea 100644 --- a/src/server/routes/callback.js +++ b/src/server/routes/callback.js @@ -5,7 +5,7 @@ import { hashToken } from "../lib/utils" /** * Handle callbacks from login services - * @type {import("types/internals").NextAuthApiHandler} + * @type {import("src/types/internals").NextAuthApiHandler} */ export default async function callback(req, res) { const { @@ -195,7 +195,7 @@ export default async function callback(req, res) { email: identifier, } - /** @type {import("types").Account} */ + /** @type {import("src/types").Account} */ const account = { providerAccountId: profile.email, type: "email", @@ -335,7 +335,7 @@ export default async function callback(req, res) { ) } - /** @type {import("types").Account} */ + /** @type {import("src/types").Account} */ const account = { providerAccountId: user.id, type: "credentials", diff --git a/src/server/routes/providers.js b/src/server/routes/providers.js index ab3399765d..ad5b74458d 100644 --- a/src/server/routes/providers.js +++ b/src/server/routes/providers.js @@ -2,8 +2,8 @@ * Return a JSON object with a list of all OAuth providers currently configured * and their signin and callback URLs. This makes it possible to automatically * generate buttons for all providers when rendering client side. - * @param {import("types/internals").NextAuthRequest} req - * @param {import("types/internals").NextAuthResponse} res + * @param {import("src/types/internals").NextAuthRequest} req + * @param {import("src/types/internals").NextAuthResponse} res */ export default function providers(req, res) { const { providers } = req.options diff --git a/src/server/routes/session.js b/src/server/routes/session.js index 7add2fee62..928f1a4c58 100644 --- a/src/server/routes/session.js +++ b/src/server/routes/session.js @@ -4,8 +4,8 @@ import { fromDate } from "../lib/utils" /** * Return a session object (without any private fields) * for Single Page App clients - * @param {import("types/internals").NextAuthRequest} req - * @param {import("types/internals").NextAuthResponse} res + * @param {import("src/types/internals").NextAuthRequest} req + * @param {import("src/types/internals").NextAuthResponse} res */ export default async function session(req, res) { const { cookies, adapter, jwt, events, callbacks, logger } = req.options diff --git a/src/server/routes/signin.js b/src/server/routes/signin.js index 82cd98c645..322a94d320 100644 --- a/src/server/routes/signin.js +++ b/src/server/routes/signin.js @@ -3,12 +3,12 @@ import emailSignin from "../lib/email/signin" /** * Handle requests to /api/auth/signin - * @type {import("types/internals").NextAuthApiHandler} + * @type {import("src/types/internals").NextAuthApiHandler} */ export default async function signin(req, res) { const { baseUrl, basePath, adapter, callbacks, logger } = req.options - /** @type {import("types/providers").OAuthConfig | import("types/providers").EmailConfig} */ + /** @type {import("src/providers").OAuthConfig | import("src/providers").EmailConfig} */ const provider = req.options.provider if (!provider.type) { @@ -43,7 +43,7 @@ export default async function signin(req, res) { // If is an existing user return a user object (otherwise use placeholder) const user = (email ? await getUserByEmail(email) : null) ?? { email } - /** @type {import("types").Account} */ + /** @type {import("src/types").Account} */ const account = { providerAccountId: user.email, type: "email", diff --git a/src/server/routes/signout.js b/src/server/routes/signout.js index 2996335b95..804964c939 100644 --- a/src/server/routes/signout.js +++ b/src/server/routes/signout.js @@ -2,8 +2,8 @@ import * as cookie from "../lib/cookie" /** * Handle requests to /api/auth/signout - * @param {import("types/internals").NextAuthRequest} req - * @param {import("types/internals").NextAuthResponse} res + * @param {import("src/types/internals").NextAuthRequest} req + * @param {import("src/types/internals").NextAuthResponse} res */ export default async function signout(req, res) { const { adapter, cookies, events, jwt, callbackUrl, logger } = req.options From 0fd70187ad6385994327bcecd5fd68422b02b3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 18:41:11 +0200 Subject: [PATCH 30/62] test(ts): remove type tests --- src/types/tests/providers.test.ts | 294 ------------------------------ src/types/tests/react.test.ts | 99 ---------- src/types/tests/server.test.ts | 241 ------------------------ src/types/tests/test-helpers.ts | 13 -- src/types/tsconfig.json | 23 --- src/types/tslint.json | 7 - 6 files changed, 677 deletions(-) delete mode 100644 src/types/tests/providers.test.ts delete mode 100644 src/types/tests/react.test.ts delete mode 100644 src/types/tests/server.test.ts delete mode 100644 src/types/tests/test-helpers.ts delete mode 100644 src/types/tsconfig.json delete mode 100644 src/types/tslint.json diff --git a/src/types/tests/providers.test.ts b/src/types/tests/providers.test.ts deleted file mode 100644 index d56de1770e..0000000000 --- a/src/types/tests/providers.test.ts +++ /dev/null @@ -1,294 +0,0 @@ -import EmailProvider from "next-auth/providers/email" -import CredentialsProvider from "next-auth/providers/credentials" -import AppleProvider from "next-auth/providers/apple" -import TwitterProvider from "next-auth/providers/twitter" -import FacebookProvider from "next-auth/providers/facebook" -import GitHubProvider from "next-auth/providers/github" -import GitLabProvider from "next-auth/providers/gitlab" -import SlackProvider from "next-auth/providers/slack" -import GoogleProvider from "next-auth/providers/google" -import Auth0Provider from "next-auth/providers/auth0" -import IdentityServer4Provider from "next-auth/providers/identity-server4" -import DiscordProvider from "next-auth/providers/discord" -import TwitchProvider from "next-auth/providers/twitch" -import OktaProvider from "next-auth/providers/okta" -import OneLoginProvider from "next-auth/providers/onelogin" -import BattleNetProvider from "next-auth/providers/battlenet" -import BoxProvider from "next-auth/providers/box" -import CognitoProvider from "next-auth/providers/cognito" -import YandexProvider from "next-auth/providers/yandex" -import LinkedInProvider from "next-auth/providers/linkedin" -import SpotifyProvider from "next-auth/providers/spotify" -import RedditProvider from "next-auth/providers/reddit" -import AzureADB2CProvider from "next-auth/providers/azure-ad-b2c" -import FusionAuthProvider from "next-auth/providers/fusionauth" -import FACEITProvider from "next-auth/providers/faceit" -import InstagramProvider from "next-auth/providers/instagram" -import KakaoProvider from "next-auth/providers/kakao" -import OssoProvider from "next-auth/providers/osso" -import ZohoProvider from "next-auth/providers/zoho" -import FreshbooksProvider from "next-auth/providers/freshbooks" - -// $ExpectType EmailConfig -EmailProvider({ - server: "path/to/server", - from: "path/from", -}) - -// $ExpectType EmailConfig -EmailProvider({ - server: { - host: "host", - port: 123, - auth: { - user: "foo", - pass: "123", - }, - }, - from: "path/from", -}) - -// $ExpectType CredentialsConfig<{ username: { label: string; type: string; }; password: { label: string; type: string; }; }> -CredentialsProvider({ - id: "login", - name: "account", - credentials: { - username: { - label: "Password", - type: "password", - }, - password: { - label: "Password", - type: "password", - }, - }, - async authorize({ username, password }) { - return null - }, -}) - -// $ExpectType OAuthConfig -AppleProvider({ - clientId: "foo123", - clientSecret: { - appleId: "foo@icloud.com", - teamId: "foo", - privateKey: "123xyz", - keyId: "1234", - }, -}) - -// $ExpectType OAuthConfig -TwitterProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -FacebookProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -GitHubProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -GitHubProvider({ - clientId: "foo123", - clientSecret: "bar123", - authorization: { params: { scope: "change:thing read:that" } }, -}) - -// $ExpectType OAuthConfig -GitLabProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -SlackProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -GoogleProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -GoogleProvider({ - clientId: "foo123", - clientSecret: "bar123", - authorization: "https://foo.google.com", -}) - -// $ExpectType OAuthConfig -Auth0Provider({ - clientId: "foo123", - clientSecret: "bar123", - issuer: "https://foo.auth0.com", -}) - -// $ExpectType OAuthConfig -Auth0Provider({ - clientId: "foo123", - clientSecret: "bar123", - issuer: "https://foo.auth0.com", - profile() { - return { - id: "foo123", - name: "foo", - email: "foo@bar.io", - image: "https://foo.auth0.com/image/1.png", - } - }, -}) - -// $ExpectType OAuthConfig -IdentityServer4Provider({ - id: "identity-server4", - name: "IdentityServer4", - authorization: { params: { scope: "change:thing read:that" } }, - issuer: "https://foo.is4.com", - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -DiscordProvider({ - clientId: "foo123", - clientSecret: "bar123", - authorization: { params: { scope: "identify" } }, -}) - -// $ExpectType OAuthConfig -TwitchProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -OktaProvider({ - clientId: "foo123", - clientSecret: "bar123", - issuer: "https://foo.auth0.com", -}) - -// $ExpectType OAuthConfig -OneLoginProvider({ - clientId: "foo123", - clientSecret: "bar123", - issuer: "https://foo.onelogin.com", -}) - -// $ExpectType OAuthConfig -BattleNetProvider({ - clientId: "foo123", - clientSecret: "bar123", - region: "europe", -}) - -// $ExpectType OAuthConfig -BoxProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -CognitoProvider({ - clientId: "foo123", - clientSecret: "bar123", - issuer: "https://foo.auth0.com", -}) - -// $ExpectType OAuthConfig -YandexProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -LinkedInProvider({ - clientId: "foo123", - clientSecret: "bar123", - authorization: { params: { scope: "r_emailaddress r_liteprofile" } }, -}) - -// $ExpectType OAuthConfig -SpotifyProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -SpotifyProvider({ - clientId: "foo123", - clientSecret: "bar123", - authorization: { params: { scope: "user-read-email" } }, -}) - -// $ExpectType OAuthConfig -RedditProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -AzureADB2CProvider({ - clientId: "foo123", - clientSecret: "bar123", - authorization: { params: { scope: "offline_access User.Read" } }, - tenantId: "tenantId", - idToken: true, -}) - -// $ExpectType OAuthConfig -FusionAuthProvider({ - name: "FusionAuth", - issuer: "domain", - clientId: "clientId", - clientSecret: "clientSecret", - tenantId: "tenantId", -}) - -// $ExpectType OAuthConfig -FACEITProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -InstagramProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -KakaoProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -OssoProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -ZohoProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) - -// $ExpectType OAuthConfig -FreshbooksProvider({ - clientId: "foo123", - clientSecret: "bar123", -}) diff --git a/src/types/tests/react.test.ts b/src/types/tests/react.test.ts deleted file mode 100644 index b81ea6c73d..0000000000 --- a/src/types/tests/react.test.ts +++ /dev/null @@ -1,99 +0,0 @@ -import * as client from "next-auth/react" -import { nextReq } from "./test-helpers" - -const clientSession = { - user: { - name: "Bruce", - email: "bruce@lee.com", - image: "path/to/img", - }, - accessToken: "123z", - expires: "1234", -} - -/** - * $ExpectType - * | { data: Session; status: "authenticated"; } - * | { data: null; status: "unauthenticated" | "loading"; } - * | { //// data: Session; status: "authenticated"; } - * | { data: null; status: "loading"; } - */ -client.useSession() - -// $ExpectType { data: Session; status: "authenticated"; } | { data: null; status: "loading"; } -const session = client.useSession({ required: true }) -if (session.status === "loading") { - // $ExpectType null - session.data -} else { - // $ExpectType Session - session.data -} - -// $ExpectType Promise -client.getSession({ req: nextReq }) - -// $ExpectType Promise | null> -client.getProviders() - -// $ExpectType Promise -client.getCsrfToken({ req: nextReq }) - -// $ExpectType Promise -client.getCsrfToken({ ctx: { req: nextReq } }) - -// $ExpectType Promise -client.signIn("github", { callbackUrl: "foo" }, { login: "username" }) - -// $ExpectType Promise -client.signIn("credentials", { callbackUrl: "foo", redirect: true }) - -// $ExpectType Promise -client.signIn("credentials", { redirect: false }) - -// $ExpectType Promise -client.signIn("email", { callbackUrl: "foo", redirect: false }) - -// $ExpectType Promise -client.signIn("email", { callbackUrl: "foo", redirect: true }) - -// $ExpectType Promise -client.signOut() - -// $ExpectType Promise -client.signOut({ callbackUrl: "https://foo.com/callback", redirect: true }) - -// $ExpectType Promise -client.signOut({ callbackUrl: "https://foo.com/callback", redirect: false }) - -// $ExpectType ReactElement | null -client.SessionProvider({ - children: null, - session: clientSession, - baseUrl: "https://foo.com", - basePath: "/", - staleTime: 1234, -}) - -// $ExpectType ReactElement | null -client.SessionProvider({ - children: null, - session: clientSession, -}) - -// $ExpectType ReactElement | null -client.SessionProvider({ - children: null, -}) - -// $ExpectType ReactElement | null -client.SessionProvider({ - children: null, - session: { - expires: "1234", - }, - baseUrl: "https://foo.com", - basePath: "/", - staleTime: 1234, - refetchInterval: 4321, -}) diff --git a/src/types/tests/server.test.ts b/src/types/tests/server.test.ts deleted file mode 100644 index 54cb497cc8..0000000000 --- a/src/types/tests/server.test.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { OAuthConfig } from "next-auth/providers" -import { Adapter, AdapterSession, AdapterUser } from "next-auth/adapters" -import NextAuth, * as NextAuthTypes from "next-auth" -import { IncomingMessage, ServerResponse } from "http" -import { Socket } from "net" -import { NextApiRequest, NextApiResponse } from "internals/utils" -import GitHubProvider from "next-auth/providers/github" -import TwitterProvider from "next-auth/providers/twitter" - -const req: NextApiRequest = Object.assign(new IncomingMessage(new Socket()), { - query: {}, - cookies: {}, - body: {}, - env: {}, -}) - -const res: NextApiResponse = Object.assign(new ServerResponse(req), { - send: (body: string) => undefined, - json: (body: string) => undefined, - status: (code: number) => res, - redirect: (statusOrUrl: number | string, url?: string) => res as any, - setPreviewData: (data: object | string) => res, - clearPreviewData: () => res, -}) - -const pageOptions = { - signin: "path/to/signin", - signout: "path/to/signout", - error: "path/to/error", - verifyRequest: "path/to/verify", - newUsers: "path/to/signup", -} - -const simpleConfig = { - providers: [ - GitHubProvider({ - clientId: "123", - clientSecret: "123", - authorization: { - params: { - scope: - "user public_repo repo repo_deployment repo:status read:repo_hook read:org read:public_key read:gpg_key", - }, - }, - }), - ], -} - -const exampleUser: AdapterUser = { - id: "", - emailVerified: null, - name: "", - image: "", - email: "", -} - -const exampleSession: AdapterSession = { - sessionToken: "0000", - id: "", - userId: "", - expires: new Date(), -} - -interface Client { - c(): void - r(): void - u(): void - d(): void -} - -function MyAdapter(client: Client): Adapter { - return { - async createUser(profile) { - return exampleUser - }, - async getUser(id) { - return exampleUser - }, - async getUserByEmail(email) { - return exampleUser - }, - async getUserByAccount(providerAccountId) { - return exampleUser - }, - async updateUser(user) { - return exampleUser - }, - async linkAccount({}) { - return undefined - }, - async createSession(user) { - return exampleSession - }, - async getSessionAndUser() { - return { session: exampleSession, user: exampleUser } - }, - async updateSession(session) { - return exampleSession - }, - async deleteSession(sessionToken) { - return exampleSession - }, - async createVerificationToken(params) { - return undefined - }, - async useVerificationToken(params) { - return null - }, - } -} - -const client = { c() {}, r() {}, u() {}, d() {} } // Create a fake db client - -const allConfig: NextAuthTypes.NextAuthOptions = { - providers: [ - TwitterProvider({ - clientId: "123", - clientSecret: "123", - }), - ], - debug: true, - secret: "my secret", - theme: "dark", - logger: { - debug: () => undefined, - }, - session: { - jwt: true, - maxAge: 365, - updateAge: 60, - }, - jwt: { - secret: "secret-thing", - maxAge: 365, - encryption: true, - signingKey: "some-key", - encryptionKey: "some-key", - encode: async () => "foo", - decode: async () => ({}), - }, - pages: pageOptions, - callbacks: { - async signIn({ user, account, email, credentials, profile }) { - return true - }, - async redirect({ url, baseUrl }) { - return "path/to/foo" - }, - async session({ session, user, token }) { - return session - }, - async jwt({ token, user, account, profile, isNewUser }) { - return token - }, - }, - events: { - async signIn(message) { - return undefined - }, - async signOut(message) { - return undefined - }, - async createUser(message) { - return undefined - }, - async updateUser(message) { - return undefined - }, - async linkAccount(message) { - return undefined - }, - async session(message) { - return undefined - }, - }, - adapter: MyAdapter(client), - useSecureCookies: true, - cookies: { - sessionToken: { - name: "__Secure-next-auth.session-token", - options: { - httpOnly: true, - sameSite: true as true, - path: "/", - secure: true, - domain: "foo.com", - }, - }, - }, -} - -const customProvider: OAuthConfig<{ - id: string - name: string - email: string - picture: string -}> = { - id: "google", - name: "Google", - type: "oauth", - version: "2.0", - authorization: { - url: "https://accounts.google.com/o/oauth2/auth", - params: { - response_type: "code", - scope: - "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email", - }, - }, - token: "https://accounts.google.com/o/oauth2/token", - userinfo: "https://www.googleapis.com/oauth2/v1/userinfo?alt=json", - async profile(profile) { - return { - id: profile.id, - name: profile.name, - email: profile.email, - image: profile.picture, - } - }, - clientId: "", - clientSecret: "", -} - -const customProviderConfig = { - providers: [customProvider], -} - -// $ExpectType void | Promise -NextAuth(simpleConfig) - -// $ExpectType void | Promise -NextAuth(allConfig) - -// $ExpectType void | Promise -NextAuth(customProviderConfig) - -// $ExpectType void | Promise -NextAuth(req, res, simpleConfig) - -// $ExpectType void | Promise -NextAuth(req, res, allConfig) diff --git a/src/types/tests/test-helpers.ts b/src/types/tests/test-helpers.ts deleted file mode 100644 index 3465aac99e..0000000000 --- a/src/types/tests/test-helpers.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IncomingMessage } from "http" -import { Socket } from "net" -import { NextApiRequest } from "internals/utils" - -export const nextReq: NextApiRequest = Object.assign( - new IncomingMessage(new Socket()), - { - query: {}, - cookies: {}, - body: {}, - env: {}, - } -) diff --git a/src/types/tsconfig.json b/src/types/tsconfig.json deleted file mode 100644 index b69817e5cc..0000000000 --- a/src/types/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "lib": ["es6", "dom"], - "jsx": "react", - "noImplicitAny": true, - "noImplicitThis": true, - "strictFunctionTypes": true, - "strictNullChecks": true, - "esModuleInterop": true, - "noEmit": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": ".", - "paths": { - "next-auth": ["."], - "next-auth/providers": ["./providers"], - "next-auth/providers/*": ["./providers/*"], - "next-auth/adapters": ["./adapters"], - "next-auth/react": ["./react-client"], - "next-auth/jwt": ["./jwt"] - } - } -} diff --git a/src/types/tslint.json b/src/types/tslint.json deleted file mode 100644 index 456e0907ff..0000000000 --- a/src/types/tslint.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "dtslint/dtslint.json", - "rules": { - "semicolon": false, - "no-redundant-jsdoc": false - } -} From 5fc1dab3e8055b08b9a0c1d8ef5bbf0084930391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 18:42:50 +0200 Subject: [PATCH 31/62] chore: remove test:types script --- .github/workflows/release.yml | 2 +- package-lock.json | 2489 +-------------------------------- package.json | 4 +- 3 files changed, 24 insertions(+), 2471 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 152c6aab78..854d007a59 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: # - name: Build # run: npm run build # - name: Run tests - # run: npm test -- --coverage --verbose && npm run test:types + # run: npm test -- --coverage --verbose # - name: Coverage # uses: codecov/codecov-action@v1 # with: diff --git a/package-lock.json b/package-lock.json index 21c8fd60d2..56c0e9fd0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,6 @@ "babel-preset-preact": "^2.0.0", "conventional-changelog-conventionalcommits": "4.6.0", "cssnano": "^5.0.6", - "dtslint": "^4.1.0", "eslint": "^7.29.0", "eslint-config-prettier": "^8.3.0", "eslint-config-standard-with-typescript": "^20.0.0", @@ -1811,77 +1810,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@definitelytyped/header-parser": { - "version": "0.0.85", - "resolved": "https://registry.npmjs.org/@definitelytyped/header-parser/-/header-parser-0.0.85.tgz", - "integrity": "sha512-fH37Yt5VjBKFu/2rFzn6xrjkASaIEqjED77V7vxb8JFCalTvGhiPpTrWzfp2EjK0Lhd8bkCZhRpYoW8GKatcdA==", - "dev": true, - "dependencies": { - "@definitelytyped/typescript-versions": "^0.0.85", - "@types/parsimmon": "^1.10.1", - "parsimmon": "^1.13.0" - } - }, - "node_modules/@definitelytyped/typescript-versions": { - "version": "0.0.85", - "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.0.85.tgz", - "integrity": "sha512-+yHqi887UMZ4TlLBkA2QcYNP/EZSKGKSAFJtSWY6J5DiBQq3k0yLN1yTfbLonQ52IBenI1iJo/4ePr5A3co5ZQ==", - "dev": true - }, - "node_modules/@definitelytyped/utils": { - "version": "0.0.85", - "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.0.85.tgz", - "integrity": "sha512-GHfMwIroQf3jrvps3a0rClpm5thyHajXGkMUTk4tJ4ew5I53wCnJSPMwlknsFD70F7a1hNDJGySu0PRg4px32Q==", - "dev": true, - "dependencies": { - "@definitelytyped/typescript-versions": "^0.0.85", - "@types/node": "^14.14.35", - "charm": "^1.0.2", - "fs-extra": "^8.1.0", - "fstream": "^1.0.12", - "npm-registry-client": "^8.6.0", - "tar": "^2.2.2", - "tar-stream": "^2.1.4" - } - }, - "node_modules/@definitelytyped/utils/node_modules/@types/node": { - "version": "14.17.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz", - "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g==", - "dev": true - }, - "node_modules/@definitelytyped/utils/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@definitelytyped/utils/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@definitelytyped/utils/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -3598,12 +3526,6 @@ "@types/node": "*" } }, - "node_modules/@types/parsimmon": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@types/parsimmon/-/parsimmon-1.10.6.tgz", - "integrity": "sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA==", - "dev": true - }, "node_modules/@types/prettier": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", @@ -4042,50 +3964,6 @@ "node": ">=0.10.0" } }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4217,15 +4095,6 @@ "node": ">=8" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -4256,15 +4125,6 @@ "util": "^0.12.0" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -4366,93 +4226,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/babel-jest": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz", @@ -4745,15 +4518,6 @@ } ] }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -4784,18 +4548,6 @@ "readable-stream": "^3.4.0" } }, - "node_modules/block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "dependencies": { - "inherits": "~2.0.0" - }, - "engines": { - "node": "0.4 || >=0.5.8" - } - }, "node_modules/bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", @@ -4999,27 +4751,12 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, - "node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true - }, "node_modules/bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -5142,12 +4879,6 @@ "url": "https://opencollective.com/browserslist" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -5177,15 +4908,6 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "node_modules/charm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", - "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", - "dev": true, - "dependencies": { - "inherits": "^2.0.1" - } - }, "node_modules/chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", @@ -5447,17 +5169,6 @@ "node": ">= 10" } }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, "node_modules/clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -5485,16 +5196,6 @@ "node": ">= 0.12.0" } }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -5554,12 +5255,6 @@ "node": ">= 0.8" } }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -5598,58 +5293,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, "node_modules/constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -6072,18 +5721,6 @@ "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-uri-to-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", @@ -6124,15 +5761,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decimal.js": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", @@ -6246,13 +5874,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -6290,15 +5911,6 @@ "node": ">=8" } }, - "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", @@ -6455,123 +6067,25 @@ "node": ">=8" } }, - "node_modules/dts-critic": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/dts-critic/-/dts-critic-3.3.8.tgz", - "integrity": "sha512-7kBza3f+RV/3hVCQ9yIskkrC+49kzDDM7qogbBFgLQCiGOLmUhpjE9FSw2iOWLVyeLagRNj7SmxAhD2SizJ49w==", + "node_modules/electron-to-chromium": { + "version": "1.3.796", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz", + "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "dependencies": { - "@definitelytyped/header-parser": "latest", - "command-exists": "^1.2.8", - "rimraf": "^3.0.2", - "semver": "^6.2.0", - "tmp": "^0.2.1", - "yargs": "^15.3.1" - }, - "engines": { - "node": ">=10.17.0" - }, - "peerDependencies": { - "typescript": "*" - } - }, - "node_modules/dtslint": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-4.1.3.tgz", - "integrity": "sha512-UHW14DNpWnE5GkmORiDP0f4pc3AvgV7N0grB0skamXyExGOsbsHtNIe+8xeuAkPCrsf10O+Ph3W6+UgXvE4fiA==", - "dev": true, - "dependencies": { - "@definitelytyped/header-parser": "latest", - "@definitelytyped/typescript-versions": "latest", - "@definitelytyped/utils": "latest", - "dts-critic": "latest", - "fs-extra": "^6.0.1", - "json-stable-stringify": "^1.0.1", - "strip-json-comments": "^2.0.1", - "tslint": "5.14.0", - "tsutils": "^2.29.0", - "yargs": "^15.1.0" - }, - "bin": { - "dtslint": "bin/index.js" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "typescript": ">= 3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev || >= 3.8.0-dev || >= 3.9.0-dev || >= 4.0.0-dev" - } - }, - "node_modules/dtslint/node_modules/fs-extra": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", - "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/dtslint/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/dtslint/node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "node_modules/dtslint/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.3.796", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz", - "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, "node_modules/elliptic/node_modules/bn.js": { @@ -7727,12 +7241,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -7805,15 +7313,6 @@ "node": ">=0.10.0" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -8059,15 +7558,6 @@ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -8108,12 +7598,6 @@ "node": ">=0.10.0" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "node_modules/fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -8154,33 +7638,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -8201,74 +7658,6 @@ "node": ">=8" } }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8353,15 +7742,6 @@ "node": ">=0.10.0" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -8486,29 +7866,6 @@ "node": ">= 10.x" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -8521,27 +7878,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", @@ -8572,13 +7908,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -8777,21 +8106,6 @@ "node": ">= 6" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -9631,12 +8945,6 @@ "node": ">=0.10.0" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "node_modules/istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -11928,12 +11236,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -12015,39 +11317,18 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "dependencies": { - "jsonify": "~0.0.0" - } - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, "node_modules/json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -12075,30 +11356,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "node_modules/keyv": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", @@ -12705,18 +11962,6 @@ "node": ">=0.10.0" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mri": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", @@ -13555,58 +12800,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-package-arg": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "node_modules/npm-package-arg/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npm-registry-client": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-8.6.0.tgz", - "integrity": "sha512-Qs6P6nnopig+Y8gbzpeN/dkt+n7IyVd8f45NTMotGk6Qo7GfBmzwYx6jRLoOOgKiMnaQfYxsuyQlD8Mc3guBhg==", - "dev": true, - "dependencies": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "safe-buffer": "^5.1.1", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3", - "ssri": "^5.2.4" - }, - "optionalDependencies": { - "npmlog": "2 || ^3.1.0 || ^4.0.0" - } - }, - "node_modules/npm-registry-client/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -13619,19 +12812,6 @@ "node": ">=8" } }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "node_modules/nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -13644,16 +12824,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -13665,15 +12835,6 @@ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -14046,15 +13207,6 @@ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -14064,16 +13216,6 @@ "node": ">=0.10.0" } }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -14204,12 +13346,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/parsimmon": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.0.tgz", - "integrity": "sha512-EtVsGuQfDgwGgXzsSDe+5egRPwbcgKRd/omQ1L3Oj2pHy0gYqd+Q7zrBIQ7P/BN6DWUP9vV45HIgZHCmssdzMg==", - "dev": true - }, "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -14284,12 +13420,6 @@ "node": ">=0.12" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "node_modules/picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -15534,15 +14664,6 @@ "teleport": ">=0.2.0" } }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/querystring": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", @@ -16026,74 +15147,6 @@ "node": ">=0.10" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -16112,12 +15165,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -16196,15 +15243,6 @@ "node": ">=0.12" } }, - "node_modules/retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -16349,12 +15387,6 @@ "semver": "bin/semver.js" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "node_modules/set-cookie-parser": { "version": "2.4.8", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", @@ -16514,15 +15546,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -16812,40 +15835,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ssri": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -17166,15 +16155,6 @@ "node": ">=8" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/styled-jsx": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-3.3.2.tgz", @@ -17445,33 +16425,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "dev": true, - "dependencies": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -17538,18 +16491,6 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -17743,63 +16684,6 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/tslint": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.14.0.tgz", - "integrity": "sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ==", - "dev": true, - "dependencies": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.7.0", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.8.0" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" - } - }, - "node_modules/tslint/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/tslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/tslint/node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -17821,24 +16705,6 @@ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -17872,12 +16738,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -18152,16 +17012,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -18201,15 +17051,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "dev": true, - "dependencies": { - "builtins": "^1.0.3" - } - }, "node_modules/vendors": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", @@ -18220,20 +17061,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -18367,12 +17194,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "node_modules/which-typed-array": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", @@ -18394,63 +17215,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "optional": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "optional": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "optional": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -18460,53 +17224,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -18575,12 +17292,6 @@ "node": ">=0.4" } }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -18595,41 +17306,6 @@ "node": ">= 6" } }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -19844,73 +18520,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@definitelytyped/header-parser": { - "version": "0.0.85", - "resolved": "https://registry.npmjs.org/@definitelytyped/header-parser/-/header-parser-0.0.85.tgz", - "integrity": "sha512-fH37Yt5VjBKFu/2rFzn6xrjkASaIEqjED77V7vxb8JFCalTvGhiPpTrWzfp2EjK0Lhd8bkCZhRpYoW8GKatcdA==", - "dev": true, - "requires": { - "@definitelytyped/typescript-versions": "^0.0.85", - "@types/parsimmon": "^1.10.1", - "parsimmon": "^1.13.0" - } - }, - "@definitelytyped/typescript-versions": { - "version": "0.0.85", - "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.0.85.tgz", - "integrity": "sha512-+yHqi887UMZ4TlLBkA2QcYNP/EZSKGKSAFJtSWY6J5DiBQq3k0yLN1yTfbLonQ52IBenI1iJo/4ePr5A3co5ZQ==", - "dev": true - }, - "@definitelytyped/utils": { - "version": "0.0.85", - "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.0.85.tgz", - "integrity": "sha512-GHfMwIroQf3jrvps3a0rClpm5thyHajXGkMUTk4tJ4ew5I53wCnJSPMwlknsFD70F7a1hNDJGySu0PRg4px32Q==", - "dev": true, - "requires": { - "@definitelytyped/typescript-versions": "^0.0.85", - "@types/node": "^14.14.35", - "charm": "^1.0.2", - "fs-extra": "^8.1.0", - "fstream": "^1.0.12", - "npm-registry-client": "^8.6.0", - "tar": "^2.2.2", - "tar-stream": "^2.1.4" - }, - "dependencies": { - "@types/node": { - "version": "14.17.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz", - "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g==", - "dev": true - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -21260,12 +19869,6 @@ "@types/node": "*" } }, - "@types/parsimmon": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@types/parsimmon/-/parsimmon-1.10.6.tgz", - "integrity": "sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA==", - "dev": true - }, "@types/prettier": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", @@ -21585,52 +20188,6 @@ } } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -21722,18 +20279,9 @@ }, "arrify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true }, "asn1.js": { "version": "5.4.1", @@ -21767,12 +20315,6 @@ "util": "^0.12.0" } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -21837,77 +20379,6 @@ "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==", "dev": true }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "babel-jest": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz", @@ -22130,15 +20601,6 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -22163,15 +20625,6 @@ "readable-stream": "^3.4.0" } }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "requires": { - "inherits": "~2.0.0" - } - }, "bn.js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", @@ -22350,24 +20803,12 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -22461,12 +20902,6 @@ "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -22490,15 +20925,6 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "charm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", - "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", - "dev": true, - "requires": { - "inherits": "^2.0.1" - } - }, "chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", @@ -22704,17 +21130,6 @@ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -22735,13 +21150,6 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -22795,12 +21203,6 @@ "delayed-stream": "~1.0.0" } }, - "command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true - }, "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -22836,57 +21238,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -23226,15 +21583,6 @@ "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "data-uri-to-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", @@ -23261,12 +21609,6 @@ "ms": "2.1.2" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, "decimal.js": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", @@ -23352,13 +21694,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -23387,12 +21722,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, "diff-sequences": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", @@ -23511,85 +21840,6 @@ "is-obj": "^2.0.0" } }, - "dts-critic": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/dts-critic/-/dts-critic-3.3.8.tgz", - "integrity": "sha512-7kBza3f+RV/3hVCQ9yIskkrC+49kzDDM7qogbBFgLQCiGOLmUhpjE9FSw2iOWLVyeLagRNj7SmxAhD2SizJ49w==", - "dev": true, - "requires": { - "@definitelytyped/header-parser": "latest", - "command-exists": "^1.2.8", - "rimraf": "^3.0.2", - "semver": "^6.2.0", - "tmp": "^0.2.1", - "yargs": "^15.3.1" - } - }, - "dtslint": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-4.1.3.tgz", - "integrity": "sha512-UHW14DNpWnE5GkmORiDP0f4pc3AvgV7N0grB0skamXyExGOsbsHtNIe+8xeuAkPCrsf10O+Ph3W6+UgXvE4fiA==", - "dev": true, - "requires": { - "@definitelytyped/header-parser": "latest", - "@definitelytyped/typescript-versions": "latest", - "@definitelytyped/utils": "latest", - "dts-critic": "latest", - "fs-extra": "^6.0.1", - "json-stable-stringify": "^1.0.1", - "strip-json-comments": "^2.0.1", - "tslint": "5.14.0", - "tsutils": "^2.29.0", - "yargs": "^15.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", - "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "electron-to-chromium": { "version": "1.3.796", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz", @@ -24464,12 +22714,6 @@ } } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -24531,12 +22775,6 @@ } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -24732,12 +22970,6 @@ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -24765,12 +22997,6 @@ "map-cache": "^0.2.2" } }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -24801,29 +23027,6 @@ "dev": true, "optional": true }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -24841,64 +23044,6 @@ "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.4.2.tgz", "integrity": "sha512-2BggwLEJOTfXzKq4Tl2bIT37p0IqqKkblH4e0cMp2sXTdmwg/ADBKMxvxaEytYYcgdxgng8+acsi3WgMVUl6CQ==" }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -24956,15 +23101,6 @@ "dev": true, "optional": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -25058,22 +23194,6 @@ "integrity": "sha512-FeTRX67T3LoE3LWAxxOlW2K3Bz+rMYAC18rRguK4wgXaTZMiJwSUwDmPFo3UadAKbzirKIg5Qy+sNJXbpPRnQw==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -25083,23 +23203,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, "has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", @@ -25118,13 +23221,6 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -25288,17 +23384,6 @@ "debug": "4" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, "http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -25901,12 +23986,6 @@ "dev": true, "optional": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -27621,12 +25700,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -27683,14 +25756,8 @@ }, "json-parse-better-errors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema-traverse": { @@ -27699,27 +25766,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -27739,24 +25791,6 @@ "universalify": "^2.0.0" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "keyv": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", @@ -28251,15 +26285,6 @@ } } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "mri": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz", @@ -28930,54 +26955,6 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, - "npm-package-arg": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", - "dev": true, - "requires": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", - "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "npm-registry-client": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-8.6.0.tgz", - "integrity": "sha512-Qs6P6nnopig+Y8gbzpeN/dkt+n7IyVd8f45NTMotGk6Qo7GfBmzwYx6jRLoOOgKiMnaQfYxsuyQlD8Mc3guBhg==", - "dev": true, - "requires": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", - "npmlog": "2 || ^3.1.0 || ^4.0.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "safe-buffer": "^5.1.1", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3", - "ssri": "^5.2.4" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -28987,19 +26964,6 @@ "path-key": "^3.0.0" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -29009,13 +26973,6 @@ "boolbase": "^1.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -29027,12 +26984,6 @@ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -29308,28 +27259,12 @@ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -29426,12 +27361,6 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "parsimmon": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.0.tgz", - "integrity": "sha512-EtVsGuQfDgwGgXzsSDe+5egRPwbcgKRd/omQ1L3Oj2pHy0gYqd+Q7zrBIQ7P/BN6DWUP9vV45HIgZHCmssdzMg==", - "dev": true - }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -29488,12 +27417,6 @@ "sha.js": "^2.4.8" } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -30364,12 +28287,6 @@ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, "querystring": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", @@ -30754,63 +28671,6 @@ "dev": true, "optional": true }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -30823,12 +28683,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -30891,12 +28745,6 @@ "dev": true, "optional": true }, - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -31005,12 +28853,6 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "set-cookie-parser": { "version": "2.4.8", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", @@ -31139,12 +28981,6 @@ } } }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -31399,32 +29235,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.1" - } - }, "stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -31686,12 +29496,6 @@ "min-indent": "^1.0.0" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "styled-jsx": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-3.3.2.tgz", @@ -31907,30 +29711,6 @@ } } }, - "tar": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", - "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", - "dev": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.12", - "inherits": "2" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -31985,15 +29765,6 @@ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", "dev": true }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -32148,50 +29919,6 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "tslint": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.14.0.tgz", - "integrity": "sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ==", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.7.0", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, "tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -32207,21 +29934,6 @@ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", "dev": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -32243,12 +29955,6 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -32470,12 +30176,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -32511,32 +30211,12 @@ "spdx-expression-parse": "^3.0.0" } }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "dev": true, - "requires": { - "builtins": "^1.0.3" - } - }, "vendors": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", "dev": true }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -32649,12 +30329,6 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "which-typed-array": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", @@ -32670,96 +30344,12 @@ "is-typed-array": "^1.1.3" } }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "optional": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -32808,12 +30398,6 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -32825,35 +30409,6 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index f4b66221bd..21b19dfafc 100644 --- a/package.json +++ b/package.json @@ -45,8 +45,7 @@ "watch:js": "babel --config-file ./config/babel.config.js --watch src --out-dir dist", "watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir dist", "test": "jest --config ./config/jest.config.js", - "test:ci": "npm run lint && npm run test:types && npm run test -- --ci", - "test:types": "dtslint types --onlyTestTsNext", + "test:ci": "npm run lint && npm run test -- --ci", "prepublishOnly": "npm run build", "lint": "eslint .", "lint:fix": "eslint . --fix", @@ -97,7 +96,6 @@ "babel-preset-preact": "^2.0.0", "conventional-changelog-conventionalcommits": "4.6.0", "cssnano": "^5.0.6", - "dtslint": "^4.1.0", "eslint": "^7.29.0", "eslint-config-prettier": "^8.3.0", "eslint-config-standard-with-typescript": "^20.0.0", From 40255198f6e0977c9db4305f47655b72f32ed8eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 18:43:58 +0200 Subject: [PATCH 32/62] refactor(ts): move more code to TypeScript --- src/{types/adapters.d.ts => adapters.ts} | 50 +- src/{lib/errors.js => errors.ts} | 52 +- src/index.ts | 481 +++++++++++++++++- src/lib/client.ts | 4 +- src/lib/logger.js | 2 +- src/providers/email.ts | 2 + src/server/index.ts | 34 +- src/server/lib/callback-handler.ts | 22 +- ...url-handler.js => callback-url-handler.ts} | 7 +- src/server/lib/{cookie.js => cookie.ts} | 39 +- src/server/lib/create-secret.js | 13 - ...token-handler.js => csrf-token-handler.ts} | 35 +- src/server/lib/default-callbacks.ts | 2 +- src/server/lib/email/signin.d.ts | 11 + src/server/lib/email/signin.js | 2 +- src/server/lib/oauth/callback.js | 2 +- src/server/lib/utils.js | 24 - src/server/lib/utils.ts | 55 ++ src/types/errors.d.ts | 23 - src/types/index.ts | 480 ----------------- src/types/internals/cookies.d.ts | 9 - src/types/internals/index.d.ts | 8 +- src/types/react-client.d.ts | 178 ------- 23 files changed, 701 insertions(+), 834 deletions(-) rename src/{types/adapters.d.ts => adapters.ts} (70%) rename src/{lib/errors.js => errors.ts} (56%) rename src/server/lib/{callback-url-handler.js => callback-url-handler.ts} (88%) rename src/server/lib/{cookie.js => cookie.ts} (82%) delete mode 100644 src/server/lib/create-secret.js rename src/server/lib/{csrf-token-handler.js => csrf-token-handler.ts} (66%) create mode 100644 src/server/lib/email/signin.d.ts delete mode 100644 src/server/lib/utils.js create mode 100644 src/server/lib/utils.ts delete mode 100644 src/types/errors.d.ts delete mode 100644 src/types/index.ts delete mode 100644 src/types/internals/cookies.d.ts delete mode 100644 src/types/react-client.d.ts diff --git a/src/types/adapters.d.ts b/src/adapters.ts similarity index 70% rename from src/types/adapters.d.ts rename to src/adapters.ts index 5cc213a8f6..8e50b8c223 100644 --- a/src/types/adapters.d.ts +++ b/src/adapters.ts @@ -1,5 +1,5 @@ import { Account, User } from "." -import { Awaitable } from "./internals/utils" +import { Awaitable } from "./types/internals/utils" export interface AdapterUser extends User { id: string @@ -57,54 +57,54 @@ export interface VerificationToken { * [Create a custom adapter](https://next-auth.js.org/tutorials/creating-a-database-adapter) */ export interface Adapter { - createUser(user: Omit): Awaitable - getUser(id: string): Awaitable - getUserByEmail(email: string): Awaitable + createUser: (user: Omit) => Awaitable + getUser: (id: string) => Awaitable + getUserByEmail: (email: string) => Awaitable /** Using the provider id and the id of the user for a specific account, get the user. */ - getUserByAccount( + getUserByAccount: ( providerAccountId: Pick - ): Awaitable - updateUser(user: Partial): Awaitable + ) => Awaitable + updateUser: (user: Partial) => Awaitable /** @todo Implement */ - deleteUser?( + deleteUser?: ( userId: string - ): Promise | Awaitable - linkAccount( + ) => Promise | Awaitable + linkAccount: ( account: Account - ): Promise | Awaitable + ) => Promise | Awaitable /** @todo Implement */ - unlinkAccount?( + unlinkAccount?: ( providerAccountId: Pick - ): Promise | Awaitable + ) => Promise | Awaitable /** Creates a session for the user and returns it. */ - createSession(session: { + createSession: (session: { sessionToken: string userId: string expires: Date - }): Awaitable - getSessionAndUser( + }) => Awaitable + getSessionAndUser: ( sessionToken: string - ): Awaitable<{ session: AdapterSession; user: AdapterUser } | null> - updateSession( + ) => Awaitable<{ session: AdapterSession; user: AdapterUser } | null> + updateSession: ( session: Partial & Pick - ): Awaitable + ) => Awaitable /** * Deletes a session from the database. * It is preferred that this method also returns the session * that is being deleted for logging purposes. */ - deleteSession( + deleteSession: ( sessionToken: string - ): Promise | Awaitable - createVerificationToken?( + ) => Promise | Awaitable + createVerificationToken?: ( verificationToken: VerificationToken - ): Awaitable + ) => Awaitable /** * Return verification token from the database * and delete it so it cannot be used again. */ - useVerificationToken?(params: { + useVerificationToken?: (params: { identifier: string token: string - }): Awaitable + }) => Awaitable } diff --git a/src/lib/errors.js b/src/errors.ts similarity index 56% rename from src/lib/errors.js rename to src/errors.ts index 437a93f95b..987083b2a3 100644 --- a/src/lib/errors.js +++ b/src/errors.ts @@ -1,3 +1,6 @@ +import { EventCallbacks, LoggerInstance } from "." +import { Adapter } from "./adapters" + /** * Same as the default `Error`, but it is JSON serializable. * @source https://iaincollins.medium.com/error-handling-in-javascript-a6172ccdf9af @@ -33,55 +36,56 @@ export class AccountNotLinkedError extends UnknownError { name = "AccountNotLinkedError" } -export function upperSnake(s) { +type Method = (...args: any[]) => Promise + +export function upperSnake(s: string) { return s.replace(/([A-Z])/g, "_$1").toUpperCase() } -export function capitalize(s) { +export function capitalize(s: string) { return `${s[0].toUpperCase()}${s.slice(1)}` } /** * Wraps an object of methods and adds error handling. - * @param {import("src/types").EventCallbacks} methods - * @param {import("src/types").LoggerInstance} logger - * @return {import("src/types").EventCallbacks} */ -export function eventsErrorHandler(methods, logger) { - return Object.entries(methods).reduce((acc, [name, method]) => { - acc[name] = async (...args) => { +export function eventsErrorHandler( + methods: Partial, + logger: LoggerInstance +): Partial { + return Object.keys(methods).reduce((acc, name) => { + acc[name] = async (...args: any[]) => { try { + const method: Method = methods[name] return await method(...args) } catch (e) { logger.error(`${upperSnake(name)}_EVENT_ERROR`, e) } } return acc - }, {}) + }, methods) } -/** - * Handles adapter induced errors. - * @param {import("src/types/adapters").Adapter} [adapter] - * @param {import("src/types").LoggerInstance} logger - * @return {import("src/types/adapters").Adapter} - */ -export function adapterErrorHandler(adapter, logger) { +/** Handles adapter induced errors. */ +export function adapterErrorHandler( + adapter: Adapter | undefined, + logger: LoggerInstance +): Adapter | undefined { if (!adapter) return - return Object.keys(adapter).reduce((acc, method) => { - acc[method] = async (...args) => { + return Object.keys(adapter).reduce((acc, name) => { + acc[name] = async (...args: any[]) => { try { - logger.debug(`adapter_${method}`, ...args) - const adapterMethod = adapter[method] - return await adapterMethod(...args) + logger.debug(`adapter_${name}`, { args }) + const method: Method = adapter[name as any] + return await method(...args) } catch (error) { - logger.error(`adapter_error_${method}`, error) + logger.error(`adapter_error_${name}`, error) const e = new UnknownError(error) - e.name = `${capitalize(method)}Error` + e.name = `${capitalize(name)}Error` throw e } } return acc - }, {}) + }, adapter) } diff --git a/src/index.ts b/src/index.ts index 380eae5d64..a8337a2126 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,481 @@ +import { Adapter } from "./adapters" +import { Provider, CredentialInput, ProviderType } from "./providers" +import { Awaitable } from "./types/internals/utils" +import { TokenSetParameters } from "openid-client" +import { JWT, JWTOptions } from "./jwt" + export { default } from "./server" -export * from "./types" +/** + * Configure your NextAuth instance + * + * [Documentation](https://next-auth.js.org/configuration/options#options) + */ +export interface NextAuthOptions { + /** + * An array of authentication providers for signing in + * (e.g. Google, Facebook, Twitter, GitHub, Email, etc) in any order. + * This can be one of the built-in providers or an object with a custom provider. + * * **Default value**: `[]` + * * **Required**: *Yes* + * + * [Documentation](https://next-auth.js.org/configuration/options#providers) | [Providers documentation](https://next-auth.js.org/configuration/providers) + */ + providers: Provider[] + /** + * A random string used to hash tokens, sign cookies and generate cryptographic keys. + * If not specified is uses a hash of all configuration options, including Client ID / Secrets for entropy. + * The default behavior is volatile, and **it is strongly recommended** you explicitly specify a value + * to avoid invalidating end user sessions when configuration changes are deployed. + * * **Default value**: `string` (SHA hash of the "options" object) + * * **Required**: No - **but strongly recommended**! + * + * [Documentation](https://next-auth.js.org/configuration/options#secret) + */ + secret?: string + /** + * Configure your session like if you want to use JWT or a database, + * how long until an idle session expires, or to throttle write operations in case you are using a database. + * * **Default value**: See the documentation page + * * **Required**: No + * + * [Documentation](https://next-auth.js.org/configuration/options#session) + */ + session?: Partial + /** + * JSON Web Tokens can be used for session tokens if enabled with the `session: { jwt: true }` option. + * JSON Web Tokens are enabled by default if you have not specified a database. + * By default JSON Web Tokens are signed (JWS) but not encrypted (JWE), + * as JWT encryption adds additional overhead and comes with some caveats. + * You can enable encryption by setting `encryption: true`. + * * **Default value**: See the documentation page + * * **Required**: *No* + * + * [Documentation](https://next-auth.js.org/configuration/options#jwt) + */ + jwt?: Partial + /** + * Specify URLs to be used if you want to create custom sign in, sign out and error pages. + * Pages specified will override the corresponding built-in page. + * * **Default value**: `{}` + * * **Required**: *No* + * @example + * + * ```js + * pages: { + * signIn: '/auth/signin', + * signOut: '/auth/signout', + * error: '/auth/error', + * verifyRequest: '/auth/verify-request', + * newUser: '/auth/new-user' + * } + * ``` + * + * [Documentation](https://next-auth.js.org/configuration/options#pages) | [Pages documentation](https://next-auth.js.org/configuration/pages) + */ + pages?: Partial + /** + * Callbacks are asynchronous functions you can use to control what happens when an action is performed. + * Callbacks are *extremely powerful*, especially in scenarios involving JSON Web Tokens + * as they **allow you to implement access controls without a database** and to **integrate with external databases or APIs**. + * * **Default value**: See the Callbacks documentation + * * **Required**: *No* + * + * [Documentation](https://next-auth.js.org/configuration/options#callbacks) | [Callbacks documentation](https://next-auth.js.org/configuration/callbacks) + */ + callbacks?: Partial + /** + * Events are asynchronous functions that do not return a response, they are useful for audit logging. + * You can specify a handler for any of these events below - e.g. for debugging or to create an audit log. + * The content of the message object varies depending on the flow + * (e.g. OAuth or Email authentication flow, JWT or database sessions, etc), + * but typically contains a user object and/or contents of the JSON Web Token + * and other information relevant to the event. + * * **Default value**: `{}` + * * **Required**: *No* + * + * [Documentation](https://next-auth.js.org/configuration/options#events) | [Events documentation](https://next-auth.js.org/configuration/events) + */ + events?: Partial + /** + * You can use the adapter option to pass in your database adapter. + * + * * **Required**: *No* + * + * [Documentation](https://next-auth.js.org/configuration/options#adapter) | + * [Community adapters](https://github.com/nextauthjs/adapters) + */ + adapter?: Adapter + /** + * Set debug to true to enable debug messages for authentication and database operations. + * * **Default value**: `false` + * * **Required**: *No* + * + * - âš  If you added a custom `logger`, this setting is ignored. + * + * [Documentation](https://next-auth.js.org/configuration/options#debug) | [Logger documentation](https://next-auth.js.org/configuration/options#logger) + */ + debug?: boolean + /** + * Override any of the logger levels (`undefined` levels will use the built-in logger), + * and intercept logs in NextAuth. You can use this option to send NextAuth logs to a third-party logging service. + * * **Default value**: `console` + * * **Required**: *No* + * + * @example + * + * ```js + * // /pages/api/auth/[...nextauth].js + * import log from "logging-service" + * export default NextAuth({ + * logger: { + * error(code, ...message) { + * log.error(code, message) + * }, + * warn(code, ...message) { + * log.warn(code, message) + * }, + * debug(code, ...message) { + * log.debug(code, message) + * } + * } + * }) + * ``` + * + * - âš  When set, the `debug` option is ignored + * + * [Documentation](https://next-auth.js.org/configuration/options#logger) | + * [Debug documentation](https://next-auth.js.org/configuration/options#debug) + */ + logger?: Partial + /** + * Changes the theme of pages. + * Set to `"light"` if you want to force pages to always be light. + * Set to `"dark"` if you want to force pages to always be dark. + * Set to `"auto"`, (or leave this option out)if you want the pages to follow the preferred system theme. + * * **Default value**: `"auto"` + * * **Required**: *No* + * + * [Documentation](https://next-auth.js.org/configuration/options#theme) | [Pages documentation]("https://next-auth.js.org/configuration/pages") + */ + theme?: Theme + /** + * When set to `true` then all cookies set by NextAuth.js will only be accessible from HTTPS URLs. + * This option defaults to `false` on URLs that start with `http://` (e.g. http://localhost:3000) for developer convenience. + * You can manually set this option to `false` to disable this security feature and allow cookies + * to be accessible from non-secured URLs (this is not recommended). + * * **Default value**: `true` for HTTPS and `false` for HTTP sites + * * **Required**: No + * + * [Documentation](https://next-auth.js.org/configuration/options#usesecurecookies) + * + * - âš  **This is an advanced option.** Advanced options are passed the same way as basic options, + * but **may have complex implications** or side effects. + * You should **try to avoid using advanced options** unless you are very comfortable using them. + */ + useSecureCookies?: boolean + /** + * You can override the default cookie names and options for any of the cookies used by NextAuth.js. + * You can specify one or more cookies with custom properties, + * but if you specify custom options for a cookie you must provide all the options for that cookie. + * If you use this feature, you will likely want to create conditional behavior + * to support setting different cookies policies in development and production builds, + * as you will be opting out of the built-in dynamic policy. + * * **Default value**: `{}` + * * **Required**: No + * + * - âš  **This is an advanced option.** Advanced options are passed the same way as basic options, + * but **may have complex implications** or side effects. + * You should **try to avoid using advanced options** unless you are very comfortable using them. + * + * [Documentation](https://next-auth.js.org/configuration/options#cookies) | [Usage example](https://next-auth.js.org/configuration/options#example) + */ + cookies?: Partial +} + +/** + * Change the theme of the built-in pages. + * + * [Documentation](https://next-auth.js.org/configuration/options#theme) | + * [Pages](https://next-auth.js.org/configuration/pages) + */ +export type Theme = "auto" | "dark" | "light" + +/** + * Override any of the methods, and the rest will use the default logger. + * + * [Documentation](https://next-auth.js.org/configuration/options#logger) + */ +export interface LoggerInstance { + warn: ( + code: + | "JWT_AUTO_GENERATED_SIGNING_KEY" + | "JWT_AUTO_GENERATED_ENCRYPTION_KEY" + | "NEXTAUTH_URL" + ) => void + error: ( + code: string, + /** + * Either an instance of (JSON serializable) Error + * or an object that contains some debug information. + * (Error is still available through `metadata.error`) + */ + metadata: Error | { error: Error; [key: string]: unknown } + ) => void + debug: (code: string, metadata: unknown) => void +} + +/** + * Different tokens returned by OAuth Providers. + * Some of them are available with different casing, + * but they refer to the same value. + */ +export type TokenSet = TokenSetParameters + +/** + * Usually contains information about the provider being used + * and also extends `TokenSet`, which is different tokens returned by OAuth Providers. + */ +export interface DefaultAccount extends Partial { + /** + * This value depends on the type of the provider being used to create the account. + * - oauth: The OAuth account's id, returned from the `profile()` callback. + * - email: The user's email address. + * - credentials: `id` returned from the `authorize()` callback + */ + providerAccountId: string + /** id of the user this account belongs to. */ + userId: string + /** id of the provider used for this account */ + provider: string + /** Provider's type for this account */ + type: ProviderType +} + +export interface Account extends Record, DefaultAccount {} + +export interface DefaultProfile { + sub?: string + name?: string + email?: string + image?: string +} + +/** The OAuth profile returned from your provider */ +export interface Profile extends Record, DefaultProfile {} + +/** [Documentation](https://next-auth.js.org/configuration/callbacks) */ +export interface CallbacksOptions< + P extends Record = Profile, + A extends Record = Account +> { + /** + * Use this callback to control if a user is allowed to sign in. + * Returning true will continue the sign-in flow. + * Throwing an error or returning a string will stop the flow, and redirect the user. + * + * [Documentation](https://next-auth.js.org/configuration/callbacks#sign-in-callback) + */ + signIn: (params: { + user: User + account: A + /** + * If OAuth provider is used, it contains the full + * OAuth profile returned by your provider. + */ + profile: P & Record + /** + * If Email provider is used, on the first call, it contains a + * `verificationRequest: true` property to indicate it is being triggered in the verification request flow. + * When the callback is invoked after a user has clicked on a sign in link, + * this property will not be present. You can check for the `verificationRequest` property + * to avoid sending emails to addresses or domains on a blocklist or to only explicitly generate them + * for email address in an allow list. + */ + email: { + verificationRequest?: boolean + } + /** If Credentials provider is used, it contains the user credentials */ + credentials: Record + }) => Awaitable + /** + * This callback is called anytime the user is redirected to a callback URL (e.g. on signin or signout). + * By default only URLs on the same URL as the site are allowed, + * you can use this callback to customise that behaviour. + * + * [Documentation](https://next-auth.js.org/configuration/callbacks#redirect-callback) + */ + redirect: (params: { + /** URL provided as callback URL by the client */ + url: string + /** Default base URL of site (can be used as fallback) */ + baseUrl: string + }) => Awaitable + /** + * This callback is called whenever a session is checked. + * (Eg.: invoking the `/api/session` endpoint, using `useSession` or `getSession`) + * + * âš  By default, only a subset (email, name, imgage) + * of the token is returned for increased security. + * + * If you want to make something available you added to the token through the `jwt` callback, + * you have to explicitely forward it here to make it available to the client. + * + * [Documentation](https://next-auth.js.org/configuration/callbacks#session-callback) | + * [`jwt` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | + * [`useSession`](https://next-auth.js.org/getting-started/client#usesession) | + * [`getSession`](https://next-auth.js.org/getting-started/client#getsession) | + * + */ + session: (params: { + session: Session + user: User + token: JWT + }) => Awaitable + /** + * This callback is called whenever a JSON Web Token is created (i.e. at sign in) + * or updated (i.e whenever a session is accessed in the client). + * Its content is forwarded to the `session` callback, + * where you can control what should be returned to the client. + * Anything else will be kept from your front-end. + * + * âš  By default the JWT is signed, but not encrypted. + * + * [Documentation](https://next-auth.js.org/configuration/callbacks#jwt-callback) | + * [`session` callback](https://next-auth.js.org/configuration/callbacks#session-callback) + */ + jwt: (params: { + token: JWT + user?: User + account?: A + profile?: P + isNewUser?: boolean + }) => Awaitable +} + +/** [Documentation](https://next-auth.js.org/configuration/options#cookies) */ +export interface CookieOption { + name: string + options: { + httpOnly?: boolean + sameSite: true | "strict" | "lax" | "none" + path?: string + secure: boolean + maxAge?: number + domain?: string + } +} + +/** [Documentation](https://next-auth.js.org/configuration/options#cookies) */ +export interface CookiesOptions { + sessionToken: CookieOption + callbackUrl: CookieOption + csrfToken: CookieOption + pkceCodeVerifier: CookieOption +} + +/** + * The various event callbacks you can register for from next-auth + * + * [Documentation](https://next-auth.js.org/configuration/events) + */ +export interface EventCallbacks { + /** + * If using a `credentials` type auth, the user is the raw response from your + * credential provider. + * For other providers, you'll get the User object from your adapter, the account, + * and an indicator if the user was new to your Adapter. + */ + signIn: (message: { + user: User + account: Account + profile?: Profile + isNewUser?: boolean + }) => Awaitable + /** + * The message object will contain one of these depending on + * if you use JWT or database persisted sessions: + * - `token`: The JWT token for this session. + * - `session`: The session object from your adapter that is being ended. + */ + signOut: (message: { session: Session; token: JWT }) => Awaitable + createUser: (message: { user: User }) => Awaitable + updateUser: (message: { user: User }) => Awaitable + linkAccount: (message: { user: User; account: Account }) => Awaitable + /** + * The message object will contain one of these depending on + * if you use JWT or database persisted sessions: + * - `token`: The JWT token for this session. + * - `session`: The session object from your adapter. + */ + session: (message: { session: Session; token: JWT }) => Awaitable +} + +export type EventType = keyof EventCallbacks + +/** [Documentation](https://next-auth.js.org/configuration/pages) */ +export interface PagesOptions { + signIn: string + signOut: string + /** Error code passed in query string as ?error= */ + error: string + verifyRequest: string + /** If set, new users will be directed here on first sign in */ + newUser: string +} + +export type ISODateString = string + +export interface DefaultSession extends Record { + user?: { + name?: string | null + email?: string | null + image?: string | null + } + expires: ISODateString +} + +/** + * Returned by `useSession`, `getSession`, returned by the `session` callback + * and also the shape received as a prop on the `SessionProvider` React Context + * + * [`useSession`](https://next-auth.js.org/getting-started/client#usesession) | + * [`getSession`](https://next-auth.js.org/getting-started/client#getsession) | + * [`SessionProvider`](https://next-auth.js.org/getting-started/client#sessionprovider) | + * [`session` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) + */ +export interface Session extends Record, DefaultSession {} + +/** [Documentation](https://next-auth.js.org/configuration/options#session) */ +export interface SessionOptions { + jwt: boolean + /** + * Relative time from now in seconds when to expire the session + * @default 2592000 // 30 days + */ + maxAge: number + /** + * How often the session should be updated in seconds. + * If set to `0`, session is updated every time. + * @default 86400 // 1 day + */ + updateAge: number +} + +export interface DefaultUser { + id: string + name?: string | null + email?: string | null + image?: string | null +} + +/** + * The shape of the returned object in the OAuth providers' `profile` callback, + * available in the `jwt` and `session` callbacks, + * or the second parameter of the `session` callback, when using a database. + * + * [`signIn` callback](https://next-auth.js.org/configuration/callbacks#sign-in-callback) | + * [`session` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | + * [`jwt` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | + * [`profile` OAuth provider callback](https://next-auth.js.org/configuration/providers#using-a-custom-provider) + */ +export interface User extends Record, DefaultUser {} diff --git a/src/lib/client.ts b/src/lib/client.ts index 5036b19c49..9d80efc7e9 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -1,6 +1,6 @@ import type { IncomingMessage } from "http" -import { NextAuthClientConfig } from "src/react" -import { LoggerInstance } from "src/types" +import { LoggerInstance } from ".." +import { NextAuthClientConfig } from "../react" export interface CtxOrReq { req?: IncomingMessage diff --git a/src/lib/logger.js b/src/lib/logger.js index 5ee92b0978..d7b155f610 100644 --- a/src/lib/logger.js +++ b/src/lib/logger.js @@ -1,4 +1,4 @@ -import { UnknownError } from "./errors" +import { UnknownError } from "../errors" /** Makes sure that error is always serializable */ function formatError(o) { diff --git a/src/providers/email.ts b/src/providers/email.ts index d470d68210..cfa3d61f1e 100644 --- a/src/providers/email.ts +++ b/src/providers/email.ts @@ -37,6 +37,8 @@ export interface EmailConfig extends CommonProviderOptions { * [Documentation](https://next-auth.js.org/providers/email#customising-the-verification-token) */ generateVerificationToken?: () => Awaitable + /** If defined, it is used to hash the verification token when saving to the database . */ + secret?: string options: EmailUserConfig } diff --git a/src/server/index.ts b/src/server/index.ts index 9901adc1ff..c1427b7790 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -7,13 +7,18 @@ import { defaultCallbacks } from "./lib/default-callbacks" import parseProviders from "./lib/providers" import * as routes from "./routes" import renderPage from "./pages" -import createSecret from "./lib/create-secret" import callbackUrlHandler from "./lib/callback-url-handler" import extendRes from "./lib/extend-res" import csrfTokenHandler from "./lib/csrf-token-handler" -import { eventsErrorHandler, adapterErrorHandler } from "../lib/errors" -import { NextApiRequest, NextApiResponse } from "../types/internals/utils" -import { NextAuthOptions } from "../types" +import { eventsErrorHandler, adapterErrorHandler } from "../errors" +import { NextApiRequest, NextApiResponse } from "next" +import { NextAuthOptions } from ".." +import { + InternalOptions, + NextAuthRequest, + NextAuthResponse, +} from "../types/internals" +import createSecret from "./lib/utils" // To work properly in production with OAuth providers the NEXTAUTH_URL // environment variable must be set. @@ -21,12 +26,11 @@ if (!process.env.NEXTAUTH_URL) { logger.warn("NEXTAUTH_URL") } -/** - * @param {import("next").NextApiRequest} req - * @param {import("next").NextApiResponse} res - * @param {import("types").NextAuthOptions} userOptions - */ -async function NextAuthHandler(req, res, userOptions) { +async function NextAuthHandler( + req: NextAuthRequest, + res: NextAuthResponse, + userOptions: NextAuthOptions +) { if (userOptions.logger) { setLogger(userOptions.logger) } @@ -61,7 +65,7 @@ async function NextAuthHandler(req, res, userOptions) { const cookies = { ...cookie.defaultCookies( - userOptions.useSecureCookies || baseUrl.startsWith("https://") + userOptions.useSecureCookies ?? baseUrl.startsWith("https://") ), // Allow user cookie options to override any cookie settings above ...userOptions.cookies, @@ -90,8 +94,7 @@ async function NextAuthHandler(req, res, userOptions) { // User provided options are overriden by other options, // except for the options with special handling above - /** @type {import("types/internals").InternalOptions} */ - const options = { + const options: InternalOptions = { debug: false, pages: {}, theme: "auto", @@ -101,7 +104,7 @@ async function NextAuthHandler(req, res, userOptions) { // and are request-specific. baseUrl, basePath, - action, + action: action as InternalOptions["action"], provider, cookies, secret, @@ -130,6 +133,7 @@ async function NextAuthHandler(req, res, userOptions) { ...userOptions.callbacks, }, logger, + callbackUrl: process.env.NEXTAUTH_URL ?? "http://localhost:3000", } req.options = options @@ -196,7 +200,7 @@ async function NextAuthHandler(req, res, userOptions) { "EmailSignin", "CredentialsSignin", "SessionRequired", - ].includes(error) + ].includes(error as string) ) { return res.redirect(`${baseUrl}${basePath}/signin?error=${error}`) } diff --git a/src/server/lib/callback-handler.ts b/src/server/lib/callback-handler.ts index c2bcec2bcb..ea3fef49ab 100644 --- a/src/server/lib/callback-handler.ts +++ b/src/server/lib/callback-handler.ts @@ -1,11 +1,11 @@ -import { AccountNotLinkedError } from "../../lib/errors" +import { AccountNotLinkedError } from "../../errors" import { fromDate } from "./utils" import { randomBytes, randomUUID } from "crypto" -import { SessionToken } from "src/types/internals/cookies" -import { InternalOptions } from "src/types/internals" -import { AdapterSession, AdapterUser } from "src/types/adapters" -import { JWT } from "src/jwt" -import { Account, User } from "src/types" +import { InternalOptions } from "../../types/internals" +import { AdapterSession, AdapterUser } from "../../adapters" +import { JWT } from "../../jwt" +import { Account, User } from "../.." +import { SessionToken } from "./cookie" /** * This function handles the complex flow of signing users in, and either creating, @@ -129,9 +129,11 @@ export default async function callbackHandler( return { session, user, isNewUser } } // If the user is currently signed in, but the new account they are signing in - // with is already associated with another account, then we cannot link them + // with is already associated with another user, then we cannot link them // and need to return an error. - throw new AccountNotLinkedError() + throw new AccountNotLinkedError( + "The account is already associated with another user" + ) } // If there is no active session, but the account being signed in with is already // associated with a valid user then create session to sign the user in. @@ -183,7 +185,9 @@ export default async function callbackHandler( // We don't want to have two accounts with the same email address, and we don't // want to link them in case it's not safe to do so, so instead we prompt the user // to sign in via email to verify their identity and then link the accounts. - throw new AccountNotLinkedError() + throw new AccountNotLinkedError( + "Another account already exists with the same e-mail address" + ) } // If the current user is not logged in and the profile isn't linked to any user // accounts (by email or provider account id)... diff --git a/src/server/lib/callback-url-handler.js b/src/server/lib/callback-url-handler.ts similarity index 88% rename from src/server/lib/callback-url-handler.js rename to src/server/lib/callback-url-handler.ts index e906fe95f5..814e973428 100644 --- a/src/server/lib/callback-url-handler.js +++ b/src/server/lib/callback-url-handler.ts @@ -1,12 +1,15 @@ // @ts-check +import { NextAuthRequest, NextAuthResponse } from "../../types/internals" import * as cookie from "../lib/cookie" /** * Get callback URL based on query param / cookie + validation, * and add it to `req.options.callbackUrl`. - * @type {import("src/types/internals").NextAuthApiHandler} */ -export default async function callbackUrlHandler(req, res) { +export default async function callbackUrlHandler( + req: NextAuthRequest, + res: NextAuthResponse +) { const { query } = req const { body } = req const { cookies, baseUrl, callbacks } = req.options diff --git a/src/server/lib/cookie.js b/src/server/lib/cookie.ts similarity index 82% rename from src/server/lib/cookie.js rename to src/server/lib/cookie.ts index c4ab12f31c..2e0a7543ef 100644 --- a/src/server/lib/cookie.js +++ b/src/server/lib/cookie.ts @@ -1,3 +1,15 @@ +// REVIEW: Is there any way to defer two types of strings? + +import { CookiesOptions } from "../.." + +/** Stringified form of `JWT`. Extract the content with `jwt.decode` */ +export type JWTString = string + +/** If `options.session.jwt` is set to `true`, this is a stringified `JWT`. In case of a database persisted session, this is the `sessionToken` of the session in the database.. */ +export type SessionToken = T extends "jwt" + ? JWTString + : string + /** * Function to set cookies server side * @@ -8,13 +20,21 @@ * As only partial functionlity is required, only the code we need has been incorporated here * (with fixes for specific issues) to keep dependancy size down. */ -export function set(res, name, value, options = {}) { +export function set( + res, + name, + value, + options: { + expires?: Date + maxAge?: number + } = {} +) { const stringValue = typeof value === "object" ? "j:" + JSON.stringify(value) : String(value) if ("maxAge" in options) { - options.expires = new Date(Date.now() + options.maxAge) - options.maxAge /= 1000 + options.expires = new Date(Date.now() + (options.maxAge ?? 0)) + options.maxAge = (options.maxAge ?? 0) / 1000 } // Preserve any existing cookies that have already been set in the same session @@ -47,7 +67,7 @@ function _serialize(name, val, options) { throw new TypeError("argument val is invalid") } - let str = name + "=" + value + let str = `${name}=${value}` if (opt.maxAge != null) { const maxAge = opt.maxAge - 0 @@ -56,7 +76,7 @@ function _serialize(name, val, options) { throw new TypeError("option maxAge is invalid") } - str += "; Max-Age=" + Math.floor(maxAge) + str += `; Max-Age=${Math.floor(maxAge)}` } if (opt.domain) { @@ -64,7 +84,7 @@ function _serialize(name, val, options) { throw new TypeError("option domain is invalid") } - str += "; Domain=" + opt.domain + str += `; Domain=${opt.domain}` } if (opt.path) { @@ -72,7 +92,7 @@ function _serialize(name, val, options) { throw new TypeError("option path is invalid") } - str += "; Path=" + opt.path + str += `; Path=${opt.path}` } else { str += "; Path=/" } @@ -85,7 +105,7 @@ function _serialize(name, val, options) { const dateExpires = new Date(opt.expires) expires = dateExpires.toUTCString() } - str += "; Expires=" + expires + str += `; Expires=${expires}` } if (opt.httpOnly) { @@ -132,9 +152,8 @@ function _serialize(name, val, options) { * For more on prefixes see https://googlechrome.github.io/samples/cookie-prefixes/ * * @TODO Review cookie settings (names, options) - * @return {import("src/types").CookiesOptions} */ -export function defaultCookies(useSecureCookies) { +export function defaultCookies(useSecureCookies): CookiesOptions { const cookiePrefix = useSecureCookies ? "__Secure-" : "" return { // default cookie options diff --git a/src/server/lib/create-secret.js b/src/server/lib/create-secret.js deleted file mode 100644 index 0364156a2b..0000000000 --- a/src/server/lib/create-secret.js +++ /dev/null @@ -1,13 +0,0 @@ -import { createHash } from 'crypto' - -/** - * Secret used salt cookies and tokens (e.g. for CSRF protection). - * If no secret option is specified then it creates one on the fly - * based on options passed here. A options contains unique data, such as - * OAuth provider secrets and database credentials it should be sufficent. - */ -export default function createSecret ({ userOptions, basePath, baseUrl }) { - return userOptions.secret || createHash('sha256').update(JSON.stringify({ - baseUrl, basePath, ...userOptions - })).digest('hex') -} diff --git a/src/server/lib/csrf-token-handler.js b/src/server/lib/csrf-token-handler.ts similarity index 66% rename from src/server/lib/csrf-token-handler.js rename to src/server/lib/csrf-token-handler.ts index afb8ff2fbd..1a46f21ebb 100644 --- a/src/server/lib/csrf-token-handler.js +++ b/src/server/lib/csrf-token-handler.ts @@ -1,5 +1,6 @@ -import { createHash, randomBytes } from 'crypto' -import * as cookie from './cookie' +import { createHash, randomBytes } from "crypto" +import { NextAuthRequest, NextAuthResponse } from "../../types/internals" +import * as cookie from "./cookie" /** * Ensure CSRF Token cookie is set for any subsequent requests. @@ -14,19 +15,24 @@ import * as cookie from './cookie' * For more details, see the following OWASP links: * https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie * https://owasp.org/www-chapter-london/assets/slides/David_Johansson-Double_Defeat_of_Double-Submit_Cookie.pdf - * @param {import("..").NextAuthRequest} req - * @param {import("..").NextAuthResponse} res */ -export default function csrfTokenHandler (req, res) { +export default function csrfTokenHandler( + req: NextAuthRequest, + res: NextAuthResponse +) { const { cookies, secret } = req.options if (cookies.csrfToken.name in req.cookies) { - const [csrfToken, csrfTokenHash] = req.cookies[cookies.csrfToken.name].split('|') - const expectedCsrfTokenHash = createHash('sha256').update(`${csrfToken}${secret}`).digest('hex') + const [csrfToken, csrfTokenHash] = + req.cookies[cookies.csrfToken.name].split("|") + const expectedCsrfTokenHash = createHash("sha256") + .update(`${csrfToken}${secret}`) + .digest("hex") if (csrfTokenHash === expectedCsrfTokenHash) { // If hash matches then we trust the CSRF token value // If this is a POST request and the CSRF Token in the POST request matches // the cookie we have already verified is the one we have set, then the token is verified! - const csrfTokenVerified = req.method === 'POST' && csrfToken === req.body.csrfToken + const csrfTokenVerified = + req.method === "POST" && csrfToken === req.body.csrfToken req.options.csrfToken = csrfToken req.options.csrfTokenVerified = csrfTokenVerified return @@ -35,9 +41,16 @@ export default function csrfTokenHandler (req, res) { // If no csrfToken from cookie - because it's not been set yet, // or because the hash doesn't match (e.g. because it's been modifed or because the secret has changed) // create a new token. - const csrfToken = randomBytes(32).toString('hex') - const csrfTokenHash = createHash('sha256').update(`${csrfToken}${secret}`).digest('hex') + const csrfToken = randomBytes(32).toString("hex") + const csrfTokenHash = createHash("sha256") + .update(`${csrfToken}${secret}`) + .digest("hex") const csrfTokenCookie = `${csrfToken}|${csrfTokenHash}` - cookie.set(res, cookies.csrfToken.name, csrfTokenCookie, cookies.csrfToken.options) + cookie.set( + res, + cookies.csrfToken.name, + csrfTokenCookie, + cookies.csrfToken.options + ) req.options.csrfToken = csrfToken } diff --git a/src/server/lib/default-callbacks.ts b/src/server/lib/default-callbacks.ts index 080d46bb83..1550c81e01 100644 --- a/src/server/lib/default-callbacks.ts +++ b/src/server/lib/default-callbacks.ts @@ -1,4 +1,4 @@ -import { CallbacksOptions } from "src/types/index" +import { CallbacksOptions } from "../.." export const defaultCallbacks: CallbacksOptions = { signIn() { diff --git a/src/server/lib/email/signin.d.ts b/src/server/lib/email/signin.d.ts new file mode 100644 index 0000000000..50a32a62a7 --- /dev/null +++ b/src/server/lib/email/signin.d.ts @@ -0,0 +1,11 @@ +/** + * @typedef {import("src/providers").EmailConfig} EmailConfig + */ +/** + * Starts an e-mail login flow, by generating a token, + * and sending it to the user's e-mail (with the help of a DB adapter) + * @param {string} identifier + * @param {import("src/types/internals").InternalOptions} options + */ +export default function email(identifier: string, options: import("src/types/internals").InternalOptions): Promise; +export type EmailConfig = import("src/providers").EmailConfig; diff --git a/src/server/lib/email/signin.js b/src/server/lib/email/signin.js index 33c49a59d3..dcc6aa45fb 100644 --- a/src/server/lib/email/signin.js +++ b/src/server/lib/email/signin.js @@ -10,7 +10,7 @@ import { hashToken } from "../utils" * Starts an e-mail login flow, by generating a token, * and sending it to the user's e-mail (with the help of a DB adapter) * @param {string} identifier - * @param {import("src/types/internals").InternalOptions} options + * @param {import("src/types/internals").InternalOptions} options */ export default async function email(identifier, options) { const { baseUrl, basePath, adapter, provider, logger } = options diff --git a/src/server/lib/oauth/callback.js b/src/server/lib/oauth/callback.js index 40ff1102df..4bd3de817a 100644 --- a/src/server/lib/oauth/callback.js +++ b/src/server/lib/oauth/callback.js @@ -2,7 +2,7 @@ import { openidClient } from "./client" import { oAuth1Client } from "./client-legacy" import { getState } from "./state-handler" import { usePKCECodeVerifier } from "./pkce-handler" -import { OAuthCallbackError } from "../../../lib/errors" +import { OAuthCallbackError } from "../../../errors" import { TokenSet } from "openid-client" /** @type {import("src/types/internals").NextAuthApiHandler} */ diff --git a/src/server/lib/utils.js b/src/server/lib/utils.js deleted file mode 100644 index 73b67509e6..0000000000 --- a/src/server/lib/utils.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createHash } from "crypto" - -/** - * Takes a number in seconds and returns the date in the future. - * Optionally takes a second date parameter. In that case - * the date in the future will be calculated from that date instead of now. - */ -export function fromDate(time, date = Date.now()) { - return new Date(date + time * 1000) -} - -/** - * @param {string} token - * @param {import("src/types/internals").InternalOptions} options - */ -export function hashToken(token, options) { - const { provider, secret } = options - return ( - createHash("sha256") - // Prefer provider specific secret, but use default secret if none specified - .update(`${token}${provider.secret ?? secret}`) - .digest("hex") - ) -} diff --git a/src/server/lib/utils.ts b/src/server/lib/utils.ts new file mode 100644 index 0000000000..e8e6419aad --- /dev/null +++ b/src/server/lib/utils.ts @@ -0,0 +1,55 @@ +import { createHash } from "crypto" +import { NextAuthOptions } from "../.." +import { EmailConfig } from "../../providers" +import { InternalOptions, InternalProvider } from "../../types/internals" + +/** + * Takes a number in seconds and returns the date in the future. + * Optionally takes a second date parameter. In that case + * the date in the future will be calculated from that date instead of now. + */ +export function fromDate(time, date = Date.now()) { + return new Date(date + time * 1000) +} + +export function hashToken( + token: string, + options: InternalOptions +) { + const { provider, secret } = options + return ( + createHash("sha256") + // Prefer provider specific secret, but use default secret if none specified + .update(`${token}${provider.secret ?? secret}`) + .digest("hex") + ) +} + +/** + * Secret used salt cookies and tokens (e.g. for CSRF protection). + * If no secret option is specified then it creates one on the fly + * based on options passed here. A options contains unique data, such as + * OAuth provider secrets and database credentials it should be sufficent. + */ +export default function createSecret({ + userOptions, + basePath, + baseUrl, +}: { + userOptions: NextAuthOptions + basePath: string + baseUrl: string +}) { + return ( + userOptions.secret ?? + createHash("sha256") + .update( + JSON.stringify({ + baseUrl, + basePath, + ...userOptions, + }) + ) + .digest("hex") + ) +} diff --git a/src/types/errors.d.ts b/src/types/errors.d.ts deleted file mode 100644 index 7e5963d04a..0000000000 --- a/src/types/errors.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Same as the default `Error`, but it is JSON serializable. - * @source https://iaincollins.medium.com/error-handling-in-javascript-a6172ccdf9af - */ -export class UnknownError extends Error {} -export class OAuthCallbackError extends UnknownError {} -export class AccountNotLinkedError extends UnknownError {} -export class CreateUserError extends UnknownError {} -export class GetUserError extends UnknownError {} -export class GetUserByEmailError extends UnknownError {} -export class GetUserByIdError extends UnknownError {} -export class GetUserByProviderAccountIdError extends UnknownError {} -export class UpdateUserError extends UnknownError {} -export class DeleteUserError extends UnknownError {} -export class LinkAccountError extends UnknownError {} -export class UnlinkAccountError extends UnknownError {} -export class CreateSessionError extends UnknownError {} -export class GetSessionError extends UnknownError {} -export class UpdateSessionError extends UnknownError {} -export class DeleteSessionError extends UnknownError {} -export class CreateVerificationRequestError extends UnknownError {} -export class GetVerificationRequestError extends UnknownError {} -export class DeleteVerificationRequestError extends UnknownError {} diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index a995a8b239..0000000000 --- a/src/types/index.ts +++ /dev/null @@ -1,480 +0,0 @@ -import { Adapter } from "./adapters" -import { Provider, CredentialInput, ProviderType } from "../providers" -import { Awaitable } from "./internals/utils" -import { TokenSetParameters } from "openid-client" -import { JWT, JWTOptions } from "../jwt" - -/** - * Configure your NextAuth instance - * - * [Documentation](https://next-auth.js.org/configuration/options#options) - */ -export interface NextAuthOptions { - /** - * An array of authentication providers for signing in - * (e.g. Google, Facebook, Twitter, GitHub, Email, etc) in any order. - * This can be one of the built-in providers or an object with a custom provider. - * * **Default value**: `[]` - * * **Required**: *Yes* - * - * [Documentation](https://next-auth.js.org/configuration/options#providers) | [Providers documentation](https://next-auth.js.org/configuration/providers) - */ - providers: Provider[] - /** - * A random string used to hash tokens, sign cookies and generate cryptographic keys. - * If not specified is uses a hash of all configuration options, including Client ID / Secrets for entropy. - * The default behavior is volatile, and **it is strongly recommended** you explicitly specify a value - * to avoid invalidating end user sessions when configuration changes are deployed. - * * **Default value**: `string` (SHA hash of the "options" object) - * * **Required**: No - **but strongly recommended**! - * - * [Documentation](https://next-auth.js.org/configuration/options#secret) - */ - secret?: string - /** - * Configure your session like if you want to use JWT or a database, - * how long until an idle session expires, or to throttle write operations in case you are using a database. - * * **Default value**: See the documentation page - * * **Required**: No - * - * [Documentation](https://next-auth.js.org/configuration/options#session) - */ - session?: Partial - /** - * JSON Web Tokens can be used for session tokens if enabled with the `session: { jwt: true }` option. - * JSON Web Tokens are enabled by default if you have not specified a database. - * By default JSON Web Tokens are signed (JWS) but not encrypted (JWE), - * as JWT encryption adds additional overhead and comes with some caveats. - * You can enable encryption by setting `encryption: true`. - * * **Default value**: See the documentation page - * * **Required**: *No* - * - * [Documentation](https://next-auth.js.org/configuration/options#jwt) - */ - jwt?: Partial - /** - * Specify URLs to be used if you want to create custom sign in, sign out and error pages. - * Pages specified will override the corresponding built-in page. - * * **Default value**: `{}` - * * **Required**: *No* - * @example - * - * ```js - * pages: { - * signIn: '/auth/signin', - * signOut: '/auth/signout', - * error: '/auth/error', - * verifyRequest: '/auth/verify-request', - * newUser: '/auth/new-user' - * } - * ``` - * - * [Documentation](https://next-auth.js.org/configuration/options#pages) | [Pages documentation](https://next-auth.js.org/configuration/pages) - */ - pages?: Partial - /** - * Callbacks are asynchronous functions you can use to control what happens when an action is performed. - * Callbacks are *extremely powerful*, especially in scenarios involving JSON Web Tokens - * as they **allow you to implement access controls without a database** and to **integrate with external databases or APIs**. - * * **Default value**: See the Callbacks documentation - * * **Required**: *No* - * - * [Documentation](https://next-auth.js.org/configuration/options#callbacks) | [Callbacks documentation](https://next-auth.js.org/configuration/callbacks) - */ - callbacks?: Partial - /** - * Events are asynchronous functions that do not return a response, they are useful for audit logging. - * You can specify a handler for any of these events below - e.g. for debugging or to create an audit log. - * The content of the message object varies depending on the flow - * (e.g. OAuth or Email authentication flow, JWT or database sessions, etc), - * but typically contains a user object and/or contents of the JSON Web Token - * and other information relevant to the event. - * * **Default value**: `{}` - * * **Required**: *No* - * - * [Documentation](https://next-auth.js.org/configuration/options#events) | [Events documentation](https://next-auth.js.org/configuration/events) - */ - events?: Partial - /** - * You can use the adapter option to pass in your database adapter. - * - * * **Required**: *No* - * - * [Documentation](https://next-auth.js.org/configuration/options#adapter) | - * [Community adapters](https://github.com/nextauthjs/adapters) - */ - adapter?: Adapter - /** - * Set debug to true to enable debug messages for authentication and database operations. - * * **Default value**: `false` - * * **Required**: *No* - * - * - âš  If you added a custom `logger`, this setting is ignored. - * - * [Documentation](https://next-auth.js.org/configuration/options#debug) | [Logger documentation](https://next-auth.js.org/configuration/options#logger) - */ - debug?: boolean - /** - * Override any of the logger levels (`undefined` levels will use the built-in logger), - * and intercept logs in NextAuth. You can use this option to send NextAuth logs to a third-party logging service. - * * **Default value**: `console` - * * **Required**: *No* - * - * @example - * - * ```js - * // /pages/api/auth/[...nextauth].js - * import log from "logging-service" - * export default NextAuth({ - * logger: { - * error(code, ...message) { - * log.error(code, message) - * }, - * warn(code, ...message) { - * log.warn(code, message) - * }, - * debug(code, ...message) { - * log.debug(code, message) - * } - * } - * }) - * ``` - * - * - âš  When set, the `debug` option is ignored - * - * [Documentation](https://next-auth.js.org/configuration/options#logger) | - * [Debug documentation](https://next-auth.js.org/configuration/options#debug) - */ - logger?: Partial - /** - * Changes the theme of pages. - * Set to `"light"` if you want to force pages to always be light. - * Set to `"dark"` if you want to force pages to always be dark. - * Set to `"auto"`, (or leave this option out)if you want the pages to follow the preferred system theme. - * * **Default value**: `"auto"` - * * **Required**: *No* - * - * [Documentation](https://next-auth.js.org/configuration/options#theme) | [Pages documentation]("https://next-auth.js.org/configuration/pages") - */ - theme?: Theme - /** - * When set to `true` then all cookies set by NextAuth.js will only be accessible from HTTPS URLs. - * This option defaults to `false` on URLs that start with `http://` (e.g. http://localhost:3000) for developer convenience. - * You can manually set this option to `false` to disable this security feature and allow cookies - * to be accessible from non-secured URLs (this is not recommended). - * * **Default value**: `true` for HTTPS and `false` for HTTP sites - * * **Required**: No - * - * [Documentation](https://next-auth.js.org/configuration/options#usesecurecookies) - * - * - âš  **This is an advanced option.** Advanced options are passed the same way as basic options, - * but **may have complex implications** or side effects. - * You should **try to avoid using advanced options** unless you are very comfortable using them. - */ - useSecureCookies?: boolean - /** - * You can override the default cookie names and options for any of the cookies used by NextAuth.js. - * You can specify one or more cookies with custom properties, - * but if you specify custom options for a cookie you must provide all the options for that cookie. - * If you use this feature, you will likely want to create conditional behavior - * to support setting different cookies policies in development and production builds, - * as you will be opting out of the built-in dynamic policy. - * * **Default value**: `{}` - * * **Required**: No - * - * - âš  **This is an advanced option.** Advanced options are passed the same way as basic options, - * but **may have complex implications** or side effects. - * You should **try to avoid using advanced options** unless you are very comfortable using them. - * - * [Documentation](https://next-auth.js.org/configuration/options#cookies) | [Usage example](https://next-auth.js.org/configuration/options#example) - */ - cookies?: Partial -} - -/** - * Change the theme of the built-in pages. - * - * [Documentation](https://next-auth.js.org/configuration/options#theme) | - * [Pages](https://next-auth.js.org/configuration/pages) - */ -export type Theme = "auto" | "dark" | "light" - -/** - * Override any of the methods, and the rest will use the default logger. - * - * [Documentation](https://next-auth.js.org/configuration/options#logger) - */ -export interface LoggerInstance { - warn( - code: - | "JWT_AUTO_GENERATED_SIGNING_KEY" - | "JWT_AUTO_GENERATED_ENCRYPTION_KEY" - | "NEXTAUTH_URL" - ): void - error( - code: string, - /** - * Either an instance of (JSON serializable) Error - * or an object that contains some debug information. - * (Error is still available through `metadata.error`) - */ - metadata: Error | { error: Error; [key: string]: unknown } - ): void - debug(code: string, metadata: unknown): void -} - -/** - * Different tokens returned by OAuth Providers. - * Some of them are available with different casing, - * but they refer to the same value. - */ -export type TokenSet = TokenSetParameters - -/** - * Usually contains information about the provider being used - * and also extends `TokenSet`, which is different tokens returned by OAuth Providers. - */ -export interface DefaultAccount extends Partial { - /** - * This value depends on the type of the provider being used to create the account. - * - oauth: The OAuth account's id, returned from the `profile()` callback. - * - email: The user's email address. - * - credentials: `id` returned from the `authorize()` callback - */ - providerAccountId: string - /** id of the user this account belongs to. */ - userId: string - /** id of the provider used for this account */ - provider: string - /** Provider's type for this account */ - type: ProviderType -} - -export interface Account extends Record, DefaultAccount {} - -export interface DefaultProfile { - sub?: string - name?: string - email?: string - image?: string -} - -/** The OAuth profile returned from your provider */ -export interface Profile extends Record, DefaultProfile {} - -/** [Documentation](https://next-auth.js.org/configuration/callbacks) */ -export interface CallbacksOptions< - P extends Record = Profile, - A extends Record = Account -> { - /** - * Use this callback to control if a user is allowed to sign in. - * Returning true will continue the sign-in flow. - * Throwing an error or returning a string will stop the flow, and redirect the user. - * - * [Documentation](https://next-auth.js.org/configuration/callbacks#sign-in-callback) - */ - signIn(params: { - user: User - account: A - /** - * If OAuth provider is used, it contains the full - * OAuth profile returned by your provider. - */ - profile: P & Record - /** - * If Email provider is used, on the first call, it contains a - * `verificationRequest: true` property to indicate it is being triggered in the verification request flow. - * When the callback is invoked after a user has clicked on a sign in link, - * this property will not be present. You can check for the `verificationRequest` property - * to avoid sending emails to addresses or domains on a blocklist or to only explicitly generate them - * for email address in an allow list. - */ - email: { - verificationRequest?: boolean - } - /** If Credentials provider is used, it contains the user credentials */ - credentials: Record - }): Awaitable - /** - * This callback is called anytime the user is redirected to a callback URL (e.g. on signin or signout). - * By default only URLs on the same URL as the site are allowed, - * you can use this callback to customise that behaviour. - * - * [Documentation](https://next-auth.js.org/configuration/callbacks#redirect-callback) - */ - redirect(params: { - /** URL provided as callback URL by the client */ - url: string - /** Default base URL of site (can be used as fallback) */ - baseUrl: string - }): Awaitable - /** - * This callback is called whenever a session is checked. - * (Eg.: invoking the `/api/session` endpoint, using `useSession` or `getSession`) - * - * âš  By default, only a subset (email, name, imgage) - * of the token is returned for increased security. - * - * If you want to make something available you added to the token through the `jwt` callback, - * you have to explicitely forward it here to make it available to the client. - * - * [Documentation](https://next-auth.js.org/configuration/callbacks#session-callback) | - * [`jwt` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | - * [`useSession`](https://next-auth.js.org/getting-started/client#usesession) | - * [`getSession`](https://next-auth.js.org/getting-started/client#getsession) | - * - */ - session(params: { - session: Session - user: User - token: JWT - }): Awaitable - /** - * This callback is called whenever a JSON Web Token is created (i.e. at sign in) - * or updated (i.e whenever a session is accessed in the client). - * Its content is forwarded to the `session` callback, - * where you can control what should be returned to the client. - * Anything else will be kept from your front-end. - * - * âš  By default the JWT is signed, but not encrypted. - * - * [Documentation](https://next-auth.js.org/configuration/callbacks#jwt-callback) | - * [`session` callback](https://next-auth.js.org/configuration/callbacks#session-callback) - */ - jwt(params: { - token: JWT - user?: User - account?: A - profile?: P - isNewUser?: boolean - }): Awaitable -} - -/** [Documentation](https://next-auth.js.org/configuration/options#cookies) */ -export interface CookieOption { - name: string - options: { - httpOnly: boolean - sameSite: true | "strict" | "lax" | "none" - path?: string - secure: boolean - maxAge?: number - domain?: string - } -} - -/** [Documentation](https://next-auth.js.org/configuration/options#cookies) */ -export interface CookiesOptions { - sessionToken: CookieOption - callbackUrl: CookieOption - csrfToken: CookieOption - pkceCodeVerifier: CookieOption -} - -/** - * The various event callbacks you can register for from next-auth - * - * [Documentation](https://next-auth.js.org/configuration/events) - */ -export interface EventCallbacks { - /** - * If using a `credentials` type auth, the user is the raw response from your - * credential provider. - * For other providers, you'll get the User object from your adapter, the account, - * and an indicator if the user was new to your Adapter. - */ - signIn(message: { - user: User - account: Account - profile?: Profile - isNewUser?: boolean - }): Awaitable - /** - * The message object will contain one of these depending on - * if you use JWT or database persisted sessions: - * - `token`: The JWT token for this session. - * - `session`: The session object from your adapter that is being ended. - */ - signOut(message: { session: Session; token: JWT }): Awaitable - createUser(message: { user: User }): Awaitable - updateUser(message: { user: User }): Awaitable - linkAccount(message: { user: User; account: Account }): Awaitable - /** - * The message object will contain one of these depending on - * if you use JWT or database persisted sessions: - * - `token`: The JWT token for this session. - * - `session`: The session object from your adapter. - */ - session(message: { session: Session; token: JWT }): Awaitable -} - -export type EventType = keyof EventCallbacks - -/** [Documentation](https://next-auth.js.org/configuration/pages) */ -export interface PagesOptions { - signIn: string - signOut: string - /** Error code passed in query string as ?error= */ - error: string - verifyRequest: string - /** If set, new users will be directed here on first sign in */ - newUser: string -} - -export type ISODateString = string - -export interface DefaultSession extends Record { - user?: { - name?: string | null - email?: string | null - image?: string | null - } - expires: ISODateString -} - -/** - * Returned by `useSession`, `getSession`, returned by the `session` callback - * and also the shape received as a prop on the `SessionProvider` React Context - * - * [`useSession`](https://next-auth.js.org/getting-started/client#usesession) | - * [`getSession`](https://next-auth.js.org/getting-started/client#getsession) | - * [`SessionProvider`](https://next-auth.js.org/getting-started/client#sessionprovider) | - * [`session` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) - */ -export interface Session extends Record, DefaultSession {} - -/** [Documentation](https://next-auth.js.org/configuration/options#session) */ -export interface SessionOptions { - jwt: boolean - /** - * Relative time from now in seconds when to expire the session - * @default 2592000 // 30 days - */ - maxAge: number - /** - * How often the session should be updated in seconds. - * If set to `0`, session is updated every time. - * @default 86400 // 1 day - */ - updateAge: number -} - -export interface DefaultUser { - id: string - name?: string | null - email?: string | null - image?: string | null -} - -/** - * The shape of the returned object in the OAuth providers' `profile` callback, - * available in the `jwt` and `session` callbacks, - * or the second parameter of the `session` callback, when using a database. - * - * [`signIn` callback](https://next-auth.js.org/configuration/callbacks#sign-in-callback) | - * [`session` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | - * [`jwt` callback](https://next-auth.js.org/configuration/callbacks#jwt-callback) | - * [`profile` OAuth provider callback](https://next-auth.js.org/configuration/providers#using-a-custom-provider) - */ -export interface User extends Record, DefaultUser {} diff --git a/src/types/internals/cookies.d.ts b/src/types/internals/cookies.d.ts deleted file mode 100644 index dc6e14aa94..0000000000 --- a/src/types/internals/cookies.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// REVIEW: Is there any way to defer two types of strings? - -/** Stringified form of `JWT`. Extract the content with `jwt.decode` */ -export type JWTString = string - -/** If `options.session.jwt` is set to `true`, this is a stringified `JWT`. In case of a database persisted session, this is the `sessionToken` of the session in the database.. */ -export type SessionToken = T extends "jwt" - ? JWTString - : string diff --git a/src/types/internals/index.d.ts b/src/types/internals/index.d.ts index 35e8bd1c0a..ef8ddc60c5 100644 --- a/src/types/internals/index.d.ts +++ b/src/types/internals/index.d.ts @@ -8,9 +8,9 @@ import { SessionOptions, Theme, } from ".." -import { Provider } from "../providers" -import { JWTOptions } from "../jwt" -import { Adapter } from "../adapters" +import { Provider } from "../../providers" +import { JWTOptions } from "../../jwt" +import { Adapter } from "../../adapters" export type InternalProvider = Provider & { signinUrl: string @@ -43,7 +43,7 @@ export interface InternalOptions< pages: Partial jwt: JWTOptions events: Partial - adapter: Adapter + adapter?: Adapter callbacks: CallbacksOptions cookies: CookiesOptions callbackUrl: string diff --git a/src/types/react-client.d.ts b/src/types/react-client.d.ts deleted file mode 100644 index 9d0f67daea..0000000000 --- a/src/types/react-client.d.ts +++ /dev/null @@ -1,178 +0,0 @@ -import * as React from "react" -import { IncomingMessage } from "http" -import { Session } from "." -import { ProviderType } from "./providers" -import { SessionContextValue } from "./internals/react" - -export interface CtxOrReq { - req?: IncomingMessage - ctx?: { req: IncomingMessage } -} - -/*************** - * Session types - **************/ - -export type GetSessionOptions = CtxOrReq & { - event?: "storage" | "timer" | "hidden" | string - triggerEvent?: boolean -} - -export interface UseSessionOptions { - required: R - /** Defaults to `signIn` */ - action?(): void -} - -/** - * React Hook that gives you access - * to the logged in user's session data. - * - * [Documentation](https://next-auth.js.org/getting-started/client#usesession) - */ -export function useSession( - options?: UseSessionOptions -): SessionContextValue - -export function getSession(options?: GetSessionOptions): Promise - -/******************* - * CSRF Token types - ******************/ - -/** - * Returns the current Cross Site Request Forgery Token (CSRF Token) - * required to make POST requests (e.g. for signing in and signing out). - * You likely only need to use this if you are not using the built-in - * `signIn()` and `signOut()` methods. - * - * [Documentation](https://next-auth.js.org/getting-started/client#getcsrftoken) - */ -export function getCsrfToken(ctxOrReq?: CtxOrReq): Promise - -/****************** - * Providers types - *****************/ - -export interface ClientSafeProvider { - id: string - name: string - type: ProviderType - signinUrl: string - callbackUrl: string -} - -/** - * It calls `/api/auth/providers` and returns - * a list of the currently configured authentication providers. - * It can be useful if you are creating a dynamic custom sign in page. - * - * [Documentation](https://next-auth.js.org/getting-started/client#getproviders) - */ -export function getProviders(): Promise | null> - -/**************** - * Sign in types - ***************/ - -export type RedirectableProvider = "email" | "credentials" - -export type SignInProvider = RedirectableProvider | string | undefined - -export interface SignInOptions extends Record { - /** - * Defaults to the current URL. - * @docs https://next-auth.js.org/getting-started/client#specifying-a-callbackurl - */ - callbackUrl?: string - /** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option */ - redirect?: boolean -} - -export interface SignInResponse { - error: string | undefined - status: number - ok: boolean - url: string | null -} - -/** Match `inputType` of `new URLSearchParams(inputType)` */ -export type SignInAuthorisationParams = - | string - | string[][] - | Record - | URLSearchParams - -/** - * Client-side method to initiate a signin flow - * or send the user to the signin page listing all possible providers. - * Automatically adds the CSRF token to the request. - * - * [Documentation](https://next-auth.js.org/getting-started/client#signin) - */ -export function signIn

( - provider?: P, - options?: SignInOptions, - authorizationParams?: SignInAuthorisationParams -): Promise< - P extends RedirectableProvider ? SignInResponse | undefined : undefined -> - -/**************** - * Sign out types - ****************/ - -/** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */ -export interface SignOutResponse { - url: string -} - -export interface SignOutParams { - /** @docs https://next-auth.js.org/getting-started/client#specifying-a-callbackurl-1 */ - callbackUrl?: string - /** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */ - redirect?: R -} - -/** - * Signs the user out, by removing the session cookie. - * Automatically adds the CSRF token to the request. - * - * [Documentation](https://next-auth.js.org/getting-started/client#signout) - */ -export function signOut( - params?: SignOutParams -): Promise - -/************************ - * SessionProvider types - ***********************/ - -/** @docs: https://next-auth.js.org/getting-started/client#options */ -export interface SessionProviderProps { - session?: Session - baseUrl?: string - basePath?: string - /** - * The amount of time (in seconds) after a session should be considered stale. - * If set to `0` (default), the session will never be re-fetched. - */ - staleTime?: number - /** - * A time interval (in seconds) after which the session will be re-fetched. - * If set to `0` (default), the session is not polled. - */ - refetchInterval?: number -} - -/** - * Provider to wrap the app in to make session data available globally. - * Can also be used to throttle the number of requests to the endpoint - * `/api/auth/session`. - * - * [Documentation](https://next-auth.js.org/getting-started/client#sessionprovider) - */ -export const SessionProvider: React.FC From 0274bb290548a7fe837f6ec4e136e9412299f216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 18:53:12 +0200 Subject: [PATCH 33/62] refactor: fix some imports --- package.json | 2 +- src/providers/oauth.ts | 2 +- src/react.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 21b19dfafc..150217ac05 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "scripts": { "build": "npm run build:js && npm run build:css", - "clean": "rm -rf client css dist lib providers server types index.d.ts index.js jwt.d.ts jwt.js react.d.ts react.js", + "clean": "rm -rf client css dist lib providers server types index.d.ts index.js adapters.d.ts adapters.js jwt.d.ts jwt.js react.d.ts react.js", "build:js": "npm run clean && tsc", "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js", "dev:setup": "npm i && npm run build:css && cd app && npm i", diff --git a/src/providers/oauth.ts b/src/providers/oauth.ts index 6edad65a49..1cab91a2bd 100644 --- a/src/providers/oauth.ts +++ b/src/providers/oauth.ts @@ -1,5 +1,5 @@ import { CommonProviderOptions } from "../providers" -import { Profile, TokenSet, User } from "../types" +import { Profile, TokenSet, User } from ".." import { Awaitable } from "../types/internals/utils" import { diff --git a/src/react.tsx b/src/react.tsx index b7ec35a36e..01a222fed8 100644 --- a/src/react.tsx +++ b/src/react.tsx @@ -11,7 +11,7 @@ import * as React from "react" import _logger, { proxyLogger } from "./lib/logger" import parseUrl from "./lib/parse-url" -import { Session } from "./types" +import { Session } from "." import { ProviderType } from "./providers" import { BroadcastChannel, From fc85e391ca5b7216404be2e1867f59eec01b1e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:06:24 +0200 Subject: [PATCH 34/62] refactor(ts): move error module into server --- src/lib/logger.js | 2 +- src/{ => server}/errors.ts | 4 ++-- src/server/index.ts | 2 +- src/server/lib/callback-handler.ts | 2 +- src/server/lib/oauth/callback.js | 2 +- tsconfig.json | 2 ++ 6 files changed, 8 insertions(+), 6 deletions(-) rename src/{ => server}/errors.ts (96%) diff --git a/src/lib/logger.js b/src/lib/logger.js index d7b155f610..6ed169bafb 100644 --- a/src/lib/logger.js +++ b/src/lib/logger.js @@ -1,4 +1,4 @@ -import { UnknownError } from "../errors" +import { UnknownError } from "../server/errors" /** Makes sure that error is always serializable */ function formatError(o) { diff --git a/src/errors.ts b/src/server/errors.ts similarity index 96% rename from src/errors.ts rename to src/server/errors.ts index 987083b2a3..4281ca38a8 100644 --- a/src/errors.ts +++ b/src/server/errors.ts @@ -1,5 +1,5 @@ -import { EventCallbacks, LoggerInstance } from "." -import { Adapter } from "./adapters" +import { EventCallbacks, LoggerInstance } from ".." +import { Adapter } from "../adapters" /** * Same as the default `Error`, but it is JSON serializable. diff --git a/src/server/index.ts b/src/server/index.ts index c1427b7790..8f018ea3e4 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -10,7 +10,7 @@ import renderPage from "./pages" import callbackUrlHandler from "./lib/callback-url-handler" import extendRes from "./lib/extend-res" import csrfTokenHandler from "./lib/csrf-token-handler" -import { eventsErrorHandler, adapterErrorHandler } from "../errors" +import { eventsErrorHandler, adapterErrorHandler } from "./errors" import { NextApiRequest, NextApiResponse } from "next" import { NextAuthOptions } from ".." import { diff --git a/src/server/lib/callback-handler.ts b/src/server/lib/callback-handler.ts index ea3fef49ab..1ea00d519e 100644 --- a/src/server/lib/callback-handler.ts +++ b/src/server/lib/callback-handler.ts @@ -1,4 +1,4 @@ -import { AccountNotLinkedError } from "../../errors" +import { AccountNotLinkedError } from "../errors" import { fromDate } from "./utils" import { randomBytes, randomUUID } from "crypto" import { InternalOptions } from "../../types/internals" diff --git a/src/server/lib/oauth/callback.js b/src/server/lib/oauth/callback.js index 4bd3de817a..6b36797474 100644 --- a/src/server/lib/oauth/callback.js +++ b/src/server/lib/oauth/callback.js @@ -2,7 +2,7 @@ import { openidClient } from "./client" import { oAuth1Client } from "./client-legacy" import { getState } from "./state-handler" import { usePKCECodeVerifier } from "./pkce-handler" -import { OAuthCallbackError } from "../../../errors" +import { OAuthCallbackError } from "../../errors" import { TokenSet } from "openid-client" /** @type {import("src/types/internals").NextAuthApiHandler} */ diff --git a/tsconfig.json b/tsconfig.json index d63bcf3bc8..1bee5f3143 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,8 @@ "declaration": true, }, "exclude": [ + "./*.js", + "./*.d.ts", "app", "types", "**/tests", From aef779d8d8f7769139353b0602f91e332cdcbacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:16:32 +0200 Subject: [PATCH 35/62] fix(ts): add type to .js providers --- src/providers/42.js | 1 + src/providers/apple.js | 1 + src/providers/atlassian.js | 1 + src/providers/azure-ad-b2c.js | 1 + src/providers/azure-ad.js | 1 + src/providers/battlenet.js | 1 + src/providers/box.js | 1 + src/providers/bungie.js | 1 + src/providers/cognito.js | 1 + src/providers/coinbase.js | 1 + src/providers/discord.js | 1 + src/providers/dropbox.js | 1 + src/providers/eveonline.js | 1 + src/providers/facebook.js | 2 +- src/providers/faceit.js | 1 + src/providers/foursquare.js | 1 + src/providers/freshbooks.js | 36 ++++++++++++++++--------------- src/providers/fusionauth.js | 1 + src/providers/github.js | 1 + src/providers/gitlab.js | 1 + src/providers/identity-server4.js | 2 +- src/providers/instagram.js | 1 + src/providers/kakao.js | 1 + src/providers/line.js | 1 + src/providers/linkedin.js | 1 + src/providers/mailchimp.js | 1 + src/providers/mailru.js | 1 + src/providers/medium.js | 1 + src/providers/naver.js | 1 + src/providers/netlify.js | 1 + src/providers/okta.js | 1 + src/providers/onelogin.js | 2 +- src/providers/osso.js | 1 + src/providers/reddit.js | 1 + src/providers/salesforce.js | 1 + src/providers/slack.js | 1 + src/providers/spotify.js | 1 + src/providers/strava.js | 1 + src/providers/twitch.js | 2 +- src/providers/twitter.js | 1 + src/providers/vk.js | 1 + src/providers/wordpress.js | 1 + src/providers/workos.js | 1 + src/providers/yandex.js | 1 + src/providers/zoho.js | 1 + src/providers/zoom.js | 1 + 46 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/providers/42.js b/src/providers/42.js index aaa7e5e01b..a479df0c54 100644 --- a/src/providers/42.js +++ b/src/providers/42.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function FortyTwo(options) { return { id: "42-school", diff --git a/src/providers/apple.js b/src/providers/apple.js index c84b74839b..f0f92cb003 100644 --- a/src/providers/apple.js +++ b/src/providers/apple.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Apple(options) { return { id: "apple", diff --git a/src/providers/atlassian.js b/src/providers/atlassian.js index cb8d0aea97..bc8b9456ac 100644 --- a/src/providers/atlassian.js +++ b/src/providers/atlassian.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Atlassian(options) { return { id: "atlassian", diff --git a/src/providers/azure-ad-b2c.js b/src/providers/azure-ad-b2c.js index 572ba5da88..ae909b8aaa 100644 --- a/src/providers/azure-ad-b2c.js +++ b/src/providers/azure-ad-b2c.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function AzureADB2C(options) { const { tenantName, primaryUserFlow } = options diff --git a/src/providers/azure-ad.js b/src/providers/azure-ad.js index b3ad817b23..539e841b7f 100644 --- a/src/providers/azure-ad.js +++ b/src/providers/azure-ad.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function AzureAD(options) { const tenant = options.tenantId ?? "common" diff --git a/src/providers/battlenet.js b/src/providers/battlenet.js index 186fd62f2a..349790a03d 100644 --- a/src/providers/battlenet.js +++ b/src/providers/battlenet.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function BattleNet(options) { const { region } = options const base = diff --git a/src/providers/box.js b/src/providers/box.js index 3953e8c4c8..da0386bf7c 100644 --- a/src/providers/box.js +++ b/src/providers/box.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Box(options) { return { id: "box", diff --git a/src/providers/bungie.js b/src/providers/bungie.js index 090d101ccf..dc6c998fa2 100644 --- a/src/providers/bungie.js +++ b/src/providers/bungie.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Bungie(options) { return { id: "bungie", diff --git a/src/providers/cognito.js b/src/providers/cognito.js index 9b903b7a77..78f3cb59c7 100644 --- a/src/providers/cognito.js +++ b/src/providers/cognito.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Cognito(options) { return { id: "cognito", diff --git a/src/providers/coinbase.js b/src/providers/coinbase.js index c32876a941..1a2cb1d4a0 100644 --- a/src/providers/coinbase.js +++ b/src/providers/coinbase.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Coinbase(options) { return { id: "coinbase", diff --git a/src/providers/discord.js b/src/providers/discord.js index 067d18fc36..3065e8f336 100644 --- a/src/providers/discord.js +++ b/src/providers/discord.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Discord(options) { return { id: "discord", diff --git a/src/providers/dropbox.js b/src/providers/dropbox.js index 76d75d77c2..c26bbf3d83 100644 --- a/src/providers/dropbox.js +++ b/src/providers/dropbox.js @@ -27,6 +27,7 @@ * - [Dropbox Documentation](https://developers.dropbox.com/oauth-guide) * - [Configuration](https://www.dropbox.com/developers/apps) */ +/** @type {import(".").OAuthProvider} */ export default function Dropbox(options) { return { id: "dropbox", diff --git a/src/providers/eveonline.js b/src/providers/eveonline.js index 10ef311ffa..f09bde30a8 100644 --- a/src/providers/eveonline.js +++ b/src/providers/eveonline.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function EVEOnline(options) { return { id: "eveonline", diff --git a/src/providers/facebook.js b/src/providers/facebook.js index 891e71b179..e2c2e53028 100644 --- a/src/providers/facebook.js +++ b/src/providers/facebook.js @@ -1,4 +1,4 @@ -/** @type {import("src/providers").OAuthProvider} */ +/** @type {import(".").OAuthProvider} */ export default function Facebook(options) { return { id: "facebook", diff --git a/src/providers/faceit.js b/src/providers/faceit.js index 90483d2780..503d2823cf 100644 --- a/src/providers/faceit.js +++ b/src/providers/faceit.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function FACEIT(options) { return { id: "faceit", diff --git a/src/providers/foursquare.js b/src/providers/foursquare.js index 2318c36986..86c0cc322e 100644 --- a/src/providers/foursquare.js +++ b/src/providers/foursquare.js @@ -1,4 +1,5 @@ /** @type {import("src/providers").OAuthProvider} */ +/** @type {import(".").OAuthProvider} */ export default function Foursquare(options) { const { apiVersion = "20210801" } = options return { diff --git a/src/providers/freshbooks.js b/src/providers/freshbooks.js index 7045eb7807..6301008f06 100644 --- a/src/providers/freshbooks.js +++ b/src/providers/freshbooks.js @@ -1,20 +1,22 @@ +/** @type {import(".").OAuthProvider} */ export default function Freshbooks(options) { return { - id: 'freshbooks', - name: 'Freshbooks', - type: 'oauth', - version: '2.0', - params: { grant_type: 'authorization_code' }, - accessTokenUrl: 'https://api.freshbooks.com/auth/oauth/token', - authorizationUrl: 'https://auth.freshbooks.com/service/auth/oauth/authorize?response_type=code', - profileUrl: 'https://api.freshbooks.com/auth/api/v1/users/me', - async profile(profile) { - return { - id: profile.response.id, - name: `${profile.response.first_name} ${profile.response.last_name}`, - email: profile.response.email, - }; - }, - ...options - }; + id: "freshbooks", + name: "Freshbooks", + type: "oauth", + version: "2.0", + params: { grant_type: "authorization_code" }, + accessTokenUrl: "https://api.freshbooks.com/auth/oauth/token", + authorizationUrl: + "https://auth.freshbooks.com/service/auth/oauth/authorize?response_type=code", + profileUrl: "https://api.freshbooks.com/auth/api/v1/users/me", + async profile(profile) { + return { + id: profile.response.id, + name: `${profile.response.first_name} ${profile.response.last_name}`, + email: profile.response.email, + } + }, + ...options, + } } diff --git a/src/providers/fusionauth.js b/src/providers/fusionauth.js index c916e0565a..83990744a6 100644 --- a/src/providers/fusionauth.js +++ b/src/providers/fusionauth.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function FusionAuth(options) { return { id: "fusionauth", diff --git a/src/providers/github.js b/src/providers/github.js index 55505fc489..5ac5d2bcbe 100644 --- a/src/providers/github.js +++ b/src/providers/github.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function GitHub(options) { return { id: "github", diff --git a/src/providers/gitlab.js b/src/providers/gitlab.js index 7ea4c2cbe9..318d646d4f 100644 --- a/src/providers/gitlab.js +++ b/src/providers/gitlab.js @@ -1,4 +1,5 @@ /** @type {import("src/providers").OAuthProvider} */ +/** @type {import(".").OAuthProvider} */ export default function GitLab(options) { return { id: "gitlab", diff --git a/src/providers/identity-server4.js b/src/providers/identity-server4.js index 6ddd461613..b105712b10 100644 --- a/src/providers/identity-server4.js +++ b/src/providers/identity-server4.js @@ -1,4 +1,4 @@ -/** @return {import("src/providers").OAuthConfig} */ +/** @type {import(".").OAuthProvider} */ export default function IdentityServer4(options) { return { id: "identity-server4", diff --git a/src/providers/instagram.js b/src/providers/instagram.js index 7a1775ad0f..ac16c0e22a 100644 --- a/src/providers/instagram.js +++ b/src/providers/instagram.js @@ -24,6 +24,7 @@ * ``` * [NextAuth.js Documentation](https://next-auth.js.org/providers/instagram) | [Instagram Documentation](https://developers.facebook.com/docs/instagram-basic-display-api/getting-started) | [Configuration](https://developers.facebook.com/apps) */ +/** @type {import(".").OAuthProvider} */ export default function Instagram(options) { return { id: "instagram", diff --git a/src/providers/kakao.js b/src/providers/kakao.js index f72acbfced..834642fbd6 100644 --- a/src/providers/kakao.js +++ b/src/providers/kakao.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Kakao(options) { return { id: "kakao", diff --git a/src/providers/line.js b/src/providers/line.js index d3daeb38e9..27c74eddb1 100644 --- a/src/providers/line.js +++ b/src/providers/line.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function LINE(options) { return { id: "line", diff --git a/src/providers/linkedin.js b/src/providers/linkedin.js index e92db8d8a9..16a898897a 100644 --- a/src/providers/linkedin.js +++ b/src/providers/linkedin.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function LinkedIn(options) { return { id: "linkedin", diff --git a/src/providers/mailchimp.js b/src/providers/mailchimp.js index 1705d7a32b..9b815e4a92 100644 --- a/src/providers/mailchimp.js +++ b/src/providers/mailchimp.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Mailchimp(options) { return { id: "mailchimp", diff --git a/src/providers/mailru.js b/src/providers/mailru.js index c9db73581e..eee3cfd5fe 100644 --- a/src/providers/mailru.js +++ b/src/providers/mailru.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function MailRu(options) { return { id: "mailru", diff --git a/src/providers/medium.js b/src/providers/medium.js index fcb72087af..4ec8792ff0 100644 --- a/src/providers/medium.js +++ b/src/providers/medium.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Medium(options) { return { id: "medium", diff --git a/src/providers/naver.js b/src/providers/naver.js index b1a1979cfb..2b2c7a134b 100644 --- a/src/providers/naver.js +++ b/src/providers/naver.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Naver(options) { return { id: "naver", diff --git a/src/providers/netlify.js b/src/providers/netlify.js index 48b4f79316..7c31aed0bb 100644 --- a/src/providers/netlify.js +++ b/src/providers/netlify.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Netlify(options) { return { id: "netlify", diff --git a/src/providers/okta.js b/src/providers/okta.js index cf1c1962f2..de7e4abbf9 100644 --- a/src/providers/okta.js +++ b/src/providers/okta.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Okta(options) { return { id: "okta", diff --git a/src/providers/onelogin.js b/src/providers/onelogin.js index 762c57a9dd..c8593ae661 100644 --- a/src/providers/onelogin.js +++ b/src/providers/onelogin.js @@ -1,4 +1,4 @@ -/** @returns {import("src/providers").OAuthConfig} */ +/** @type {import(".").OAuthProvider} */ export default function OneLogin(options) { return { id: "onelogin", diff --git a/src/providers/osso.js b/src/providers/osso.js index 252104223e..6a1e001b5e 100644 --- a/src/providers/osso.js +++ b/src/providers/osso.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Osso(options) { return { id: "osso", diff --git a/src/providers/reddit.js b/src/providers/reddit.js index 8ce35d2a96..814b32e005 100644 --- a/src/providers/reddit.js +++ b/src/providers/reddit.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Reddit(options) { return { id: "reddit", diff --git a/src/providers/salesforce.js b/src/providers/salesforce.js index f4d07c1a66..40b1a0eca9 100644 --- a/src/providers/salesforce.js +++ b/src/providers/salesforce.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Salesforce(options) { return { id: "salesforce", diff --git a/src/providers/slack.js b/src/providers/slack.js index 7897ab4b74..ecc9fd8150 100644 --- a/src/providers/slack.js +++ b/src/providers/slack.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Slack(options) { return { id: "slack", diff --git a/src/providers/spotify.js b/src/providers/spotify.js index 4873153366..9bc29823fd 100644 --- a/src/providers/spotify.js +++ b/src/providers/spotify.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Spotify(options) { return { id: "spotify", diff --git a/src/providers/strava.js b/src/providers/strava.js index fb17fc8d46..4840930afc 100644 --- a/src/providers/strava.js +++ b/src/providers/strava.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Strava(options) { return { id: "strava", diff --git a/src/providers/twitch.js b/src/providers/twitch.js index d16443b5b4..f56e2a59fd 100644 --- a/src/providers/twitch.js +++ b/src/providers/twitch.js @@ -1,4 +1,4 @@ -/** @return {import("src/providers").OAuthConfig} */ +/** @type {import(".").OAuthProvider} */ export default function Twitch(options) { return { wellKnown: "https://id.twitch.tv/oauth2/.well-known/openid-configuration", diff --git a/src/providers/twitter.js b/src/providers/twitter.js index d343cec5ff..199fdcf6d2 100644 --- a/src/providers/twitter.js +++ b/src/providers/twitter.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Twitter(options) { return { id: "twitter", diff --git a/src/providers/vk.js b/src/providers/vk.js index e56e5d23b5..8530e1e4b8 100644 --- a/src/providers/vk.js +++ b/src/providers/vk.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function VK(options) { const apiVersion = "5.126" // https://vk.com/dev/versions diff --git a/src/providers/wordpress.js b/src/providers/wordpress.js index aedbd53239..22a7288554 100644 --- a/src/providers/wordpress.js +++ b/src/providers/wordpress.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function WordPress(options) { return { id: "wordpress", diff --git a/src/providers/workos.js b/src/providers/workos.js index 90d84f63ae..d5d6378b4b 100644 --- a/src/providers/workos.js +++ b/src/providers/workos.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function WorkOS(options) { const { issuer = "https://api.workos.com/" } = options diff --git a/src/providers/yandex.js b/src/providers/yandex.js index 8edf8cc0c2..3b9cdf6477 100644 --- a/src/providers/yandex.js +++ b/src/providers/yandex.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Yandex(options) { return { id: "yandex", diff --git a/src/providers/zoho.js b/src/providers/zoho.js index 5136bc2787..27c3eca835 100644 --- a/src/providers/zoho.js +++ b/src/providers/zoho.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Zoho(options) { return { id: "zoho", diff --git a/src/providers/zoom.js b/src/providers/zoom.js index 0c58305c05..0f8f442317 100644 --- a/src/providers/zoom.js +++ b/src/providers/zoom.js @@ -1,3 +1,4 @@ +/** @type {import(".").OAuthProvider} */ export default function Zoom(options) { return { id: "zoom", From c22316d1bef9c0f615e1ad67c39abf82c7a13bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:16:44 +0200 Subject: [PATCH 36/62] chore: rename adapters.ts to adapters.d.ts --- src/{adapters.ts => adapters.d.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{adapters.ts => adapters.d.ts} (100%) diff --git a/src/adapters.ts b/src/adapters.d.ts similarity index 100% rename from src/adapters.ts rename to src/adapters.d.ts From 53cdaffb5b6564f3e448f3d411a207795219600f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:20:00 +0200 Subject: [PATCH 37/62] fix: update exports field --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 150217ac05..7c76d29257 100644 --- a/package.json +++ b/package.json @@ -25,10 +25,10 @@ "import": "./index.js" }, "./jwt": { - "import": "./lib/jwt.js" + "import": "./jwt.js" }, "./react": { - "import": "./client/react.js" + "import": "./react.js" }, "./providers/*": { "import": "./providers/*.js" From c8aeae27f8edc8ef087b4ab1c6c3b50327b0343d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:31:24 +0200 Subject: [PATCH 38/62] chore: add files that should end up on npm --- package.json | 11 ++++++++++- src/lib/parse-url.js | 23 ----------------------- 2 files changed, 10 insertions(+), 24 deletions(-) delete mode 100644 src/lib/parse-url.js diff --git a/package.json b/package.json index 7c76d29257..9a53e9990a 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,16 @@ }, "files": [ "dist", - "types" + "lib", + "index.d.ts", + "index.js", + "adapters.d.ts", + "jwt.d.ts", + "jwt.js", + "react.d.ts", + "react.js", + "providers", + "server" ], "license": "ISC", "dependencies": { diff --git a/src/lib/parse-url.js b/src/lib/parse-url.js deleted file mode 100644 index eca4eace6c..0000000000 --- a/src/lib/parse-url.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Simple universal (client/server) function to split host and path. - * We use this rather than a library because we need to use the same logic both - * client and server side and we only need to parse out the host and path, while - * supporting a default value, so a simple split is sufficent. - */ -export default function parseUrl(url) { - // Default values - const defaultHost = "http://localhost:3000"; - const defaultPath = "/api/auth"; - if (!url) { - url = `${defaultHost}${defaultPath}`; - } - // Default to HTTPS if no protocol explictly specified - const protocol = url.startsWith("http:") ? "http" : "https"; - // Normalize URLs by stripping protocol and no trailing slash - url = url.replace(/^https?:\/\//, "").replace(/\/$/, ""); - // Simple split based on first / - const [_host, ..._path] = url.split("/"); - const baseUrl = _host ? `${protocol}://${_host}` : defaultHost; - const basePath = _path.length > 0 ? `/${_path.join("/")}` : defaultPath; - return { baseUrl, basePath }; -} From 367eb911dcac6a31016d9e7b72839e3e73339fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:58:57 +0200 Subject: [PATCH 39/62] chore: add stricter lib checking --- package-lock.json | 33 ++++++++++++++++++++++++++------- package.json | 3 ++- tsconfig.json | 1 - 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 56c0e9fd0f..670d6b7167 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,8 @@ "@testing-library/user-event": "^13.1.9", "@types/nodemailer": "^6.4.4", "@types/oauth": "^0.9.1", - "@types/react": "^17.0.18", + "@types/react": "^17.0.19", + "@types/react-dom": "^17.0.9", "@typescript-eslint/eslint-plugin": "^4.29.2", "@typescript-eslint/parser": "^4.29.2", "autoprefixer": "^10.2.6", @@ -3539,9 +3540,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.18", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.18.tgz", - "integrity": "sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg==", + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.19.tgz", + "integrity": "sha512-sX1HisdB1/ZESixMTGnMxH9TDe8Sk709734fEQZzCV/4lSu9kJCPbo2PbTRoZM+53Pp0P10hYVyReUueGwUi4A==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -3549,6 +3550,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", + "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -19882,9 +19892,9 @@ "dev": true }, "@types/react": { - "version": "17.0.18", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.18.tgz", - "integrity": "sha512-YTLgu7oS5zvSqq49X5Iue5oAbVGhgPc5Au29SJC4VeE17V6gASoOxVkUDy9pXFMRFxCWCD9fLeweNFizo3UzOg==", + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.19.tgz", + "integrity": "sha512-sX1HisdB1/ZESixMTGnMxH9TDe8Sk709734fEQZzCV/4lSu9kJCPbo2PbTRoZM+53Pp0P10hYVyReUueGwUi4A==", "dev": true, "requires": { "@types/prop-types": "*", @@ -19892,6 +19902,15 @@ "csstype": "^3.0.2" } }, + "@types/react-dom": { + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", + "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", diff --git a/package.json b/package.json index 9a53e9990a..8386adc6f2 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,8 @@ "@testing-library/user-event": "^13.1.9", "@types/nodemailer": "^6.4.4", "@types/oauth": "^0.9.1", - "@types/react": "^17.0.18", + "@types/react": "^17.0.19", + "@types/react-dom": "^17.0.9", "@typescript-eslint/eslint-plugin": "^4.29.2", "@typescript-eslint/parser": "^4.29.2", "autoprefixer": "^10.2.6", diff --git a/tsconfig.json b/tsconfig.json index 1bee5f3143..a10743376e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,6 @@ "target": "es2019", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, - "skipLibCheck": true, "strict": false, "forceConsistentCasingInFileNames": true, "esModuleInterop": true, From 14b6d2252afd1b6d15214831ccdae01a4f5e43e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 19:59:20 +0200 Subject: [PATCH 40/62] refactor(ts): remove unnecessary files, fix imports --- src/adapters.d.ts | 2 +- src/index.ts | 2 +- src/jwt.ts | 2 +- src/lib/client.ts | 3 +- src/providers/credentials.ts | 3 +- src/providers/email.ts | 2 +- src/providers/oauth.ts | 2 +- .../lib/oauth/{callback.js => callback.ts} | 38 +++++++++++++---- src/server/lib/oauth/pkce-handler.js | 3 +- src/types/internals/env.d.ts | 11 ----- src/types/internals/index.d.ts | 15 ++++--- src/types/internals/next.d.ts | 40 ------------------ src/types/internals/oauth.d.ts | 18 -------- src/types/internals/react.d.ts | 37 ---------------- src/types/internals/utils.d.ts | 42 ------------------- 15 files changed, 50 insertions(+), 170 deletions(-) rename src/server/lib/oauth/{callback.js => callback.ts} (81%) delete mode 100644 src/types/internals/env.d.ts delete mode 100644 src/types/internals/next.d.ts delete mode 100644 src/types/internals/react.d.ts delete mode 100644 src/types/internals/utils.d.ts diff --git a/src/adapters.d.ts b/src/adapters.d.ts index 8e50b8c223..7b768df889 100644 --- a/src/adapters.d.ts +++ b/src/adapters.d.ts @@ -1,5 +1,5 @@ import { Account, User } from "." -import { Awaitable } from "./types/internals/utils" +import { Awaitable } from "./types/internals" export interface AdapterUser extends User { id: string diff --git a/src/index.ts b/src/index.ts index a8337a2126..e9a07e34b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import { Adapter } from "./adapters" import { Provider, CredentialInput, ProviderType } from "./providers" -import { Awaitable } from "./types/internals/utils" +import { Awaitable } from "./types/internals" import { TokenSetParameters } from "openid-client" import { JWT, JWTOptions } from "./jwt" diff --git a/src/jwt.ts b/src/jwt.ts index 44f7bd1853..9779917a0b 100644 --- a/src/jwt.ts +++ b/src/jwt.ts @@ -1,7 +1,7 @@ import crypto from "crypto" import jose from "jose" import logger from "./lib/logger" -import { NextApiRequest } from "./types/internals/utils" +import { NextApiRequest } from "next" export interface DefaultJWT extends Record { name?: string | null diff --git a/src/lib/client.ts b/src/lib/client.ts index 9d80efc7e9..d975a1ecef 100644 --- a/src/lib/client.ts +++ b/src/lib/client.ts @@ -71,8 +71,7 @@ export function BroadcastChannel(name = "nextauth.message") { receive(onReceive: (message: BroadcastMessage) => void) { const handler = (event) => { if (event.key !== name) return - /** @type {import("types/internals/react").BroadcastMessage} */ - const message = JSON.parse(event.newValue) + const message: BroadcastMessage = JSON.parse(event.newValue) if (message?.event !== "session" || !message?.data) return onReceive(message) diff --git a/src/providers/credentials.ts b/src/providers/credentials.ts index 7ec89e3cfa..f5e9b85cb1 100644 --- a/src/providers/credentials.ts +++ b/src/providers/credentials.ts @@ -1,4 +1,5 @@ -import { Awaitable, NextApiRequest } from "../types/internals/utils" +import { Awaitable } from "../types/internals" +import { NextApiRequest } from "next" import { CommonProviderOptions } from "." import { User } from ".." diff --git a/src/providers/email.ts b/src/providers/email.ts index cfa3d61f1e..29b8358486 100644 --- a/src/providers/email.ts +++ b/src/providers/email.ts @@ -2,7 +2,7 @@ import { createTransport } from "nodemailer" import { CommonProviderOptions } from "." import { Options as SMTPConnectionOptions } from "nodemailer/lib/smtp-connection" -import { Awaitable } from "../types/internals/utils" +import { Awaitable } from "../types/internals" export interface EmailConfig extends CommonProviderOptions { type: "email" diff --git a/src/providers/oauth.ts b/src/providers/oauth.ts index 1cab91a2bd..216f7f9a69 100644 --- a/src/providers/oauth.ts +++ b/src/providers/oauth.ts @@ -1,6 +1,6 @@ import { CommonProviderOptions } from "../providers" import { Profile, TokenSet, User } from ".." -import { Awaitable } from "../types/internals/utils" +import { Awaitable } from "../types/internals" import { AuthorizationParameters, diff --git a/src/server/lib/oauth/callback.js b/src/server/lib/oauth/callback.ts similarity index 81% rename from src/server/lib/oauth/callback.js rename to src/server/lib/oauth/callback.ts index 6b36797474..565582eab0 100644 --- a/src/server/lib/oauth/callback.js +++ b/src/server/lib/oauth/callback.ts @@ -4,6 +4,8 @@ import { getState } from "./state-handler" import { usePKCECodeVerifier } from "./pkce-handler" import { OAuthCallbackError } from "../../errors" import { TokenSet } from "openid-client" +import { Account, LoggerInstance, Profile } from "src" +import { OAuthChecks, OAuthConfig } from "src/providers" /** @type {import("src/types/internals").NextAuthApiHandler} */ export default async function oAuthCallback(req, res) { @@ -28,12 +30,15 @@ export default async function oAuthCallback(req, res) { const client = await oAuth1Client(req.options) // Handle OAuth v1.x const { oauth_token, oauth_verifier } = req.query - const tokens = await client.getOAuthAccessToken( + // @ts-expect-error + const tokens: TokenSet = await client.getOAuthAccessToken( oauth_token, + // @ts-expect-error null, oauth_verifier ) - let profile = await client.get( + // @ts-expect-error + let profile: Profile = await client.get( provider.profileUrl, tokens.oauth_token, tokens.oauth_token_secret @@ -43,7 +48,7 @@ export default async function oAuthCallback(req, res) { profile = JSON.parse(profile) } - return getProfile({ profile, tokens, provider, logger }) + return await getProfile({ profile, tokens, provider, logger }) } catch (error) { logger.error("OAUTH_V1_GET_ACCESS_TOKEN_ERROR", error) throw error @@ -56,8 +61,7 @@ export default async function oAuthCallback(req, res) { /** @type {import("openid-client").TokenSet} */ let tokens - /** @type {import("src/providers").OAuthChecks} */ - const checks = { + const checks: OAuthChecks = { code_verifier: await usePKCECodeVerifier(req, res), state: getState(req), } @@ -102,20 +106,40 @@ export default async function oAuthCallback(req, res) { // TODO: Remove/extract to Apple provider? profile.user = JSON.parse(req.body.user ?? req.query.user ?? null) - return getProfile({ profile, provider, tokens, logger }) + return await getProfile({ profile, provider, tokens, logger }) } catch (error) { logger.error("OAUTH_CALLBACK_ERROR", { error, providerId: provider.id }) throw new OAuthCallbackError(error) } } +export interface GetProfileParams { + profile: Profile + tokens: TokenSet + provider: OAuthConfig + logger: LoggerInstance +} + +export interface GetProfileResult { + // @ts-expect-error + profile: ReturnType | null + account: Omit | null + OAuthProfile: Profile +} + /** * Returns profile, raw profile and auth provider details * @type {import("src/types/internals/oauth").GetProfile} */ -async function getProfile({ profile: OAuthProfile, tokens, provider, logger }) { +async function getProfile({ + profile: OAuthProfile, + tokens, + provider, + logger, +}: GetProfileParams): Promise { try { logger.debug("PROFILE_DATA", { OAuthProfile }) + // @ts-expect-error const profile = await provider.profile(OAuthProfile, tokens) profile.email = profile.email?.toLowerCase() // Return profile, raw profile and auth provider details diff --git a/src/server/lib/oauth/pkce-handler.js b/src/server/lib/oauth/pkce-handler.js index 0434eb6300..2bcfcbd909 100644 --- a/src/server/lib/oauth/pkce-handler.js +++ b/src/server/lib/oauth/pkce-handler.js @@ -1,5 +1,5 @@ import * as cookie from "../cookie" -import * as jwt from "../../../lib/jwt" +import * as jwt from "../../../jwt" import { generators } from "openid-client" const PKCE_LENGTH = 64 @@ -56,6 +56,7 @@ export async function createPKCE(req, res) { * Returns code_verifier if provider uses PKCE, * and clears the cookie afterwards. * @param {import("src/types/internals").NextAuthRequest} req + * @return {Promise} */ export async function usePKCECodeVerifier(req, res) { /** @type {import("src/providers").OAuthConfig} */ diff --git a/src/types/internals/env.d.ts b/src/types/internals/env.d.ts deleted file mode 100644 index a61d9ab45f..0000000000 --- a/src/types/internals/env.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -// See: https://stackoverflow.com/a/59499895/5364135 -export {} - -declare global { - export namespace NodeJS { - interface ProcessEnv extends NodeJS.ProcessEnv { - NEXTAUTH_URL?: string - VERCEL_URL?: string - } - } -} diff --git a/src/types/internals/index.d.ts b/src/types/internals/index.d.ts index ef8ddc60c5..ae973207e4 100644 --- a/src/types/internals/index.d.ts +++ b/src/types/internals/index.d.ts @@ -1,4 +1,5 @@ -import { Awaitable, NextApiRequest, NextApiResponse } from "./utils" +import { NextApiRequest, NextApiResponse } from "next" + import { CallbacksOptions, CookiesOptions, @@ -7,7 +8,7 @@ import { PagesOptions, SessionOptions, Theme, -} from ".." +} from "../.." import { Provider } from "../../providers" import { JWTOptions } from "../../jwt" import { Adapter } from "../../adapters" @@ -53,9 +54,11 @@ export interface NextAuthRequest extends NextApiRequest { options: InternalOptions } -export type NextAuthResponse = NextApiResponse +export type NextAuthResponse = NextApiResponse -export type NextAuthApiHandler = ( +export type NextAuthApiHandler = ( req: NextAuthRequest, - res: NextAuthResponse -) => Awaitable + res: NextAuthResponse +) => Awaitable + +export type Awaitable = T | PromiseLike diff --git a/src/types/internals/next.d.ts b/src/types/internals/next.d.ts deleted file mode 100644 index 5e39a008b8..0000000000 --- a/src/types/internals/next.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { IncomingMessage, ServerResponse } from "http" - -// ------------------------------------------------------ -// Types from next@10, -// see: https://github.com/microsoft/dtslint/issues/297 -// ------------------------------------------------------ -export interface NextApiRequest extends IncomingMessage { - query: { - [key: string]: string | string[] - } - cookies: { - [key: string]: string - } - body: any - env: any - preview?: boolean - previewData?: any -} - -export type Send = (body: T) => void - -export type NextApiResponse = ServerResponse & { - send: Send - json: Send - status: (statusCode: number) => NextApiResponse - redirect: ((url: string) => NextApiResponse) & - ((status: number, url: string) => NextApiResponse) - setPreviewData: ( - data: object | string, - options?: { - maxAge?: number - } - ) => NextApiResponse - clearPreviewData: () => NextApiResponse -} - -export type NextApiHandler = ( - req: NextApiRequest, - res: NextApiResponse -) => void | Promise diff --git a/src/types/internals/oauth.d.ts b/src/types/internals/oauth.d.ts index 708d3e083f..e69de29bb2 100644 --- a/src/types/internals/oauth.d.ts +++ b/src/types/internals/oauth.d.ts @@ -1,18 +0,0 @@ -import { OAuthConfig } from "../providers" -import { Profile, LoggerInstance, Account } from "../index" -import { TokenSet } from "openid-client" - -export interface GetProfileParams { - profile: Profile - tokens: TokenSet - provider: OAuthConfig - logger: LoggerInstance -} - -export interface GetProfileResult { - profile: ReturnType | null - account: Omit | null - OAuthProfile: Profile -} - -export type GetProfile = (params: GetProfileParams) => Promise diff --git a/src/types/internals/react.d.ts b/src/types/internals/react.d.ts deleted file mode 100644 index 57dd378355..0000000000 --- a/src/types/internals/react.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from "react" -import { Session } from ".." - -export interface BroadcastMessage { - event?: "session" - data?: { - trigger?: "signout" | "getSession" - } - clientId: string - timestamp: number -} - -export interface NextAuthConfig { - baseUrl: string - basePath: string - baseUrlServer: string - basePathServer: string - /** Stores last session response */ - _session?: Session | null - /** Used for timestamp since last sycned (in seconds) */ - _lastSync: number - /** - * Stores the `SessionProvider`'s session update method to be able to - * trigger session updates from places like `signIn` or `signOut` - */ - _getSession: any -} - -export type SessionContextValue = R extends true - ? - | { data: Session; status: "authenticated" } - | { data: null; status: "loading" } - : - | { data: Session; status: "authenticated" } - | { data: null; status: "unauthenticated" | "loading" } - -export type SessionContext = React.Context diff --git a/src/types/internals/utils.d.ts b/src/types/internals/utils.d.ts deleted file mode 100644 index 4f5fa07133..0000000000 --- a/src/types/internals/utils.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { IncomingMessage, ServerResponse } from "http" - -export type Awaitable = T | PromiseLike - -// ------------------------------------------------------ -// Types from next@10, -// see: https://github.com/microsoft/dtslint/issues/297 -// ------------------------------------------------------ -export interface NextApiRequest extends IncomingMessage { - query: { - [key: string]: string | string[] - } - cookies: { - [key: string]: string - } - body: any - env: any - preview?: boolean - previewData?: any -} - -export type Send = (body: T) => void - -export type NextApiResponse = ServerResponse & { - send: Send - json: Send - status: (statusCode: number) => NextApiResponse - redirect: ((url: string) => NextApiResponse) & - ((status: number, url: string) => NextApiResponse) - setPreviewData: ( - data: object | string, - options?: { - maxAge?: number - } - ) => NextApiResponse - clearPreviewData: () => NextApiResponse -} - -export type NextApiHandler = ( - req: NextApiRequest, - res: NextApiResponse -) => void | Promise From b0c9c6ca39b902e02f7d77777a1e2a5e323f2f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 20:04:42 +0200 Subject: [PATCH 41/62] chore: autocomplete env variables --- src/index.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/index.ts b/src/index.ts index e9a07e34b5..1456b2ae1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -479,3 +479,13 @@ export interface DefaultUser { * [`profile` OAuth provider callback](https://next-auth.js.org/configuration/providers#using-a-custom-provider) */ export interface User extends Record, DefaultUser {} + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace NodeJS { + interface ProcessEnv { + NEXTAUTH_URL?: string + VERCEL_URL?: string + } + } +} From 8c84def998dc818d13c8ed258a14bf30673569ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 20:06:44 +0200 Subject: [PATCH 42/62] fix: add css folder to npm files --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 8386adc6f2..dbd2c5cc68 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "files": [ "dist", "lib", + "css", "index.d.ts", "index.js", "adapters.d.ts", From fbd2d3693a2edf539b7e5845ee3756769b4a71d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 20:21:08 +0200 Subject: [PATCH 43/62] fix: fix CSS import/generation --- .gitignore | 1 - config/wrap-css.js | 13 ++++++------- package.json | 9 ++++----- src/css/index.js | 10 +++++----- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 75eb4aa906..f888b58984 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ node_modules # Build dirs .next /build -/dist /www/build # Generated files diff --git a/config/wrap-css.js b/config/wrap-css.js index e70dc7116f..d59d7892d2 100644 --- a/config/wrap-css.js +++ b/config/wrap-css.js @@ -5,14 +5,13 @@ // To work around this issue, this script is a manual step that wraps CSS in a // JavaScript file that has the compiled CSS embedded in it, and exports only // a function that returns the CSS as a string. -const fs = require('fs') -const path = require('path') +const fs = require("fs") +const path = require("path") -const pathToCssJs = path.join(__dirname, '../dist/css/index.js') -const pathToCss = path.join(__dirname, '../dist/css/index.css') - -const css = fs.readFileSync(pathToCss, 'utf8') +const pathToCss = path.join(__dirname, "../css/index.css") +const css = fs.readFileSync(pathToCss, "utf8") const cssWithEscapedQuotes = css.replace(/"/gm, '\\"') -const js = `module.exports = function() { return "${cssWithEscapedQuotes}" }` +const js = `module.exports = function() { return "${cssWithEscapedQuotes}" }` +const pathToCssJs = path.join(__dirname, "../css/index.js") fs.writeFileSync(pathToCssJs, js) diff --git a/package.json b/package.json index dbd2c5cc68..6a24e300a5 100644 --- a/package.json +++ b/package.json @@ -36,14 +36,14 @@ }, "scripts": { "build": "npm run build:js && npm run build:css", - "clean": "rm -rf client css dist lib providers server types index.d.ts index.js adapters.d.ts adapters.js jwt.d.ts jwt.js react.d.ts react.js", + "clean": "rm -rf client css lib providers server types index.d.ts index.js adapters.d.ts adapters.js jwt.d.ts jwt.js react.d.ts react.js", "build:js": "npm run clean && tsc", - "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir dist && node config/wrap-css.js", + "build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir . && node config/wrap-css.js", "dev:setup": "npm i && npm run build:css && cd app && npm i", "dev": "cd app && npm run dev", "watch": "npm run watch:js | npm run watch:css", - "watch:js": "babel --config-file ./config/babel.config.js --watch src --out-dir dist", - "watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir dist", + "watch:js": "tsc --watch", + "watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir .", "test": "jest --config ./config/jest.config.js", "test:ci": "npm run lint && npm run test -- --ci", "prepublishOnly": "npm run build", @@ -52,7 +52,6 @@ "website": "cd www && npm run start" }, "files": [ - "dist", "lib", "css", "index.d.ts", diff --git a/src/css/index.js b/src/css/index.js index a1021c3dc4..96eba6ca0b 100644 --- a/src/css/index.js +++ b/src/css/index.js @@ -1,11 +1,11 @@ // To support serverless targets (which don't work if you try to read in things // like CSS files at run time) this file is replaced in production builds with // a function that returns compiled CSS (embedded as a string in the function). -import fs from 'fs' -import path from 'path' +import fs from "fs" +import path from "path" -const pathToCss = path.join(process.cwd(), '/dist/css/index.css') +const pathToCss = path.join(process.cwd(), "/src/css/index.css") -export default function css () { - return fs.readFileSync(pathToCss, 'utf8') +export default function css() { + return fs.readFileSync(pathToCss, "utf8") } From 9fdf6173bfe22d45c35e6103dea1dbe9cf07e0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Tue, 24 Aug 2021 20:29:40 +0200 Subject: [PATCH 44/62] feat: log provider when authorization url error happens --- src/server/routes/signin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/routes/signin.js b/src/server/routes/signin.js index 322a94d320..32a29dac42 100644 --- a/src/server/routes/signin.js +++ b/src/server/routes/signin.js @@ -20,7 +20,7 @@ export default async function signin(req, res) { const authorizationUrl = await getAuthorizationUrl(req, res) return res.redirect(authorizationUrl) } catch (error) { - logger.error("SIGNIN_OAUTH_ERROR", error) + logger.error("SIGNIN_OAUTH_ERROR", { error, provider }) return res.redirect(`${baseUrl}${basePath}/error?error=OAuthSignin`) } } else if (provider.type === "email") { From 4ad7ec5bab582e84329f052a05197e46b84d8012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 25 Aug 2021 00:15:17 +0200 Subject: [PATCH 45/62] refactor(ts): turn pages into .tsx --- src/server/pages/{error.js => error.tsx} | 5 +---- src/server/pages/{index.js => index.ts} | 0 src/server/pages/{signin.js => signin.tsx} | 10 ++++------ src/server/pages/signout.js | 13 ------------- src/server/pages/signout.tsx | 11 +++++++++++ src/server/pages/verify-request.js | 11 ----------- src/server/pages/verify-request.tsx | 13 +++++++++++++ 7 files changed, 29 insertions(+), 34 deletions(-) rename src/server/pages/{error.js => error.tsx} (92%) rename src/server/pages/{index.js => index.ts} (100%) rename src/server/pages/{signin.js => signin.tsx} (93%) delete mode 100644 src/server/pages/signout.js create mode 100644 src/server/pages/signout.tsx delete mode 100644 src/server/pages/verify-request.js create mode 100644 src/server/pages/verify-request.tsx diff --git a/src/server/pages/error.js b/src/server/pages/error.tsx similarity index 92% rename from src/server/pages/error.js rename to src/server/pages/error.tsx index 15194f3ac5..6841e0aa03 100644 --- a/src/server/pages/error.js +++ b/src/server/pages/error.tsx @@ -1,6 +1,3 @@ -// @ts-check -import { h } from "preact" // eslint-disable-line no-unused-vars - /** * Renders an error page. * @param {{ @@ -10,7 +7,7 @@ import { h } from "preact" // eslint-disable-line no-unused-vars * res: import("src/types/internals").NextAuthResponse * }} params */ -export default function error({ baseUrl, basePath, error = "default", res }) { +export default function Error({ baseUrl, basePath, error = "default", res }) { const signinPageUrl = `${baseUrl}${basePath}/signin` const errors = { diff --git a/src/server/pages/index.js b/src/server/pages/index.ts similarity index 100% rename from src/server/pages/index.js rename to src/server/pages/index.ts diff --git a/src/server/pages/signin.js b/src/server/pages/signin.tsx similarity index 93% rename from src/server/pages/signin.js rename to src/server/pages/signin.tsx index ebccbd0176..994e78653c 100644 --- a/src/server/pages/signin.js +++ b/src/server/pages/signin.tsx @@ -1,6 +1,4 @@ -import { h } from "preact" // eslint-disable-line no-unused-vars - -export default function signin({ +export default function Signin({ csrfToken, providers, callbackUrl, @@ -44,7 +42,7 @@ export default function signin({

{error}

)} - {providersToRender.map((provider, i) => ( + {providersToRender.map((provider, i: number) => (
{provider.type === "oauth" && (
@@ -64,7 +62,7 @@ export default function signin({ {provider.type === "email" && ( -