Skip to content

Commit

Permalink
fix(javascript-sdk): change x-requested-platform to opt-in
Browse files Browse the repository at this point in the history
  • Loading branch information
cerebrl committed Apr 8, 2024
1 parent 642a32b commit dc11b74
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 11 deletions.
2 changes: 2 additions & 0 deletions e2e/autoscript-apps/src/authn-basic/autoscript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function autoscript() {
const amUrl = url.searchParams.get('amUrl') || 'https://auth.example.com:9443/am';
const realmPath = url.searchParams.get('realmPath') || 'root';
const un = url.searchParams.get('un') || 'sdkuser';
const platformHeader = url.searchParams.get('platformHeader') === 'true' ? true : false;
const pw = url.searchParams.get('pw') || 'password';
const tree = url.searchParams.get('tree') || 'UsernamePassword';

Expand All @@ -41,6 +42,7 @@ function autoscript() {
next();
},
],
platformHeader,
realmPath,
tree,
serverConfig: {
Expand Down
4 changes: 3 additions & 1 deletion e2e/autoscript-suites/src/suites/authn-basic.lc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import { setupAndGo } from '../utilities/setup-and-go';

test.describe('Test Basic login flow', () => {
test(`should login successfully and then log out`, async ({ browserName, page }) => {
const { messageArray } = await setupAndGo(page, browserName, 'authn-basic/');
const { headerArray, messageArray } = await setupAndGo(page, browserName, 'authn-basic/');

// Test assertions
expect(messageArray.includes('Basic login successful')).toBe(true);
expect(messageArray.includes('Logout successful')).toBe(true);
expect(messageArray.includes('Starting authentication with service')).toBe(true);
expect(messageArray.includes('Continuing authentication with service')).toBe(true);

expect(headerArray.find((headers) => headers.get('x-requested-platform'))).toBeFalsy();
});
});
7 changes: 5 additions & 2 deletions e2e/autoscript-suites/src/suites/send-request-header.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ test(`should verifies x-requested-platform header is present in the request`, as
page,
browserName,
}) => {
const { networkArray } = await setupAndGo(page, browserName, 'authn-central-login/');
expect(networkArray.includes('x-requested-platform')).toBe(true);
const { headerArray } = await setupAndGo(page, browserName, 'authn-basic/', {
platformHeader: 'true',
});

expect(headerArray.find((headers) => headers.get('x-requested-platform'))).toBeTruthy();
});
16 changes: 12 additions & 4 deletions e2e/autoscript-suites/src/utilities/setup-and-go.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export async function setupAndGo(
dialogInput?: string;
email?: string;
middleware?: string;
platformHeader?: string;
preAuthenticated?: string;
pw?: string;
realmPath?: string;
Expand All @@ -40,7 +41,12 @@ export async function setupAndGo(
wellknown?: string;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Promise<{ messageArray: string[]; networkArray: string[] }> {
): Promise<{
headerArray: Headers[];
messageArray: string[];
networkArray: string[];
}> {
const headerArray: Headers[] = [];
const messageArray: string[] = [];
const networkArray: string[] = [];

Expand All @@ -53,6 +59,7 @@ export async function setupAndGo(
config && config.code && url.searchParams.set('code', (config && config.code) || '');
url.searchParams.set('email', (config && config.email) || '');
url.searchParams.set('middleware', (config && config.middleware) || '');
url.searchParams.set('platformHeader', (config && config.platformHeader) || '');
url.searchParams.set('preAuthenticated', (config && config.preAuthenticated) || '');
url.searchParams.set('pw', (config && config.pw) || USERS[0].pw);
url.searchParams.set('realmPath', (config && config.realmPath) || REALM_PATH);
Expand Down Expand Up @@ -81,10 +88,11 @@ export async function setupAndGo(

page.on('request', async (req) => {
networkArray.push(`${new URL(req.url()).pathname}, ${req.resourceType()}`);
});

page.on('request', async (req) => {
const headers = await req.allHeaders();
const headersKeys = Object.keys(headers);
networkArray.push(...headersKeys);
headerArray.push(new Headers(headers));
});

page.on('dialog', async (dialog) => {
Expand All @@ -93,5 +101,5 @@ export async function setupAndGo(

await page.waitForSelector(config?.selector || '.Test_Complete');

return { messageArray, networkArray };
return { headerArray, messageArray, networkArray };
}
23 changes: 21 additions & 2 deletions packages/javascript-sdk/src/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class Auth {
* @return {Step} The next step in the authentication tree.
*/
public static async next(previousStep?: Step, options?: StepOptions): Promise<Step> {
const { middleware, realmPath, serverConfig, tree, type } = Config.get(options);
const { middleware, platformHeader, realmPath, serverConfig, tree, type } = Config.get(options);
const query = options ? options.query : {};
const url = this.constructUrl(serverConfig, realmPath, tree, query);
const runMiddleware = middlewareWrapper(
Expand All @@ -47,6 +47,25 @@ abstract class Auth {
},
);
const req = runMiddleware(middleware);

/**
* Run after as to now allow mutation by user
* Since the init headers can be an array, object or Headers class,
* we need to handle all types.
*/
if (platformHeader) {
if (req.init.headers instanceof Headers) {
req.init.headers.set('X-Requested-Platform', X_REQUESTED_PLATFORM);
} else if (Array.isArray(req.init.headers)) {
req.init.headers.push(['X-Requested-Platform', X_REQUESTED_PLATFORM]);
} else if (req.init.headers) {
req.init.headers['X-Requested-Platform'] = X_REQUESTED_PLATFORM;
} else {
req.init.headers = {
'X-Requested-Platform': X_REQUESTED_PLATFORM,
};
}
}
const res = await withTimeout(fetch(req.url.toString(), req.init), serverConfig.timeout);
const json = await this.getResponseJson<Step>(res);
return json;
Expand Down Expand Up @@ -75,10 +94,10 @@ abstract class Auth {
'Accept-API-Version': 'protocol=1.0,resource=2.1',
'Content-Type': 'application/json',
'X-Requested-With': REQUESTED_WITH,
'X-Requested-Platform': X_REQUESTED_PLATFORM,
}),
method: 'POST',
};

return init;
}

Expand Down
1 change: 1 addition & 0 deletions packages/javascript-sdk/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function setDefaults(options: ConfigOptions): ConfigOptions {
...options,
oauthThreshold: options.oauthThreshold || DEFAULT_OAUTH_THRESHOLD,
logLevel: options.logLevel || 'none',
platformHeader: options.platformHeader || false,
prefix: options.prefix || PREFIX,
};
}
Expand Down
2 changes: 2 additions & 0 deletions packages/javascript-sdk/src/config/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface Action {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
payload: any;
}

/**
* Custom Logger for logger
*/
Expand Down Expand Up @@ -50,6 +51,7 @@ interface ConfigOptions {
oauthThreshold?: number;
logLevel?: LogLevel;
logger?: LoggerFunctions;
platformHeader?: boolean;
prefix?: string;
}

Expand Down
23 changes: 21 additions & 2 deletions packages/javascript-sdk/src/session-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ abstract class SessionManager {
* Ends the current session.
*/
public static async logout(options?: ConfigOptions): Promise<Response> {
const { middleware, realmPath, serverConfig } = Config.get(options);
const { middleware, platformHeader, realmPath, serverConfig } = Config.get(options);
const init: RequestInit = {
credentials: 'include',
headers: new Headers({
'Accept-API-Version': 'protocol=1.0,resource=2.0',
'X-Requested-With': REQUESTED_WITH,
'X-Requested-Platform': X_REQUESTED_PLATFORM,
}),
method: 'POST',
};
Expand All @@ -44,6 +43,26 @@ abstract class SessionManager {
{ type: ActionTypes.Logout },
);
const req = runMiddleware(middleware);

/**
* Run after as to now allow mutation by user
* Since the init headers can be an array, object or Headers class,
* we need to handle all types.
*/
if (platformHeader) {
if (req.init.headers instanceof Headers) {
req.init.headers.set('X-Requested-Platform', X_REQUESTED_PLATFORM);
} else if (Array.isArray(req.init.headers)) {
req.init.headers.push(['X-Requested-Platform', X_REQUESTED_PLATFORM]);
} else if (req.init.headers) {
req.init.headers['X-Requested-Platform'] = X_REQUESTED_PLATFORM;
} else {
req.init.headers = {
'X-Requested-Platform': X_REQUESTED_PLATFORM,
};
}
}

const response = await withTimeout(fetch(req.url.toString(), req.init), serverConfig.timeout);
if (!isOkOr4xx(response)) {
throw new Error(`Failed to log out; received ${response.status}`);
Expand Down

0 comments on commit dc11b74

Please sign in to comment.