UNPKG

4.9 kBJavaScriptView Raw
1/****************
2 * IMPORTS
3 */
4
5var util = require('util');
6var OAuth2Strategy = require('passport-oauth2');
7var InternalOAuthError = require('passport-oauth2').InternalOAuthError;
8var querystring = require('query-string');
9
10/**
11 * `Strategy` constructor.
12 *
13 * The Microsoft authentication strategy authenticates requests by delegating to
14 * Microsoft using the OAuth 2.0 protocol.
15 *
16 * Applications must supply a `verify` callback which accepts an `accessToken`,
17 * `refreshToken` and service-specific `profile`, and then calls the `done`
18 * callback supplying a `user`, which should be set to `false` if the
19 * credentials are not valid. If an exception occured, `err` should be set.
20 *
21 * Options:
22 * - `clientId` your Microsoft application's client id
23 * - `clientSecret` your Microsoft application's client secret
24 * - `callbackURL` URL to which Microsoft will redirect the user after granting authorization in your Microsoft Application
25 *
26 * Examples:
27 *
28 * var MicrosoftStrategy = require('passport-microsoft').Strategy;
29 *
30 * passport.use(new MicrosoftStrategy({
31 * clientID: '123-456-789',
32 * clientSecret: 'shhh-its-a-secret'
33 * callbackURL: 'https://www.example.net/auth/microsoft/callback'
34 * },
35 * function(accessToken, refreshToken, profile, done) {
36 * User.findOrCreate(..., function (err, user) {
37 * done(err, user);
38 * });
39 * }
40 * ));
41 *
42 * @param {Object} options
43 * @param {Function} verify
44 * @api public
45 */
46
47function MicrosoftStrategy(options, verify) {
48 options = options || {};
49 options.authorizationURL = options.authorizationURL || 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
50 options.tokenURL = options.tokenURL || 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
51 options.scopeSeparator = options.scopeSeparator || ' ';
52 options.customHeaders = options.customHeaders || {};
53
54 OAuth2Strategy.call(this, options, verify);
55 this.name = 'microsoft';
56
57 this._userProfileURL =
58 options.userProfileURL || 'https://graph.microsoft.com/v1.0/me/';
59
60 this._oauth2.getOAuthAccessToken = function (code, params, callback) {
61 params = params || {};
62 var codeParam =
63 params.grant_type === 'refresh_token' ? 'refresh_token' : 'code';
64 params[ codeParam ] = code;
65 params[ 'client_id' ] = this._clientId;
66 params[ 'client_secret' ] = this._clientSecret;
67
68 var post_data = querystring.stringify(params);
69 var post_headers = {
70 'Content-Type': 'application/x-www-form-urlencoded'
71 };
72
73 this._request(
74 'POST',
75 this._getAccessTokenUrl(),
76 post_headers,
77 post_data,
78 null,
79 function (error, data, response) {
80 if ( error ) callback(error);
81 else {
82 var results = JSON.parse(data);
83 console.log('results', results);
84 var access_token = results.access_token;
85 var refresh_token = results.refresh_token;
86 var expires_in = results.expires_in;
87 delete results.refresh_token;
88 callback(null, access_token, refresh_token, expires_in, results); // callback results =-=
89 }
90 }
91 );
92 };
93}
94
95/**
96 * Inherit from `OAuth2Strategy`.
97 */
98
99util.inherits(MicrosoftStrategy, OAuth2Strategy);
100
101/**
102 * Retrieve user profile from Microsoft Graph.
103 *
104 * This function constructs a normalized profile, with the following properties:
105 *
106 * - `provider` always set to `microsoft`
107 * - `id`
108 * - etc..
109 *
110 * @param {String} accessToken
111 * @param {Function} done
112 * @api protected
113 */
114
115MicrosoftStrategy.prototype.userProfile = function (accessToken, done) {
116 this._oauth2.useAuthorizationHeaderforGET(true);
117 this._oauth2.get(
118 this._userProfileURL,
119 accessToken,
120 function (err, body, res) {
121
122 if ( err ) {
123 return done(new InternalOAuthError('failed to fetch user profile', err));
124 }
125 try {
126 var json = JSON.parse(body);
127
128 var profile = {
129 provider: 'microsoft',
130 name: {}
131 };
132 profile.id = json.id;
133 profile.displayName = json.displayName;
134 profile.name.familyName = json.surname;
135 profile.name.givenName = json.givenName;
136 profile.emails = [ { type: 'work', value: json.mail } ];
137
138 profile._raw = body;
139 profile._json = json;
140
141 done(null, profile);
142 } catch (e) {
143 done(e);
144 }
145 }
146 );
147};
148
149/**
150 * Expose `Strategy`.
151 */
152
153module.exports = MicrosoftStrategy;