diff --git a/packages/api/package.json b/packages/api/package.json index e3dc03f09..236d4211c 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -17,6 +17,7 @@ "dbgate" ], "dependencies": { + "activedirectory2": "^2.1.0", "async-lock": "^1.2.4", "axios": "^0.21.1", "body-parser": "^1.19.0", diff --git a/packages/api/src/controllers/auth.js b/packages/api/src/controllers/auth.js index e6d36bb72..df33d4f57 100644 --- a/packages/api/src/controllers/auth.js +++ b/packages/api/src/controllers/auth.js @@ -2,6 +2,8 @@ const axios = require('axios'); const jwt = require('jsonwebtoken'); const getExpressPath = require('../utility/getExpressPath'); const uuidv1 = require('uuid/v1'); +const { getLogins } = require('../utility/hasPermission'); +const AD = require('activedirectory2').promiseWrapper; const tokenSecret = uuidv1(); @@ -20,7 +22,7 @@ function unauthorizedResponse(req, res, text) { } function authMiddleware(req, res, next) { - const SKIP_AUTH_PATHS = ['/config/get', '/auth/oauth-token', '/stream']; + const SKIP_AUTH_PATHS = ['/config/get', '/auth/oauth-token', 'auth/login', '/stream']; if (!shouldAuthorizeApi()) { return next(); @@ -60,16 +62,51 @@ module.exports = { const login = process.env.OAUTH_LOGIN_FIELD ? payload[process.env.OAUTH_LOGIN_FIELD] : 'oauth'; - console.log(payload); - if (access_token) { return { - accessToken: jwt.sign({ user: 'oauth' }, tokenSecret, { expiresIn: '1m' }), + accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: '1m' }), }; } return { error: 'Token not found' }; }, + login_meta: true, + async login(params) { + const { login, password } = params; + + if (process.env.AD_URL && process.env.AD_BASEDN) { + const adConfig = { + url: process.env.AD_URL, + baseDN: process.env.AD_BASEDN, + username: process.env.AD_USERNAME, + password: process.env.AD_PASSOWRD, + }; + const ad = new AD(adConfig); + try { + const res = await ad.authenticate(login, password); + if (!res) { + return { error: 'login failed' }; + } + return { + accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: '1m' }), + }; + } catch (err) { + console.log('Failed active directory authentization', err.message); + return { error: err.message }; + } + } + + const logins = getLogins(); + if (!logins) { + return { error: 'Logins not configured' }; + } + if (logins[login] == password) { + return { + accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: '1m' }), + }; + } + return { error: 'Invalid credentials' }; + }, authMiddleware, shouldAuthorizeApi, diff --git a/packages/web/src/LoginPage.svelte b/packages/web/src/LoginPage.svelte index 705d8321b..026b3874c 100644 --- a/packages/web/src/LoginPage.svelte +++ b/packages/web/src/LoginPage.svelte @@ -5,6 +5,7 @@ import FormProvider from './forms/FormProvider.svelte'; import FormSubmit from './forms/FormSubmit.svelte'; import FormTextField from './forms/FormTextField.svelte'; + import { apiCall, enableApi } from './utility/api'; onMount(() => { const removed = document.getElementById('starting_dbgate_zero'); @@ -28,7 +29,8 @@ { - console.log('log in', e); + enableApi(); + apiCall('auth/login', e.detail); }} /> @@ -51,8 +53,10 @@ position: fixed; top: 1rem; left: 1rem; - font-size: 40pt; + font-size: 30pt; + font-family: monospace; color: var(--theme-bg-2); + text-transform: uppercase; } .submit { margin: var(--dim-large-form-margin); @@ -78,8 +82,10 @@ } .box { - max-width: 600px; - width: 40vw; + width: 600px; + max-width: 80vw; + /* max-width: 600px; + width: 40vw; */ border: 1px solid var(--theme-border); border-radius: 4px; background-color: var(--theme-bg-0); diff --git a/packages/web/src/utility/api.ts b/packages/web/src/utility/api.ts index ee878f257..2ca869a00 100644 --- a/packages/web/src/utility/api.ts +++ b/packages/web/src/utility/api.ts @@ -16,6 +16,10 @@ export function disableApi() { apiDisabled = true; } +export function enableApi() { + apiDisabled = false; +} + function wantEventSource() { if (!eventSource) { eventSource = new EventSource(`${resolveApi()}/stream`); diff --git a/yarn.lock b/yarn.lock index f5a01b77e..ccb5e7f07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1701,6 +1701,11 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abstract-logging@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" + integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== + accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -1765,6 +1770,16 @@ acorn@^8.2.4, acorn@^8.5.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +activedirectory2@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/activedirectory2/-/activedirectory2-2.1.0.tgz#4293f72ade8ff36e9199cf5fa5cae3818bdb947a" + integrity sha512-HaccG+/mf5NpHL1mAcLzXed4+gGlO6l7mkBi8vNIo6sTJvLoJjHgvJg12F4cy5CNcRqvPS48++s5tfdSiafn4Q== + dependencies: + abstract-logging "^2.0.0" + async "^3.1.0" + ldapjs "^2.1.0" + merge-options "^2.0.0" + adler-32@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25" @@ -2058,7 +2073,7 @@ async@^2.6.2: dependencies: lodash "^4.17.14" -async@^3.2.0, async@^3.2.3: +async@^3.1.0, async@^3.2.0, async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== @@ -2225,6 +2240,13 @@ babel-preset-jest@^28.1.3: babel-plugin-jest-hoist "^28.1.3" babel-preset-current-node-syntax "^1.0.0" +backoff@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" + integrity sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA== + dependencies: + precond "0.2" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -5416,6 +5438,11 @@ is-plain-obj@^1.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== +is-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -7044,6 +7071,27 @@ kleur@^3.0.0, kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +ldap-filter@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/ldap-filter/-/ldap-filter-0.3.3.tgz#2b14c68a2a9d4104dbdbc910a1ca85fd189e9797" + integrity sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg== + dependencies: + assert-plus "^1.0.0" + +ldapjs@^2.1.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/ldapjs/-/ldapjs-2.3.3.tgz#06c317d3cbb5ac42fbba741e1a8b130ffcf997ab" + integrity sha512-75QiiLJV/PQqtpH+HGls44dXweviFwQ6SiIK27EqzKQ5jU/7UFrl2E5nLdQ3IYRBzJ/AVFJI66u0MZ0uofKYwg== + dependencies: + abstract-logging "^2.0.0" + asn1 "^0.2.4" + assert-plus "^1.0.0" + backoff "^2.5.0" + ldap-filter "^0.3.3" + once "^1.4.0" + vasync "^2.2.0" + verror "^1.8.1" + leaflet@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.8.0.tgz#4615db4a22a304e8e692cae9270b983b38a2055e" @@ -7398,6 +7446,13 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-options@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-options/-/merge-options-2.0.0.tgz#36ca5038badfc3974dbde5e58ba89d3df80882c3" + integrity sha512-S7xYIeWHl2ZUKF7SDeBhGg6rfv5bKxVBdk95s/I7wVF8d+hjLSztJ/B271cnUiF6CAFduEQ5Zn3HYwAjT16DlQ== + dependencies: + is-plain-obj "^2.0.0" + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -8623,6 +8678,11 @@ prebuild-install@^7.0.1, prebuild-install@^7.1.0, prebuild-install@^7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" +precond@0.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" + integrity sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -10864,6 +10924,13 @@ vary@^1, vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +vasync@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vasync/-/vasync-2.2.1.tgz#d881379ff3685e4affa8e775cf0fd369262a201b" + integrity sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ== + dependencies: + verror "1.10.0" + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -10873,6 +10940,15 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +verror@^1.8.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb" + integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"