Merge pull request #8596 from cmpadden/adr013-adherance

Replace `got` and `axios` dependencies with `node-fetch`
This commit is contained in:
Patrik Oldsberg
2021-12-27 17:05:51 +01:00
committed by GitHub
9 changed files with 240 additions and 74 deletions
-1
View File
@@ -46,7 +46,6 @@
"express-promise-router": "^4.1.0",
"express-session": "^1.17.1",
"fs-extra": "9.1.0",
"got": "^11.5.2",
"helmet": "^4.0.0",
"jose": "^1.27.1",
"jwt-decode": "^3.1.0",
@@ -20,6 +20,9 @@ import { OAuthResult } from '../../lib/oauth';
import { getVoidLogger } from '@backstage/backend-common';
import { TokenIssuer } from '../../identity/types';
import { CatalogIdentityClient } from '../../lib/catalog';
import { setupRequestMockHandlers } from '@backstage/test-utils';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const mockFrameHandler = jest.spyOn(
helpers,
@@ -28,8 +31,62 @@ const mockFrameHandler = jest.spyOn(
() => Promise<{ result: OAuthResult; privateInfo: any }>
>;
const mockResult = {
result: {
fullProfile: {
emails: [
{
type: 'work',
value: 'conrad@example.com',
},
],
displayName: 'Conrad',
name: {
familyName: 'Ribas',
givenName: 'Francisco',
},
id: 'conrad',
provider: 'microsoft',
photos: [
{
value: 'some-data',
},
],
},
params: {
id_token: 'idToken',
scope: 'scope',
expires_in: 123,
},
accessToken: 'accessToken',
},
privateInfo: {
refreshToken: 'wacka',
},
};
const server = setupServer();
setupRequestMockHandlers(server);
const setupHandlers = () => {
server.use(
rest.get(
'https://graph.microsoft.com/v1.0/me/photos/*',
async (_, res, ctx) => {
const imageBuffer = new Uint8Array([104, 111, 119, 100, 121]).buffer;
return res(
ctx.set('Content-Length', imageBuffer.byteLength.toString()),
ctx.set('Content-Type', 'image/jpeg'),
ctx.body(imageBuffer),
);
},
),
);
};
describe('createMicrosoftProvider', () => {
it('should auth', async () => {
setupHandlers();
const tokenIssuer = {
issueToken: jest.fn(),
listPublicKeys: jest.fn(),
@@ -55,39 +112,7 @@ describe('createMicrosoftProvider', () => {
callbackUrl: 'mock',
});
mockFrameHandler.mockResolvedValueOnce({
result: {
fullProfile: {
emails: [
{
type: 'work',
value: 'conrad@example.com',
},
],
displayName: 'Conrad',
name: {
familyName: 'Ribas',
givenName: 'Francisco',
},
id: 'conrad',
provider: 'microsoft',
photos: [
{
value: 'some-data',
},
],
},
params: {
id_token: 'idToken',
scope: 'scope',
expires_in: 123,
},
accessToken: 'accessToken',
},
privateInfo: {
refreshToken: 'wacka',
},
});
mockFrameHandler.mockResolvedValueOnce(mockResult);
const { response } = await provider.handler({} as any);
expect(response).toEqual({
providerInfo: {
@@ -103,4 +128,45 @@ describe('createMicrosoftProvider', () => {
},
});
});
it('should return the base64 encoded photo data of the profile', async () => {
setupHandlers();
const tokenIssuer = {
issueToken: jest.fn(),
listPublicKeys: jest.fn(),
};
const catalogIdentityClient = {
findUser: jest.fn(),
};
const provider = new MicrosoftAuthProvider({
logger: getVoidLogger(),
catalogIdentityClient:
catalogIdentityClient as unknown as CatalogIdentityClient,
tokenIssuer: tokenIssuer as unknown as TokenIssuer,
authHandler: async ({ fullProfile }) => ({
profile: {
email: fullProfile.emails![0]!.value,
displayName: fullProfile.displayName,
picture: 'http://microsoft.com/lols',
},
}),
clientId: 'mock',
clientSecret: 'mock',
callbackUrl: 'mock',
// define resolver to return user `info` for photo validation
signInResolver: async (info, _) => {
return {
id: 'user.name',
token: 'token',
info: info,
};
},
});
mockFrameHandler.mockResolvedValueOnce(mockResult);
const { response } = await provider.handler({} as any);
const overloadedIdentity = response.backstageIdentity as any;
const photo = overloadedIdentity.info.result.fullProfile.photos[0];
expect(photo.value).toEqual('data:image/jpeg;base64,aG93ZHk=');
});
});
@@ -45,7 +45,7 @@ import {
SignInResolver,
} from '../types';
import { Logger } from 'winston';
import got from 'got';
import fetch from 'node-fetch';
type PrivateInfo = {
refreshToken: string;
@@ -173,19 +173,17 @@ export class MicrosoftAuthProvider implements OAuthHandlers {
private getUserPhoto(accessToken: string): Promise<string | undefined> {
return new Promise(resolve => {
got
.get('https://graph.microsoft.com/v1.0/me/photos/48x48/$value', {
encoding: 'binary',
responseType: 'buffer',
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
.then(photoData => {
const photoURL = `data:image/jpeg;base64,${Buffer.from(
photoData.body,
fetch('https://graph.microsoft.com/v1.0/me/photos/48x48/$value', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
})
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
const imageUrl = `data:image/jpeg;base64,${Buffer.from(
arrayBuffer,
).toString('base64')}`;
resolve(photoURL);
resolve(imageUrl);
})
.catch(error => {
this.logger.warn(