From 38e899e7b4ea0593ea6d48ef45674a96cef9f3c3 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Mon, 20 Nov 2023 14:36:59 +0100 Subject: [PATCH] refactor: use URL constructor (#328) Co-authored-by: yoko <25644062+sidemt@users.noreply.github.com> --- apps/cron/src/jobs/check-and-publish.ts | 2 +- apps/frontend/src/lib/invite-user.js | 36 +++++++------ apps/frontend/src/lib/posts.js | 37 ++++++------- apps/frontend/src/lib/roles.js | 6 +-- apps/frontend/src/lib/tags.js | 52 ++++++++++--------- apps/frontend/src/lib/users.js | 43 ++++++++------- .../src/pages/api/auth/[...nextauth].js | 44 +++++++++------- 7 files changed, 115 insertions(+), 105 deletions(-) diff --git a/apps/cron/src/jobs/check-and-publish.ts b/apps/cron/src/jobs/check-and-publish.ts index 2f0daa2b5..1cb7bd6b8 100644 --- a/apps/cron/src/jobs/check-and-publish.ts +++ b/apps/cron/src/jobs/check-and-publish.ts @@ -2,7 +2,7 @@ require("dotenv").config(); (async () => { const res = await fetch( - `${process.env.STRAPI_URL}/api/posts/check-and-publish`, + new URL("/api/posts/check-and-publish", process.env.STRAPI_URL), { method: "GET", headers: { diff --git a/apps/frontend/src/lib/invite-user.js b/apps/frontend/src/lib/invite-user.js index e5b8dabb9..592fd9049 100644 --- a/apps/frontend/src/lib/invite-user.js +++ b/apps/frontend/src/lib/invite-user.js @@ -1,20 +1,19 @@ import qs from "qs"; -const api_root = `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api`; +const base = process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL; export async function getInvitedUsers(token, queryParams) { - const res = await fetch( - `${api_root}/invited-users?${qs.stringify(queryParams, { - encodeValuesOnly: true, - })}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, + const url = new URL("/api/invited-users", base); + url.search = qs.stringify(queryParams, { + encodeValuesOnly: true, + }); + const res = await fetch(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, }, - ); + }); try { const data = await res.json(); @@ -32,7 +31,8 @@ export async function getInvitedUsers(token, queryParams) { } export async function inviteUser(token, data) { - const res = await fetch(`${api_root}/invited-users`, { + const url = new URL("/api/invited-users", base); + const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", @@ -58,7 +58,8 @@ export async function inviteUser(token, data) { } export async function invitedUserExists(token, email) { - const endpoint = `${api_root}/invited-users?${qs.stringify( + const url = new URL("/api/invited-users", base); + url.search = qs.stringify( { filters: { email: { @@ -69,7 +70,7 @@ export async function invitedUserExists(token, email) { { encodeValuesOnly: true, }, - )}`; + ); const options = { method: "GET", @@ -79,7 +80,7 @@ export async function invitedUserExists(token, email) { }, }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("invitedUserExists Failed"); @@ -90,7 +91,8 @@ export async function invitedUserExists(token, email) { } export async function deleteInvitedUser(token, id) { - const res = await fetch(`${api_root}/invited-users/${id}`, { + const url = new URL(`/api/invited-users/${id}`, base); + const res = await fetch(url, { method: "DELETE", headers: { "Content-Type": "application/json", diff --git a/apps/frontend/src/lib/posts.js b/apps/frontend/src/lib/posts.js index 65ffecd0c..d4a7fd3c8 100644 --- a/apps/frontend/src/lib/posts.js +++ b/apps/frontend/src/lib/posts.js @@ -2,12 +2,13 @@ import qs from "qs"; // Post API calls -const api_root = `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api`; +const base = process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL; export async function getAllPosts(token, queryParams) { - const endpoint = `${api_root}/posts?${qs.stringify(queryParams, { + const url = new URL("/api/posts", base); + url.search = qs.stringify(queryParams, { encodeValuesOnly: true, - })}`; + }); const options = { method: "GET", @@ -18,7 +19,7 @@ export async function getAllPosts(token, queryParams) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { console.error("getAllPosts responded with error. Status: ", res.status); @@ -35,9 +36,10 @@ export async function getAllPosts(token, queryParams) { } export async function getUserPosts(token, queryParams) { - const endpoint = `${api_root}/posts?${qs.stringify(queryParams, { + const url = new URL("/api/posts", base); + url.search = qs.stringify(queryParams, { encodeValuesOnly: true, - })}`; + }); const options = { method: "GET", @@ -48,7 +50,7 @@ export async function getUserPosts(token, queryParams) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { console.error("getUserPosts responded with error. Status: ", res.status); @@ -65,7 +67,8 @@ export async function getUserPosts(token, queryParams) { } export async function getPost(postId, token) { - const endpoint = `${api_root}/posts/${postId}?populate=*`; + const url = new URL(`/api/posts/${postId}`, base); + url.search = "populate=*"; const options = { method: "GET", @@ -76,7 +79,7 @@ export async function getPost(postId, token) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { console.error( @@ -95,13 +98,10 @@ export async function getPost(postId, token) { } export async function createPost(data, token) { - // API endpoint where we send form data. - const endpoint = `${api_root}/posts`; + const url = new URL("/api/posts", base); - // Form the request for sending data to the server. const options = { method: "POST", - // Tell the server we're sending JSON. headers: { "Content-Type": "application/json", accept: "application/json", @@ -109,8 +109,7 @@ export async function createPost(data, token) { }, body: JSON.stringify(data), }; - // Send the form data to our forms API and get a response. - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("createPost Failed"); } @@ -119,13 +118,10 @@ export async function createPost(data, token) { } export async function updatePost(postId, data, token) { - // API endpoint where we send form data. - const endpoint = `${api_root}/posts/${postId}`; + const url = new URL(`/api/posts/${postId}`, base); - // Form the request for sending data to the server. const options = { method: "PUT", - // Tell the server we're sending JSON. headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, @@ -133,8 +129,7 @@ export async function updatePost(postId, data, token) { body: JSON.stringify(data), }; - // Send the form data to our forms API and get a response. - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("updatePost Failed"); diff --git a/apps/frontend/src/lib/roles.js b/apps/frontend/src/lib/roles.js index 9b8faf73e..d8966cca2 100644 --- a/apps/frontend/src/lib/roles.js +++ b/apps/frontend/src/lib/roles.js @@ -1,7 +1,7 @@ -const api_root = `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api`; +const base = process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL; export async function getRoles(token) { - const endpoint = `${api_root}/users-permissions/roles`; + const url = new URL("/api/users-permissions/roles", base); const options = { method: "GET", @@ -12,7 +12,7 @@ export async function getRoles(token) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); return res.json(); } catch (error) { diff --git a/apps/frontend/src/lib/tags.js b/apps/frontend/src/lib/tags.js index 254be4803..52c4d56b6 100644 --- a/apps/frontend/src/lib/tags.js +++ b/apps/frontend/src/lib/tags.js @@ -1,13 +1,13 @@ import qs from "qs"; // Tag API calls - -const api_root = `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api`; +const base = process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL; export async function getTags(token, queryParams) { - const endpoint = `${api_root}/tags?${qs.stringify(queryParams, { + const url = new URL("/api/tags", base); + url.search = qs.stringify(queryParams, { encodeValuesOnly: true, - })}`; + }); const options = { method: "GET", @@ -18,17 +18,17 @@ export async function getTags(token, queryParams) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); return res.json(); } catch (error) { - console.error("getTags responded with error. Status: ", res?.body); - throw new Error(`getTags responded with error. Status: ${res?.body}`); + console.error("getTags responded with error. Status: ", res.body); + throw new Error(`getTags responded with error. Status: ${res.body}`); } } export async function createTag(token, data) { - const endpoint = `${api_root}/tags`; + const url = new URL("/api/tags", base); const options = { method: "POST", @@ -40,11 +40,11 @@ export async function createTag(token, data) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { - console.error("createTag responded with error. Status: ", res?.status); - throw new Error(`createTag responded with error. Status: ${res?.status}`); + console.error("createTag responded with error. Status: ", res.status); + throw new Error(`createTag responded with error. Status: ${res.status}`); } return res.json(); @@ -55,14 +55,15 @@ export async function createTag(token, data) { } export async function getTag(token, tagId) { - const endpoint = `${api_root}/tags/${tagId}?${qs.stringify( + const url = new URL(`/api/tags/${tagId}`, base); + url.search = qs.stringify( { populate: "*", }, { encodeValuesOnly: true, }, - )}`; + ); const options = { method: "GET", @@ -73,24 +74,25 @@ export async function getTag(token, tagId) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); return res.json(); } catch (error) { - console.error("getTag responded with error. Status: ", res?.body); - throw new Error(`getTag responded with error. Status: ${res?.body}`); + console.error("getTag responded with error. Status: ", res.body); + throw new Error(`getTag responded with error. Status: ${res.body}`); } } export async function updateTag(token, tagId, data) { - const endpoint = `${api_root}/tags/${tagId}?${qs.stringify( + const url = new URL(`/api/tags/${tagId}`, base); + url.search = qs.stringify( { populate: "*", }, { encodeValuesOnly: true, }, - )}`; + ); const options = { method: "PUT", @@ -102,17 +104,17 @@ export async function updateTag(token, tagId, data) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); return res.json(); } catch (error) { - console.error("updateTag responded with error. Status: ", res?.body); - throw new Error(`updateTag responded with error. Status: ${res?.body}`); + console.error("updateTag responded with error. Status: ", res.body); + throw new Error(`updateTag responded with error. Status: ${res.body}`); } } export async function deleteTag(token, tagId) { - const endpoint = `${api_root}/tags/${tagId}`; + const url = new URL(`/api/tags/${tagId}`, base); const options = { method: "DELETE", @@ -123,11 +125,11 @@ export async function deleteTag(token, tagId) { }; try { - const res = await fetch(endpoint, options); + const res = await fetch(url, options); return res.json(); } catch (error) { - console.error("deleteTag responded with error. Status: ", res?.body); - throw new Error(`deleteTag responded with error. Status: ${res?.body}`); + console.error("deleteTag responded with error. Status: ", res.body); + throw new Error(`deleteTag responded with error. Status: ${res.body}`); } } diff --git a/apps/frontend/src/lib/users.js b/apps/frontend/src/lib/users.js index 93bdb771d..60732b138 100644 --- a/apps/frontend/src/lib/users.js +++ b/apps/frontend/src/lib/users.js @@ -1,12 +1,12 @@ import qs from "qs"; // Users & Permissions API calls - -const api_root = `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api`; +const base = process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL; export async function getMe(token, queryParams) { - const endpoint = `${api_root}/users/me?${qs.stringify(queryParams, { + const url = new URL("/api/users/me", base); + url.search = qs.stringify(queryParams, { encodeValuesOnly: true, - })}`; + }); const options = { method: "GET", @@ -16,7 +16,7 @@ export async function getMe(token, queryParams) { }, }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("getMe Failed"); } @@ -24,7 +24,7 @@ export async function getMe(token, queryParams) { } export async function updateMe(token, data) { - const endpoint = `${api_root}/users/me`; + const url = new URL("/api/users/me", base); const options = { method: "PUT", @@ -35,7 +35,7 @@ export async function updateMe(token, data) { body: JSON.stringify(data), }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("updateUsers Failed"); @@ -44,9 +44,10 @@ export async function updateMe(token, data) { } export async function getUsers(token, queryParams) { - const endpoint = `${api_root}/users?${qs.stringify(queryParams, { + const url = new URL("/api/users", base); + url.search = qs.stringify(queryParams, { encodeValuesOnly: true, - })}`; + }); const options = { method: "GET", @@ -56,7 +57,7 @@ export async function getUsers(token, queryParams) { }, }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("getUsers Failed"); @@ -65,7 +66,8 @@ export async function getUsers(token, queryParams) { } export async function userExists(token, email) { - const endpoint = `${api_root}/users?${qs.stringify( + const url = new URL("/api/users", base); + url.search = qs.stringify( { filters: { email: { @@ -76,7 +78,7 @@ export async function userExists(token, email) { { encodeValuesOnly: true, }, - )}`; + ); const options = { method: "GET", @@ -86,7 +88,7 @@ export async function userExists(token, email) { }, }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("userExists Failed"); @@ -97,14 +99,15 @@ export async function userExists(token, email) { } export async function getUser(token, userId) { - const endpoint = `${api_root}/users/${userId}?${qs.stringify( + const url = new URL(`/api/users/${userId}`, base); + url.search = qs.stringify( { populate: ["role"], }, { encodeValuesOnly: true, }, - )}`; + ); const options = { method: "GET", @@ -114,7 +117,7 @@ export async function getUser(token, userId) { }, }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("getUsers Failed"); @@ -123,7 +126,7 @@ export async function getUser(token, userId) { } export async function updateUser(token, userId, data) { - const endpoint = `${api_root}/users/${userId}`; + const url = new URL(`/api/users/${userId}`, base); const options = { method: "PUT", @@ -134,7 +137,7 @@ export async function updateUser(token, userId, data) { body: JSON.stringify(data), }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("updateUsers Failed"); @@ -143,7 +146,7 @@ export async function updateUser(token, userId, data) { } export async function deleteUser(token, userId) { - const endpoint = `${api_root}/users/${userId}`; + const url = new URL(`/api/users/${userId}`, base); const options = { method: "DELETE", @@ -153,7 +156,7 @@ export async function deleteUser(token, userId) { }, }; - const res = await fetch(endpoint, options); + const res = await fetch(url, options); if (!res.ok) { throw new Error("deleteUsers Failed"); diff --git a/apps/frontend/src/pages/api/auth/[...nextauth].js b/apps/frontend/src/pages/api/auth/[...nextauth].js index d410fded7..1ab46c061 100644 --- a/apps/frontend/src/pages/api/auth/[...nextauth].js +++ b/apps/frontend/src/pages/api/auth/[...nextauth].js @@ -18,14 +18,15 @@ export const authOptions = { }, async authorize(credentials) { const { identifier, password } = credentials; - const res = await fetch( - `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api/auth/local`, - { - method: "POST", - body: JSON.stringify({ identifier, password }), - headers: { "Content-Type": "application/json" }, - }, + const url = new URL( + "api/auth/local", + process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL, ); + const res = await fetch(url, { + method: "POST", + body: JSON.stringify({ identifier, password }), + headers: { "Content-Type": "application/json" }, + }); const data = await res.json(); if (res.ok && data.jwt) { @@ -46,9 +47,12 @@ export const authOptions = { callbacks: { async signIn({ user }) { const { email } = user; - const res = await fetch( - `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api/invited-users?filters[email][$eq]=${email}`, + const url = new URL( + "api/invited-users", + process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL, ); + url.search = `filters[email][$eq]=${email}`; + const res = await fetch(url); const { data } = await res.json(); if (data.length === 0) { return false; @@ -63,9 +67,11 @@ export const authOptions = { // Get JWT token to access the Strapi API // Note: This is different from the session JWT that is stored in the cookie at the end of this callback if (account.provider === "auth0") { - const res = await fetch( - `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api/auth/${account.provider}/callback?access_token=${account.access_token}`, + const url = new URL( + `/api/auth/${account.provider}/callback`, + process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL, ); + url.search = `access_token=${account.access_token}`; const data = await res.json(); // Note: If the email is already registered on Strapi app without using Auth0 // then it will fail to get JWT token @@ -78,14 +84,16 @@ export const authOptions = { } // Fetch user role data from /api/users/me?populate=role - const res2 = await fetch( - `${process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL}/api/users/me?populate=*`, - { - headers: { - Authorization: `Bearer ${token.jwt}`, - }, - }, + const usersUrl = new URL( + "/api/users/me", + process.env.NEXT_PUBLIC_STRAPI_BACKEND_URL, ); + usersUrl.search = "populate=*"; + const res2 = await fetch(usersUrl, { + headers: { + Authorization: `Bearer ${token.jwt}`, + }, + }); if (res2.ok) { const userData = await res2.json();