diff --git a/docs/Advanced Authentication.md b/docs/Advanced Authentication.md new file mode 100644 index 000000000..a8d650631 --- /dev/null +++ b/docs/Advanced Authentication.md @@ -0,0 +1,8 @@ +# Advanced Authentication + +If you don't want to use the internal authentication method (username & password), you must leave the username **and** password blank. + +When you do so, the authentication is disabled completely, but no tokens can be generated! + +## Integrate custom authenticator +You need to protect all ackee routes except `/api`, which is the GraphQL endpoint for the tracker and must be accessible for everyone to work properly \ No newline at end of file diff --git a/docs/Options.md b/docs/Options.md index 1fc122d6d..a36afe462 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -41,6 +41,8 @@ PORT=3000 Username and password. Both are required to generate a new token. +They can be unset to use a custom authentication provider like authelia: [Advanved Authentication](Advanced%20Authentication.md) + ``` ACKEE_USERNAME=username ACKEE_PASSWORD=password diff --git a/package.json b/package.json index 7d1407bc2..cf5be8d7e 100644 --- a/package.json +++ b/package.json @@ -24,13 +24,13 @@ }, "scripts": { "start": "npm run build && npm run server", - "start:dev": "NODE_ENV=development nodemon", - "build:pre": "BUILD_ENV=pre npm run build", + "start:dev": "cross-env NODE_ENV=development nodemon", + "build:pre": "cross-env BUILD_ENV=pre npm run build", "build": "node build.js", "server": "node src/index.js", - "coveralls": "nyc report --reporter=lcov", - "test": "nyc ava", - "lint": "eslint '{functions,src,test}/**/*.js'" + "coveralls": "cross-env nyc report --reporter=lcov", + "test": "cross-env nyc ava", + "lint": "cross-env eslint '{functions,src,test}/**/*.js'" }, "dependencies": { "ackee-tracker": "^5.0.1", @@ -61,6 +61,7 @@ "ava": "3.15.0", "classnames": "^2.2.6", "coveralls": "^3.1.0", + "cross-env": "^7.0.3", "eslint": "^7.20.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-react": "^7.22.0", diff --git a/src/index.js b/src/index.js index b9a24c0df..6c0b39e19 100644 --- a/src/index.js +++ b/src/index.js @@ -33,6 +33,10 @@ connect(config.dbUrl).then(() => { signale.info('Demo mode enabled') } + if (!config.username && !config.password) { + signale.warn('disabling username/password based authentication') + } + }).catch((err) => { signale.fatal(err) diff --git a/src/resolvers/tokens.js b/src/resolvers/tokens.js index e4c7f68d7..542702c99 100644 --- a/src/resolvers/tokens.js +++ b/src/resolvers/tokens.js @@ -18,7 +18,7 @@ module.exports = { const { username, password } = input if (config.username == null) throw new KnownError('Ackee username missing in environment') - if (config.password == null) throw new KnownError('Ackee username missing in environment') + if (config.password == null) throw new KnownError('Ackee password missing in environment') if (username !== config.username) throw new KnownError('Username or password incorrect') if (password !== config.password) throw new KnownError('Username or password incorrect') diff --git a/src/ui/index.js b/src/ui/index.js index 86b5ba166..582a8daf3 100644 --- a/src/ui/index.js +++ b/src/ui/index.js @@ -12,7 +12,8 @@ const index = async () => { return layout('
', 'favicon.ico', [ 'index.css' ], [ 'index.js' ], { isDemoMode: config.isDemoMode, - customTracker + customTracker, + authDisabled: !config.username && !config.password }) } diff --git a/src/ui/scripts/components/Main.js b/src/ui/scripts/components/Main.js index b3b7854a2..6741c0efc 100644 --- a/src/ui/scripts/components/Main.js +++ b/src/ui/scripts/components/Main.js @@ -29,7 +29,9 @@ const Main = (props) => { const hasToken = props.token.value != null if (hasError === true) return h(OverlayFailure, { errors: unknownErrors }) - if (hasToken === false) return h(OverlayLogin, { token: props.token, addToken: props.addToken.bind(null, props) }) + if (hasToken === false && !window.env.authDisabled) { + return h(OverlayLogin, { token: props.token, addToken: props.addToken.bind(null, props) }) + } return h(Fragment, {}, h(Filter, enhancedProps), diff --git a/src/ui/scripts/components/routes/RouteSettings.js b/src/ui/scripts/components/routes/RouteSettings.js index 71af42da1..8e719f63e 100644 --- a/src/ui/scripts/components/routes/RouteSettings.js +++ b/src/ui/scripts/components/routes/RouteSettings.js @@ -76,8 +76,10 @@ const RouteSettings = (props) => { headline: 'Account' }, h(LinkItem, { type: 'p', disabled: true, text: version }, 'Version'), - h(Line), - h(LinkItem, { type: 'button', onClick: () => props.deleteToken(props) }, 'Sign Out') + ...(!window.env.authDisabled ? [ + h(LinkItem, { type: 'button', onClick: () => props.deleteToken(props) }, 'Sign Out'), + h(Line) + ] : []) ), h(CardSetting, { diff --git a/src/utils/isAuthenticated.js b/src/utils/isAuthenticated.js index a01f89896..40a4ddb52 100644 --- a/src/utils/isAuthenticated.js +++ b/src/utils/isAuthenticated.js @@ -4,9 +4,15 @@ const KnownError = require('../utils/KnownError') const isExpired = require('../utils/isExpired') const tokens = require('../database/tokens') const permanentTokens = require('../database/permanentTokens') +const config = require('../utils/config') module.exports = async (authorization, ttl) => { + // username/password authentication is disabled + if (!config.username && !config.password) { + return true + } + // Token not in request if (authorization == null) { return new KnownError('Token missing') diff --git a/yarn.lock b/yarn.lock index d5f261af5..92ac747ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2827,6 +2827,13 @@ cron-parser@^3.1.0: is-nan "^1.3.0" luxon "^1.25.0" +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-fetch@3.0.6, cross-fetch@^3.0.4: version "3.0.6" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" @@ -2834,7 +2841,7 @@ cross-fetch@3.0.6, cross-fetch@^3.0.4: dependencies: node-fetch "2.6.1" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==