Skip to content

Microsoft Graph Authentication #6051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 26, 2019
18 changes: 17 additions & 1 deletion spec/AuthenticationAdapters.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const responses = {
weibo: { uid: 'userId' },
qq: 'callback( {"openid":"userId"} );', // yes it's like that, run eval in the client :P
phantauth: { sub: 'userId' },
microsoft: { id: 'userId', mail: 'userMail' },
};

describe('AuthenticationProviders', function() {
Expand All @@ -37,7 +38,8 @@ describe('AuthenticationProviders', function() {
'wechat',
'weibo',
'phantauth',
].map(function(providerName) {
'microsoft',
].map(function (providerName) {
it('Should validate structure of ' + providerName, done => {
const provider = require('../lib/Adapters/Auth/' + providerName);
jequal(typeof provider.validateAuthData, 'function');
Expand Down Expand Up @@ -1194,3 +1196,17 @@ describe('phant auth adapter', () => {
}
});
});

describe('microsoft graph auth adapter', () => {
const microsoft = require('../lib/Adapters/Auth/microsoft');
const httpsRequest = require('../lib/Adapters/Auth/httpsRequest');

it('should use access_token for validation is passed and responds with id and mail', async () => {
spyOn(httpsRequest, 'get').and.callFake(() => {
return Promise.resolve({ id: 'userId', mail: 'userMail' });
});
await microsoft.validateAuthData(
{ id: 'userId', access_token: 'the_token' }
);
});
});
18 changes: 18 additions & 0 deletions spec/MicrosoftAuth.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const microsoft = require('../lib/Adapters/Auth/microsoft');

describe('Microsoft Auth', () => {
it('should fail to validate Microsoft Graph auth with bad token', done => {
const authData = {
id: 'fake-id',
mail: '[email protected]',
access_token: 'very.long.bad.token',
};
microsoft.validateAuthData(authData).then(done.fail, err => {
expect(err.code).toBe(101);
expect(err.message).toBe(
'Microsoft Graph auth is invalid for this user.'
);
done();
});
});
});
2 changes: 2 additions & 0 deletions src/Adapters/Auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const wechat = require('./wechat');
const weibo = require('./weibo');
const oauth2 = require('./oauth2');
const phantauth = require('./phantauth');
const microsoft = require('./microsoft');

const anonymous = {
validateAuthData: () => {
Expand Down Expand Up @@ -51,6 +52,7 @@ const providers = {
wechat,
weibo,
phantauth,
microsoft,
};

function authDataValidator(adapter, appIds, options) {
Expand Down
39 changes: 39 additions & 0 deletions src/Adapters/Auth/microsoft.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Helper functions for accessing the microsoft graph API.
var Parse = require('parse/node').Parse;
const httpsRequest = require('./httpsRequest');

// Returns a promise that fulfills if this user mail is valid.
function validateAuthData(authData) {
return request('me', authData.access_token).then(
response => {
if (response && response.id && response.id == authData.id) {
return;
}
throw new Parse.Error(
Parse.Error.OBJECT_NOT_FOUND,
'Microsoft Graph auth is invalid for this user.'
);
}
);
}

// Returns a promise that fulfills if this app id is valid.
function validateAppId() {
return Promise.resolve();
}

// A promisey wrapper for api requests
function request(path, access_token) {
return httpsRequest.get({
host: 'graph.microsoft.com',
path: '/v1.0/' + path,
headers: {
Authorization: 'Bearer ' + access_token,
},
});
}

module.exports = {
validateAppId: validateAppId,
validateAuthData: validateAuthData,
};