Updates to redirect implementation after initial PR review.
Signed-off-by: headphonejames <generalfuzz@gmail.com>
This commit is contained in:
@@ -19,7 +19,6 @@ import {
|
||||
safelyEncodeURIComponent,
|
||||
ensuresXRequestedWith,
|
||||
postMessageResponse,
|
||||
redirectMessageResponse,
|
||||
} from './authFlowHelpers';
|
||||
import { WebMessageResponse } from './types';
|
||||
|
||||
@@ -179,22 +178,6 @@ describe('oauth helpers', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('redirectMessageResponse', () => {
|
||||
const redirectUrl = 'http://localhost:3000/catalog';
|
||||
it('should perform redirect', () => {
|
||||
const mockResponse = {
|
||||
end: jest.fn().mockReturnThis(),
|
||||
setHeader: jest.fn().mockReturnThis(),
|
||||
redirect: jest.fn().mockReturnThis(),
|
||||
} as unknown as express.Response;
|
||||
|
||||
redirectMessageResponse(mockResponse, redirectUrl);
|
||||
expect(mockResponse.redirect).toHaveBeenCalledTimes(1);
|
||||
expect(mockResponse.end).not.toHaveBeenCalled();
|
||||
expect(mockResponse.setHeader).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ensuresXRequestedWith', () => {
|
||||
it('should return false if no header present', () => {
|
||||
const mockRequest = {
|
||||
|
||||
@@ -69,14 +69,6 @@ export const postMessageResponse = (
|
||||
res.end(`<html><body><script>${script}</script></body></html>`);
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const redirectMessageResponse = (
|
||||
res: express.Response,
|
||||
redirectUrl: string,
|
||||
) => {
|
||||
res.redirect(redirectUrl);
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const ensuresXRequestedWith = (req: express.Request) => {
|
||||
const requiredHeader = req.header('X-Requested-With');
|
||||
|
||||
@@ -74,7 +74,6 @@ describe('OAuthAdapter', () => {
|
||||
providerId: 'test-provider',
|
||||
appOrigin: 'http://localhost:3000',
|
||||
baseUrl: 'http://domain.org/auth',
|
||||
isPopupAuthenticationRequest: true,
|
||||
cookieConfigurer: mockCookieConfigurer,
|
||||
tokenIssuer: {
|
||||
issueToken: async () => 'my-id-token',
|
||||
@@ -174,10 +173,14 @@ describe('OAuthAdapter', () => {
|
||||
const oauthProvider = new OAuthAdapter(providerInstance, {
|
||||
...oAuthProviderOptions,
|
||||
isOriginAllowed: () => false,
|
||||
isPopupAuthenticationRequest: false,
|
||||
});
|
||||
|
||||
const mockRequest = createEncodedQueryMockRequest(defaultState);
|
||||
const state = {
|
||||
...defaultState,
|
||||
redirectUrl: 'http://localhost:3000',
|
||||
authFlow: 'redirect',
|
||||
};
|
||||
const mockRequest = createEncodedQueryMockRequest(state);
|
||||
|
||||
await oauthProvider.frameHandler(mockRequest, mockResponse);
|
||||
expect(mockResponse.redirect).toHaveBeenCalledTimes(1);
|
||||
@@ -343,7 +346,6 @@ describe('OAuthAdapter', () => {
|
||||
baseUrl: 'http://domain.org/auth',
|
||||
appUrl: 'http://domain.org',
|
||||
isOriginAllowed: () => false,
|
||||
isPopupAuthenticationRequest: true,
|
||||
};
|
||||
|
||||
const oauthProvider = OAuthAdapter.fromConfig(config, providerInstance, {
|
||||
@@ -365,7 +367,6 @@ describe('OAuthAdapter', () => {
|
||||
baseUrl: 'http://domain.org/auth',
|
||||
appUrl: 'http://domain.org',
|
||||
isOriginAllowed: () => false,
|
||||
isPopupAuthenticationRequest: true,
|
||||
};
|
||||
|
||||
const mockStartRequestWithOrigin = {
|
||||
@@ -505,7 +506,7 @@ describe('OAuthAdapter', () => {
|
||||
expect(mockResponse.redirect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('executed a response redirect when isPopupAuthenticationRequest is false', async () => {
|
||||
it('executed a response redirect when authFlow query string is set to "redirect"', async () => {
|
||||
const handlers = {
|
||||
start: jest.fn(async (_req: { state: OAuthState }) => ({
|
||||
url: '/url',
|
||||
@@ -516,7 +517,6 @@ describe('OAuthAdapter', () => {
|
||||
};
|
||||
const configWithNoPopupEnabled = {
|
||||
...configOriginAllowed,
|
||||
isPopupAuthenticationRequest: false,
|
||||
};
|
||||
const oauthProvider = OAuthAdapter.fromConfig(
|
||||
configWithNoPopupEnabled,
|
||||
@@ -531,6 +531,7 @@ describe('OAuthAdapter', () => {
|
||||
...defaultState,
|
||||
origin: 'http://other.domain',
|
||||
redirectUrl: 'http://domain.org',
|
||||
authFlow: 'redirect',
|
||||
};
|
||||
|
||||
const mockRequest = {
|
||||
@@ -540,7 +541,6 @@ describe('OAuthAdapter', () => {
|
||||
|
||||
await oauthProvider.frameHandler(mockRequest, mockResponse);
|
||||
expect(mockRequest.get).not.toHaveBeenCalled();
|
||||
expect(mockResponse.end).not.toHaveBeenCalled();
|
||||
expect(mockCookieConfigurer).not.toHaveBeenCalled();
|
||||
expect(mockResponse.cookie).not.toHaveBeenCalled();
|
||||
expect(mockResponse.redirect).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
import { defaultCookieConfigurer, readState, verifyNonce } from './helpers';
|
||||
import {
|
||||
postMessageResponse,
|
||||
redirectMessageResponse,
|
||||
ensuresXRequestedWith,
|
||||
WebMessageResponse,
|
||||
} from '../flow';
|
||||
@@ -61,7 +60,6 @@ export type OAuthAdapterOptions = {
|
||||
cookieConfigurer: CookieConfigurer;
|
||||
isOriginAllowed: (origin: string) => boolean;
|
||||
callbackUrl: string;
|
||||
isPopupAuthenticationRequest: boolean;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
@@ -74,8 +72,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
'providerId' | 'persistScopes' | 'callbackUrl' | 'redirectUrl'
|
||||
>,
|
||||
): OAuthAdapter {
|
||||
const { appUrl, baseUrl, isOriginAllowed, isPopupAuthenticationRequest } =
|
||||
config;
|
||||
const { appUrl, baseUrl, isOriginAllowed } = config;
|
||||
const { origin: appOrigin } = new URL(appUrl);
|
||||
|
||||
const cookieConfigurer = config.cookieConfigurer ?? defaultCookieConfigurer;
|
||||
@@ -86,7 +83,6 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
baseUrl,
|
||||
cookieConfigurer,
|
||||
isOriginAllowed,
|
||||
isPopupAuthenticationRequest: isPopupAuthenticationRequest,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -108,6 +104,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
const env = req.query.env?.toString();
|
||||
const origin = req.query.origin?.toString();
|
||||
const redirectUrl = req.query.redirectUrl?.toString();
|
||||
const authFlow = req.query.authFlow?.toString();
|
||||
if (!env) {
|
||||
throw new InputError('No env provided in request query parameters');
|
||||
}
|
||||
@@ -118,7 +115,7 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
// set a nonce cookie before redirecting to oauth provider
|
||||
this.setNonceCookie(res, nonce, cookieConfig);
|
||||
|
||||
const state: OAuthState = { nonce, env, origin, redirectUrl };
|
||||
const state: OAuthState = { nonce, env, origin, redirectUrl, authFlow };
|
||||
|
||||
// If scopes are persisted then we pass them through the state so that we
|
||||
// can set the cookie on successful auth
|
||||
@@ -184,8 +181,8 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
|
||||
response: { ...response, backstageIdentity: identity },
|
||||
};
|
||||
|
||||
if (!this.options.isPopupAuthenticationRequest) {
|
||||
return redirectMessageResponse(res, redirectUrl);
|
||||
if (state.authFlow === 'redirect') {
|
||||
res.redirect(redirectUrl);
|
||||
}
|
||||
// post message back to popup if successful
|
||||
return postMessageResponse(res, appOrigin, responseObj);
|
||||
|
||||
@@ -91,6 +91,7 @@ export type OAuthState = {
|
||||
origin?: string;
|
||||
scope?: string;
|
||||
redirectUrl?: string;
|
||||
authFlow?: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -131,8 +131,6 @@ export type AuthProviderConfig = {
|
||||
* The function used to resolve cookie configuration based on the auth provider options.
|
||||
*/
|
||||
cookieConfigurer?: CookieConfigurer;
|
||||
|
||||
isPopupAuthenticationRequest: boolean;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -107,8 +107,6 @@ export async function createRouter(
|
||||
...providerFactories,
|
||||
};
|
||||
const providersConfig = config.getConfig('auth.providers');
|
||||
const isPopupAuthenticationRequest =
|
||||
config.getOptionalBoolean('auth.usePopup') ?? true;
|
||||
|
||||
const configuredProviders = providersConfig.keys();
|
||||
|
||||
@@ -126,7 +124,6 @@ export async function createRouter(
|
||||
baseUrl: authUrl,
|
||||
appUrl,
|
||||
isOriginAllowed,
|
||||
isPopupAuthenticationRequest: isPopupAuthenticationRequest,
|
||||
},
|
||||
config: providersConfig.getConfig(providerId),
|
||||
logger,
|
||||
|
||||
Reference in New Issue
Block a user