From d1495df5a108e5f776cff21ef99c358cb9442ce4 Mon Sep 17 00:00:00 2001
From: Ben Ramey
Date: Tue, 5 Jul 2022 21:15:42 -0500
Subject: [PATCH] A few more api call basics
---
web/lib/apiHelpers.js | 17 +++++-
web/pages/api/v1/bookmarks.js | 66 ++++++++++++----------
web/pages/api/v1/bookmarks/[bookmarkId].js | 46 +++++++++++++++
web/pages/index.js | 18 +++---
4 files changed, 108 insertions(+), 39 deletions(-)
create mode 100644 web/pages/api/v1/bookmarks/[bookmarkId].js
diff --git a/web/lib/apiHelpers.js b/web/lib/apiHelpers.js
index 8c3932a..6e443d8 100644
--- a/web/lib/apiHelpers.js
+++ b/web/lib/apiHelpers.js
@@ -1,3 +1,5 @@
+import auth0 from "./auth0";
+
function withErrorHandling(handler) {
return async (req, res) => {
try {
@@ -9,4 +11,17 @@ function withErrorHandling(handler) {
};
}
-export { withErrorHandling };
+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/pages/api/v1/bookmarks.js b/web/pages/api/v1/bookmarks.js
index 9d5b714..e2c0c48 100644
--- a/web/pages/api/v1/bookmarks.js
+++ b/web/pages/api/v1/bookmarks.js
@@ -1,27 +1,45 @@
-import db from "../../../lib/db";
import Ajv from "ajv";
import addFormats from "ajv-formats";
-import { withErrorHandling } from "../../../lib/apiHelpers";
-const handler = withErrorHandling(async (req, res) => {
- const { method } = req;
+import db from "../../../lib/db";
+import { withErrorHandling, withSession } from "../../../lib/apiHelpers";
- switch (method) {
- case "GET":
- await getBookmark(req, res);
- break;
- case "POST":
- await createBookmark(req, res);
- break;
- default:
- res.setHeader("Allow", ["GET", "POST"]);
- res.status(405).end(`Method ${method} Not Allowed`);
- }
-});
+const handler = withErrorHandling(
+ withSession(async (req, res, session) => {
+ const { method } = req;
+ const { user } = session;
+
+ switch (method) {
+ case "GET":
+ await getBookmarks(req, res, user);
+ break;
+ case "POST":
+ await createBookmark(req, res, user);
+ break;
+ default:
+ res.setHeader("Allow", ["GET", "POST"]);
+ res.status(405).end(`Method ${method} Not Allowed`);
+ }
+ })
+);
const ajv = new Ajv();
addFormats(ajv);
+const getBookmarks = async (req, res, user) => {
+ const params = {
+ TableName: process.env.FMN_DYNAMODB_TABLENAME,
+ KeyConditionExpression: "hk = :hk AND begins_with(sk, :sk)",
+ ExpressionAttributeValues: {
+ ":hk": `user#${user.sub}`,
+ ":sk": "bookmark#",
+ },
+ };
+
+ let bookmarks = await db.query(params).promise();
+ res.status(200).json(bookmarks.Items);
+};
+
const createBookmarkSchema = {
type: "object",
properties: {
@@ -33,18 +51,7 @@ const createBookmarkSchema = {
const validateCreateBookmarkSchema = ajv.compile(createBookmarkSchema);
-const getBookmark = async (req, res) => {
- const params = {
- TableName: process.env.FMN_DYNAMODB_TABLENAME,
- KeyConditionExpression: "hk = :hk",
- ExpressionAttributeValues: { ":hk": "user#123" },
- };
-
- let bookmark = await db.query(params).promise();
- res.status(200).json(bookmark);
-};
-
-const createBookmark = async (req, res) => {
+const createBookmark = async (req, res, user) => {
if (!validateCreateBookmarkSchema(req.body)) {
console.warn(validateCreateBookmarkSchema.errors);
res.status(400).json(validateCreateBookmarkSchema.errors);
@@ -54,7 +61,7 @@ const createBookmark = async (req, res) => {
const params = {
TableName: process.env.FMN_DYNAMODB_TABLENAME,
Item: {
- hk: `user#${123}`,
+ hk: `user#${user.sub}`,
sk: `bookmark#${"abc"}`,
title: req.body.title,
url: req.body.url,
@@ -62,6 +69,7 @@ const createBookmark = async (req, res) => {
};
await db.put(params).promise();
+ res.status(200).json(params.Item);
};
export default handler;
diff --git a/web/pages/api/v1/bookmarks/[bookmarkId].js b/web/pages/api/v1/bookmarks/[bookmarkId].js
new file mode 100644
index 0000000..00f0603
--- /dev/null
+++ b/web/pages/api/v1/bookmarks/[bookmarkId].js
@@ -0,0 +1,46 @@
+import db from "../../../../lib/db";
+import { withErrorHandling, withSession } from "../../../../lib/apiHelpers";
+
+const handler = withErrorHandling(
+ withSession(async (req, res, session) => {
+ const { method } = req;
+ const { user } = session;
+
+ switch (method) {
+ case "GET":
+ await getBookmark(req, res, user);
+ break;
+ default:
+ res.setHeader("Allow", ["GET", "POST"]);
+ res.status(405).end(`Method ${method} Not Allowed`);
+ }
+ })
+);
+
+const getBookmark = async (req, res, user) => {
+ const { bookmarkId } = req.query;
+
+ if (!bookmarkId) {
+ res.status(404).end();
+ return;
+ }
+
+ const params = {
+ TableName: process.env.FMN_DYNAMODB_TABLENAME,
+ KeyConditionExpression: "hk = :hk AND sk = :sk",
+ ExpressionAttributeValues: {
+ ":hk": `user#${user.sub}`,
+ ":sk": `bookmark#${bookmarkId}`,
+ },
+ };
+
+ let bookmarks = await db.query(params).promise();
+
+ if (bookmarks.Items.length == 1) {
+ res.status(200).json(bookmarks.Items[0]);
+ } else {
+ res.status(404).end();
+ }
+};
+
+export default handler;
diff --git a/web/pages/index.js b/web/pages/index.js
index 806760b..4dde3e8 100644
--- a/web/pages/index.js
+++ b/web/pages/index.js
@@ -19,6 +19,15 @@ function Home() {
Once you have logged in you should be able to click in{" "}
Profile and Logout
+ >
+ )}
+
+ {user && (
+ <>
+ Rendered user info on the client
+
+ nickname: {user.nickname}
+ name: {user.name}