import type { ServerResponse } from 'http' import type { OperationContext, OperationOptions, } from '@commerce/api/operations' import type { LoginOperation } from '../../types/login' import type { LoginMutation } from '../../schema' import type { RecursivePartial } from '../utils/types' import concatHeader from '../utils/concat-cookie' import type { BigcommerceConfig, Provider } from '..' export const loginMutation = /* GraphQL */ ` mutation login($email: String!, $password: String!) { login(email: $email, password: $password) { result } } ` export default function loginOperation({ commerce, }: OperationContext) { async function login(opts: { variables: T['variables'] config?: BigcommerceConfig res: ServerResponse }): Promise async function login( opts: { variables: T['variables'] config?: BigcommerceConfig res: ServerResponse } & OperationOptions ): Promise async function login({ query = loginMutation, variables, res: response, config, }: { query?: string variables: T['variables'] res: ServerResponse config?: BigcommerceConfig }): Promise { config = commerce.getConfig(config) const { data, res } = await config.fetch>( query, { variables } ) // Bigcommerce returns a Set-Cookie header with the auth cookie let cookie = res.headers.get('Set-Cookie') if (cookie && typeof cookie === 'string') { // In development, don't set a secure cookie or the browser will ignore it if (process.env.NODE_ENV !== 'production') { cookie = cookie.replace('; Secure', '') // SameSite=none can't be set unless the cookie is Secure // bc seems to sometimes send back SameSite=None rather than none so make // this case insensitive cookie = cookie.replace(/; SameSite=none/gi, '; SameSite=lax') } response.setHeader( 'Set-Cookie', concatHeader(response.getHeader('Set-Cookie'), cookie)! ) } return { result: data.login?.result, } } return login }