@scayle/storefront-core
Version:
Collection of essential utilities to work with the Storefront API
123 lines (122 loc) • 3.62 kB
JavaScript
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
});
await 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 };