From f809368e4ffca330c41038609c139dd58f71502b Mon Sep 17 00:00:00 2001 From: Lukasz Ostrowski Date: Mon, 22 May 2023 19:26:03 +0200 Subject: [PATCH] Add tokenRefresh event (#244) * Add tokenRefresh event * Create slow-oranges-serve.md * update docs --- .changeset/slow-oranges-serve.md | 12 ++++++++++++ docs/app-bridge.md | 1 + src/app-bridge/app-bridge.test.ts | 27 +++++++++++++++++++++++++++ src/app-bridge/app-bridge.ts | 7 +++++++ src/app-bridge/events.test.ts | 9 +++++++++ src/app-bridge/events.ts | 19 ++++++++++++++++++- 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 .changeset/slow-oranges-serve.md diff --git a/.changeset/slow-oranges-serve.md b/.changeset/slow-oranges-serve.md new file mode 100644 index 0000000..dc5b52d --- /dev/null +++ b/.changeset/slow-oranges-serve.md @@ -0,0 +1,12 @@ +--- +"@saleor/app-sdk": patch +--- + +Added `tokenRefresh` event to AppBridge. + +It's meant to be triggered by dashboard, when token is refreshed. +Apps that use new AppBridge will receive fresh token. + +This fixes [this issue](https://github.com/saleor/saleor-app-sdk/issues/222) + +For Saleor Cloud where token lives for 24h it was rare, but Saleor can be set to have any token duration, causing app to fail fast. diff --git a/docs/app-bridge.md b/docs/app-bridge.md index 3908f24..022fa17 100644 --- a/docs/app-bridge.md +++ b/docs/app-bridge.md @@ -128,6 +128,7 @@ appBridge.unsubscribeAll(); | `redirect` | Fired when Dashboard changes a subpath within the app path | | `theme` | Fired when Dashboard changes the theme | | `localeChanged` | Fired when Dashboard changes locale (and passes locale code in payload) | +| `tokenRefresh` | Fired when Dashboard receives a new auth token and passes it to the app | See [source code for detailed payload](./src/app-bridge/events.ts) diff --git a/src/app-bridge/app-bridge.test.ts b/src/app-bridge/app-bridge.test.ts index 9049f2a..4efa4cb 100644 --- a/src/app-bridge/app-bridge.test.ts +++ b/src/app-bridge/app-bridge.test.ts @@ -7,6 +7,7 @@ import { actions, ActionType, AppBridge, + DashboardEventFactory, DispatchResponseEvent, HandshakeEvent, ThemeEvent, @@ -286,4 +287,30 @@ describe("AppBridge", () => { appBridge = new AppBridge({ autoNotifyReady: true }); })); + + it("Overwrites token after tokenRefresh action is triggered", () => { + const tokenRefreshEvent = DashboardEventFactory.createTokenRefreshEvent("new-token"); + + expect(appBridge.getState().token).toBeUndefined(); + + fireEvent( + window, + new MessageEvent("message", { + data: handshakeEvent, + origin, + }) + ); + + expect(appBridge.getState().token).toEqual(handshakeEvent.payload.token); + + fireEvent( + window, + new MessageEvent("message", { + data: tokenRefreshEvent, + origin, + }) + ); + + expect(appBridge.getState().token).toEqual(tokenRefreshEvent.payload.token); + }); }); diff --git a/src/app-bridge/app-bridge.ts b/src/app-bridge/app-bridge.ts index 5db0bad..b032ee2 100644 --- a/src/app-bridge/app-bridge.ts +++ b/src/app-bridge/app-bridge.ts @@ -52,6 +52,12 @@ function eventStateReducer(state: AppBridgeState, event: Events) { locale: event.payload.locale, }; } + case EventType.tokenRefresh: { + return { + ...state, + token: event.payload.token, + }; + } case EventType.response: { return state; } @@ -72,6 +78,7 @@ const createEmptySubscribeMap = (): SubscribeMap => ({ redirect: {}, theme: {}, localeChanged: {}, + tokenRefresh: {}, }); export type AppBridgeOptions = { diff --git a/src/app-bridge/events.test.ts b/src/app-bridge/events.test.ts index 2cf2b5e..9b6b868 100644 --- a/src/app-bridge/events.test.ts +++ b/src/app-bridge/events.test.ts @@ -49,4 +49,13 @@ describe("DashboardEventFactory", () => { type: "localeChanged", }); }); + + it("Creates token refresh event", () => { + expect(DashboardEventFactory.createTokenRefreshEvent("TOKEN")).toEqual({ + payload: { + token: "TOKEN", + }, + type: "tokenRefresh", + }); + }); }); diff --git a/src/app-bridge/events.ts b/src/app-bridge/events.ts index 44f3199..ec76680 100644 --- a/src/app-bridge/events.ts +++ b/src/app-bridge/events.ts @@ -9,6 +9,7 @@ export const EventType = { redirect: "redirect", theme: "theme", localeChanged: "localeChanged", + tokenRefresh: "tokenRefresh", } as const; export type EventType = Values; @@ -56,12 +57,20 @@ export type LocaleChangedEvent = Event< } >; +export type TokenRefreshEvent = Event< + "tokenRefresh", + { + token: string; + } +>; + export type Events = | HandshakeEvent | DispatchResponseEvent | RedirectEvent | ThemeEvent - | LocaleChangedEvent; + | LocaleChangedEvent + | TokenRefreshEvent; export type PayloadOfEvent< TEventType extends EventType, @@ -112,4 +121,12 @@ export const DashboardEventFactory = { }, }; }, + createTokenRefreshEvent(newToken: string): TokenRefreshEvent { + return { + type: "tokenRefresh", + payload: { + token: newToken, + }, + }; + }, };