import * as Sentry from "@sentry/nextjs" import { createCounter } from "@scandic-hotels/common/telemetry" import * as api from "../../../api" import { cache } from "../../../DUPLICATED/cache" import { extractResponseDetails, serverErrorByStatus, sessionExpiredError, } from "../../../errors" import { scandicMembershipTypes } from "../helpers" import { getBasicUserSchema } from "../output" import type z from "zod" import type { DeepPartial } from "../../../types/deepPartial" export const getBasicUser = cache( async ({ token, }: { token: { expires_at?: number; access_token: string } }) => { const getBasicUserCounter = createCounter("user.getBasicUser") const metricsGetBasicUser = getBasicUserCounter.init() metricsGetBasicUser.start() const now = Date.now() if (token.expires_at && token.expires_at < now) { throw sessionExpiredError() } const apiResponse = await api.get(api.endpoints.v2.Profile.basicProfile, { headers: { Authorization: `Bearer ${token.access_token}`, }, }) if (!apiResponse.ok) { await metricsGetBasicUser.httpError(apiResponse) throw serverErrorByStatus( apiResponse.status, await extractResponseDetails(apiResponse), "getBasicUser failed" ) } const apiJson = await apiResponse.json() const verifiedData = getBasicUserSchema.safeParse(apiJson) if (!verifiedData.success) { addUserToSentry(apiJson) metricsGetBasicUser.validationError(verifiedData.error) throw verifiedData.error } metricsGetBasicUser.success() return verifiedData.data } ) function addUserToSentry(apiJson: unknown) { const typedData = apiJson as DeepPartial> const memberShipNumber = typedData?.loyalty?.memberships?.find( (m) => m?.membershipType === scandicMembershipTypes.SCANDIC_NATIVE )?.membershipNumber if ( typeof typedData?.profileId === "undefined" || typeof memberShipNumber === "undefined" ) { return } Sentry.setUser({ id: typedData?.profileId, username: memberShipNumber, }) }