mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-18 03:16:01 +00:00
131 lines
3.7 KiB
JavaScript
131 lines
3.7 KiB
JavaScript
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();
|
|
|
|
function shouldAuthorizeApi() {
|
|
const logins = getLogins();
|
|
return !!process.env.OAUTH_AUTH || !!process.env.AD_URL || (!!logins && !process.env.BASIC_AUTH);
|
|
}
|
|
|
|
function unauthorizedResponse(req, res, text) {
|
|
// if (req.path == getExpressPath('/config/get-settings')) {
|
|
// return res.json({});
|
|
// }
|
|
// if (req.path == getExpressPath('/connections/list')) {
|
|
// return res.json([]);
|
|
// }
|
|
return res.sendStatus(401).send(text);
|
|
}
|
|
|
|
function authMiddleware(req, res, next) {
|
|
const SKIP_AUTH_PATHS = ['/config/get', '/auth/oauth-token', '/auth/login', '/stream'];
|
|
|
|
if (!shouldAuthorizeApi()) {
|
|
return next();
|
|
}
|
|
let skipAuth = !!SKIP_AUTH_PATHS.find(x => req.path == getExpressPath(x));
|
|
|
|
const authHeader = req.headers.authorization;
|
|
if (!authHeader) {
|
|
if (skipAuth) {
|
|
return next();
|
|
}
|
|
return unauthorizedResponse(req, res, 'missing authorization header');
|
|
}
|
|
const token = authHeader.split(' ')[1];
|
|
try {
|
|
const decoded = jwt.verify(token, tokenSecret);
|
|
req.user = decoded;
|
|
return next();
|
|
} catch (err) {
|
|
if (skipAuth) {
|
|
return next();
|
|
}
|
|
|
|
console.log('Sending invalid token error', err.message);
|
|
|
|
return unauthorizedResponse(req, res, 'invalid token');
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
oauthToken_meta: true,
|
|
async oauthToken(params) {
|
|
const { redirectUri, code } = params;
|
|
|
|
const resp = await axios.default.post(
|
|
`${process.env.OAUTH_TOKEN}`,
|
|
`grant_type=authorization_code&code=${encodeURIComponent(code)}&redirect_uri=${encodeURIComponent(
|
|
redirectUri
|
|
)}&client_id=${process.env.OAUTH_CLIENT_ID}&client_secret=${process.env.OAUTH_CLIENT_SECRET}`
|
|
);
|
|
|
|
const { access_token, refresh_token } = resp.data;
|
|
|
|
const payload = jwt.decode(access_token);
|
|
|
|
const login = process.env.OAUTH_LOGIN_FIELD ? payload[process.env.OAUTH_LOGIN_FIELD] : 'oauth';
|
|
|
|
if (
|
|
process.env.OAUTH_ALLOWED_LOGINS &&
|
|
!process.env.OAUTH_ALLOWED_LOGINS.split(',').find(x => x.toLowerCase().trim() != login.toLowerCase().trim())
|
|
) {
|
|
return { error: `Username ${login} not allowed to log in` };
|
|
}
|
|
if (access_token) {
|
|
return {
|
|
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) {
|
|
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.find(x => x.login == login)?.password == password) {
|
|
return {
|
|
accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: '1m' }),
|
|
};
|
|
}
|
|
return { error: 'Invalid credentials' };
|
|
},
|
|
|
|
authMiddleware,
|
|
shouldAuthorizeApi,
|
|
};
|