UNPKG

passport-wpoauth

Version:

Authentication strategy for Passport for Wordpress with WP-OAuth plugin.

197 lines (169 loc) 5.46 kB
'use strict'; /** * Module dependencies. */ var util = require('util'), OAuth2Strategy = require('passport-oauth2'), Profile = require('./profile'), InternalOAuthError = require('passport-oauth2').InternalOAuthError; // Polyfills require('string.prototype.endswith'); /** * `Strategy` constructor. * * The WP-OAuth authentication strategy authenticates requests by delegating * to the configured WP-OAuth Server using the OAuth 2.0 protocol. * * Applications must supply a `verify` callback which accepts an `accessToken`, * `refreshToken` and the service-specific `profile`, an then calls the `done` * callback supplying a `user`, which should be set to `false` if the * credentials are not valid. If an exception/error occured, `err` is set. * * Options: * - `clientID` the Client ID you created in WP-OAuth * - `clientSecret` the corresponding Client Secret * - `callbackURL` URL to which WP-OAuth will redirect the user after granting authorization. * * - `authorizationURL` the URL to the authorization endpoint, defaults to localhost. * - `tokenURL` the URL to get token endpoint, defaults to localhost. * - `userProfileURL` the URL to the profile information endpoint, defaults to localhost. * * Examples: * * passport.use(new WPOAuthStrategy({ * clientID: '123abc456def789ghi', * clientSecret: 'shhh-its-a-secret', * callbackURL: 'https://www.example.net/auth/wpoauth/callback', * authorizationURL: 'https://www.example.net/blog/oauth/authorize', * tokenURL: 'https://www.example.net/blog/oauth/token', * userProfileURL: 'https://www.example.net/blog/oauth/me' * }, function(accessToken, refreshToken, profile, done) { * User.findOrCreate(..., function(err, user) { * ... * done(err, user); * }); * } * )); * * @param {Object} options * @param {Function} verify * @api public */ function Strategy(o, verify) { var options = JSON.parse(JSON.stringify(o)) || {}; options.authorizationURL = options.authorizationURL || 'http://localhost/oauth/authorize'; options.tokenURL = options.tokenURL || 'http://localhost/oauth/token'; options.customHeaders = options.customHeaders || {}; if (!options.customHeaders['User-Agent']) { options.customHeaders['User-Agent'] = options.userAgent || 'passport-wpoauth'; } OAuth2Strategy.call(this, options, verify); this.name = 'wpoauth'; this._userProfileURL = options.userProfileURL || 'http://localhost/oauth/me/'; // Otherwise we get a 301 which unforutunaly not handled by http/https if (!this._userProfileURL.endsWith('/')) { this._userProfileURL = this._userProfileURL + '/'; } } /** * Inherit from `OAuth2Strategy`. */ util.inherits(Strategy, OAuth2Strategy); /** * */ Strategy.prototype.authenticate = function(req, options) { options = options || {}; var self = this; if (req && req.query && req.query.error) { return self.error('Request not provided or has errors'); } if (!req.body) { return self.error(); } if (!req.body.redirectUri) { return self.error('You need to provide a redirectUri'); } else { self._callbackURL = req.body.redirectUri; } var authCode = req.body.code || req.query.code; if (!authCode) { return self.error(); } self._exchangeAuthCode(authCode, function(error, accessToken, refreshToken, results) { if (error) { return self.error(error); } self.userProfile(accessToken, function(err, profile) { if (err) { return self.fail(err); } var verified = function(e, user, info) { if (e) { return self.error(e); } if (!user) { return self.fail(info); } self.success(user, info); }; if (self._passReqToCallback) { self._verify(req, accessToken, refreshToken, profile, verified); } else { self._verify(accessToken, refreshToken, profile, verified); } }); }); }; /** * Exchange authorization code for tokens * * @param {String} authCode * @param {Function} done * @api private */ Strategy.prototype._exchangeAuthCode = function(authCode, done) { var params = { 'grant_type': 'authorization_code', 'redirect_uri': this._callbackURL }; this._oauth2.getOAuthAccessToken(authCode, params, done); }; /** * Retrive user profile from WP OAuth. * * This function constructs a normalized profile with the following properties: * * - `provider` always set to `wpoauth` * - `id` the user's WordPress ID * - `username` the user's login name * - `displayName` the user's preferred identification (can be username or full name or both) * - `emails` the user's email address * * @param {String} accessToken * @param {Function} done * @api protected */ Strategy.prototype.userProfile = function(accessToken, done) { this._oauth2.get(this._userProfileURL, accessToken, function(err, body, res) { var json; if (err) { return done(new InternalOAuthError('Failed to fetch user profile', err)); } try { json = JSON.parse(body); } catch (ex) { return done(ex); } var profile = Profile.parse(json); profile.provider = 'wpoauth'; profile._raw = body; profile._json = json; done(null, profile); }); }; /** * Expose `Strategy`. */ module.exports = Strategy;