From 0f95a513bf8c092d7166a521586333eb2fe8788d Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Tue, 17 Mar 2020 14:02:43 +0200 Subject: Meteor 1.8 only in use at Sandstorm. --- .sandstorm-meteor-1.8/oidc_server.js | 149 +++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 .sandstorm-meteor-1.8/oidc_server.js (limited to '.sandstorm-meteor-1.8/oidc_server.js') diff --git a/.sandstorm-meteor-1.8/oidc_server.js b/.sandstorm-meteor-1.8/oidc_server.js new file mode 100644 index 00000000..326238da --- /dev/null +++ b/.sandstorm-meteor-1.8/oidc_server.js @@ -0,0 +1,149 @@ +Oidc = {}; + +OAuth.registerService('oidc', 2, null, function (query) { + + var debug = process.env.DEBUG || false; + var token = getToken(query); + if (debug) console.log('XXX: register token:', token); + + var accessToken = token.access_token || token.id_token; + var expiresAt = (+new Date) + (1000 * parseInt(token.expires_in, 10)); + + var userinfo = getUserInfo(accessToken); + if (debug) console.log('XXX: userinfo:', userinfo); + + var serviceData = {}; + serviceData.id = userinfo[process.env.OAUTH2_ID_MAP]; // || userinfo["id"]; + serviceData.username = userinfo[process.env.OAUTH2_USERNAME_MAP]; // || userinfo["uid"]; + serviceData.fullname = userinfo[process.env.OAUTH2_FULLNAME_MAP]; // || userinfo["displayName"]; + serviceData.accessToken = accessToken; + serviceData.expiresAt = expiresAt; + serviceData.email = userinfo[process.env.OAUTH2_EMAIL_MAP]; // || userinfo["email"]; + + if (accessToken) { + var tokenContent = getTokenContent(accessToken); + var fields = _.pick(tokenContent, getConfiguration().idTokenWhitelistFields); + _.extend(serviceData, fields); + } + + if (token.refresh_token) + serviceData.refreshToken = token.refresh_token; + if (debug) console.log('XXX: serviceData:', serviceData); + + var profile = {}; + profile.name = userinfo[process.env.OAUTH2_FULLNAME_MAP]; // || userinfo["displayName"]; + profile.email = userinfo[process.env.OAUTH2_EMAIL_MAP]; // || userinfo["email"]; + if (debug) console.log('XXX: profile:', profile); + + return { + serviceData: serviceData, + options: { profile: profile } + }; +}); + +var userAgent = "Meteor"; +if (Meteor.release) { + userAgent += "/" + Meteor.release; +} + +var getToken = function (query) { + var debug = process.env.DEBUG || false; + var config = getConfiguration(); + if(config.tokenEndpoint.includes('https://')){ + var serverTokenEndpoint = config.tokenEndpoint; + }else{ + var serverTokenEndpoint = config.serverUrl + config.tokenEndpoint; + } + var requestPermissions = config.requestPermissions; + var response; + + try { + response = HTTP.post( + serverTokenEndpoint, + { + headers: { + Accept: 'application/json', + "User-Agent": userAgent + }, + params: { + code: query.code, + client_id: config.clientId, + client_secret: OAuth.openSecret(config.secret), + redirect_uri: OAuth._redirectUri('oidc', config), + grant_type: 'authorization_code', + scope: requestPermissions, + state: query.state + } + } + ); + } catch (err) { + throw _.extend(new Error("Failed to get token from OIDC " + serverTokenEndpoint + ": " + err.message), + { response: err.response }); + } + if (response.data.error) { + // if the http response was a json object with an error attribute + throw new Error("Failed to complete handshake with OIDC " + serverTokenEndpoint + ": " + response.data.error); + } else { + if (debug) console.log('XXX: getToken response: ', response.data); + return response.data; + } +}; + +var getUserInfo = function (accessToken) { + var debug = process.env.DEBUG || false; + var config = getConfiguration(); + // Some userinfo endpoints use a different base URL than the authorization or token endpoints. + // This logic allows the end user to override the setting by providing the full URL to userinfo in their config. + if (config.userinfoEndpoint.includes("https://")) { + var serverUserinfoEndpoint = config.userinfoEndpoint; + } else { + var serverUserinfoEndpoint = config.serverUrl + config.userinfoEndpoint; + } + var response; + try { + response = HTTP.get( + serverUserinfoEndpoint, + { + headers: { + "User-Agent": userAgent, + "Authorization": "Bearer " + accessToken + } + } + ); + } catch (err) { + throw _.extend(new Error("Failed to fetch userinfo from OIDC " + serverUserinfoEndpoint + ": " + err.message), + {response: err.response}); + } + if (debug) console.log('XXX: getUserInfo response: ', response.data); + return response.data; +}; + +var getConfiguration = function () { + var config = ServiceConfiguration.configurations.findOne({ service: 'oidc' }); + if (!config) { + throw new ServiceConfiguration.ConfigError('Service oidc not configured.'); + } + return config; +}; + +var getTokenContent = function (token) { + var content = null; + if (token) { + try { + var parts = token.split('.'); + var header = JSON.parse(new Buffer(parts[0], 'base64').toString()); + content = JSON.parse(new Buffer(parts[1], 'base64').toString()); + var signature = new Buffer(parts[2], 'base64'); + var signed = parts[0] + '.' + parts[1]; + } catch (err) { + this.content = { + exp: 0 + }; + } + } + return content; +} + +Oidc.retrieveCredential = function (credentialToken, credentialSecret) { + return OAuth.retrieveCredential(credentialToken, credentialSecret); +}; -- cgit v1.2.3-1-g7c22