UNPKG

@scayle/storefront-core

Version:

Collection of essential utilities to work with the Storefront API

123 lines (122 loc) 3.61 kB
import { hasSession } from "../../types/index.mjs"; import { CustomerAPIClient } from "../../api/customer.mjs"; import { getOAuthClient } from "../../api/oauth.mjs"; import { HttpStatusCode, HttpStatusMessage } from "../../constants/index.mjs"; import { ErrorResponse } from "../../errors/index.mjs"; import { FetchError } from "../../utils/fetch.mjs"; import { defineRpcHandler } from "../../utils/rpc.mjs"; import { sha256 } from "../../utils/index.mjs"; const getUser = defineRpcHandler( (context) => { const { user } = context; if (user) { user.authentication = user.authentication ?? { type: "idp" }; } return { user }; }, // We use POST here to prevent user data to be leaking into caches. { method: "POST" } ); const fetchUser = defineRpcHandler( async ({ accessToken }, context) => { const { shopId } = context; const client = new CustomerAPIClient(context); const user = await client.getMe(shopId, accessToken); if (!user.authentication) { user.authentication = { type: "idp" }; } if (user.email) { user.emailHash = await sha256(user.email); } user.orderSummary = user.orderSummary?.filter( ({ shopId: shopId2 }) => shopId2 === context.shopId ); return user; }, { method: "POST" } ); const refreshUser = defineRpcHandler( async (context) => { if (!hasSession(context)) { return new ErrorResponse( HttpStatusCode.BAD_REQUEST, HttpStatusMessage.BAD_REQUEST, "No Session found" ); } const { accessToken } = context; if (!accessToken) { return { user: void 0 }; } try { const user = await context.callRpc?.("fetchUser", { accessToken }); if (!user) { return { user: void 0 }; } context.updateUser(user); return { user }; } catch { await context.destroySession(); return { user: void 0 }; } }, { method: "POST" } ); const getAccessToken = defineRpcHandler( async ({ forceTokenRefresh = false } = { forceTokenRefresh: false }, context) => { if (!hasSession(context)) { return new ErrorResponse( HttpStatusCode.BAD_REQUEST, HttpStatusMessage.BAD_REQUEST, "No Session found" ); } if (!context.accessToken) { return new ErrorResponse( HttpStatusCode.UNAUTHORIZED, HttpStatusMessage.UNAUTHORIZED, "No access token present" ); } if (forceTokenRefresh) { if (!context.refreshToken) { return new ErrorResponse( HttpStatusCode.UNAUTHORIZED, HttpStatusMessage.UNAUTHORIZED, "No refresh token present" ); } const client = getOAuthClient(context); try { const tokens = await client.refreshToken({ grant_type: "refresh_token", refresh_token: context.refreshToken }); context.updateTokens({ accessToken: tokens.access_token, refreshToken: tokens.refresh_token }); } catch (e) { if (e instanceof FetchError && e.response.status === HttpStatusCode.UNAUTHORIZED) { context.log.debug( "Failed to refresh Checkout Token due to invalid refresh token. Deleting session" ); await context.destroySession(); } else { context.log.debug( "Failed to refresh Checkout Token for unknown reason." ); } } } return context.accessToken; }, { method: "POST" } ); export { getUser, fetchUser, refreshUser, getAccessToken };