Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okta/okta-client-js",
"version": "0.6.0",
"version": "0.7.0",
"private": true,
"packageManager": "yarn@1.22.19",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion packages/auth-foundation/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okta/auth-foundation",
"version": "0.6.0",
"version": "0.7.0",
"type": "module",
"main": "dist/esm/index.js",
"module": "dist/esm/index.js",
Expand Down
23 changes: 23 additions & 0 deletions packages/auth-foundation/src/utils/TaskBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import { AuthSdkError } from '../errors/AuthSdkError.ts';
/** @useDeclaredType */
type TypeMap = Record<string, any>;

/** @internal */
function warn (message: string) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (TaskBridge.warnOnBusMessageMismatch) {
console.warn(message);
}
}

/**
* A bridge for passing messages between a `TaskHandler` and a `Requestor`. The `Requestor` is "asking" the `TaskHandler`
* To perform a `Task` on it's behave. Loosely based on TCP
Expand Down Expand Up @@ -111,6 +119,11 @@ export abstract class TaskBridge<M extends TypeMap, R extends TypeMap> {
// This channel is meant for the Receiver to send the results (aka `HandlerMessage<M>` messages)
// ignore all Requestor events received (aka `RequestorMessage`)
responseChannel.onmessage = (event) => {
const { __v } = event.data;
if (__v !== TaskBridge.BridgeVersion) {
warn(`[Requestor] received mismatched message (requestor=${TaskBridge.BridgeVersion}, message=${__v})`);
}

if (request.signal.aborted || 'action' in event.data) {
return; // ignore message
}
Expand Down Expand Up @@ -162,6 +175,10 @@ export abstract class TaskBridge<M extends TypeMap, R extends TypeMap> {
this.#channel.onmessage = async (evt, reply) => {
const { requestId, __v, ...rest } = evt.data;

if (__v !== TaskBridge.BridgeVersion) {
warn(`[Subscriber] received mismatched message (subscriber=${TaskBridge.BridgeVersion}, message=${__v})`);
}

if (!requestId) {
return;
}
Expand Down Expand Up @@ -260,6 +277,12 @@ export namespace TaskBridge {
// NOTE: update this value when the payload structure of the TaskBridge changes
export const BridgeVersion = 2;

/**
* Toggles whether `console.warn` messages are broadcasted when bus messages are received with
* a mismatched BridgeVersion. Useful for debugging communication issues.
*/
export let warnOnBusMessageMismatch: boolean = false;

/**
* Possible `status` values indicating the process of an orchestrated request
*/
Expand Down
57 changes: 57 additions & 0 deletions packages/auth-foundation/test/spec/utils/TaskBridge.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,61 @@ describe('TaskBridge', () => {
jest.useRealTimers();
});

describe('features', () => {
describe('Mismatch message version warning', () => {
let channel: BroadcastChannel;

beforeEach(() => {
TaskBridge.warnOnBusMessageMismatch = true;
channel = new BroadcastChannel('test');
jest.spyOn(console, 'warn').mockReturnValue();
});

afterEach(() => {
channel.close();
TaskBridge.warnOnBusMessageMismatch = false;
});

test('Requestor will warn get reply doesn\'t match version', async () => {
channel.onmessage = (event) => {
const responseChannel = new BroadcastChannel(event.data.requestId);
responseChannel.postMessage({ status: 'SUCCESS', data: { foo: '1' }, __v: 'foo' });
responseChannel.close();
};

const { result } = sender.send({ foo: 1, bar: 2 });
await result;

expect(console.warn).toHaveBeenCalled();
});

test('Subscriber will warn get reply doesn\'t match version', async () => {
receiver.subscribe(async (message, reply) => {
reply({ foo: '2', bar: '1' });
});

channel.postMessage({ requestId: 'foo', __v: 'foo', data: { foo: 1 }});

// this message is only used in the test to give time for the first message to send
const { result } = sender.send({ foo: 1, bar: 2 });
await result;

expect(console.warn).toHaveBeenCalled();
});

test('No warnings when disabled', async () => {
TaskBridge.warnOnBusMessageMismatch = false;

receiver.subscribe(async (message, reply) => {
reply({ foo: '2', bar: '1' });
});

const { result } = sender.send({ foo: 1, bar: 2 });
await result;

expect(console.warn).not.toHaveBeenCalled();
});
});
});

});
2 changes: 1 addition & 1 deletion packages/oauth2-flows/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okta/oauth2-flows",
"version": "0.6.0",
"version": "0.7.0",
"type": "module",
"main": "dist/esm/index.js",
"module": "dist/esm/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/spa-platform/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okta/spa-platform",
"version": "0.6.0",
"version": "0.7.0",
"type": "module",
"main": "dist/esm/index.js",
"module": "dist/esm/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class MockOrchestrator extends TokenOrchestrator {

describe('HostOrchestrator', () => {

jest.retryTimes(3);

const authParams = {
issuer: 'http://fake.okta.com',
clientId: 'fakeClientId',
Expand Down