Fix OIDC sso issues

This commit is contained in:
yflory 2023-10-18 15:39:54 +02:00
parent bd62461347
commit e8d719c438
8 changed files with 306 additions and 27 deletions

View File

@ -13,7 +13,8 @@ module.exports = {
type: 'oidc',
url: 'https://accounts.google.com',
client_id: "{your_client_id}",
client_secret: "{your_client_secret}"
client_secret: "{your_client_secret}",
jwt_alg: 'RS256' (optional)
}
*/
]

View File

@ -113,8 +113,8 @@ define([
// We need a setTimeout(cb, 0) otherwise the loading screen is only displayed
// after hashing the password
window.setTimeout(function () {
Exports.loginOrRegister({
uname,
Login.loginOrRegister({
uname,
passwd,
isRegister,
onOTP

View File

@ -1,14 +1,22 @@
const OID = require('openid-client');
const SSOUtils = require('../../sso-utils');
const TYPE = 'oidc';
const opts = SSOUtils.getoptions();
const getClient = (cfg, cb) => {
OID.Issuer.discover(cfg.url).then((issuer) => { // XXX Only once for all users?
let alg = cfg.jwt_alg || 'PS256';
if (Array.isArray(issuer.id_token_signing_alg_values_supported) &&
!issuer.id_token_signing_alg_values_supported.includes(alg)) {
alg = issuer.id_token_signing_alg_values_supported[0] || 'RS256';
}
const client = new issuer.Client({
client_id: cfg.client_id,
client_secret: cfg.client_secret,
redirect_uris: ['http://localhost:3000/ssoauth'], // XXX Use httpUnsafeOrigin or...
redirect_uris: [opts.callbackURL],
response_types: ['code'],
id_token_signed_response_alg: alg
});
cb(void 0, client);
}, (err) => {
@ -28,8 +36,8 @@ module.exports = {
const code_verifier = generators.codeVerifier();
const code_challenge = generators.codeChallenge(code_verifier);
const url = client.authorizationUrl({
scope: 'openid email profile',// https://www.googleapis.com/auth/contacts.readonly', // https://www.google.com/m8/feeds
resource: 'http://localhost:3000/ssoauth/',
scope: 'openid email profile',
resource: opts.callbackURL,
access_type: 'offline',
code_challenge,
code_challenge_method: 'S256',
@ -43,29 +51,35 @@ module.exports = {
if (err) { return void cb ('E_OIDC_CONNECT'); }
const params = client.callbackParams(url);
delete params.state;
client.callback('http://localhost:3000/ssoauth', params, { code_verifier: token })
.then((tokenSet) => {
let j = tokenSet;
let c = tokenSet.claims();
cb(void 0, {
id: c.sub,
name: c.name,
idpData: {
expires_at: j.expires_at,
access_token: j.access_token,
refresh_token: j.refresh_token,
//id_token: j.id_token // XXX no need to store id_token?
}
let name = c.name;
const end = () => {
cb(void 0, {
id: c.sub,
name: name,
idpData: {
expires_at: j.expires_at,
access_token: j.access_token,
refresh_token: j.refresh_token,
//id_token: j.id_token // XXX no need to store id_token?
}
});
};
if (name) { return void end(); }
let t = client.userinfo(j.access_token).then((data) => {
name = data.name;
end();
console.log(t);
}, (err) => {
console.error(err);
name = 'Unknown'; // XXX
end();
});
});
});
},
/*
getData: (Env, cfg, data, cb) => {
// data = { refresh_token, access_token, expires_at }
let t = new OID.TokenSet(data);
// TODO get userinfo using access_token
// use refresh_token if access expired
}
*/
};

View File

@ -3,14 +3,24 @@ const Sessions = require("./storage/sessions");
const Nacl = require("tweetnacl/nacl-fast");
const JWT = require("jsonwebtoken");
const Util = require("./common-util");
const config = require("./lib/load-config");
const SSOUtils = module.exports;
const SESSION_EXPIRATIION = 12 * 3600 * 1000; // XXX Hours? Days? Weeks? Configurable?
SSOUtils.getOptions = () => {
return {
callbackURL: config.httpUnsafeOrigin + '/ssoauth'
};
};
// XXX const SAML = require('node-saml'); // https://www.npmjs.com/package/node-saml
const TYPES = SSOUtils.TYPES = {
oidc: require('./plugins/sso/oidc')
oidc: require('./plugins/sso/oidc'),
saml: require('./plugins/sso/saml')
};
const checkConfig = SSOUtils.checkConfig = (Env) => {

249
package-lock.json generated
View File

@ -10,6 +10,7 @@
"license": "AGPL-3.0+",
"dependencies": {
"@mcrowe/minibloom": "^0.2.0",
"@node-saml/node-saml": "^4.0.5",
"alertify.js": "1.0.11",
"bootstrap": "^4.0.0",
"bootstrap-tokenfield": "^0.12.0",
@ -88,6 +89,48 @@
"node": ">=4"
}
},
"node_modules/@node-saml/node-saml": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-4.0.5.tgz",
"integrity": "sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==",
"dependencies": {
"@types/debug": "^4.1.7",
"@types/passport": "^1.0.11",
"@types/xml-crypto": "^1.4.2",
"@types/xml-encryption": "^1.2.1",
"@types/xml2js": "^0.4.11",
"@xmldom/xmldom": "^0.8.6",
"debug": "^4.3.4",
"xml-crypto": "^3.0.1",
"xml-encryption": "^3.0.2",
"xml2js": "^0.5.0",
"xmlbuilder": "^15.1.1"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/@node-saml/node-saml/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/@node-saml/node-saml/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/@nodelib/fs.stat": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
@ -97,6 +140,53 @@
"node": ">= 6"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.4",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.4.tgz",
"integrity": "sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==",
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
}
},
"node_modules/@types/connect": {
"version": "3.4.37",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.37.tgz",
"integrity": "sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/debug": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz",
"integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==",
"dependencies": {
"@types/ms": "*"
}
},
"node_modules/@types/express": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz",
"integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"node_modules/@types/express-serve-static-core": {
"version": "4.17.38",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.38.tgz",
"integrity": "sha512-hXOtc0tuDHZPFwwhuBJXPbjemWtXnJjbvuuyNH2Y5Z6in+iXc63c4eXYDc7GGGqHy+iwYqAJMdaItqdnbcBKmg==",
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*",
"@types/send": "*"
}
},
"node_modules/@types/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
@ -107,6 +197,11 @@
"@types/node": "*"
}
},
"node_modules/@types/http-errors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.3.tgz",
"integrity": "sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA=="
},
"node_modules/@types/http-proxy": {
"version": "1.17.12",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.12.tgz",
@ -115,17 +210,89 @@
"@types/node": "*"
}
},
"node_modules/@types/mime": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz",
"integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg=="
},
"node_modules/@types/minimatch": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
"dev": true
},
"node_modules/@types/ms": {
"version": "0.7.33",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz",
"integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ=="
},
"node_modules/@types/node": {
"version": "20.6.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz",
"integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA=="
},
"node_modules/@types/passport": {
"version": "1.0.14",
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.14.tgz",
"integrity": "sha512-D6p2ygR2S7Cq5PO7iUaEIQu/5WrM0tONu6Lxgk0C9r3lafQIlVpWCo3V/KI9To3OqHBxcfQaOeK+8AvwW5RYmw==",
"dependencies": {
"@types/express": "*"
}
},
"node_modules/@types/qs": {
"version": "6.9.9",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz",
"integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg=="
},
"node_modules/@types/range-parser": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.6.tgz",
"integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA=="
},
"node_modules/@types/send": {
"version": "0.17.2",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz",
"integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==",
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/serve-static": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz",
"integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==",
"dependencies": {
"@types/http-errors": "*",
"@types/mime": "*",
"@types/node": "*"
}
},
"node_modules/@types/xml-crypto": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@types/xml-crypto/-/xml-crypto-1.4.3.tgz",
"integrity": "sha512-pnvKYb7vUsUIMc+C6JM/j779YWQgOMcwjnqHJ9cdaWXwWEBE1hAqthzeszRx62V5RWMvS+XS9w9tXMOYyUc8zg==",
"dependencies": {
"@types/node": "*",
"xpath": "0.0.27"
}
},
"node_modules/@types/xml-encryption": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.2.tgz",
"integrity": "sha512-UeuYOqW3ZzUQfwb/mb3GNZ2/DlVdh5mjJNmB/yFXgQr8/pwlVJ9I2w+AHPfRDzLshe7YpgUB4T1//qgbk6U87Q==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/xml2js": {
"version": "0.4.12",
"resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.12.tgz",
"integrity": "sha512-CZPpQKBZ8db66EP5hCjwvYrLThgZvnyZrPXK2W+UI1oOaWezGt34iOaUCX4Jah2X8+rQqjvl9VKEIT8TR1I0rA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
@ -3939,6 +4106,11 @@
"resolved": "https://registry.npmjs.org/saferphore/-/saferphore-0.0.1.tgz",
"integrity": "sha512-/KaXQyumYbALQwhl4/Qov6voayHwtBD12AWRI3zxYBW7cY3Mjtkk7PLttZPq+25nyfu/k3APHUptPLZI9A7yHA=="
},
"node_modules/sax": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
"integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="
},
"node_modules/scrypt-async": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-1.2.0.tgz",
@ -4869,6 +5041,83 @@
"node": "*"
}
},
"node_modules/xml-crypto": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz",
"integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==",
"dependencies": {
"@xmldom/xmldom": "^0.8.8",
"xpath": "0.0.32"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xml-crypto/node_modules/xpath": {
"version": "0.0.32",
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
"integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==",
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/xml-encryption": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-3.0.2.tgz",
"integrity": "sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==",
"dependencies": {
"@xmldom/xmldom": "^0.8.5",
"escape-html": "^1.0.3",
"xpath": "0.0.32"
},
"engines": {
"node": ">=12"
}
},
"node_modules/xml-encryption/node_modules/xpath": {
"version": "0.0.32",
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
"integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==",
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/xml2js": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xml2js/node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"engines": {
"node": ">=4.0"
}
},
"node_modules/xmlbuilder": {
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"engines": {
"node": ">=8.0"
}
},
"node_modules/xpath": {
"version": "0.0.27",
"resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
"integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==",
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",

View File

@ -25,6 +25,7 @@
"notp": "^2.0.3",
"nthen": "0.1.8",
"openid-client": "^5.4.2",
"@node-saml/node-saml": "^4.0.5",
"prompt-confirm": "^2.0.4",
"pull-stream": "^3.6.1",
"saferphore": "0.0.1",

View File

@ -301,7 +301,6 @@ define([
register: isRegister,
uname: uname
};
if (ssoAuth && ssoAuth.name) { uname = res.uname = ssoAuth.name; }
var RT, blockKeys, blockUrl;
@ -312,6 +311,7 @@ define([
res.opt = allocateBytes(bytes);
res.blockHash = res.opt.blockHash;
blockKeys = res.opt.blockKeys;
if (ssoAuth && ssoAuth.name) { uname = res.uname = ssoAuth.name; }
}));
}).nThen(function (waitFor) {
// the allocated bytes can be used either in a legacy fashion,

View File

@ -51,8 +51,12 @@ define([
}
}, function (err) {
if (err) {
console.error(err);
return void UI.warn(Messages.error);
UI.removeLoadingScreen();
var msg = Messages.error;
if (err === 'NO_SUCH_USER') { msg = Messages.drive_sfPasswordError; }
let $button = $('button#cp-ssoauth-button');
$button.prop('disabled', '');
return void UI.warn(msg);
}
window.location.href = '/drive/';
});