auth-node: move parseWebPessageResponse to test util + fix error value handling
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2023 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { WebMessageResponse } from '../sendWebMessageResponse';
|
||||
|
||||
export function parseWebMessageResponse(text: string): {
|
||||
response: WebMessageResponse;
|
||||
origin: string;
|
||||
} {
|
||||
const [response, origin] = text.matchAll(/decodeURIComponent\('(.+?)'\)/g);
|
||||
return {
|
||||
response: JSON.parse(decodeURIComponent(response[1])),
|
||||
origin: decodeURIComponent(origin[1]),
|
||||
};
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
sendWebMessageResponse,
|
||||
type WebMessageResponse,
|
||||
} from './sendWebMessageResponse';
|
||||
import { parseWebMessageResponse } from './__testUtils__/parseWebMessageResponse';
|
||||
|
||||
describe('oauth helpers', () => {
|
||||
describe('safelyEncodeURIComponent', () => {
|
||||
@@ -78,7 +79,12 @@ describe('oauth helpers', () => {
|
||||
type: 'authorization_response',
|
||||
error: new Error('Unknown error occurred'),
|
||||
};
|
||||
const encoded = safelyEncodeURIComponent(JSON.stringify(data));
|
||||
const encoded = safelyEncodeURIComponent(
|
||||
JSON.stringify({
|
||||
type: 'authorization_response',
|
||||
error: { name: 'Error', message: 'Unknown error occurred' },
|
||||
}),
|
||||
);
|
||||
|
||||
sendWebMessageResponse(mockResponse, appOrigin, data);
|
||||
expect(mockResponse.setHeader).toHaveBeenCalledTimes(3);
|
||||
@@ -122,20 +128,29 @@ describe('oauth helpers', () => {
|
||||
},
|
||||
};
|
||||
sendWebMessageResponse(mockResponse, appOrigin, data);
|
||||
expect(responseBody.match(/.postMessage\(/g)).toHaveLength(2);
|
||||
expect(
|
||||
responseBody.match(/.postMessage\([a-zA-z.()]*, \'\*\'\)/g),
|
||||
).toHaveLength(1);
|
||||
expect(parseWebMessageResponse(responseBody).response).toEqual({
|
||||
type: 'authorization_response',
|
||||
response: {
|
||||
providerInfo: expect.any(Object),
|
||||
profile: {
|
||||
email: 'foo@bar.com',
|
||||
},
|
||||
backstageIdentity: expect.any(Object),
|
||||
},
|
||||
});
|
||||
|
||||
const errData: WebMessageResponse = {
|
||||
type: 'authorization_response',
|
||||
error: new Error('Unknown error occurred'),
|
||||
};
|
||||
sendWebMessageResponse(mockResponse, appOrigin, errData);
|
||||
expect(responseBody.match(/.postMessage\(/g)).toHaveLength(2);
|
||||
expect(
|
||||
responseBody.match(/.postMessage\([a-zA-z.()]*, \'\*\'\)/g),
|
||||
).toHaveLength(1);
|
||||
expect(parseWebMessageResponse(responseBody).response).toEqual({
|
||||
type: 'authorization_response',
|
||||
error: {
|
||||
name: 'Error',
|
||||
message: 'Unknown error occurred',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('handles single quotes and unicode chars safely', () => {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { Response } from 'express';
|
||||
import crypto from 'crypto';
|
||||
import { ClientAuthResponse } from '../types';
|
||||
import { serializeError } from '@backstage/errors';
|
||||
|
||||
/**
|
||||
* Payload sent as a post message after the auth request is complete.
|
||||
@@ -47,7 +48,12 @@ export function sendWebMessageResponse(
|
||||
appOrigin: string,
|
||||
response: WebMessageResponse,
|
||||
): void {
|
||||
const jsonData = JSON.stringify(response);
|
||||
const jsonData = JSON.stringify(response, (_, value) => {
|
||||
if (value instanceof Error) {
|
||||
return serializeError(value);
|
||||
}
|
||||
return value;
|
||||
});
|
||||
const base64Data = safelyEncodeURIComponent(jsonData);
|
||||
const base64Origin = safelyEncodeURIComponent(appOrigin);
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import { createOAuthRouteHandlers } from './createOAuthRouteHandlers';
|
||||
import { OAuthAuthenticator } from './types';
|
||||
import { errorHandler } from '@backstage/backend-common';
|
||||
import { encodeOAuthState, OAuthState } from './state';
|
||||
import { WebMessageResponse } from '../flow';
|
||||
import { PassportProfile } from '../passport';
|
||||
import { parseWebMessageResponse } from '../flow/__testUtils__/parseWebMessageResponse';
|
||||
|
||||
const mockAuthenticator: jest.Mocked<OAuthAuthenticator<unknown, unknown>> = {
|
||||
initialize: jest.fn(_r => ({ ctx: 'authenticator' })),
|
||||
@@ -109,17 +109,6 @@ function getGrantedScopesCookie(test: SuperAgentTest) {
|
||||
});
|
||||
}
|
||||
|
||||
function parseWebMessageResponse(text: string): {
|
||||
response: WebMessageResponse;
|
||||
origin: string;
|
||||
} {
|
||||
const [response, origin] = text.matchAll(/decodeURIComponent\('(.+?)'\)/g);
|
||||
return {
|
||||
response: JSON.parse(decodeURIComponent(response[1])),
|
||||
origin: decodeURIComponent(origin[1]),
|
||||
};
|
||||
}
|
||||
|
||||
describe('createOAuthRouteHandlers', () => {
|
||||
afterEach(() => jest.clearAllMocks());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user