diff --git a/web/lib/apiHelpers.js b/web/lib/apiHelpers.js deleted file mode 100644 index 6e443d8..0000000 --- a/web/lib/apiHelpers.js +++ /dev/null @@ -1,27 +0,0 @@ -import auth0 from "./auth0"; - -function withErrorHandling(handler) { - return async (req, res) => { - try { - await handler(req, res); - } catch (error) { - console.error(error); - res.status(error.status || 500).end(error.message); - } - }; -} - -function withSession(handler) { - return async (req, res) => { - const session = await auth0.getSession(req, res); - - if (!session || !session.user) { - res.status(401).end(); - return; - } - - await handler(req, res, session); - } -} - -export { withErrorHandling, withSession }; diff --git a/web/lib/jsonapi.js b/web/lib/jsonapi.js new file mode 100644 index 0000000..45a415d --- /dev/null +++ b/web/lib/jsonapi.js @@ -0,0 +1,42 @@ +import auth0 from "./auth0"; + +async function jsonApi(handler) { + var unauthenticationHandler = async (req, res) => { + try { + await handler(req, res); + } catch (error) { + handleError(res, error); + } + + res.end(); + }; + + return unauthenticationHandler; +} + +function authenticatedJsonApi(handler) { + var authenticatedHandler = async (req, res) => { + try { + const session = await auth0.getSession(req, res); + + if (!session || !session.user) { + res.status(401); + } else { + await handler(req, res, session); + } + } catch (error) { + handleError(res, error); + } + + res.end(); + }; + + return authenticatedHandler; +} + +function handleError(res, error) { + console.error(error); + res.status(error.status || 500).end(error.message); +} + +export { jsonApi, authenticatedJsonApi }; diff --git a/web/next.config.js b/web/next.config.js index a843cbe..c88ace0 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -1,6 +1,23 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, + async headers() { + return [ + { + source: "/api/:path*", + headers: [ + { + key: "Content-Type", + value: "application/vnd.api+json" + }, + { + key: "x-testing", + value: "true" + } + ] + } + ] + } } module.exports = nextConfig diff --git a/web/pages/api/v1/[entityName]/[entityId].js b/web/pages/api/v1/[entityName]/[entityId].js index adf6ed4..e12a31b 100644 --- a/web/pages/api/v1/[entityName]/[entityId].js +++ b/web/pages/api/v1/[entityName]/[entityId].js @@ -1,28 +1,26 @@ import db from "../../../../lib/db"; -import { withErrorHandling, withSession } from "../../../../lib/apiHelpers"; +import { authenticatedJsonApi } from "../../../../lib/jsonapi"; import models from "../../../../lib/models"; -const handler = withErrorHandling( - withSession(async (req, res, session) => { - const { method } = req; - const { user } = session; +const handler = authenticatedJsonApi(async (req, res, session) => { + const { method } = req; + const { user } = session; - switch (method) { - case "GET": - await getEntity(req, res, user); - break; - default: - res.setHeader("Allow", ["GET"]); - res.status(405).end(`Method ${method} Not Allowed`); - } - }) -); + switch (method) { + case "GET": + await getEntity(req, res, user); + break; + default: + res.setHeader("Allow", ["GET"]); + res.status(405).send(`Method ${method} Not Allowed`); + } +}); const getEntity = async (req, res, user) => { const { entityName, entityId } = req.query; if (!models[entityName]) { - res.status(404).end(); + res.status(404); return; } @@ -30,7 +28,7 @@ const getEntity = async (req, res, user) => { if (!model.validateId(entityId)) { console.warn(model.validateId.errors); - res.status(404).end(); + res.status(404); return; } @@ -48,7 +46,7 @@ const getEntity = async (req, res, user) => { if (entities.Items.length == 1) { res.status(200).json(entities.Items[0]); } else { - res.status(404).end(); + res.status(404); } }; diff --git a/web/pages/api/v1/[entityName]/index.js b/web/pages/api/v1/[entityName]/index.js index 19a0068..068369f 100644 --- a/web/pages/api/v1/[entityName]/index.js +++ b/web/pages/api/v1/[entityName]/index.js @@ -1,31 +1,29 @@ import db from "../../../../lib/db"; -import { withErrorHandling, withSession } from "../../../../lib/apiHelpers"; +import { authenticatedJsonApi } from "../../../../lib/jsonapi"; import models from "../../../../lib/models"; -const handler = withErrorHandling( - withSession(async (req, res, session) => { - const { method } = req; - const { user } = session; +const handler = authenticatedJsonApi(async (req, res, session) => { + const { method } = req; + const { user } = session; - switch (method) { - case "GET": - await getEntities(req, res, user); - break; - case "POST": - await createEntity(req, res, user); - break; - default: - res.setHeader("Allow", ["GET", "POST"]); - res.status(405).end(`Method ${method} Not Allowed`); - } - }) -); + switch (method) { + case "GET": + await getEntities(req, res, user); + break; + case "POST": + await createEntity(req, res, user); + break; + default: + res.setHeader("Allow", ["GET", "POST"]); + res.status(405).json(`Method ${method} Not Allowed`); + } +}); const getEntities = async (req, res, user) => { const { entityName } = req.query; if (!models[entityName]) { - res.status(404).end(); + res.status(404); return; } @@ -46,7 +44,7 @@ const createEntity = async (req, res, user) => { const { entityName } = req.query; if (!models[entityName]) { - res.status(404).end(); + res.status(404); return; } diff --git a/web/pages/api/v1/callback.js b/web/pages/api/v1/callback.js index 1f86452..fb9e59d 100644 --- a/web/pages/api/v1/callback.js +++ b/web/pages/api/v1/callback.js @@ -1,8 +1,7 @@ import auth0 from "../../../lib/auth0"; -import { withErrorHandling } from "../../../lib/apiHelpers"; -const callback = withErrorHandling(async (req, res) => { +const callback = async (req, res) => { await auth0.handleCallback(req, res); -}); +}; export default callback; diff --git a/web/pages/api/v1/hello.js b/web/pages/api/v1/hello.js index 4ddfb1f..4a0a103 100644 --- a/web/pages/api/v1/hello.js +++ b/web/pages/api/v1/hello.js @@ -1,7 +1,6 @@ import db from "../../../lib/db"; -import { withErrorHandling } from "../../../lib/apiHelpers"; -const handler = withErrorHandling(async (req, res) => { +const handler = async (req, res) => { const { method } = req; switch (method) { @@ -11,7 +10,7 @@ const handler = withErrorHandling(async (req, res) => { res.setHeader("Allow", ["GET"]); res.status(405).end(`Method ${method} Not Allowed`); } -}); +}; const get = async (req, res) => { const params = { diff --git a/web/pages/api/v1/login.js b/web/pages/api/v1/login.js index c9334f6..7982f7c 100644 --- a/web/pages/api/v1/login.js +++ b/web/pages/api/v1/login.js @@ -1,8 +1,7 @@ import auth0 from "../../../lib/auth0"; -import { withErrorHandling } from "../../../lib/apiHelpers"; -const login = withErrorHandling(async (req, res) => { +const login = async (req, res) => { await auth0.handleLogin(req, res); -}); +}; export default login; diff --git a/web/pages/api/v1/me.js b/web/pages/api/v1/me.js index d3ad9f1..68e97a6 100644 --- a/web/pages/api/v1/me.js +++ b/web/pages/api/v1/me.js @@ -1,8 +1,7 @@ import auth0 from "../../../lib/auth0"; -import { withErrorHandling } from "../../../lib/apiHelpers"; -const me = withErrorHandling(async (req, res) => { +const me = async (req, res) => { await auth0.handleProfile(req, res); -}); +}; export default me;