211 lines
5.9 KiB
JavaScript
211 lines
5.9 KiB
JavaScript
(function(module) {
|
|
"use strict";
|
|
|
|
var User = module.parent.require('./user'),
|
|
meta = module.parent.require('./meta'),
|
|
db = module.parent.require('../src/database'),
|
|
passport = module.parent.require('passport'),
|
|
fs = module.parent.require('fs'),
|
|
path = module.parent.require('path'),
|
|
nconf = module.parent.require('nconf'),
|
|
winston = module.parent.require('winston'),
|
|
passportOAuth;
|
|
|
|
if (meta.config['social:oauth:type'] === '2') {
|
|
passportOAuth = require('passport-oauth').OAuth2Strategy;
|
|
} else if (meta.config['social:oauth:type'] === '1') {
|
|
passportOAuth = require('passport-oauth').OAuthStrategy;
|
|
}
|
|
|
|
var constants = Object.freeze({
|
|
'name': "Generic OAuth",
|
|
'admin': {
|
|
'route': '/oauth',
|
|
'icon': 'fa-key'
|
|
}
|
|
});
|
|
|
|
var OAuth = {};
|
|
|
|
OAuth.getStrategy = function(strategies) {
|
|
var oAuthKeys = ['social:oauth:reqTokenUrl', 'social:oauth:accessTokenUrl', 'social:oauth:authUrl', 'social:oauth:key', 'social:oauth:secret'],
|
|
oAuth2Keys = ['social:oauth2:authUrl', 'social:oauth2:tokenUrl', 'social:oauth2:id', 'social:oauth2:secret'],
|
|
configOk = oAuthKeys.every(function(key) {
|
|
return meta.config[key];
|
|
}) || oAuth2Keys.every(function(key) {
|
|
return meta.config[key];
|
|
}),
|
|
opts;
|
|
|
|
if (passportOAuth && configOk) {
|
|
if (meta.config['social:oauth:type'] === '1') {
|
|
// OAuth options
|
|
opts = {
|
|
requestTokenURL: meta.config['social:oauth:reqTokenUrl'],
|
|
accessTokenURL: meta.config['social:oauth:accessTokenUrl'],
|
|
userAuthorizationURL: meta.config['social:oauth:authUrl'],
|
|
consumerKey: meta.config['social:oauth:key'],
|
|
consumerSecret: meta.config['social:oauth:secret'],
|
|
callbackURL: nconf.get('url') + '/auth/generic/callback'
|
|
};
|
|
|
|
passportOAuth.Strategy.prototype.userProfile = function(token, secret, params, done) {
|
|
this._oauth.get(meta.config['social:oauth:userProfileUrl'], token, secret, function(err, body, res) {
|
|
if (err) { return done(new InternalOAuthError('failed to fetch user profile', err)); }
|
|
|
|
try {
|
|
var json = JSON.parse(body);
|
|
|
|
var profile = { provider: 'generic' };
|
|
// Alter this section to include whatever data is necessary
|
|
// NodeBB requires the following: id, displayName, emails, e.g.:
|
|
// profile.id = json.id;
|
|
// profile.displayName = json.name;
|
|
// profile.emails = [{ value: json.email }];
|
|
|
|
done(null, profile);
|
|
} catch(e) {
|
|
done(e);
|
|
}
|
|
});
|
|
};
|
|
} else if (meta.config['social:oauth:type'] === '2') {
|
|
// OAuth 2 options
|
|
opts = {
|
|
authorizationURL: meta.config['social:oauth2:authUrl'],
|
|
tokenURL: meta.config['social:oauth2:tokenUrl'],
|
|
clientID: meta.config['social:oauth2:id'],
|
|
clientSecret: meta.config['social:oauth2:secret'],
|
|
callbackURL: nconf.get('url') + '/auth/generic/callback'
|
|
};
|
|
|
|
passportOAuth.Strategy.prototype.userProfile = function(accessToken, done) {
|
|
this._oauth2.get(meta.config['social:oauth:userProfileUrl'], accessToken, function(err, body, res) {
|
|
if (err) { return done(new InternalOAuthError('failed to fetch user profile', err)); }
|
|
|
|
try {
|
|
var json = JSON.parse(body);
|
|
|
|
var profile = { provider: 'generic' };
|
|
// Alter this section to include whatever data is necessary
|
|
// NodeBB requires the following: id, displayName, emails, e.g.:
|
|
// profile.id = json.id;
|
|
// profile.displayName = json.name;
|
|
// profile.emails = [{ value: json.email }];
|
|
|
|
done(null, profile);
|
|
} catch(e) {
|
|
done(e);
|
|
}
|
|
});
|
|
};
|
|
}
|
|
|
|
passport.use('Generic OAuth', new passportOAuth(opts, function(token, secret, profile, done) {
|
|
OAuth.login(profile.id, profile.displayName, profile.emails[0].value, function(err, user) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
done(null, user);
|
|
});
|
|
}));
|
|
|
|
strategies.push({
|
|
name: 'Generic OAuth',
|
|
url: '/auth/oauth',
|
|
callbackURL: '/auth/generic/callback',
|
|
icon: 'check',
|
|
scope: (meta.config['social:oauth:scope'] || '').split(',')
|
|
});
|
|
|
|
return strategies;
|
|
} else {
|
|
winston.info('[plugins/sso-oauth] OAuth Disabled or misconfigured. Proceeding without Generic OAuth Login');
|
|
return strategies;
|
|
}
|
|
};
|
|
|
|
OAuth.login = function(oAuthid, handle, email, callback) {
|
|
OAuth.getUidByOAuthid(oAuthid, function(err, uid) {
|
|
if(err) {
|
|
return callback(err);
|
|
}
|
|
|
|
if (uid !== null) {
|
|
// Existing User
|
|
callback(null, {
|
|
uid: uid
|
|
});
|
|
} else {
|
|
// New User
|
|
var success = function(uid) {
|
|
// Save provider-specific information to the user
|
|
User.setUserField(uid, 'oAuthid', oAuthid);
|
|
db.setObjectField('oAuthid:uid', oAuthid, uid);
|
|
callback(null, {
|
|
uid: uid
|
|
});
|
|
};
|
|
|
|
User.getUidByEmail(email, function(err, uid) {
|
|
if(err) {
|
|
return callback(err);
|
|
}
|
|
|
|
if (!uid) {
|
|
User.create({username: handle, email: email}, function(err, uid) {
|
|
if(err) {
|
|
return callback(err);
|
|
}
|
|
|
|
success(uid);
|
|
});
|
|
} else {
|
|
success(uid); // Existing account -- merge
|
|
}
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
OAuth.getUidByOAuthid = function(oAuthid, callback) {
|
|
db.getObjectField('oAuthid:uid', oAuthid, function(err, uid) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
callback(null, uid);
|
|
});
|
|
};
|
|
|
|
OAuth.addMenuItem = function(custom_header) {
|
|
custom_header.authentication.push({
|
|
"route": constants.admin.route,
|
|
"icon": constants.admin.icon,
|
|
"name": constants.name
|
|
});
|
|
|
|
return custom_header;
|
|
}
|
|
|
|
OAuth.addAdminRoute = function(custom_routes, callback) {
|
|
fs.readFile(path.resolve(__dirname, './static/admin.tpl'), function (err, template) {
|
|
custom_routes.routes.push({
|
|
"route": constants.admin.route,
|
|
"method": "get",
|
|
"options": function(req, res, callback) {
|
|
callback({
|
|
req: req,
|
|
res: res,
|
|
route: constants.admin.route,
|
|
name: constants.name,
|
|
content: template
|
|
});
|
|
}
|
|
});
|
|
|
|
callback(null, custom_routes);
|
|
});
|
|
};
|
|
|
|
module.exports = OAuth;
|
|
}(module)); |