From 0f381d4cc6aa5197d8629e942382de9f5d6a3c75 Mon Sep 17 00:00:00 2001 From: Alessandro Casazza Date: Fri, 6 Aug 2021 17:33:00 +0200 Subject: [PATCH] feat: Add customer authentication --- components/auth/LoginView.tsx | 3 +- framework/commerce/api/endpoints/login.ts | 2 +- framework/commerce/api/index.ts | 1 + framework/commercelayer/.env.template | 4 -- framework/commercelayer/README.md | 24 +------ .../api/endpoints/login/index.ts | 45 ++++++++---- .../api/endpoints/login/login.ts | 47 ------------- .../api/endpoints/signup/index.ts | 19 +----- .../api/endpoints/signup/signup.ts | 55 --------------- framework/commercelayer/api/index.ts | 68 +++---------------- .../api/operations/get-all-pages.ts | 4 +- .../api/operations/get-all-products.ts | 4 +- .../api/operations/get-product.ts | 4 +- .../api/operations/get-site-info.ts | 4 +- framework/commercelayer/api/utils/cookies.ts | 15 ++++ .../api/utils/credentials-validator.ts | 11 --- framework/commercelayer/api/utils/errors.ts | 22 ------ .../commercelayer/api/utils/fetch-api.ts | 40 ----------- .../commercelayer/api/utils/fetch-local.ts | 35 ++++++++++ .../commercelayer/api/utils/get-token.ts | 40 ----------- framework/commercelayer/auth/use-login.tsx | 52 +++++++------- framework/commercelayer/auth/use-signup.tsx | 47 +++---------- framework/commercelayer/fetcher.ts | 1 + framework/commercelayer/index.tsx | 8 +-- framework/commercelayer/provider.ts | 4 +- framework/commercelayer/types/cart.ts | 1 - framework/commercelayer/types/checkout.ts | 1 - framework/commercelayer/types/common.ts | 1 - framework/commercelayer/types/customer.ts | 1 - framework/commercelayer/types/index.ts | 25 ------- framework/commercelayer/types/login.ts | 11 --- framework/commercelayer/types/logout.ts | 1 - framework/commercelayer/types/page.ts | 1 - framework/commercelayer/types/product.ts | 1 - framework/commercelayer/types/signup.ts | 1 - framework/commercelayer/types/site.ts | 1 - framework/commercelayer/types/wishlist.ts | 1 - package.json | 2 +- 38 files changed, 147 insertions(+), 460 deletions(-) delete mode 100644 framework/commercelayer/api/endpoints/login/login.ts delete mode 100644 framework/commercelayer/api/endpoints/signup/signup.ts create mode 100644 framework/commercelayer/api/utils/cookies.ts delete mode 100644 framework/commercelayer/api/utils/credentials-validator.ts delete mode 100644 framework/commercelayer/api/utils/errors.ts delete mode 100644 framework/commercelayer/api/utils/fetch-api.ts create mode 100644 framework/commercelayer/api/utils/fetch-local.ts delete mode 100644 framework/commercelayer/api/utils/get-token.ts delete mode 100644 framework/commercelayer/types/cart.ts delete mode 100644 framework/commercelayer/types/checkout.ts delete mode 100644 framework/commercelayer/types/common.ts delete mode 100644 framework/commercelayer/types/customer.ts delete mode 100644 framework/commercelayer/types/index.ts delete mode 100644 framework/commercelayer/types/login.ts delete mode 100644 framework/commercelayer/types/logout.ts delete mode 100644 framework/commercelayer/types/page.ts delete mode 100644 framework/commercelayer/types/product.ts delete mode 100644 framework/commercelayer/types/signup.ts delete mode 100644 framework/commercelayer/types/site.ts delete mode 100644 framework/commercelayer/types/wishlist.ts diff --git a/components/auth/LoginView.tsx b/components/auth/LoginView.tsx index 3c8faef7c..9fba61ae3 100644 --- a/components/auth/LoginView.tsx +++ b/components/auth/LoginView.tsx @@ -1,6 +1,6 @@ import { FC, useEffect, useState, useCallback } from 'react' import { Logo, Button, Input } from '@components/ui' -import useLogin from '@framework/auth/use-login' +import useLogin from '@commerce/auth/use-login' import { useUI } from '@components/ui/context' import { validate } from 'email-validator' @@ -18,7 +18,6 @@ const LoginView: React.FC = () => { const handleLogin = async (e: React.SyntheticEvent) => { e.preventDefault() - if (!dirty && !disabled) { setDirty(true) handleValidation() diff --git a/framework/commerce/api/endpoints/login.ts b/framework/commerce/api/endpoints/login.ts index 6f69629b1..a066e7ae6 100644 --- a/framework/commerce/api/endpoints/login.ts +++ b/framework/commerce/api/endpoints/login.ts @@ -17,7 +17,7 @@ const loginEndpoint: GetAPISchema< ) { return } - + debugger try { const body = req.body ?? {} return await handlers['login']({ ...ctx, body }) diff --git a/framework/commerce/api/index.ts b/framework/commerce/api/index.ts index 6914b9364..3e34b3b71 100644 --- a/framework/commerce/api/index.ts +++ b/framework/commerce/api/index.ts @@ -146,6 +146,7 @@ export const createEndpoint = options?: API['schema']['endpoint']['options'] } ): NextApiHandler => { + debugger return getEndpoint(commerce, { ...endpoint, ...context }) } diff --git a/framework/commercelayer/.env.template b/framework/commercelayer/.env.template index 46725853b..417d19fb7 100644 --- a/framework/commercelayer/.env.template +++ b/framework/commercelayer/.env.template @@ -1,5 +1 @@ COMMERCE_PROVIDER=commercelayer - -COMMERCELAYER_CLIENT_ID= -COMMERCELAYER_ENDPOINT= -COMMERCELAYER_MARKET_SCOPE= \ No newline at end of file diff --git a/framework/commercelayer/README.md b/framework/commercelayer/README.md index f0544f399..a3bc1db32 100644 --- a/framework/commercelayer/README.md +++ b/framework/commercelayer/README.md @@ -1,23 +1 @@ -# Commerce Layer Provider - -⚠️ This provider is still a work in progress. - -Before getting started, you should do the following: - -- Create a Commerce Layer [developer account](https://commercelayer.io). -- Create a new [organization](https://commercelayer.io/docs/data-model/users-and-organizations/) for your business. -- Create an application with `sales_channel` kind. - -Next, copy the `.env.template` file in this directory to `.env.local` in the main directory (which will be ignored by Git): - -```bash -cp framework/commercelayer/.env.template .env.local -``` - -Next, add the application credentials from your organization application dashboard in `.env.local`. - -## Contribute - -Our commitment to Open Source can be found [here](https://vercel.com/oss). - -If you find an issue with the provider or want a new feature, feel free to open a PR or [create a new issue](https://github.com/vercel/commerce/issues). \ No newline at end of file +# Next.js Local Provider diff --git a/framework/commercelayer/api/endpoints/login/index.ts b/framework/commercelayer/api/endpoints/login/index.ts index 86aa11793..29b737af5 100644 --- a/framework/commercelayer/api/endpoints/login/index.ts +++ b/framework/commercelayer/api/endpoints/login/index.ts @@ -1,18 +1,35 @@ -import { GetAPISchema, createEndpoint } from '@commerce/api' -import loginEndpoint from '@commerce/api/endpoints/login' -import type { LoginSchema } from '../../../types/login' -import type { CommercelayerAPI } from '../..' -import login from './login' +import { GetAPISchema } from '@commerce/api' +import { CommerceAPIError } from '@commerce/api/utils/errors' +import isAllowedOperation from '@commerce/api/utils/is-allowed-operation' +import { LoginSchema } from '@commerce/types/login' -export type LoginAPI = GetAPISchema +const loginEndpoint: GetAPISchema< + any, + LoginSchema +>['endpoint']['handler'] = async (ctx) => { + const { req, res, handlers } = ctx + debugger + if ( + !isAllowedOperation(req, res, { + POST: handlers['login'], + }) + ) { + return + } + debugger + try { + const body = req.body ?? {} + return await handlers['login']({ ...ctx, body }) + } catch (error) { + console.error(error) -export type LoginEndpoint = LoginAPI['endpoint'] + const message = + error instanceof CommerceAPIError + ? 'An unexpected error ocurred with the Commerce API' + : 'An unexpected error ocurred' -export const handlers: LoginEndpoint['handlers'] = { login } + res.status(500).json({ data: null, errors: [{ message }] }) + } +} -const loginApi = createEndpoint({ - handler: loginEndpoint, - handlers, -}) - -export default loginApi \ No newline at end of file +export default loginEndpoint diff --git a/framework/commercelayer/api/endpoints/login/login.ts b/framework/commercelayer/api/endpoints/login/login.ts deleted file mode 100644 index 61cd12109..000000000 --- a/framework/commercelayer/api/endpoints/login/login.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { FetcherError } from '@commerce/utils/errors' -import { getAccessToken } from '../../index' -import type { LoginEndpoint } from '.' - -const login: LoginEndpoint['handlers']['login'] = async ({ - res, - body: { email, password }, - config, - commerce, -}) => { - if (!(email && password)) { - return res.status(400).json({ - data: null, - errors: [{ message: 'Invalid request' }], - }) - } - - try { - const user = { email, password }; - const getToken = await getAccessToken(user); - await config.apiFetch(`/api/customers/${getToken.customerId}`, { - method: 'GET' - }) - } catch (error) { - if (error instanceof FetcherError && - /invalid credentials/i.test(error.message)) { - return res.status(401).json({ - data: null, - errors: [ - { - message: - 'Cannot find an account that matches the provided credentials', - code: 'INVALID_CREDENTIALS', - }, - ], - }) - } - - throw error - } - - await commerce.login({ variables: { email, password }, config, res }) - - res.status(200).json({ data: null }) -} - -export default login \ No newline at end of file diff --git a/framework/commercelayer/api/endpoints/signup/index.ts b/framework/commercelayer/api/endpoints/signup/index.ts index 3d43b121e..491bf0ac9 100644 --- a/framework/commercelayer/api/endpoints/signup/index.ts +++ b/framework/commercelayer/api/endpoints/signup/index.ts @@ -1,18 +1 @@ -import { GetAPISchema, createEndpoint } from '@commerce/api' -import signupEndpoint from '@commerce/api/endpoints/signup' -import type { SignupSchema } from '../../../types/signup' -import type { CommercelayerAPI } from '../..' -import signup from './signup' - -export type SignupAPI = GetAPISchema - -export type SignupEndpoint = SignupAPI['endpoint'] - -export const handlers: SignupEndpoint['handlers'] = { signup } - -const singupApi = createEndpoint({ - handler: signupEndpoint, - handlers, -}) - -export default singupApi +export default function noopApi(...args: any[]): void {} diff --git a/framework/commercelayer/api/endpoints/signup/signup.ts b/framework/commercelayer/api/endpoints/signup/signup.ts deleted file mode 100644 index 204379a30..000000000 --- a/framework/commercelayer/api/endpoints/signup/signup.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { CommercelayerApiError } from '../../utils/errors' -import type { SignupEndpoint } from '.' - -const signup: SignupEndpoint['handlers']['signup'] = async ({ - res, - body: { email, password }, - config, - commerce, -}) => { - if (!(email && password)) { - return res.status(400).json({ - data: null, - errors: [{ message: 'Invalid request' }], - }) - } - - try { - await config.apiFetch('/api/customers', { - method: 'POST', - body: { - data: { - type: 'customers', - attributes: { - email: email, - password: password, - }, - }, - }, - }) - } catch (error) { - if (error instanceof CommercelayerApiError && error.status === 422) { - const inputEmail = error.data?.errors.meta.value - - if ('code' in error.data?.errors) { - return res.status(400).json({ - data: null, - errors: [ - { - message: `A user already exists with ${inputEmail}`, - code: 'USER_EXISTS', - }, - ], - }) - } - } - - throw error - } - - await commerce.login({ variables: { email, password }, res, config }) - - res.status(200).json({ data: null }) -} - -export default signup diff --git a/framework/commercelayer/api/index.ts b/framework/commercelayer/api/index.ts index 2af8db558..9f403d2b3 100644 --- a/framework/commercelayer/api/index.ts +++ b/framework/commercelayer/api/index.ts @@ -1,7 +1,6 @@ import type { CommerceAPI, CommerceAPIConfig } from '@commerce/api' -import type { RequestInit, Response, Fetch } from '@vercel/fetch' import { getCommerceApi as commerceApi } from '@commerce/api' -import createFetcher from './utils/fetch-api' +import createFetcher from './utils/fetch-local' import getAllPages from './operations/get-all-pages' import getPage from './operations/get-page' @@ -11,63 +10,14 @@ import getAllProductPaths from './operations/get-all-product-paths' import getAllProducts from './operations/get-all-products' import getProduct from './operations/get-product' -import { getToken } from './utils/get-token' - -export interface CommercelayerConfig extends Omit { - apiClientId: string - apiToken: string - apiFetch( - query: string, - endpoint: string, - fetchOptions?: RequestInit, - user?: UserCredentials - ): Promise<{ data: any; res: Response }> -} - -export type UserCredentials = { - email: string - password: string -} - -const CLIENT_ID = process.env.COMMERCELAYER_CLIENT_ID -const ENDPOINT = process.env.COMMERCELAYER_ENDPOINT -const MARKET_SCOPE = process.env.COMMERCELAYER_MARKET_SCOPE - -if (!CLIENT_ID) { - throw new Error( - `The environment variable COMMERCELAYER_CLIENT_ID is missing and it's required.` - ) -} - -if (!ENDPOINT) { - throw new Error( - `The environment variable COMMERCELAYER_ENDPOINT is missing and it's required.` - ) -} - -if (!MARKET_SCOPE) { - throw new Error( - `The environment variable COMMERCELAYER_MARKET_SCOPE is missing and it's required.` - ) -} - -export async function getAccessToken(user?: UserCredentials) { - return await getToken({ - clientId: CLIENT_ID, - endpoint: ENDPOINT, - scope: MARKET_SCOPE, - user, - }) -} - -const config: CommercelayerConfig = { - commerceUrl: ENDPOINT, - apiClientId: CLIENT_ID, +export interface LocalConfig extends CommerceAPIConfig {} +const config: LocalConfig = { + commerceUrl: '', + apiToken: '', cartCookie: '', customerCookie: '', cartCookieMaxAge: 2592000, - apiToken: '', - apiFetch: createFetcher(() => getCommerceApi().getConfig()), + fetch: createFetcher(() => getCommerceApi().getConfig()), } const operations = { @@ -83,12 +33,10 @@ const operations = { export const provider = { config, operations } export type Provider = typeof provider -export type CommercelayerAPI

= CommerceAPI< - P | any -> +export type LocalAPI

= CommerceAPI

export function getCommerceApi

( customProvider: P = provider as any -): CommercelayerAPI

{ +): LocalAPI

{ return commerceApi(customProvider as any) } diff --git a/framework/commercelayer/api/operations/get-all-pages.ts b/framework/commercelayer/api/operations/get-all-pages.ts index 3cfa49e19..b258fe70a 100644 --- a/framework/commercelayer/api/operations/get-all-pages.ts +++ b/framework/commercelayer/api/operations/get-all-pages.ts @@ -1,6 +1,6 @@ export type Page = { url: string } export type GetAllPagesResult = { pages: Page[] } -import type { CommercelayerConfig } from '../index' +import type { LocalConfig } from '../index' export default function getAllPagesOperation() { function getAllPages({ @@ -8,7 +8,7 @@ export default function getAllPagesOperation() { preview, }: { url?: string - config?: Partial + config?: Partial preview?: boolean }): Promise { return Promise.resolve({ diff --git a/framework/commercelayer/api/operations/get-all-products.ts b/framework/commercelayer/api/operations/get-all-products.ts index 561bc398c..21a04559d 100644 --- a/framework/commercelayer/api/operations/get-all-products.ts +++ b/framework/commercelayer/api/operations/get-all-products.ts @@ -1,7 +1,7 @@ import { Product } from '@commerce/types/product' import { GetAllProductsOperation } from '@commerce/types/product' import type { OperationContext } from '@commerce/api/operations' -import type { CommercelayerConfig, Provider } from '../index' +import type { LocalConfig, Provider } from '../index' import data from '../../data.json' export default function getAllProductsOperation({ @@ -14,7 +14,7 @@ export default function getAllProductsOperation({ }: { query?: string variables?: T['variables'] - config?: Partial + config?: Partial preview?: boolean } = {}): Promise<{ products: Product[] | any[] }> { return { diff --git a/framework/commercelayer/api/operations/get-product.ts b/framework/commercelayer/api/operations/get-product.ts index 42026c167..690b1aab9 100644 --- a/framework/commercelayer/api/operations/get-product.ts +++ b/framework/commercelayer/api/operations/get-product.ts @@ -1,4 +1,4 @@ -import type { CommercelayerConfig } from '../index' +import type { LocalConfig } from '../index' import { Product } from '@commerce/types/product' import { GetProductOperation } from '@commerce/types/product' import data from '../../data.json' @@ -14,7 +14,7 @@ export default function getProductOperation({ }: { query?: string variables?: T['variables'] - config?: Partial + config?: Partial preview?: boolean } = {}): Promise { return { diff --git a/framework/commercelayer/api/operations/get-site-info.ts b/framework/commercelayer/api/operations/get-site-info.ts index b7f3b6226..d43ed8359 100644 --- a/framework/commercelayer/api/operations/get-site-info.ts +++ b/framework/commercelayer/api/operations/get-site-info.ts @@ -1,6 +1,6 @@ import { OperationContext } from '@commerce/api/operations' import { Category } from '@commerce/types/site' -import { CommercelayerConfig } from '../index' +import { LocalConfig } from '../index' export type GetSiteInfoResult< T extends { categories: any[]; brands: any[] } = { @@ -17,7 +17,7 @@ export default function getSiteInfoOperation({}: OperationContext) { }: { query?: string variables?: any - config?: Partial + config?: Partial preview?: boolean } = {}): Promise { return Promise.resolve({ diff --git a/framework/commercelayer/api/utils/cookies.ts b/framework/commercelayer/api/utils/cookies.ts new file mode 100644 index 000000000..d17c1bfff --- /dev/null +++ b/framework/commercelayer/api/utils/cookies.ts @@ -0,0 +1,15 @@ +import Cookies, { CookieAttributes } from 'js-cookie' + +const setCookie = ( + name: string, + token?: string, + options?: CookieAttributes +) => { + if (!token) { + Cookies.remove(name) + } else { + Cookies.set(name, token, options) + } +} + +export default setCookie diff --git a/framework/commercelayer/api/utils/credentials-validator.ts b/framework/commercelayer/api/utils/credentials-validator.ts deleted file mode 100644 index b5c99aae9..000000000 --- a/framework/commercelayer/api/utils/credentials-validator.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Email must start with and contain an alphanumeric character, contain a @ character, and . character -export const validateEmail = (email: string) => { - const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test(String(email).toLowerCase()); -} - -// Passwords must be at least eight characters and must contain at least one uppercase letter, one lowercase letter, one number and one special character -export const validatePassword = (password: string) => { - const re = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; - return re.test(String(password).toLowerCase()); -} \ No newline at end of file diff --git a/framework/commercelayer/api/utils/errors.ts b/framework/commercelayer/api/utils/errors.ts deleted file mode 100644 index 6acc9fd0d..000000000 --- a/framework/commercelayer/api/utils/errors.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { Response } from '@vercel/fetch' - -export class CommercelayerApiError extends Error { - status: number - res: Response - data: any - - constructor(msg: string, res: Response, data?: any) { - super(msg) - this.name = 'CommercelayerApiError' - this.status = res.status - this.res = res - this.data = data - } -} - -export class CommercelayerNetworkError extends Error { - constructor(msg: string) { - super(msg) - this.name = 'CommercelayerNetworkError' - } -} \ No newline at end of file diff --git a/framework/commercelayer/api/utils/fetch-api.ts b/framework/commercelayer/api/utils/fetch-api.ts deleted file mode 100644 index 6764feaf5..000000000 --- a/framework/commercelayer/api/utils/fetch-api.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { RequestInit } from '@vercel/fetch' -import { FetcherError } from '@commerce/utils/errors' -import { CommercelayerConfig, getAccessToken, UserCredentials } from '../index' -import fetch from './fetch' - -const fetchApi = - (getConfig: () => CommercelayerConfig) => - async ( - query: string, - endpoint: string, - fetchOptions?: RequestInit, - user?: UserCredentials - ) => { - const config = getConfig() - const getToken = await getAccessToken(user) - const token = getToken?.accessToken - const res = await fetch(config.commerceUrl + endpoint, { - ...fetchOptions, - headers: { - ...fetchOptions?.headers, - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - body: JSON.stringify([ - query, - ]), - }) - - const json = await res.json() - if (json.errors) { - throw new FetcherError({ - errors: json.errors ?? [{ message: 'Failed to fetch Commerce Layer API' }], - status: res.status, - }) - } - - return { data: json.data, res } - } - -export default fetchApi diff --git a/framework/commercelayer/api/utils/fetch-local.ts b/framework/commercelayer/api/utils/fetch-local.ts new file mode 100644 index 000000000..de6904ee5 --- /dev/null +++ b/framework/commercelayer/api/utils/fetch-local.ts @@ -0,0 +1,35 @@ +import { FetcherError } from '@commerce/utils/errors' +import type { GraphQLFetcher } from '@commerce/api' +import type { LocalConfig } from '../index' +import fetch from './fetch' + +const fetchGraphqlApi: (getConfig: () => LocalConfig) => GraphQLFetcher = + (getConfig) => + async (query: string, { variables, preview } = {}, fetchOptions) => { + debugger + const config = getConfig() + const res = await fetch(config.commerceUrl, { + ...fetchOptions, + method: 'POST', + headers: { + ...fetchOptions?.headers, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query, + variables, + }), + }) + + const json = await res.json() + if (json.errors) { + throw new FetcherError({ + errors: json.errors ?? [{ message: 'Failed to fetch for API' }], + status: res.status, + }) + } + + return { data: json.data, res } + } + +export default fetchGraphqlApi diff --git a/framework/commercelayer/api/utils/get-token.ts b/framework/commercelayer/api/utils/get-token.ts deleted file mode 100644 index 7ab29b71d..000000000 --- a/framework/commercelayer/api/utils/get-token.ts +++ /dev/null @@ -1,40 +0,0 @@ -import Cookies from 'js-cookie' -import { getSalesChannelToken } from '@commercelayer/js-auth' - -type GetTokenObj = { - clientId?: string - endpoint?: string - scope?: string - user?: any -} - -export async function getToken({ - clientId, - endpoint, - scope = 'market:all', - user, -}: GetTokenObj) { - const getCookieToken = Cookies.get('clAccessToken') - if (!getCookieToken && clientId && endpoint) { - const auth = await getSalesChannelToken( - { - clientId, - endpoint, - scope, - }, - user - ) - Cookies.set('clAccessToken', auth?.accessToken as string, { - // @ts-ignore - expires: auth?.expires, - }) - return auth - ? { - accessToken: auth.accessToken, - customerId: auth.data.owner_id, - ...auth.data, - } - : null - } - return { accessToken: getCookieToken } -} diff --git a/framework/commercelayer/auth/use-login.tsx b/framework/commercelayer/auth/use-login.tsx index aa74689b9..2574ed8fa 100644 --- a/framework/commercelayer/auth/use-login.tsx +++ b/framework/commercelayer/auth/use-login.tsx @@ -1,40 +1,40 @@ -import { useCallback } from 'react' -import type { MutationHook } from '@commerce/utils/types' -import { CommerceError } from '@commerce/utils/errors' +import { MutationHook } from '@commerce/utils/types' import useLogin, { UseLogin } from '@commerce/auth/use-login' -import type { LoginHook } from '../types/login' -import useCustomer from '../customer/use-customer' +import { CommerceError } from '@commerce/utils/errors' +import { getCustomerToken } from '@commercelayer/js-auth' +import setCookie from '@framework/api/utils/cookies' export default useLogin as UseLogin -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/customers', - method: 'GET', + // query: 'login', + url: '/customer', }, async fetcher({ input: { email, password }, options, fetch }) { if (!(email && password)) { throw new CommerceError({ - message: - 'An email address and password are required to login', + message: 'An email and password are required to login', }) } - - return fetch({ - ...options, - body: { email, password }, - }) - }, - useHook: ({ fetch }) => () => { - const { revalidate } = useCustomer() - - return useCallback( - async function login(input) { - const data = await fetch({ input }) - await revalidate() - return data + const token = await getCustomerToken( + { + endpoint: process.env.NEXT_PUBLIC_COMMERCELAYER_ENDPOINT as string, + clientId: process.env.NEXT_PUBLIC_COMMERCELAYER_CLIENT_ID as string, + scope: process.env.NEXT_PUBLIC_COMMERCELAYER_MARKET_SCOPE as string, }, - [fetch, revalidate] + { username: email, password } ) + token && + setCookie('CL_TOKEN', token.accessToken, { expires: token.expires }) + return token }, -} \ No newline at end of file + useHook: + ({ fetch }) => + () => { + return async function login(input) { + const data = await fetch({ input }) + return data + } + }, +} diff --git a/framework/commercelayer/auth/use-signup.tsx b/framework/commercelayer/auth/use-signup.tsx index d1cfbbe9a..e9ad13458 100644 --- a/framework/commercelayer/auth/use-signup.tsx +++ b/framework/commercelayer/auth/use-signup.tsx @@ -1,44 +1,19 @@ import { useCallback } from 'react' -import type { MutationHook } from '@commerce/utils/types' -import { CommerceError } from '@commerce/utils/errors' -import useSignup, { UseSignup } from '@commerce/auth/use-signup' -import type { SignupHook } from '../types/signup' import useCustomer from '../customer/use-customer' +import { MutationHook } from '@commerce/utils/types' +import useSignup, { UseSignup } from '@commerce/auth/use-signup' export default useSignup as UseSignup -export const handler: MutationHook = { +export const handler: MutationHook = { fetchOptions: { - url: '/api/customers', - method: 'POST', + query: '', }, - async fetcher({ - input: { email, password }, - options, - fetch, - }) { - if (!(email && password)) { - throw new CommerceError({ - message: - 'An email address and password are required to signup', - }) - } - - return fetch({ - ...options, - body: { email, password }, - }) + async fetcher() { + return null }, - useHook: ({ fetch }) => () => { - const { revalidate } = useCustomer() - - return useCallback( - async function signup(input) { - const data = await fetch({ input }) - await revalidate() - return data - }, - [fetch, revalidate] - ) - }, -} \ No newline at end of file + useHook: + ({ fetch }) => + () => + () => {}, +} diff --git a/framework/commercelayer/fetcher.ts b/framework/commercelayer/fetcher.ts index 69943d1df..6a8faf507 100644 --- a/framework/commercelayer/fetcher.ts +++ b/framework/commercelayer/fetcher.ts @@ -2,6 +2,7 @@ import { Fetcher } from '@commerce/utils/types' export const fetcher: Fetcher = async () => { console.log('FETCHER') + debugger const res = await fetch('./data.json') if (res.ok) { const { data } = await res.json() diff --git a/framework/commercelayer/index.tsx b/framework/commercelayer/index.tsx index 9c614577f..2ec304f63 100644 --- a/framework/commercelayer/index.tsx +++ b/framework/commercelayer/index.tsx @@ -1,13 +1,13 @@ import * as React from 'react' import { ReactNode } from 'react' -import { commerceLayerProvider } from './provider' +import { localProvider } from './provider' import { CommerceConfig, CommerceProvider as CoreCommerceProvider, useCommerce as useCoreCommerce, } from '@commerce' -export const commerceLayerConfig: CommerceConfig = { +export const localConfig: CommerceConfig = { locale: 'en-us', cartCookie: 'session', } @@ -21,8 +21,8 @@ export function CommerceProvider({ } & Partial) { return ( {children} diff --git a/framework/commercelayer/provider.ts b/framework/commercelayer/provider.ts index f5e9e55c4..e6a2b0a21 100644 --- a/framework/commercelayer/provider.ts +++ b/framework/commercelayer/provider.ts @@ -9,8 +9,8 @@ import { handler as useLogin } from './auth/use-login' import { handler as useLogout } from './auth/use-logout' import { handler as useSignup } from './auth/use-signup' -export type Provider = typeof commerceLayerProvider -export const commerceLayerProvider = { +export type Provider = typeof localProvider +export const localProvider = { locale: 'en-us', cartCookie: 'session', fetcher: fetcher, diff --git a/framework/commercelayer/types/cart.ts b/framework/commercelayer/types/cart.ts deleted file mode 100644 index 6ed5c6c64..000000000 --- a/framework/commercelayer/types/cart.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/cart' diff --git a/framework/commercelayer/types/checkout.ts b/framework/commercelayer/types/checkout.ts deleted file mode 100644 index 4e2412ef6..000000000 --- a/framework/commercelayer/types/checkout.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/checkout' diff --git a/framework/commercelayer/types/common.ts b/framework/commercelayer/types/common.ts deleted file mode 100644 index b52c33a4d..000000000 --- a/framework/commercelayer/types/common.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/common' diff --git a/framework/commercelayer/types/customer.ts b/framework/commercelayer/types/customer.ts deleted file mode 100644 index 87c9afcc4..000000000 --- a/framework/commercelayer/types/customer.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/customer' diff --git a/framework/commercelayer/types/index.ts b/framework/commercelayer/types/index.ts deleted file mode 100644 index 7ab0b7f64..000000000 --- a/framework/commercelayer/types/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as Cart from './cart' -import * as Checkout from './checkout' -import * as Common from './common' -import * as Customer from './customer' -import * as Login from './login' -import * as Logout from './logout' -import * as Page from './page' -import * as Product from './product' -import * as Signup from './signup' -import * as Site from './site' -import * as Wishlist from './wishlist' - -export type { - Cart, - Checkout, - Common, - Customer, - Login, - Logout, - Page, - Product, - Signup, - Site, - Wishlist, -} diff --git a/framework/commercelayer/types/login.ts b/framework/commercelayer/types/login.ts deleted file mode 100644 index ab11a420a..000000000 --- a/framework/commercelayer/types/login.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as Core from '@commerce/types/login' -import { LoginBody, LoginTypes } from '@commerce/types/login' - -export * from '@commerce/types/login' - -export type LoginHook = { - data: null - actionInput: LoginBody - fetcherInput: LoginBody - body: T['body'] -} diff --git a/framework/commercelayer/types/logout.ts b/framework/commercelayer/types/logout.ts deleted file mode 100644 index 9f0a466af..000000000 --- a/framework/commercelayer/types/logout.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/logout' diff --git a/framework/commercelayer/types/page.ts b/framework/commercelayer/types/page.ts deleted file mode 100644 index 20ec8ea38..000000000 --- a/framework/commercelayer/types/page.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/page' diff --git a/framework/commercelayer/types/product.ts b/framework/commercelayer/types/product.ts deleted file mode 100644 index c776d58fa..000000000 --- a/framework/commercelayer/types/product.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/product' diff --git a/framework/commercelayer/types/signup.ts b/framework/commercelayer/types/signup.ts deleted file mode 100644 index 58543c6f6..000000000 --- a/framework/commercelayer/types/signup.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/signup' diff --git a/framework/commercelayer/types/site.ts b/framework/commercelayer/types/site.ts deleted file mode 100644 index bfef69cf9..000000000 --- a/framework/commercelayer/types/site.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/site' diff --git a/framework/commercelayer/types/wishlist.ts b/framework/commercelayer/types/wishlist.ts deleted file mode 100644 index 8907fbf82..000000000 --- a/framework/commercelayer/types/wishlist.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@commerce/types/wishlist' diff --git a/package.json b/package.json index 439bd5a89..306b514a3 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "node": ">=14.x" }, "dependencies": { - "@commercelayer/js-auth": "^2.0.6", + "@commercelayer/js-auth": "^2.0.7", "@commercelayer/js-sdk": "^4.1.3", "@chec/commerce.js": "^2.8.0", "@react-spring/web": "^9.4.1",