LoginCustomer
Implements LoginCustomer
Unified Method.
Source
/* eslint-disable etc/throw-error */
import { defineApi } from "@vsf-enterprise/unified-api-commercetools";
import {
CT_COOKIE_NAME,
isAnonymousSession,
type CommercetoolsIntegrationContext,
} from "@vsf-enterprise/commercetools-api";
import { getNormalizers } from "@vsf-enterprise/unified-api-commercetools/udl";
const MESSAGE_LOGIN_ERROR = "Could not login customer";
const MESSAGE_ALREADY_LOGGED_IN = "Customer is already logged in";
export const loginCustomer = defineApi.loginCustomer(async (context, args) => {
if (isAlreadyLoggedIn(context)) {
throw { statusCode: 403, message: MESSAGE_ALREADY_LOGGED_IN };
}
try {
const loginData = await context.api.customerSignMeIn(args);
const { normalizeCustomer } = getNormalizers(context);
const user = loginData.user.customer;
if (!user) {
throw { statusCode: 401, message: MESSAGE_LOGIN_ERROR };
}
return { customer: normalizeCustomer(user) };
} catch (error) {
throw mapGraphQlError(error);
}
});
// CT doesn't expose GQL errors type
function mapGraphQlError(err: any) {
const isInvalidCredentials = err?.graphQLErrors?.find(
(error: any) => error.extensions.code === "InvalidCredentials",
);
if (isInvalidCredentials) {
return { statusCode: 401, message: MESSAGE_LOGIN_ERROR };
}
return {
statusCode: 500,
message: "Internal Server Error",
};
}
function isAlreadyLoggedIn(context: CommercetoolsIntegrationContext) {
const rawToken = context.req.cookies[CT_COOKIE_NAME];
if (!rawToken) {
return false;
}
let parsedToken: any;
try {
parsedToken = JSON.parse(rawToken);
} catch {
parsedToken = null;
}
return parsedToken && !isAnonymousSession(parsedToken);
}