use hashed password for authentication

This commit is contained in:
spencerwooo 2021-09-02 22:54:18 +01:00
parent 81b0e3bf3f
commit 1dca4cabf3
No known key found for this signature in database
GPG key ID: 24CD550268849CA0
4 changed files with 69 additions and 31 deletions

74
package-lock.json generated
View file

@ -14,6 +14,7 @@
"@fortawesome/react-fontawesome": "^0.1.14",
"@headlessui/react": "^1.4.0",
"axios": "^0.21.1",
"crypto-js": "^4.1.1",
"emoji-regex": "^9.2.2",
"next": "^11.1.0",
"preview-office-docs": "^1.0.2",
@ -34,6 +35,7 @@
"use-clipboard-copy": "^0.2.0"
},
"devDependencies": {
"@types/crypto-js": "^4.0.2",
"@types/prismjs": "^1.16.5",
"@types/react": "17.0.11",
"@types/react-copy-to-clipboard": "^5.0.0",
@ -443,6 +445,12 @@
"integrity": "sha512-Myxw//kzromB9yWgS8qYGuGVf91oBUUJpNvy5eM50sqvmKLbKjwLxohJnkWGTeeI9v9IBMtPLxz5Gc60FIfvCA==",
"dev": true
},
"node_modules/@types/crypto-js": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.0.2.tgz",
"integrity": "sha512-sCVniU+h3GcGqxOmng11BRvf9TfN9yIs8KKjB8C8d75W69cpTfZG80gau9yTx5SxF3gvHGbJhdESzzvnjtf3Og==",
"dev": true
},
"node_modules/@types/hast": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
@ -506,14 +514,12 @@
"node_modules/@types/prop-types": {
"version": "15.7.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
"dev": true
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
},
"node_modules/@types/react": {
"version": "17.0.11",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.11.tgz",
"integrity": "sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -560,8 +566,7 @@
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"node_modules/@types/unist": {
"version": "2.0.6",
@ -1549,6 +1554,11 @@
"node": "*"
}
},
"node_modules/crypto-js": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
},
"node_modules/css-unit-converter": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz",
@ -1602,8 +1612,7 @@
"node_modules/csstype": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
"integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==",
"dev": true
"integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw=="
},
"node_modules/damerau-levenshtein": {
"version": "1.0.7",
@ -5271,7 +5280,6 @@
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz",
"integrity": "sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==",
"dev": true,
"dependencies": {
"colorette": "^1.2.2",
"nanoid": "^3.1.23",
@ -6300,7 +6308,6 @@
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
"integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -7611,7 +7618,8 @@
"@headlessui/react": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.0.tgz",
"integrity": "sha512-C+FmBVF6YGvqcEI5fa2dfVbEaXr2RGR6Kw1E5HXIISIZEfsrH/yuCgsjWw5nlRF9vbCxmQ/EKs64GAdKeb8gCw=="
"integrity": "sha512-C+FmBVF6YGvqcEI5fa2dfVbEaXr2RGR6Kw1E5HXIISIZEfsrH/yuCgsjWw5nlRF9vbCxmQ/EKs64GAdKeb8gCw==",
"requires": {}
},
"@napi-rs/triples": {
"version": "1.0.3",
@ -7666,7 +7674,8 @@
"@next/react-refresh-utils": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-11.1.0.tgz",
"integrity": "sha512-g5DtFTpLTGa36iy9DuZawtJeitI11gysFGKPQQqy+mNbSFazguArcJ10gAYFlbqpIi4boUamWNI5mAoSPx3kog=="
"integrity": "sha512-g5DtFTpLTGa36iy9DuZawtJeitI11gysFGKPQQqy+mNbSFazguArcJ10gAYFlbqpIi4boUamWNI5mAoSPx3kog==",
"requires": {}
},
"@node-rs/helper": {
"version": "1.2.1",
@ -7708,6 +7717,12 @@
"integrity": "sha512-Myxw//kzromB9yWgS8qYGuGVf91oBUUJpNvy5eM50sqvmKLbKjwLxohJnkWGTeeI9v9IBMtPLxz5Gc60FIfvCA==",
"dev": true
},
"@types/crypto-js": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.0.2.tgz",
"integrity": "sha512-sCVniU+h3GcGqxOmng11BRvf9TfN9yIs8KKjB8C8d75W69cpTfZG80gau9yTx5SxF3gvHGbJhdESzzvnjtf3Og==",
"dev": true
},
"@types/hast": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
@ -7771,14 +7786,12 @@
"@types/prop-types": {
"version": "15.7.4",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
"dev": true
"integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
},
"@types/react": {
"version": "17.0.11",
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.11.tgz",
"integrity": "sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -7825,8 +7838,7 @@
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"@types/unist": {
"version": "2.0.6",
@ -7896,7 +7908,8 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
"dev": true,
"requires": {}
},
"acorn-node": {
"version": "1.8.2",
@ -7929,7 +7942,8 @@
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"requires": {}
},
"anser": {
"version": "1.4.9",
@ -8564,6 +8578,11 @@
"randomfill": "^1.0.3"
}
},
"crypto-js": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
"integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
},
"css-unit-converter": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz",
@ -8600,8 +8619,7 @@
"csstype": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
"integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==",
"dev": true
"integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw=="
},
"damerau-levenshtein": {
"version": "1.0.7",
@ -9059,7 +9077,8 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
"dev": true
"dev": true,
"requires": {}
},
"eslint-scope": {
"version": "5.1.1",
@ -9457,7 +9476,8 @@
"goober": {
"version": "2.0.41",
"resolved": "https://registry.npmjs.org/goober/-/goober-2.0.41.tgz",
"integrity": "sha512-kwjegMT5018zWydhOQlQneCgCtrKJaPsru7TaBWmTYV0nsMeUrM6L6O8JmNYb9UbPMgWcmtf+9p4Y3oJabIH1A=="
"integrity": "sha512-kwjegMT5018zWydhOQlQneCgCtrKJaPsru7TaBWmTYV0nsMeUrM6L6O8JmNYb9UbPMgWcmtf+9p4Y3oJabIH1A==",
"requires": {}
},
"graceful-fs": {
"version": "4.2.8",
@ -11347,7 +11367,6 @@
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.6.tgz",
"integrity": "sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A==",
"dev": true,
"requires": {
"colorette": "^1.2.2",
"nanoid": "^3.1.23",
@ -11415,7 +11434,8 @@
"preview-office-docs": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/preview-office-docs/-/preview-office-docs-1.0.2.tgz",
"integrity": "sha512-dVss4jWfVgZJcVskbOPV5ifpFokRYY1ZW54Z6DvwCg/HzNqq8rZw8yVM+nJAFmcFz6Zy7aY9n1/KhPDkm+Ky6Q=="
"integrity": "sha512-dVss4jWfVgZJcVskbOPV5ifpFokRYY1ZW54Z6DvwCg/HzNqq8rZw8yVM+nJAFmcFz6Zy7aY9n1/KhPDkm+Ky6Q==",
"requires": {}
},
"prismjs": {
"version": "1.24.1",
@ -12080,8 +12100,7 @@
"source-map-js": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
"integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
"dev": true
"integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug=="
},
"space-separated-tokens": {
"version": "1.1.5",
@ -12336,7 +12355,8 @@
"stylis-rule-sheet": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
"integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
"integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==",
"requires": {}
},
"supports-color": {
"version": "7.2.0",

View file

@ -16,6 +16,7 @@
"@fortawesome/react-fontawesome": "^0.1.14",
"@headlessui/react": "^1.4.0",
"axios": "^0.21.1",
"crypto-js": "^4.1.1",
"emoji-regex": "^9.2.2",
"next": "^11.1.0",
"preview-office-docs": "^1.0.2",
@ -36,6 +37,7 @@
"use-clipboard-copy": "^0.2.0"
},
"devDependencies": {
"@types/crypto-js": "^4.0.2",
"@types/prismjs": "^1.16.5",
"@types/react": "17.0.11",
"@types/react-copy-to-clipboard": "^5.0.0",

View file

@ -4,6 +4,7 @@ import { posix as pathPosix } from 'path'
import apiConfig from '../../config/api.json'
import siteConfig from '../../config/site.json'
import { compareHashedToken } from '../../utils/tools'
const basePath = pathPosix.resolve('/', apiConfig.base)
const encodePath = (path: string) => {
@ -75,11 +76,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const odProtectedToken = await axios.get(token.data['@microsoft.graph.downloadUrl'])
// console.log(req.headers['od-protected-token'], odProtectedToken.data.trim())
if (req.headers['od-protected-token'] !== odProtectedToken.data.trim()) {
if (!compareHashedToken(req.headers['od-protected-token'] as string, odProtectedToken.data)) {
res.status(401).json({ error: 'Password required for this folder.' })
return
}
} catch (error) {
} catch (error: any) {
// Password file not found, fallback to 404
if (error.response.status === 404) {
res.status(404).json({ error: "You didn't set a password for your protected folder." })

View file

@ -1,4 +1,5 @@
import axios from 'axios'
import sha256 from 'crypto-js/sha256'
import useSWR, { cache, Key } from 'swr'
import siteConfig from '../config/site.json'
@ -37,10 +38,24 @@ export const useStaleSWR = (url: Key, path: string = '') => {
revalidateOnReconnect: true,
}
const token =
const storedToken =
typeof window !== 'undefined' ? JSON.parse(localStorage.getItem(matchProtectedRoute(path)) as string) : ''
const hashedToken = storedToken ? encryptToken(storedToken) : null
return useSWR([url, token], fetcher, revalidationOptions)
return useSWR([url, hashedToken], fetcher, revalidationOptions)
}
const encryptToken = (token: string) => {
return sha256(token).toString()
}
/**
* Compares the hash of .password and od-protected-token header
* @param odTokenHeader od-protected-token header (sha256 hashed token)
* @param dotPassword non-hashed .password file
* @returns whether the two hashes are the same
*/
export const compareHashedToken = (odTokenHeader: string, dotPassword: string) => {
return encryptToken(dotPassword.trim()) === odTokenHeader
}
export const matchProtectedRoute = (route: string) => {