From b81d04b952688bee56b20dc4cedd52a0a8eed78b Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Thu, 22 Oct 2020 18:02:41 -0500 Subject: [PATCH] Added logout API --- .../api/customers/handlers/logout.ts | 16 +++++++ lib/bigcommerce/api/customers/logout.ts | 42 +++++++++++++++++++ .../api/utils/create-api-handler.ts | 2 +- next.config.js | 6 +++ pages/api/bigcommerce/customers/logout.ts | 3 ++ 5 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 lib/bigcommerce/api/customers/handlers/logout.ts create mode 100644 lib/bigcommerce/api/customers/logout.ts create mode 100644 pages/api/bigcommerce/customers/logout.ts diff --git a/lib/bigcommerce/api/customers/handlers/logout.ts b/lib/bigcommerce/api/customers/handlers/logout.ts new file mode 100644 index 000000000..9446262e2 --- /dev/null +++ b/lib/bigcommerce/api/customers/handlers/logout.ts @@ -0,0 +1,16 @@ +import { LogoutHandlers } from '../logout' + +const logoutHandler: LogoutHandlers['logout'] = async ({ + res, + body: { redirectTo }, + config, +}) => { + // Only allow redirects to a relative URL + if (redirectTo?.startsWith('/')) { + res.redirect(redirectTo) + } else { + res.status(200).json({ data: null }) + } +} + +export default logoutHandler diff --git a/lib/bigcommerce/api/customers/logout.ts b/lib/bigcommerce/api/customers/logout.ts new file mode 100644 index 000000000..0a4965245 --- /dev/null +++ b/lib/bigcommerce/api/customers/logout.ts @@ -0,0 +1,42 @@ +import createApiHandler, { + BigcommerceApiHandler, + BigcommerceHandler, +} from '../utils/create-api-handler' +import isAllowedMethod from '../utils/is-allowed-method' +import { BigcommerceApiError } from '../utils/errors' +import logout from './handlers/logout' + +export type LogoutHandlers = { + logout: BigcommerceHandler +} + +const METHODS = ['GET'] + +const logoutApi: BigcommerceApiHandler = async ( + req, + res, + config, + handlers +) => { + if (!isAllowedMethod(req, res, METHODS)) return + + try { + const redirectTo = req.query.redirect_to + const body = typeof redirectTo === 'string' ? { redirectTo } : {} + + return await handlers['logout']({ req, res, config, body }) + } catch (error) { + console.error(error) + + const message = + error instanceof BigcommerceApiError + ? 'An unexpected error ocurred with the Bigcommerce API' + : 'An unexpected error ocurred' + + res.status(500).json({ data: null, errors: [{ message }] }) + } +} + +const handlers = { logout } + +export default createApiHandler(logoutApi, handlers, {}) diff --git a/lib/bigcommerce/api/utils/create-api-handler.ts b/lib/bigcommerce/api/utils/create-api-handler.ts index c6363cb15..315ec464b 100644 --- a/lib/bigcommerce/api/utils/create-api-handler.ts +++ b/lib/bigcommerce/api/utils/create-api-handler.ts @@ -14,7 +14,7 @@ export type BigcommerceApiHandler< options: Options ) => void | Promise -export type BigcommerceHandler = (options: { +export type BigcommerceHandler = (options: { req: NextApiRequest res: NextApiResponse> config: BigcommerceConfig diff --git a/next.config.js b/next.config.js index b487800af..7e00abe9b 100644 --- a/next.config.js +++ b/next.config.js @@ -18,6 +18,12 @@ module.exports = { source: '/checkout', destination: '/api/bigcommerce/checkout', }, + // The logout is also an action so this route is not required, but it's also another way + // you can allow a logout! + { + source: '/logout', + destination: '/api/bigcommerce/customers/logout?redirect_to=/', + }, ] }, } diff --git a/pages/api/bigcommerce/customers/logout.ts b/pages/api/bigcommerce/customers/logout.ts new file mode 100644 index 000000000..84ac2c7bf --- /dev/null +++ b/pages/api/bigcommerce/customers/logout.ts @@ -0,0 +1,3 @@ +import logoutApi from '@lib/bigcommerce/api/customers/logout' + +export default logoutApi()