diff --git a/src/app-bridge/index.ts b/src/app-bridge/index.ts index 55a9861d..a68edc19 100644 --- a/src/app-bridge/index.ts +++ b/src/app-bridge/index.ts @@ -6,6 +6,7 @@ export * from "./actions"; export * from "./app-bridge-provider"; export * from "./events"; export * from "./types"; +export * from "./use-dashboard-token"; /** * @deprecated use new AppBridge(), createApp will be removed diff --git a/src/app-bridge/use-dashboard-token.ts b/src/app-bridge/use-dashboard-token.ts new file mode 100644 index 00000000..e827f940 --- /dev/null +++ b/src/app-bridge/use-dashboard-token.ts @@ -0,0 +1,49 @@ +import debugPkg from "debug"; +import * as jose from "jose"; +import { useMemo } from "react"; + +import { useAppBridge } from "./app-bridge-provider"; + +export interface DashboardTokenPayload extends jose.JWTPayload { + app: string; +} + +export interface DashboardTokenProps { + isTokenValid: boolean; + hasAppToken: boolean; + tokenClaims: DashboardTokenPayload | null; +} + +const debug = debugPkg.debug("app-sdk:AppBridge"); + +export const useDashboardToken = (): DashboardTokenProps => { + const { appBridgeState } = useAppBridge(); + + const tokenClaims = useMemo(() => { + try { + if (appBridgeState?.token) { + debug("Trying to decode JWT token drom dashboard"); + return jose.decodeJwt(appBridgeState?.token) as DashboardTokenPayload; + } + } catch (e) { + debug("Failed decoding JWT token"); + console.error(e); + } + return null; + }, [appBridgeState?.token]); + + if (tokenClaims && !tokenClaims.iss) { + console.error(` + "iss" not found in decoded token claims. Ensure Saleor has domain assigned + Check documentation for more details + https://docs.saleor.io/docs/3.x/dashboard/configuration/site#general-information`); + } + + const isTokenValid = tokenClaims ? tokenClaims.iss === appBridgeState?.domain : false; + + return { + isTokenValid, + tokenClaims, + hasAppToken: Boolean(appBridgeState?.token), + }; +};