Vue Storefront is now Alokai! Learn More
LoginCustomer

LoginCustomer

Implements LoginCustomer Unified Method.

Source

import { defineApi, getCartFromContext } from "@vsf-enterprise/unified-api-sapcc";
import { AUTH_USER_COOKIE_NAME, AUTH_USER_TOKEN_COOKIE_NAME } from "@vsf-enterprise/sapcc-api";
import type { OAuthUserTokenResponse } from "@vsf-enterprise/sapcc-types";
import { getNormalizers } from "@vsf-enterprise/unified-api-sapcc/udl";


declare module "@vsf-enterprise/unified-api-sapcc" {
  interface LoginCustomerExtendedArgs {
    /**
     * Response configuration. List of fields returned in the response body.
     */
    fields?: "BASIC" | "DEFAULT" | "FULL" | string | string[];
  }
}


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) => {
  const { email, password } = args;
  const { normalizeCustomer } = getNormalizers(context);
  const cart = await getCartFromContext(context);

  let loginData: OAuthUserTokenResponse;

  if (context.req.cookies[AUTH_USER_TOKEN_COOKIE_NAME]) {
    throw { statusCode: 403, message: MESSAGE_ALREADY_LOGGED_IN };
  }

  try {
    loginData = await context.extendedApi.auth.OAuthUserAuthorization({
      username: email,
      password: password,
    });
  } catch {
    throw { statusCode: 401, message: MESSAGE_LOGIN_ERROR };
  }

  context.req.cookies[AUTH_USER_TOKEN_COOKIE_NAME] = JSON.stringify(loginData.token);
  const shouldCreateNewCartBasedOnGuestCart = cart.totalItems && cart.guid;

  if (shouldCreateNewCartBasedOnGuestCart) {
    await context.api.createCart({
      oldCartId: cart.guid,
    });
  }

  try {
    const { data: user } = await context.api.getUser({});

    return {
      customer: normalizeCustomer(user),
    };
  } catch {
    // customer is already logged in, but the token has to be cleared
    context.res.clearCookie(AUTH_USER_TOKEN_COOKIE_NAME);
    context.res.clearCookie(AUTH_USER_COOKIE_NAME);

    throw { statusCode: 401, message: MESSAGE_LOGIN_ERROR };
  }
});