From cba8347f884fa110a39a8dcb3d201768919a68f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 04:44:35 +0000 Subject: [PATCH 01/24] Bump @auth/prisma-adapter from 1.0.0 to 1.0.1 Bumps [@auth/prisma-adapter](https://github.com/nextauthjs/next-auth) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/nextauthjs/next-auth/releases) - [Commits](https://github.com/nextauthjs/next-auth/compare/@auth/prisma-adapter@1.0.0...@auth/prisma-adapter@1.0.1) --- updated-dependencies: - dependency-name: "@auth/prisma-adapter" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index cc005e9..fa42a55 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "lint": "next lint" }, "dependencies": { - "@auth/prisma-adapter": "^1.0.0", + "@auth/prisma-adapter": "^1.0.1", "@aws-sdk/client-s3": "^3.363.0", "@fortawesome/fontawesome-svg-core": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", diff --git a/yarn.lock b/yarn.lock index 532967f..a596408 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,10 +12,10 @@ resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== -"@auth/core@0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@auth/core/-/core-0.8.1.tgz#8fbfb7b11ed3e4b346857b033e454efb7c16df26" - integrity sha512-WudBmZudZ/cvykxHV5hIwrYsd7AlETQ535O7w3sSiiumT28+U9GvBb8oSRtfzxpW9rym3lAdfeTJqGA8U4FecQ== +"@auth/core@0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@auth/core/-/core-0.9.0.tgz#7a5d66eea0bc059cef072734698547ae2a0c86a6" + integrity sha512-W2WO0WCBg1T3P8+yjQPzurTQhPv6ecBYfJ2oE3uvXPAX5ZLWAMSjKFAIa9oLZy5pwrB+YehJZPnlIxVilhrVcg== dependencies: "@panva/hkdf" "^1.0.4" cookie "0.5.0" @@ -24,12 +24,12 @@ preact "10.11.3" preact-render-to-string "5.2.3" -"@auth/prisma-adapter@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@auth/prisma-adapter/-/prisma-adapter-1.0.0.tgz#9107498921997b6174e0189553f29d0eb49ba2a0" - integrity sha512-+x+s5dgpNmqrcQC2ZRAXZIM6yhkWP/EXjIUgqUyMepLiX1OHi2AXIUAAbXsW4oG9OpYr/rvPIzPBpuGt6sPFwQ== +"@auth/prisma-adapter@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@auth/prisma-adapter/-/prisma-adapter-1.0.1.tgz#eba93843e77018fa7ca0d68726aa959d6b60512c" + integrity sha512-sBp9l/jVr7l9y7rp2Pv6eoP7i8X2CgRNE3jDWJ0B/u+HnKRofXflD1cldPqRSAkJhqH3UxhVtMTEijT9FoofmQ== dependencies: - "@auth/core" "0.8.1" + "@auth/core" "0.9.0" "@aws-crypto/crc32@3.0.0": version "3.0.0" From 6965b42c69dbf3c382a22513358426a9f4ad5197 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 04:44:46 +0000 Subject: [PATCH 02/24] Bump postcss from 8.4.24 to 8.4.26 Bumps [postcss](https://github.com/postcss/postcss) from 8.4.24 to 8.4.26. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.24...8.4.26) --- updated-dependencies: - dependency-name: postcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index cc005e9..55cead0 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@playwright/test": "^1.35.1", "@types/bcrypt": "^5.0.0", "autoprefixer": "^10.4.14", - "postcss": "^8.4.24", + "postcss": "^8.4.26", "prisma": "^4.16.2", "tailwindcss": "^3.3.2" } diff --git a/yarn.lock b/yarn.lock index 532967f..6fd572f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3540,12 +3540,7 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== - -nanoid@^3.3.6: +nanoid@^3.3.4, nanoid@^3.3.6: version "3.3.6" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== @@ -3981,10 +3976,10 @@ postcss@8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.4.23, postcss@^8.4.24: - version "8.4.24" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" - integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== +postcss@^8.4.23, postcss@^8.4.26: + version "8.4.26" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.26.tgz#1bc62ab19f8e1e5463d98cf74af39702a00a9e94" + integrity sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" From 7be8f55d0a2d2058febea65df86ba3c144d8e337 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 04:45:07 +0000 Subject: [PATCH 03/24] Bump tailwindcss from 3.3.2 to 3.3.3 Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/v3.3.3/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.3.2...v3.3.3) --- updated-dependencies: - dependency-name: tailwindcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 27 ++++++--------------------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index cc005e9..e230ffa 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,6 @@ "autoprefixer": "^10.4.14", "postcss": "^8.4.24", "prisma": "^4.16.2", - "tailwindcss": "^3.3.2" + "tailwindcss": "^3.3.3" } } diff --git a/yarn.lock b/yarn.lock index 532967f..655b7ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3391,12 +3391,7 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -lilconfig@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== - -lilconfig@^2.1.0: +lilconfig@^2.0.5, lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== @@ -4237,16 +4232,7 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.22.2: +resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.2: version "1.22.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== @@ -4564,10 +4550,10 @@ synckit@^0.8.4: "@pkgr/utils" "^2.3.1" tslib "^2.5.0" -tailwindcss@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3" - integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w== +tailwindcss@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf" + integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w== dependencies: "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" @@ -4589,7 +4575,6 @@ tailwindcss@^3.3.2: postcss-load-config "^4.0.1" postcss-nested "^6.0.1" postcss-selector-parser "^6.0.11" - postcss-value-parser "^4.2.0" resolve "^1.22.2" sucrase "^3.32.0" From 8838756c16702bf5ad408a3ebc5b3e11344f4418 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 18 Jul 2023 18:14:26 -0400 Subject: [PATCH 04/24] small improvements --- components/LinkCard.tsx | 8 ++++---- components/Modal/Link/LinkDetails.tsx | 2 +- components/Modal/User/ProfileSettings.tsx | 2 +- pages/collections/[id].tsx | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/LinkCard.tsx b/components/LinkCard.tsx index fa28756..4f286c9 100644 --- a/components/LinkCard.tsx +++ b/components/LinkCard.tsx @@ -143,18 +143,18 @@ export default function LinkCard({ link, count, className }: Props) {

{count + 1}.

-

+

{link.name}

-
-
+
+
-

+

{collection?.name}

diff --git a/components/Modal/Link/LinkDetails.tsx b/components/Modal/Link/LinkDetails.tsx index 3d18233..1847c92 100644 --- a/components/Modal/Link/LinkDetails.tsx +++ b/components/Modal/Link/LinkDetails.tsx @@ -151,7 +151,7 @@ export default function LinkDetails({ link }: Props) { /> )}
-

+

{link.name}

)} -
+
From ac2fab1476280193138f182054993767ab3f9705 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 18 Jul 2023 23:57:47 -0400 Subject: [PATCH 05/24] minor fix --- pages/collections/[id].tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx index f47ed7f..37baacd 100644 --- a/pages/collections/[id].tsx +++ b/pages/collections/[id].tsx @@ -59,7 +59,7 @@ export default function Index() { style={{ color: activeCollection?.color }} className="sm:w-8 sm:h-8 w-6 h-6 mt-3 drop-shadow" /> -

+

{activeCollection?.name}

From 742e17351e464797683151be0f1d6d2110479c20 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 01:23:53 -0400 Subject: [PATCH 06/24] added username check --- lib/api/controllers/users/updateUser.ts | 9 +++++++++ pages/api/auth/register.ts | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/api/controllers/users/updateUser.ts b/lib/api/controllers/users/updateUser.ts index 064dd84..cdf6260 100644 --- a/lib/api/controllers/users/updateUser.ts +++ b/lib/api/controllers/users/updateUser.ts @@ -20,6 +20,15 @@ export default async function updateUser( status: 400, }; + const checkUsername = RegExp("^[a-z0-9_-]{3,31}$"); + + if (!checkUsername.test(user.username)) + return { + response: + "Username has to be between 3-30 characters, no spaces and special characters are allowed.", + status: 400, + }; + const userIsTaken = await prisma.user.findFirst({ where: { id: { not: sessionUser.id }, diff --git a/pages/api/auth/register.ts b/pages/api/auth/register.ts index 9e91bee..44406ee 100644 --- a/pages/api/auth/register.ts +++ b/pages/api/auth/register.ts @@ -52,6 +52,14 @@ export default async function Index( }, }); + const checkUsername = RegExp("^[a-z0-9_-]{3,31}$"); + + if (!checkUsername.test(body.username)) + return res.status(400).json({ + response: + "Username has to be between 3-30 characters, no spaces and special characters are allowed.", + }); + const checkIfUserExists = await prisma.user.findFirst({ where: emailEnabled ? { @@ -84,8 +92,10 @@ export default async function Index( }, }); - res.status(201).json({ response: "User successfully created." }); + return res.status(201).json({ response: "User successfully created." }); } else if (checkIfUserExists) { - res.status(400).json({ response: "Username and/or Email already exists." }); + return res + .status(400) + .json({ response: "Username and/or Email already exists." }); } } From 01a85791583cdb3d11f1d968cffbbf1c1ff68b1d Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 11:30:11 -0400 Subject: [PATCH 07/24] minor fix --- components/Modal/User/ChangePassword.tsx | 26 ++++++++++++----------- components/Modal/User/ProfileSettings.tsx | 1 - 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/components/Modal/User/ChangePassword.tsx b/components/Modal/User/ChangePassword.tsx index 6237291..09e0f3b 100644 --- a/components/Modal/User/ChangePassword.tsx +++ b/components/Modal/User/ChangePassword.tsx @@ -1,7 +1,7 @@ import { Dispatch, SetStateAction, useEffect, useState } from "react"; import { AccountSettings } from "@/types/global"; import useAccountStore from "@/store/account"; -import { useSession } from "next-auth/react"; +import { signOut, useSession } from "next-auth/react"; import { faPenToSquare } from "@fortawesome/free-regular-svg-icons"; import SubmitButton from "@/components/SubmitButton"; import { toast } from "react-hot-toast"; @@ -50,22 +50,24 @@ export default function ChangePassword({ if (response.ok) { toast.success("Settings Applied!"); - togglePasswordFormModal(); - } else toast.error(response.data as string); - setSubmitLoader(false); + if ( + user.username !== account.username || + user.name !== account.name || + user.email !== account.email + ) { + update({ + username: user.username, + email: user.username, + name: user.name, + }); - if ( - (user.username !== account.username || user.name !== account.name) && - user.username && - user.email - ) - update({ username: user.username, name: user.name }); + signOut(); + } - if (response.ok) { setUser({ ...user, newPassword: undefined }); togglePasswordFormModal(); - } + } else toast.error(response.data as string); } else { toast.error("Passwords do not match."); } diff --git a/components/Modal/User/ProfileSettings.tsx b/components/Modal/User/ProfileSettings.tsx index 3db24b6..5090846 100644 --- a/components/Modal/User/ProfileSettings.tsx +++ b/components/Modal/User/ProfileSettings.tsx @@ -77,7 +77,6 @@ export default function ProfileSettings({ if (response.ok) { toast.success("Settings Applied!"); - toggleSettingsModal(); if ( user.username !== account.username || From 35bece5f4940cd732baf89cf8a86ce61b21bb155 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 12:14:52 -0400 Subject: [PATCH 08/24] bug fix + use id instead of username for lookup --- components/Modal/User/index.tsx | 2 ++ hooks/useInitialData.tsx | 2 +- lib/api/controllers/collections/postCollection.ts | 2 +- .../controllers/collections/updateCollection.ts | 2 +- lib/api/controllers/users/getUsers.ts | 10 +++++----- lib/api/paymentCheckout.ts | 1 - pages/api/auth/[...nextauth].ts | 1 - pages/api/avatar/[id].ts | 6 +++--- pages/api/payment/index.ts | 3 +-- pages/api/routes/collections/index.ts | 2 +- pages/api/routes/links/index.ts | 2 +- pages/api/routes/users/index.ts | 14 +++++--------- store/account.ts | 6 +++--- 13 files changed, 24 insertions(+), 29 deletions(-) diff --git a/components/Modal/User/index.tsx b/components/Modal/User/index.tsx index 199d9bb..eb9ee60 100644 --- a/components/Modal/User/index.tsx +++ b/components/Modal/User/index.tsx @@ -24,6 +24,8 @@ export default function UserModal({ }: Props) { const [user, setUser] = useState(activeUser); + console.log(activeUser); + return (
diff --git a/hooks/useInitialData.tsx b/hooks/useInitialData.tsx index 5655de3..a25fadd 100644 --- a/hooks/useInitialData.tsx +++ b/hooks/useInitialData.tsx @@ -17,7 +17,7 @@ export default function useInitialData() { setCollections(); setTags(); // setLinks(); - setAccount(data.user.username as string); + setAccount(data.user.id); } }, [status]); } diff --git a/lib/api/controllers/collections/postCollection.ts b/lib/api/controllers/collections/postCollection.ts index 213266a..8e4cc99 100644 --- a/lib/api/controllers/collections/postCollection.ts +++ b/lib/api/controllers/collections/postCollection.ts @@ -42,7 +42,7 @@ export default async function postCollection( color: collection.color, members: { create: collection.members.map((e) => ({ - user: { connect: { username: e.user.username.toLowerCase() } }, + user: { connect: { id: e.user.id } }, canCreate: e.canCreate, canUpdate: e.canUpdate, canDelete: e.canDelete, diff --git a/lib/api/controllers/collections/updateCollection.ts b/lib/api/controllers/collections/updateCollection.ts index ac3dc65..7d2c65e 100644 --- a/lib/api/controllers/collections/updateCollection.ts +++ b/lib/api/controllers/collections/updateCollection.ts @@ -43,7 +43,7 @@ export default async function updateCollection( isPublic: collection.isPublic, members: { create: collection.members.map((e) => ({ - user: { connect: { username: e.user.username.toLowerCase() } }, + user: { connect: { id: e.user.id } }, canCreate: e.canCreate, canUpdate: e.canUpdate, canDelete: e.canDelete, diff --git a/lib/api/controllers/users/getUsers.ts b/lib/api/controllers/users/getUsers.ts index b75ea7f..381a713 100644 --- a/lib/api/controllers/users/getUsers.ts +++ b/lib/api/controllers/users/getUsers.ts @@ -29,16 +29,16 @@ export default async function getUser({ return { response: "This profile is private.", status: 401 }; } - const { password, ...unsensitiveInfo } = user; + const { password, ...lessSensitiveInfo } = user; const data = isSelf ? // If user is requesting its own data - unsensitiveInfo + lessSensitiveInfo : { // If user is requesting someone elses data - id: unsensitiveInfo.id, - name: unsensitiveInfo.name, - username: unsensitiveInfo.username, + id: lessSensitiveInfo.id, + name: lessSensitiveInfo.name, + username: lessSensitiveInfo.username, }; return { response: data || null, status: 200 }; diff --git a/lib/api/paymentCheckout.ts b/lib/api/paymentCheckout.ts index 63dac04..9c2893c 100644 --- a/lib/api/paymentCheckout.ts +++ b/lib/api/paymentCheckout.ts @@ -4,7 +4,6 @@ import checkSubscription from "./checkSubscription"; export default async function paymentCheckout( stripeSecretKey: string, email: string, - action: "register" | "login", priceId: string ) { const stripe = new Stripe(stripeSecretKey, { diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 6777e1d..5da3fec 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -110,7 +110,6 @@ export const authOptions: AuthOptions = { PRICE_ID && (trigger || subscriptionIsTimesUp || !token.isSubscriber) ) { - console.log("EXECUTED!!!"); const subscription = await checkSubscription( STRIPE_SECRET_KEY, token.email as string, diff --git a/pages/api/avatar/[id].ts b/pages/api/avatar/[id].ts index 0287229..d447866 100644 --- a/pages/api/avatar/[id].ts +++ b/pages/api/avatar/[id].ts @@ -8,10 +8,10 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { const session = await getServerSession(req, res, authOptions); const userId = session?.user.id; - const userName = session?.user.username?.toLowerCase(); + const username = session?.user.username?.toLowerCase(); const queryId = Number(req.query.id); - if (!userId || !userName) + if (!userId || !username) return res .setHeader("Content-Type", "text/plain") .status(401) @@ -37,7 +37,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { if ( targetUser?.isPrivate && - !targetUser.whitelistedUsers.includes(userName) + !targetUser.whitelistedUsers.includes(username) ) { return res .setHeader("Content-Type", "text/plain") diff --git a/pages/api/payment/index.ts b/pages/api/payment/index.ts index 66566b7..cd37caf 100644 --- a/pages/api/payment/index.ts +++ b/pages/api/payment/index.ts @@ -8,7 +8,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { const PRICE_ID = process.env.PRICE_ID; const session = await getServerSession(req, res, authOptions); - if (!session?.user?.username) + if (!session?.user?.id) return res.status(401).json({ response: "You must be logged in." }); else if (!STRIPE_SECRET_KEY || !PRICE_ID) { return res.status(400).json({ response: "Payment is disabled." }); @@ -18,7 +18,6 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { const users = await paymentCheckout( STRIPE_SECRET_KEY, session?.user.email, - "register", PRICE_ID ); return res.status(users.status).json({ response: users.response }); diff --git a/pages/api/routes/collections/index.ts b/pages/api/routes/collections/index.ts index 25fec73..321dcd4 100644 --- a/pages/api/routes/collections/index.ts +++ b/pages/api/routes/collections/index.ts @@ -12,7 +12,7 @@ export default async function collections( ) { const session = await getServerSession(req, res, authOptions); - if (!session?.user?.username) { + if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) res.status(401).json({ diff --git a/pages/api/routes/links/index.ts b/pages/api/routes/links/index.ts index 4a226d4..76ca629 100644 --- a/pages/api/routes/links/index.ts +++ b/pages/api/routes/links/index.ts @@ -9,7 +9,7 @@ import updateLink from "@/lib/api/controllers/links/updateLink"; export default async function links(req: NextApiRequest, res: NextApiResponse) { const session = await getServerSession(req, res, authOptions); - if (!session?.user?.username) { + if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) res.status(401).json({ diff --git a/pages/api/routes/users/index.ts b/pages/api/routes/users/index.ts index 6757bab..2a1ecc1 100644 --- a/pages/api/routes/users/index.ts +++ b/pages/api/routes/users/index.ts @@ -7,7 +7,7 @@ import updateUser from "@/lib/api/controllers/users/updateUser"; export default async function users(req: NextApiRequest, res: NextApiResponse) { const session = await getServerSession(req, res, authOptions); - if (!session?.user.username) { + if (!session?.user.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) res.status(401).json({ @@ -17,7 +17,10 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { const lookupUsername = (req.query.username as string) || undefined; const lookupId = Number(req.query.id) || undefined; - const isSelf = session.user.username === lookupUsername ? true : false; + const isSelf = + session.user.username === lookupUsername || session.user.id === lookupId + ? true + : false; if (req.method === "GET") { const users = await getUsers({ @@ -34,10 +37,3 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { return res.status(updated.status).json({ response: updated.response }); } } - -// { -// lookupUsername, -// lookupId, -// }, -// isSelf, -// session.user.username diff --git a/store/account.ts b/store/account.ts index 7df7578..ae08806 100644 --- a/store/account.ts +++ b/store/account.ts @@ -8,14 +8,14 @@ type ResponseObject = { type AccountStore = { account: AccountSettings; - setAccount: (username: string) => void; + setAccount: (id: number) => void; updateAccount: (user: AccountSettings) => Promise; }; const useAccountStore = create()((set) => ({ account: {} as AccountSettings, - setAccount: async (username) => { - const response = await fetch(`/api/routes/users?username=${username}`); + setAccount: async (id) => { + const response = await fetch(`/api/routes/users?id=${id}`); const data = await response.json(); From 0e31e92c359db0df77d005422ea562057c573509 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 14:00:45 -0400 Subject: [PATCH 09/24] small fix --- components/Modal/User/ChangePassword.tsx | 7 ++++--- components/Modal/User/PrivacySettings.tsx | 23 +++++++++++++++-------- components/Modal/User/ProfileSettings.tsx | 14 +++++++++++--- components/Modal/User/index.tsx | 2 -- pages/api/auth/[...nextauth].ts | 2 -- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/components/Modal/User/ChangePassword.tsx b/components/Modal/User/ChangePassword.tsx index 09e0f3b..5ccfe08 100644 --- a/components/Modal/User/ChangePassword.tsx +++ b/components/Modal/User/ChangePassword.tsx @@ -52,13 +52,13 @@ export default function ChangePassword({ toast.success("Settings Applied!"); if ( + user.email !== account.email || user.username !== account.username || - user.name !== account.name || - user.email !== account.email + user.name !== account.name ) { update({ username: user.username, - email: user.username, + email: user.email, name: user.name, }); @@ -71,6 +71,7 @@ export default function ChangePassword({ } else { toast.error("Passwords do not match."); } + setSubmitLoader(false); }; return ( diff --git a/components/Modal/User/PrivacySettings.tsx b/components/Modal/User/PrivacySettings.tsx index 8957d5f..79dbb5a 100644 --- a/components/Modal/User/PrivacySettings.tsx +++ b/components/Modal/User/PrivacySettings.tsx @@ -2,7 +2,7 @@ import { Dispatch, SetStateAction, useEffect, useState } from "react"; import Checkbox from "../../Checkbox"; import useAccountStore from "@/store/account"; import { AccountSettings } from "@/types/global"; -import { useSession } from "next-auth/react"; +import { signOut, useSession } from "next-auth/react"; import { faPenToSquare } from "@fortawesome/free-regular-svg-icons"; import SubmitButton from "../../SubmitButton"; import { toast } from "react-hot-toast"; @@ -59,18 +59,25 @@ export default function PrivacySettings({ if (response.ok) { toast.success("Settings Applied!"); - toggleSettingsModal(); - } else toast.error(response.data as string); - setSubmitLoader(false); + if ( + user.email !== account.email || + user.username !== account.username || + user.name !== account.name + ) { + update({ + username: user.username, + email: user.email, + name: user.name, + }); - if (user.username !== account.username || user.name !== account.name) - update({ username: user.username, name: user.name }); + signOut(); + } - if (response.ok) { setUser({ ...user, newPassword: undefined }); toggleSettingsModal(); - } + } else toast.error(response.data as string); + setSubmitLoader(false); }; return ( diff --git a/components/Modal/User/ProfileSettings.tsx b/components/Modal/User/ProfileSettings.tsx index 5090846..cee20bd 100644 --- a/components/Modal/User/ProfileSettings.tsx +++ b/components/Modal/User/ProfileSettings.tsx @@ -79,13 +79,13 @@ export default function ProfileSettings({ toast.success("Settings Applied!"); if ( + user.email !== account.email || user.username !== account.username || - user.name !== account.name || - user.email !== account.email + user.name !== account.name ) { update({ username: user.username, - email: user.username, + email: user.email, name: user.name, }); @@ -175,6 +175,14 @@ export default function ProfileSettings({ />
) : undefined} + + {user.username !== account.username || + user.name !== account.name || + user.email !== account.email ? ( +

+ You will need to log back in after you apply the changes. +

+ ) : undefined}
diff --git a/components/Modal/User/index.tsx b/components/Modal/User/index.tsx index eb9ee60..199d9bb 100644 --- a/components/Modal/User/index.tsx +++ b/components/Modal/User/index.tsx @@ -24,8 +24,6 @@ export default function UserModal({ }: Props) { const [user, setUser] = useState(activeUser); - console.log(activeUser); - return (
diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 5da3fec..6de9f51 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -116,8 +116,6 @@ export const authOptions: AuthOptions = { PRICE_ID ); - subscription.isSubscriber; - if (subscription.subscriptionCanceledAt) { token.subscriptionCanceledAt = subscription.subscriptionCanceledAt; } else token.subscriptionCanceledAt = undefined; From 7912815c9efe936224124b4b726caa620afa3b29 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 16:39:59 -0400 Subject: [PATCH 10/24] many improvements --- components/Modal/User/ChangePassword.tsx | 6 +- components/Modal/User/PrivacySettings.tsx | 6 +- components/Modal/User/ProfileSettings.tsx | 8 +- layouts/AuthRedirect.tsx | 18 ++- lib/api/paymentCheckout.ts | 31 ----- pages/api/auth/[...nextauth].ts | 19 ++- pages/api/auth/register.ts | 44 ++----- pages/api/routes/users/index.ts | 2 +- pages/choose-username.tsx | 108 ++++++++++++++++++ pages/register.tsx | 31 ++--- pages/subscribe.tsx | 6 +- .../migration.sql | 2 +- prisma/schema.prisma | 2 +- store/account.ts | 2 +- 14 files changed, 176 insertions(+), 109 deletions(-) create mode 100644 pages/choose-username.tsx rename prisma/migrations/{20230715102805_init => 20230719181459_init}/migration.sql (99%) diff --git a/components/Modal/User/ChangePassword.tsx b/components/Modal/User/ChangePassword.tsx index 5ccfe08..c299a43 100644 --- a/components/Modal/User/ChangePassword.tsx +++ b/components/Modal/User/ChangePassword.tsx @@ -23,7 +23,7 @@ export default function ChangePassword({ const [submitLoader, setSubmitLoader] = useState(false); const { account, updateAccount } = useAccountStore(); - const { update } = useSession(); + const { update, data } = useSession(); useEffect(() => { if ( @@ -57,9 +57,7 @@ export default function ChangePassword({ user.name !== account.name ) { update({ - username: user.username, - email: user.email, - name: user.name, + id: data?.user.id, }); signOut(); diff --git a/components/Modal/User/PrivacySettings.tsx b/components/Modal/User/PrivacySettings.tsx index 79dbb5a..6047448 100644 --- a/components/Modal/User/PrivacySettings.tsx +++ b/components/Modal/User/PrivacySettings.tsx @@ -18,7 +18,7 @@ export default function PrivacySettings({ setUser, user, }: Props) { - const { update } = useSession(); + const { update, data } = useSession(); const { account, updateAccount } = useAccountStore(); const [submitLoader, setSubmitLoader] = useState(false); @@ -66,9 +66,7 @@ export default function PrivacySettings({ user.name !== account.name ) { update({ - username: user.username, - email: user.email, - name: user.name, + id: data?.user.id, }); signOut(); diff --git a/components/Modal/User/ProfileSettings.tsx b/components/Modal/User/ProfileSettings.tsx index cee20bd..76b5fe4 100644 --- a/components/Modal/User/ProfileSettings.tsx +++ b/components/Modal/User/ProfileSettings.tsx @@ -23,7 +23,7 @@ export default function ProfileSettings({ setUser, user, }: Props) { - const { update } = useSession(); + const { update, data } = useSession(); const { account, updateAccount } = useAccountStore(); const [profileStatus, setProfileStatus] = useState(true); @@ -84,9 +84,7 @@ export default function ProfileSettings({ user.name !== account.name ) { update({ - username: user.username, - email: user.email, - name: user.name, + id: data?.user.id, }); signOut(); @@ -158,7 +156,7 @@ export default function ProfileSettings({

Username

setUser({ ...user, username: e.target.value })} className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" /> diff --git a/layouts/AuthRedirect.tsx b/layouts/AuthRedirect.tsx index 35c2ceb..a5fd1ad 100644 --- a/layouts/AuthRedirect.tsx +++ b/layouts/AuthRedirect.tsx @@ -14,11 +14,26 @@ export default function AuthRedirect({ children }: Props) { const { status, data } = useSession(); const [redirect, setRedirect] = useState(true); + const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER; + useInitialData(); useEffect(() => { if (!router.pathname.startsWith("/public")) { - if (status === "authenticated" && data.user.isSubscriber === false) { + if ( + emailEnabled && + status === "authenticated" && + (data.user.isSubscriber === true || + data.user.isSubscriber === undefined) && + !data.user.username + ) { + router.push("/choose-username").then(() => { + setRedirect(false); + }); + } else if ( + status === "authenticated" && + data.user.isSubscriber === false + ) { router.push("/subscribe").then(() => { setRedirect(false); }); @@ -28,6 +43,7 @@ export default function AuthRedirect({ children }: Props) { router.pathname === "/register" || router.pathname === "/confirmation" || router.pathname === "/subscribe" || + router.pathname === "/choose-username" || router.pathname === "/forgot") ) { router.push("/").then(() => { diff --git a/lib/api/paymentCheckout.ts b/lib/api/paymentCheckout.ts index 9c2893c..34f8e86 100644 --- a/lib/api/paymentCheckout.ts +++ b/lib/api/paymentCheckout.ts @@ -10,12 +10,6 @@ export default async function paymentCheckout( apiVersion: "2022-11-15", }); - // const a = await stripe.prices.retrieve("price_1NTn3PDaRUw6CJPLkw4dcwlJ"); - - // const listBySub = await stripe.subscriptions.list({ - // customer: "cus_OGUzJrRea8Qbxx", - // }); - const listByEmail = await stripe.customers.list({ email: email.toLowerCase(), expand: ["data.subscriptions"], @@ -23,31 +17,6 @@ export default async function paymentCheckout( const isExistingCostomer = listByEmail?.data[0]?.id || undefined; - // const hasPreviouslySubscribed = listByEmail.data.find((customer, i) => { - // const hasValidSubscription = customer.subscriptions?.data.some( - // (subscription) => { - // return subscription?.items?.data?.some( - // (subscriptionItem) => subscriptionItem?.plan?.id === priceId - // ); - // } - // ); - - // return ( - // customer.email?.toLowerCase() === email.toLowerCase() && - // hasValidSubscription - // ); - // }); - - // const previousSubscriptionId = - // hasPreviouslySubscribed?.subscriptions?.data[0].id; - - // if (previousSubscriptionId) { - // console.log(previousSubscriptionId); - // const subscription = await stripe.subscriptions.resume( - // previousSubscriptionId - // ); - // } - const TRIAL_PERIOD_DAYS = process.env.TRIAL_PERIOD_DAYS; const session = await stripe.checkout.sessions.create({ customer: isExistingCostomer ? isExistingCostomer : undefined, diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 6de9f51..e760f2e 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -126,11 +126,20 @@ export const authOptions: AuthOptions = { if (trigger === "signIn") { token.id = user.id; token.username = (user as any).username; - } else if (trigger === "update" && session?.name && session?.username) { - // Note, that `session` can be any arbitrary object, remember to validate it! - token.name = session.name; - token.username = session.username.toLowerCase(); - token.email = session.email.toLowerCase(); + } else if (trigger === "update" && token.id) { + console.log(token); + + const user = await prisma.user.findUnique({ + where: { + id: token.id as number, + }, + }); + + if (user) { + token.name = user.name; + token.username = user.username?.toLowerCase(); + token.email = user.email?.toLowerCase(); + } } return token; }, diff --git a/pages/api/auth/register.ts b/pages/api/auth/register.ts index 44406ee..4abf03e 100644 --- a/pages/api/auth/register.ts +++ b/pages/api/auth/register.ts @@ -11,7 +11,7 @@ interface Data { interface User { name: string; - username: string; + username?: string; email?: string; password: string; } @@ -23,7 +23,7 @@ export default async function Index( const body: User = req.body; const checkHasEmptyFields = emailEnabled - ? !body.username || !body.password || !body.name || !body.email + ? !body.password || !body.name || !body.email : !body.username || !body.password || !body.name; if (checkHasEmptyFields) @@ -31,30 +31,9 @@ export default async function Index( .status(400) .json({ response: "Please fill out all the fields." }); - const tenMinutesAgo = new Date(Date.now() - 10 * 60 * 1000); - - // Remove user's who aren't verified for more than 10 minutes - if (emailEnabled) - await prisma.user.deleteMany({ - where: { - OR: [ - { - email: body.email, - }, - { - username: body.username, - }, - ], - createdAt: { - lt: tenMinutesAgo, - }, - emailVerified: null, - }, - }); - const checkUsername = RegExp("^[a-z0-9_-]{3,31}$"); - if (!checkUsername.test(body.username)) + if (!emailEnabled && !checkUsername.test(body.username || "")) return res.status(400).json({ response: "Username has to be between 3-30 characters, no spaces and special characters are allowed.", @@ -63,18 +42,11 @@ export default async function Index( const checkIfUserExists = await prisma.user.findFirst({ where: emailEnabled ? { - OR: [ - { - username: body.username.toLowerCase(), - }, - { - email: body.email?.toLowerCase(), - }, - ], + email: body.email?.toLowerCase(), emailVerified: { not: null }, } : { - username: body.username.toLowerCase(), + username: (body.username as string).toLowerCase(), }, }); @@ -86,8 +58,10 @@ export default async function Index( await prisma.user.create({ data: { name: body.name, - username: body.username.toLowerCase(), - email: body.email?.toLowerCase(), + username: emailEnabled + ? undefined + : (body.username as string).toLowerCase(), + email: emailEnabled ? body.email?.toLowerCase() : undefined, password: hashedPassword, }, }); diff --git a/pages/api/routes/users/index.ts b/pages/api/routes/users/index.ts index 2a1ecc1..7446150 100644 --- a/pages/api/routes/users/index.ts +++ b/pages/api/routes/users/index.ts @@ -32,7 +32,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { username: session.user.username, }); return res.status(users.status).json({ response: users.response }); - } else if (req.method === "PUT" && !req.body.password) { + } else if (req.method === "PUT") { const updated = await updateUser(req.body, session.user); return res.status(updated.status).json({ response: updated.response }); } diff --git a/pages/choose-username.tsx b/pages/choose-username.tsx new file mode 100644 index 0000000..7c426cb --- /dev/null +++ b/pages/choose-username.tsx @@ -0,0 +1,108 @@ +import SubmitButton from "@/components/SubmitButton"; +import { signOut } from "next-auth/react"; +import Image from "next/image"; +import { useEffect, useState } from "react"; +import { toast } from "react-hot-toast"; +import { useSession } from "next-auth/react"; +import { useRouter } from "next/router"; +import useAccountStore from "@/store/account"; + +export default function Subscribe() { + const [submitLoader, setSubmitLoader] = useState(false); + const [inputedUsername, setInputedUsername] = useState(""); + + const { data, status, update } = useSession(); + + const { updateAccount, account } = useAccountStore(); + + useEffect(() => { + console.log(data?.user); + }, [status]); + + async function submitUsername() { + setSubmitLoader(true); + + const redirectionToast = toast.loading("Applying..."); + + const response = await updateAccount({ + ...account, + username: inputedUsername, + }); + + if (response.ok) { + toast.success("Username Applied!"); + + update({ + id: data?.user.id, + }); + + signOut(); + } else toast.error(response.data as string); + toast.dismiss(redirectionToast); + setSubmitLoader(false); + } + + return ( + <> +
+
+ Linkwarden + +
+

One Last Step...

+

+ Please choose a username to start using your account. +

+
+
+ +
+

+ Username +

+ + setInputedUsername(e.target.value)} + className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" + /> +
+ +

+ Note that you will have to log back in to complete the process. +

+
+

+ Feel free to reach out to us at{" "} + + hello@linkwarden.app + {" "} + in case of any issues. +

+
+ + + +
signOut()} + className="w-fit mx-auto cursor-pointer text-gray-500 font-semibold " + > + Sign Out +
+
+ + ); +} diff --git a/pages/register.tsx b/pages/register.tsx index 2edada5..4ae3fe2 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -9,7 +9,7 @@ const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER; type FormData = { name: string; - username: string; + username?: string; email?: string; password: string; passwordConfirmation: string; @@ -20,7 +20,7 @@ export default function Register() { const [form, setForm] = useState({ name: "", - username: "", + username: emailEnabled ? undefined : "", email: emailEnabled ? "" : undefined, password: "", passwordConfirmation: "", @@ -31,7 +31,6 @@ export default function Register() { if (emailEnabled) { return ( form.name !== "" && - form.username !== "" && form.email !== "" && form.password !== "" && form.passwordConfirmation !== "" @@ -122,19 +121,21 @@ export default function Register() { />
-
-

- Username -

+ {emailEnabled ? undefined : ( +
+

+ Username +

- setForm({ ...form, username: e.target.value })} - className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" - /> -
+ setForm({ ...form, username: e.target.value })} + className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" + /> +
+ )} {emailEnabled ? (
diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index 4d4697b..c1b427e 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -12,10 +12,6 @@ export default function Subscribe() { const { data, status } = useSession(); const router = useRouter(); - useEffect(() => { - console.log(data?.user); - }, [status]); - async function loginUser() { setSubmitLoader(true); @@ -52,7 +48,7 @@ export default function Subscribe() { You will be redirected to Stripe.

- feel free to reach out to us at{" "} + Feel free to reach out to us at{" "} hello@linkwarden.app {" "} diff --git a/prisma/migrations/20230715102805_init/migration.sql b/prisma/migrations/20230719181459_init/migration.sql similarity index 99% rename from prisma/migrations/20230715102805_init/migration.sql rename to prisma/migrations/20230719181459_init/migration.sql index 408f99f..1b7dfcf 100644 --- a/prisma/migrations/20230715102805_init/migration.sql +++ b/prisma/migrations/20230719181459_init/migration.sql @@ -30,7 +30,7 @@ CREATE TABLE "Session" ( CREATE TABLE "User" ( "id" SERIAL NOT NULL, "name" TEXT NOT NULL, - "username" TEXT NOT NULL, + "username" TEXT, "email" TEXT, "emailVerified" TIMESTAMP(3), "image" TEXT, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a3882aa..43d8b90 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -38,7 +38,7 @@ model User { id Int @id @default(autoincrement()) name String - username String @unique + username String? @unique email String? @unique emailVerified DateTime? diff --git a/store/account.ts b/store/account.ts index ae08806..638848c 100644 --- a/store/account.ts +++ b/store/account.ts @@ -3,7 +3,7 @@ import { AccountSettings } from "@/types/global"; type ResponseObject = { ok: boolean; - data: object | string; + data: Omit | object | string; }; type AccountStore = { From ae71ce20209dd875291e455fdf2a58463bd9f16f Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 16:51:53 -0400 Subject: [PATCH 11/24] bug fixed --- components/Modal/User/ChangePassword.tsx | 14 ++++++++------ components/Modal/User/PrivacySettings.tsx | 14 ++++++++------ components/Modal/User/ProfileSettings.tsx | 20 ++++++++++---------- pages/choose-username.tsx | 6 ------ 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/components/Modal/User/ChangePassword.tsx b/components/Modal/User/ChangePassword.tsx index c299a43..a007408 100644 --- a/components/Modal/User/ChangePassword.tsx +++ b/components/Modal/User/ChangePassword.tsx @@ -51,17 +51,19 @@ export default function ChangePassword({ if (response.ok) { toast.success("Settings Applied!"); - if ( - user.email !== account.email || - user.username !== account.username || - user.name !== account.name - ) { + if (user.email !== account.email) { update({ id: data?.user.id, }); signOut(); - } + } else if ( + user.username !== account.username || + user.name !== account.name + ) + update({ + id: data?.user.id, + }); setUser({ ...user, newPassword: undefined }); togglePasswordFormModal(); diff --git a/components/Modal/User/PrivacySettings.tsx b/components/Modal/User/PrivacySettings.tsx index 6047448..ef6cd58 100644 --- a/components/Modal/User/PrivacySettings.tsx +++ b/components/Modal/User/PrivacySettings.tsx @@ -60,17 +60,19 @@ export default function PrivacySettings({ if (response.ok) { toast.success("Settings Applied!"); - if ( - user.email !== account.email || - user.username !== account.username || - user.name !== account.name - ) { + if (user.email !== account.email) { update({ id: data?.user.id, }); signOut(); - } + } else if ( + user.username !== account.username || + user.name !== account.name + ) + update({ + id: data?.user.id, + }); setUser({ ...user, newPassword: undefined }); toggleSettingsModal(); diff --git a/components/Modal/User/ProfileSettings.tsx b/components/Modal/User/ProfileSettings.tsx index 76b5fe4..5716b68 100644 --- a/components/Modal/User/ProfileSettings.tsx +++ b/components/Modal/User/ProfileSettings.tsx @@ -78,17 +78,19 @@ export default function ProfileSettings({ if (response.ok) { toast.success("Settings Applied!"); - if ( - user.email !== account.email || - user.username !== account.username || - user.name !== account.name - ) { + if (user.email !== account.email) { update({ id: data?.user.id, }); signOut(); - } + } else if ( + user.username !== account.username || + user.name !== account.name + ) + update({ + id: data?.user.id, + }); setUser({ ...user, newPassword: undefined }); toggleSettingsModal(); @@ -174,11 +176,9 @@ export default function ProfileSettings({

) : undefined} - {user.username !== account.username || - user.name !== account.name || - user.email !== account.email ? ( + {user.email !== account.email ? (

- You will need to log back in after you apply the changes. + You will need to log back in after you apply this Email.

) : undefined}
diff --git a/pages/choose-username.tsx b/pages/choose-username.tsx index 7c426cb..a3fcfb1 100644 --- a/pages/choose-username.tsx +++ b/pages/choose-username.tsx @@ -35,8 +35,6 @@ export default function Subscribe() { update({ id: data?.user.id, }); - - signOut(); } else toast.error(response.data as string); toast.dismiss(redirectionToast); setSubmitLoader(false); @@ -75,10 +73,6 @@ export default function Subscribe() { className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" />
- -

- Note that you will have to log back in to complete the process. -

Feel free to reach out to us at{" "} From 67989b7c0540325e4cc0737fa4d18a96b1ce4770 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 17:08:05 -0400 Subject: [PATCH 12/24] added min password length rule --- components/Modal/User/ChangePassword.tsx | 70 +++++++++++++----------- pages/register.tsx | 42 +++++++------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/components/Modal/User/ChangePassword.tsx b/components/Modal/User/ChangePassword.tsx index a007408..4c95d8e 100644 --- a/components/Modal/User/ChangePassword.tsx +++ b/components/Modal/User/ChangePassword.tsx @@ -37,40 +37,44 @@ export default function ChangePassword({ const submit = async () => { if (newPassword == "" || newPassword2 == "") { toast.error("Please fill all the fields."); - } else if (newPassword === newPassword2) { - setSubmitLoader(true); - - const load = toast.loading("Applying..."); - - const response = await updateAccount({ - ...user, - }); - - toast.dismiss(load); - - if (response.ok) { - toast.success("Settings Applied!"); - - if (user.email !== account.email) { - update({ - id: data?.user.id, - }); - - signOut(); - } else if ( - user.username !== account.username || - user.name !== account.name - ) - update({ - id: data?.user.id, - }); - - setUser({ ...user, newPassword: undefined }); - togglePasswordFormModal(); - } else toast.error(response.data as string); - } else { - toast.error("Passwords do not match."); } + + if (newPassword !== newPassword2) + return toast.error("Passwords do not match."); + else if (newPassword.length < 8) + return toast.error("Passwords must be at least 8 characters."); + + setSubmitLoader(true); + + const load = toast.loading("Applying..."); + + const response = await updateAccount({ + ...user, + }); + + toast.dismiss(load); + + if (response.ok) { + toast.success("Settings Applied!"); + + if (user.email !== account.email) { + update({ + id: data?.user.id, + }); + + signOut(); + } else if ( + user.username !== account.username || + user.name !== account.name + ) + update({ + id: data?.user.id, + }); + + setUser({ ...user, newPassword: undefined }); + togglePasswordFormModal(); + } else toast.error(response.data as string); + setSubmitLoader(false); }; diff --git a/pages/register.tsx b/pages/register.tsx index 4ae3fe2..c047e17 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -53,35 +53,35 @@ export default function Register() { }; if (checkHasEmptyFields()) { - if (form.password === form.passwordConfirmation) { - const { passwordConfirmation, ...request } = form; + if (form.password !== form.passwordConfirmation) + return toast.error("Passwords do not match."); + else if (form.password.length < 8) + return toast.error("Passwords must be at least 8 characters."); + const { passwordConfirmation, ...request } = form; - setSubmitLoader(true); + setSubmitLoader(true); - const load = toast.loading("Creating Account..."); + const load = toast.loading("Creating Account..."); - const response = await fetch("/api/auth/register", { - body: JSON.stringify(request), - headers: { - "Content-Type": "application/json", - }, - method: "POST", - }); + const response = await fetch("/api/auth/register", { + body: JSON.stringify(request), + headers: { + "Content-Type": "application/json", + }, + method: "POST", + }); - const data = await response.json(); + const data = await response.json(); - toast.dismiss(load); - setSubmitLoader(false); + toast.dismiss(load); + setSubmitLoader(false); - if (response.ok) { - if (form.email) await sendConfirmation(); + if (response.ok) { + if (form.email) await sendConfirmation(); - toast.success("User Created!"); - } else { - toast.error(data.response); - } + toast.success("User Created!"); } else { - toast.error("Passwords do not match."); + toast.error(data.response); } } else { toast.error("Please fill out all the fields."); From 96f43dcc5998fa4b4f6d982570186827ac6d55c5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 17:49:54 -0400 Subject: [PATCH 13/24] UI improvement --- .../InputSelect/CollectionSelection.tsx | 2 +- components/NoLinksFound.tsx | 38 ++++++ components/Sidebar.tsx | 110 +++++++++++------- pages/collections/[id].tsx | 19 +-- pages/dashboard.tsx | 2 +- pages/links.tsx | 15 ++- 6 files changed, 129 insertions(+), 57 deletions(-) create mode 100644 components/NoLinksFound.tsx diff --git a/components/InputSelect/CollectionSelection.tsx b/components/InputSelect/CollectionSelection.tsx index d7307a0..f140bbc 100644 --- a/components/InputSelect/CollectionSelection.tsx +++ b/components/InputSelect/CollectionSelection.tsx @@ -45,7 +45,7 @@ export default function CollectionSelection({ onChange, defaultValue }: Props) { return ( { setMember({ ...member, @@ -174,7 +174,7 @@ export default function TeamManagement({ e.key === "Enter" && addMemberToCollection( session.data?.user.username as string, - member.user.username, + member.user.username || "", collection, setMemberState ) @@ -188,7 +188,7 @@ export default function TeamManagement({ onClick={() => addMemberToCollection( session.data?.user.username as string, - member.user.username, + member.user.username || "", collection, setMemberState ) diff --git a/lib/client/addMemberToCollection.ts b/lib/client/addMemberToCollection.ts index f1ec14f..3e705ec 100644 --- a/lib/client/addMemberToCollection.ts +++ b/lib/client/addMemberToCollection.ts @@ -9,7 +9,7 @@ const addMemberToCollection = async ( setMember: (newMember: Member) => null | undefined ) => { const checkIfMemberAlreadyExists = collection.members.find((e) => { - const username = e.user.username.toLowerCase(); + const username = (e.user.username || "").toLowerCase(); return username === memberUsername.toLowerCase(); }); From 985687ca8961a421f280e2d40314541aae6ebb54 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 18:30:22 -0400 Subject: [PATCH 16/24] minor bug fixed --- .env.sample | 3 ++- lib/api/paymentCheckout.ts | 4 ++-- types/enviornment.d.ts | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.env.sample b/.env.sample index 3413f7c..2140dd2 100644 --- a/.env.sample +++ b/.env.sample @@ -21,4 +21,5 @@ EMAIL_SERVER= STRIPE_SECRET_KEY= PRICE_ID= TRIAL_PERIOD_DAYS= -NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL= \ No newline at end of file +NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL= +BASE_URL=http://localhost:3000 \ No newline at end of file diff --git a/lib/api/paymentCheckout.ts b/lib/api/paymentCheckout.ts index 34f8e86..5610130 100644 --- a/lib/api/paymentCheckout.ts +++ b/lib/api/paymentCheckout.ts @@ -28,8 +28,8 @@ export default async function paymentCheckout( ], mode: "subscription", customer_email: isExistingCostomer ? undefined : email.toLowerCase(), - success_url: "http://localhost:3000?session_id={CHECKOUT_SESSION_ID}", - cancel_url: "http://localhost:3000/login", + success_url: `${process.env.BASE_URL}?session_id={CHECKOUT_SESSION_ID}`, + cancel_url: `${process.env.BASE_URL}/login`, automatic_tax: { enabled: true, }, diff --git a/types/enviornment.d.ts b/types/enviornment.d.ts index 0f32eb7..9655328 100644 --- a/types/enviornment.d.ts +++ b/types/enviornment.d.ts @@ -21,6 +21,7 @@ declare global { PRICE_ID?: string; NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL?: string; TRIAL_PERIOD_DAYS?: string; + BASE_URL?: string; } } } From a45774a47984082ffab75bbd39e7666c68414508 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 19 Jul 2023 18:38:36 -0400 Subject: [PATCH 17/24] minor fix --- lib/api/controllers/users/updateUser.ts | 2 +- pages/api/auth/register.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/controllers/users/updateUser.ts b/lib/api/controllers/users/updateUser.ts index cdf6260..8f4eb0f 100644 --- a/lib/api/controllers/users/updateUser.ts +++ b/lib/api/controllers/users/updateUser.ts @@ -22,7 +22,7 @@ export default async function updateUser( const checkUsername = RegExp("^[a-z0-9_-]{3,31}$"); - if (!checkUsername.test(user.username)) + if (!checkUsername.test(user.username.toLowerCase())) return { response: "Username has to be between 3-30 characters, no spaces and special characters are allowed.", diff --git a/pages/api/auth/register.ts b/pages/api/auth/register.ts index 4abf03e..c7e5136 100644 --- a/pages/api/auth/register.ts +++ b/pages/api/auth/register.ts @@ -33,7 +33,7 @@ export default async function Index( const checkUsername = RegExp("^[a-z0-9_-]{3,31}$"); - if (!emailEnabled && !checkUsername.test(body.username || "")) + if (!emailEnabled && !checkUsername.test(body.username?.toLowerCase() || "")) return res.status(400).json({ response: "Username has to be between 3-30 characters, no spaces and special characters are allowed.", From debfd36eb8492259fcc48d2f8c639d9f7e65244f Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 00:46:16 -0400 Subject: [PATCH 18/24] ui improvements --- .env.sample | 3 +- layouts/AuthRedirect.tsx | 104 ++++++++++++++++---------------- lib/api/checkSubscription.ts | 7 ++- lib/api/paymentCheckout.ts | 7 ++- lib/api/updateCustomerEmail.ts | 7 ++- pages/api/auth/[...nextauth].ts | 7 ++- pages/choose-username.tsx | 31 +++++----- pages/forgot.tsx | 34 +++++------ pages/login.tsx | 32 +++++----- pages/register.tsx | 38 +++++++----- pages/subscribe.tsx | 30 +++++---- types/enviornment.d.ts | 3 +- 12 files changed, 156 insertions(+), 147 deletions(-) diff --git a/.env.sample b/.env.sample index 2140dd2..a1703b8 100644 --- a/.env.sample +++ b/.env.sample @@ -18,8 +18,9 @@ EMAIL_FROM= EMAIL_SERVER= # Stripe settings (You don't need these, it's for the cloud instance payments) +NEXT_PUBLC_STRIPE_IS_ACTIVE= STRIPE_SECRET_KEY= PRICE_ID= -TRIAL_PERIOD_DAYS= +NEXT_PUBLIC_TRIAL_PERIOD_DAYS= NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL= BASE_URL=http://localhost:3000 \ No newline at end of file diff --git a/layouts/AuthRedirect.tsx b/layouts/AuthRedirect.tsx index a5fd1ad..8247139 100644 --- a/layouts/AuthRedirect.tsx +++ b/layouts/AuthRedirect.tsx @@ -18,57 +18,57 @@ export default function AuthRedirect({ children }: Props) { useInitialData(); - useEffect(() => { - if (!router.pathname.startsWith("/public")) { - if ( - emailEnabled && - status === "authenticated" && - (data.user.isSubscriber === true || - data.user.isSubscriber === undefined) && - !data.user.username - ) { - router.push("/choose-username").then(() => { - setRedirect(false); - }); - } else if ( - status === "authenticated" && - data.user.isSubscriber === false - ) { - router.push("/subscribe").then(() => { - setRedirect(false); - }); - } else if ( - status === "authenticated" && - (router.pathname === "/login" || - router.pathname === "/register" || - router.pathname === "/confirmation" || - router.pathname === "/subscribe" || - router.pathname === "/choose-username" || - router.pathname === "/forgot") - ) { - router.push("/").then(() => { - setRedirect(false); - }); - } else if ( - status === "unauthenticated" && - !( - router.pathname === "/login" || - router.pathname === "/register" || - router.pathname === "/confirmation" || - router.pathname === "/forgot" - ) - ) { - router.push("/login").then(() => { - setRedirect(false); - }); - } else if (status === "loading") setRedirect(true); - else setRedirect(false); - } else { - setRedirect(false); - } - }, [status]); + // useEffect(() => { + // if (!router.pathname.startsWith("/public")) { + // if ( + // emailEnabled && + // status === "authenticated" && + // (data.user.isSubscriber === true || + // data.user.isSubscriber === undefined) && + // !data.user.username + // ) { + // router.push("/choose-username").then(() => { + // setRedirect(false); + // }); + // } else if ( + // status === "authenticated" && + // data.user.isSubscriber === false + // ) { + // router.push("/subscribe").then(() => { + // setRedirect(false); + // }); + // } else if ( + // status === "authenticated" && + // (router.pathname === "/login" || + // router.pathname === "/register" || + // router.pathname === "/confirmation" || + // router.pathname === "/subscribe" || + // router.pathname === "/choose-username" || + // router.pathname === "/forgot") + // ) { + // router.push("/").then(() => { + // setRedirect(false); + // }); + // } else if ( + // status === "unauthenticated" && + // !( + // router.pathname === "/login" || + // router.pathname === "/register" || + // router.pathname === "/confirmation" || + // router.pathname === "/forgot" + // ) + // ) { + // router.push("/login").then(() => { + // setRedirect(false); + // }); + // } else if (status === "loading") setRedirect(true); + // else setRedirect(false); + // } else { + // setRedirect(false); + // } + // }, [status]); - if (status !== "loading" && !redirect) return <>{children}; - else return <>; - // return <>{children}; + // if (status !== "loading" && !redirect) return <>{children}; + // else return <>; + return <>{children}; } diff --git a/lib/api/checkSubscription.ts b/lib/api/checkSubscription.ts index 67f001c..6537c22 100644 --- a/lib/api/checkSubscription.ts +++ b/lib/api/checkSubscription.ts @@ -19,9 +19,10 @@ export default async function checkSubscription( const isSubscriber = listByEmail.data.some((customer, i) => { const hasValidSubscription = customer.subscriptions?.data.some( (subscription) => { - const TRIAL_PERIOD_DAYS = process.env.TRIAL_PERIOD_DAYS; - const secondsInTwoWeeks = TRIAL_PERIOD_DAYS - ? Number(TRIAL_PERIOD_DAYS) * 86400 + const NEXT_PUBLIC_TRIAL_PERIOD_DAYS = + process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS; + const secondsInTwoWeeks = NEXT_PUBLIC_TRIAL_PERIOD_DAYS + ? Number(NEXT_PUBLIC_TRIAL_PERIOD_DAYS) * 86400 : 1209600; subscriptionCanceledAt = subscription.canceled_at; diff --git a/lib/api/paymentCheckout.ts b/lib/api/paymentCheckout.ts index 5610130..06dd7e3 100644 --- a/lib/api/paymentCheckout.ts +++ b/lib/api/paymentCheckout.ts @@ -17,7 +17,8 @@ export default async function paymentCheckout( const isExistingCostomer = listByEmail?.data[0]?.id || undefined; - const TRIAL_PERIOD_DAYS = process.env.TRIAL_PERIOD_DAYS; + const NEXT_PUBLIC_TRIAL_PERIOD_DAYS = + process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS; const session = await stripe.checkout.sessions.create({ customer: isExistingCostomer ? isExistingCostomer : undefined, line_items: [ @@ -34,7 +35,9 @@ export default async function paymentCheckout( enabled: true, }, subscription_data: { - trial_period_days: TRIAL_PERIOD_DAYS ? Number(TRIAL_PERIOD_DAYS) : 14, + trial_period_days: NEXT_PUBLIC_TRIAL_PERIOD_DAYS + ? Number(NEXT_PUBLIC_TRIAL_PERIOD_DAYS) + : 14, }, }); diff --git a/lib/api/updateCustomerEmail.ts b/lib/api/updateCustomerEmail.ts index 07af401..95ebc60 100644 --- a/lib/api/updateCustomerEmail.ts +++ b/lib/api/updateCustomerEmail.ts @@ -18,9 +18,10 @@ export default async function updateCustomerEmail( const customer = listByEmail.data.find((customer, i) => { const hasValidSubscription = customer.subscriptions?.data.some( (subscription) => { - const TRIAL_PERIOD_DAYS = process.env.TRIAL_PERIOD_DAYS; - const secondsInTwoWeeks = TRIAL_PERIOD_DAYS - ? Number(TRIAL_PERIOD_DAYS) * 86400 + const NEXT_PUBLIC_TRIAL_PERIOD_DAYS = + process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS; + const secondsInTwoWeeks = NEXT_PUBLIC_TRIAL_PERIOD_DAYS + ? Number(NEXT_PUBLIC_TRIAL_PERIOD_DAYS) * 86400 : 1209600; const isNotCanceledOrHasTime = !( diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index e760f2e..bdf85c5 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -93,9 +93,10 @@ export const authOptions: AuthOptions = { const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY; const PRICE_ID = process.env.PRICE_ID; - const TRIAL_PERIOD_DAYS = process.env.TRIAL_PERIOD_DAYS; - const secondsInTwoWeeks = TRIAL_PERIOD_DAYS - ? Number(TRIAL_PERIOD_DAYS) * 86400 + const NEXT_PUBLIC_TRIAL_PERIOD_DAYS = + process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS; + const secondsInTwoWeeks = NEXT_PUBLIC_TRIAL_PERIOD_DAYS + ? Number(NEXT_PUBLIC_TRIAL_PERIOD_DAYS) * 86400 : 1209600; const subscriptionIsTimesUp = token.subscriptionCanceledAt && diff --git a/pages/choose-username.tsx b/pages/choose-username.tsx index a3fcfb1..7f49afd 100644 --- a/pages/choose-username.tsx +++ b/pages/choose-username.tsx @@ -42,23 +42,17 @@ export default function Subscribe() { return ( <> + Linkwarden

-
- Linkwarden - -
-

One Last Step...

-

- Please choose a username to start using your account. -

-
-
+

+ Choose a Username (Last step) +

@@ -85,7 +79,7 @@ export default function Subscribe() { @@ -97,6 +91,9 @@ export default function Subscribe() { Sign Out

+

+ © {new Date().getFullYear()} Linkwarden. All rights reserved.{" "} +

); } diff --git a/pages/forgot.tsx b/pages/forgot.tsx index 2b1f23d..8770e56 100644 --- a/pages/forgot.tsx +++ b/pages/forgot.tsx @@ -39,20 +39,21 @@ export default function Forgot() { return ( <> + Linkwarden
-
- Linkwarden -
-

Password Reset

-
-
- +

Fogot Password?

+

+ Enter your Email so we can send you a link to recover your account. +

+

+ Make sure to change your password in the profile settings afterwards. +

Email

@@ -63,10 +64,6 @@ export default function Forgot() { onChange={(e) => setForm({ ...form, email: e.target.value })} className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" /> -

- Make sure to change your password in the profile settings - afterwards. -

+

+ © {new Date().getFullYear()} Linkwarden. All rights reserved.{" "} +

); } diff --git a/pages/login.tsx b/pages/login.tsx index f17798c..afb64f1 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -46,23 +46,20 @@ export default function Login() { return ( <> + Linkwarden +

+ Sign in to your account +

-
- Linkwarden -
-

Welcome back

-

- Sign in to your account -

-
-
- +

+ Enter your credentials +

Username @@ -112,6 +109,9 @@ export default function Login() {

+

+ © {new Date().getFullYear()} Linkwarden. All rights reserved.{" "} +

); } diff --git a/pages/register.tsx b/pages/register.tsx index c047e17..877651a 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -90,23 +90,26 @@ export default function Register() { return ( <> + Linkwarden +
+

+ {process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE + ? `Start using our premium services with a ${ + process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14 + }-day free trial!` + : "Create a new account"} +

+
-
- Linkwarden -
-

Get started

-

- Create a new account -

-
-
- +

+ Enter your details +

Display Name @@ -197,6 +200,9 @@ export default function Register() {

+

+ © {new Date().getFullYear()} Linkwarden. All rights reserved.{" "} +

); } diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index c1b427e..32582fe 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -26,23 +26,18 @@ export default function Subscribe() { return ( <> + Linkwarden +

+ {process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14} days free trial, then + $5/month afterwards +

-
- Linkwarden -
-

14 days free trial

-

- Then $5/month afterwards -

-
-
-

You will be redirected to Stripe. @@ -70,6 +65,9 @@ export default function Subscribe() { Sign Out

+

+ © {new Date().getFullYear()} Linkwarden. All rights reserved.{" "} +

); } diff --git a/types/enviornment.d.ts b/types/enviornment.d.ts index 9655328..5bf5055 100644 --- a/types/enviornment.d.ts +++ b/types/enviornment.d.ts @@ -17,10 +17,11 @@ declare global { EMAIL_FROM?: string; EMAIL_SERVER?: string; + NEXT_PUBLC_STRIPE_IS_ACTIVE?: boolean; STRIPE_SECRET_KEY?: string; PRICE_ID?: string; NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL?: string; - TRIAL_PERIOD_DAYS?: string; + NEXT_PUBLIC_TRIAL_PERIOD_DAYS?: string; BASE_URL?: string; } } From 1bd3001b9581341e86fb009637b7d5a7e07d6fe0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 00:46:49 -0400 Subject: [PATCH 19/24] small fix --- layouts/AuthRedirect.tsx | 104 +++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/layouts/AuthRedirect.tsx b/layouts/AuthRedirect.tsx index 8247139..a5fd1ad 100644 --- a/layouts/AuthRedirect.tsx +++ b/layouts/AuthRedirect.tsx @@ -18,57 +18,57 @@ export default function AuthRedirect({ children }: Props) { useInitialData(); - // useEffect(() => { - // if (!router.pathname.startsWith("/public")) { - // if ( - // emailEnabled && - // status === "authenticated" && - // (data.user.isSubscriber === true || - // data.user.isSubscriber === undefined) && - // !data.user.username - // ) { - // router.push("/choose-username").then(() => { - // setRedirect(false); - // }); - // } else if ( - // status === "authenticated" && - // data.user.isSubscriber === false - // ) { - // router.push("/subscribe").then(() => { - // setRedirect(false); - // }); - // } else if ( - // status === "authenticated" && - // (router.pathname === "/login" || - // router.pathname === "/register" || - // router.pathname === "/confirmation" || - // router.pathname === "/subscribe" || - // router.pathname === "/choose-username" || - // router.pathname === "/forgot") - // ) { - // router.push("/").then(() => { - // setRedirect(false); - // }); - // } else if ( - // status === "unauthenticated" && - // !( - // router.pathname === "/login" || - // router.pathname === "/register" || - // router.pathname === "/confirmation" || - // router.pathname === "/forgot" - // ) - // ) { - // router.push("/login").then(() => { - // setRedirect(false); - // }); - // } else if (status === "loading") setRedirect(true); - // else setRedirect(false); - // } else { - // setRedirect(false); - // } - // }, [status]); + useEffect(() => { + if (!router.pathname.startsWith("/public")) { + if ( + emailEnabled && + status === "authenticated" && + (data.user.isSubscriber === true || + data.user.isSubscriber === undefined) && + !data.user.username + ) { + router.push("/choose-username").then(() => { + setRedirect(false); + }); + } else if ( + status === "authenticated" && + data.user.isSubscriber === false + ) { + router.push("/subscribe").then(() => { + setRedirect(false); + }); + } else if ( + status === "authenticated" && + (router.pathname === "/login" || + router.pathname === "/register" || + router.pathname === "/confirmation" || + router.pathname === "/subscribe" || + router.pathname === "/choose-username" || + router.pathname === "/forgot") + ) { + router.push("/").then(() => { + setRedirect(false); + }); + } else if ( + status === "unauthenticated" && + !( + router.pathname === "/login" || + router.pathname === "/register" || + router.pathname === "/confirmation" || + router.pathname === "/forgot" + ) + ) { + router.push("/login").then(() => { + setRedirect(false); + }); + } else if (status === "loading") setRedirect(true); + else setRedirect(false); + } else { + setRedirect(false); + } + }, [status]); - // if (status !== "loading" && !redirect) return <>{children}; - // else return <>; - return <>{children}; + if (status !== "loading" && !redirect) return <>{children}; + else return <>; + // return <>{children}; } From cf59d48bbedacfa2a2e7445a3a085e7343d5f580 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 00:50:15 -0400 Subject: [PATCH 20/24] small improvement. --- pages/login.tsx | 2 +- pages/register.tsx | 16 +++++++--------- pages/subscribe.tsx | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/pages/login.tsx b/pages/login.tsx index afb64f1..3de38d8 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -53,7 +53,7 @@ export default function Login() { alt="Linkwarden" className="h-12 w-fit mx-auto mt-10" /> -

+

Sign in to your account

diff --git a/pages/register.tsx b/pages/register.tsx index 877651a..c1d3b9e 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -97,15 +97,13 @@ export default function Register() { alt="Linkwarden" className="h-12 w-fit mx-auto mt-10" /> -
-

- {process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE - ? `Start using our premium services with a ${ - process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14 - }-day free trial!` - : "Create a new account"} -

-
+

+ {process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE + ? `Start using our premium services with a ${ + process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14 + }-day free trial!` + : "Create a new account"} +

Enter your details diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index 32582fe..dc63b8e 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -33,7 +33,7 @@ export default function Subscribe() { alt="Linkwarden" className="h-12 w-fit mx-auto mt-10" /> -

+

{process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14} days free trial, then $5/month afterwards

From 42719e5c6bc25b0cd7647a5ad8c22703cffac6ae Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 00:55:22 -0400 Subject: [PATCH 21/24] minor design improvement --- pages/choose-username.tsx | 2 +- pages/forgot.tsx | 2 +- pages/login.tsx | 2 +- pages/register.tsx | 2 +- pages/subscribe.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pages/choose-username.tsx b/pages/choose-username.tsx index 7f49afd..6198916 100644 --- a/pages/choose-username.tsx +++ b/pages/choose-username.tsx @@ -49,7 +49,7 @@ export default function Subscribe() { alt="Linkwarden" className="h-12 w-fit mx-auto mt-10" /> -
+

Choose a Username (Last step)

diff --git a/pages/forgot.tsx b/pages/forgot.tsx index 8770e56..c2c5764 100644 --- a/pages/forgot.tsx +++ b/pages/forgot.tsx @@ -46,7 +46,7 @@ export default function Forgot() { alt="Linkwarden" className="h-12 w-fit mx-auto mt-10" /> -
+

Fogot Password?

Enter your Email so we can send you a link to recover your account. diff --git a/pages/login.tsx b/pages/login.tsx index 3de38d8..6bdfd46 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -56,7 +56,7 @@ export default function Login() {

Sign in to your account

-
+

Enter your credentials

diff --git a/pages/register.tsx b/pages/register.tsx index c1d3b9e..355fe84 100644 --- a/pages/register.tsx +++ b/pages/register.tsx @@ -104,7 +104,7 @@ export default function Register() { }-day free trial!` : "Create a new account"}

-
+

Enter your details

diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index dc63b8e..8f920bd 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -37,7 +37,7 @@ export default function Subscribe() { {process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14} days free trial, then $5/month afterwards

-
+

You will be redirected to Stripe. From 3ba148caa98759a76bdb3788266ba3c008d425ed Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 09:46:17 -0400 Subject: [PATCH 22/24] small changes --- .env.sample | 3 ++- pages/subscribe.tsx | 2 +- types/enviornment.d.ts | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.env.sample b/.env.sample index a1703b8..91dbdb2 100644 --- a/.env.sample +++ b/.env.sample @@ -23,4 +23,5 @@ STRIPE_SECRET_KEY= PRICE_ID= NEXT_PUBLIC_TRIAL_PERIOD_DAYS= NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL= -BASE_URL=http://localhost:3000 \ No newline at end of file +BASE_URL=http://localhost:3000 +NEXT_PUBLIC_PRICING= \ No newline at end of file diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index 8f920bd..1c9dd20 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -35,7 +35,7 @@ export default function Subscribe() { />

{process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14} days free trial, then - $5/month afterwards + ${process.env.NEXT_PUBLIC_PRICING}/month afterwards

diff --git a/types/enviornment.d.ts b/types/enviornment.d.ts index 5bf5055..168c9fa 100644 --- a/types/enviornment.d.ts +++ b/types/enviornment.d.ts @@ -17,12 +17,13 @@ declare global { EMAIL_FROM?: string; EMAIL_SERVER?: string; - NEXT_PUBLC_STRIPE_IS_ACTIVE?: boolean; + NEXT_PUBLC_STRIPE_IS_ACTIVE?: string; STRIPE_SECRET_KEY?: string; PRICE_ID?: string; NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL?: string; NEXT_PUBLIC_TRIAL_PERIOD_DAYS?: string; BASE_URL?: string; + NEXT_PUBLIC_PRICING?: string; } } } From f5b71524ef88be2d169ce7cf4b9b6f48c1169915 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 11:16:58 -0400 Subject: [PATCH 23/24] fixed typo --- .env.sample | 2 +- types/enviornment.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.sample b/.env.sample index 91dbdb2..8e0d4a5 100644 --- a/.env.sample +++ b/.env.sample @@ -18,7 +18,7 @@ EMAIL_FROM= EMAIL_SERVER= # Stripe settings (You don't need these, it's for the cloud instance payments) -NEXT_PUBLC_STRIPE_IS_ACTIVE= +NEXT_PUBLIC_STRIPE_IS_ACTIVE= STRIPE_SECRET_KEY= PRICE_ID= NEXT_PUBLIC_TRIAL_PERIOD_DAYS= diff --git a/types/enviornment.d.ts b/types/enviornment.d.ts index 168c9fa..a093c11 100644 --- a/types/enviornment.d.ts +++ b/types/enviornment.d.ts @@ -17,7 +17,7 @@ declare global { EMAIL_FROM?: string; EMAIL_SERVER?: string; - NEXT_PUBLC_STRIPE_IS_ACTIVE?: string; + NEXT_PUBLIC_STRIPE_IS_ACTIVE?: string; STRIPE_SECRET_KEY?: string; PRICE_ID?: string; NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL?: string; From fb721fb67a214fc6d8920f88a32842e557c3207b Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 20 Jul 2023 18:23:57 -0400 Subject: [PATCH 24/24] changed the contact emails --- .github/SECURITY.md | 4 ++-- components/Modal/User/BillingPortal.tsx | 4 ++-- pages/api/archives/[...params].ts | 2 +- pages/api/avatar/[id].ts | 2 +- pages/api/routes/collections/index.ts | 2 +- pages/api/routes/links/index.ts | 2 +- pages/api/routes/tags/index.ts | 2 +- pages/api/routes/users/index.ts | 2 +- pages/choose-username.tsx | 4 ++-- pages/subscribe.tsx | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/SECURITY.md b/.github/SECURITY.md index cfe046c..4e1c81f 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -12,6 +12,6 @@ First off, we really appreciate the time you spent! If you found a vulnerability, these are the ways you can reach us: -Email: [hello@linkwarden.app](mailto:hello@daniel31x13.io) +Email: [security@linkwarden.app](mailto:security@linkwarden.app) -Or you can directly reach me via Twitter: [@daniel31x13](https://twitter.com/Daniel31X13). +Or you can directly DM me via Twitter: [@daniel31x13](https://twitter.com/Daniel31X13). diff --git a/components/Modal/User/BillingPortal.tsx b/components/Modal/User/BillingPortal.tsx index 2edc516..afb7950 100644 --- a/components/Modal/User/BillingPortal.tsx +++ b/components/Modal/User/BillingPortal.tsx @@ -33,8 +33,8 @@ export default function PaymentPortal() {

If you still need help or encountered any issues, feel free to reach out to us at:{" "} - - hello@linkwarden.app + + support@linkwarden.app

diff --git a/pages/api/archives/[...params].ts b/pages/api/archives/[...params].ts index bfbc4a5..757f635 100644 --- a/pages/api/archives/[...params].ts +++ b/pages/api/archives/[...params].ts @@ -18,7 +18,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { else if (session?.user?.isSubscriber === false) res.status(401).json({ response: - "You are not a subscriber, feel free to reach out to us at hello@linkwarden.app in case of any issues.", + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); const collectionIsAccessible = await getPermission( diff --git a/pages/api/avatar/[id].ts b/pages/api/avatar/[id].ts index d447866..73b155b 100644 --- a/pages/api/avatar/[id].ts +++ b/pages/api/avatar/[id].ts @@ -19,7 +19,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { else if (session?.user?.isSubscriber === false) res.status(401).json({ response: - "You are not a subscriber, feel free to reach out to us at hello@linkwarden.app in case of any issues.", + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); if (!queryId) diff --git a/pages/api/routes/collections/index.ts b/pages/api/routes/collections/index.ts index 321dcd4..2132add 100644 --- a/pages/api/routes/collections/index.ts +++ b/pages/api/routes/collections/index.ts @@ -17,7 +17,7 @@ export default async function collections( } else if (session?.user?.isSubscriber === false) res.status(401).json({ response: - "You are not a subscriber, feel free to reach out to us at hello@linkwarden.app in case of any issues.", + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); if (req.method === "GET") { diff --git a/pages/api/routes/links/index.ts b/pages/api/routes/links/index.ts index 76ca629..eb5be9d 100644 --- a/pages/api/routes/links/index.ts +++ b/pages/api/routes/links/index.ts @@ -14,7 +14,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) { } else if (session?.user?.isSubscriber === false) res.status(401).json({ response: - "You are not a subscriber, feel free to reach out to us at hello@linkwarden.app in case of any issues.", + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); if (req.method === "GET") { diff --git a/pages/api/routes/tags/index.ts b/pages/api/routes/tags/index.ts index 0df83a8..5841ace 100644 --- a/pages/api/routes/tags/index.ts +++ b/pages/api/routes/tags/index.ts @@ -11,7 +11,7 @@ export default async function tags(req: NextApiRequest, res: NextApiResponse) { } else if (session?.user?.isSubscriber === false) res.status(401).json({ response: - "You are not a subscriber, feel free to reach out to us at hello@linkwarden.app in case of any issues.", + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); if (req.method === "GET") { diff --git a/pages/api/routes/users/index.ts b/pages/api/routes/users/index.ts index 7446150..cd310bf 100644 --- a/pages/api/routes/users/index.ts +++ b/pages/api/routes/users/index.ts @@ -12,7 +12,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { } else if (session?.user?.isSubscriber === false) res.status(401).json({ response: - "You are not a subscriber, feel free to reach out to us at hello@linkwarden.app in case of any issues.", + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); const lookupUsername = (req.query.username as string) || undefined; diff --git a/pages/choose-username.tsx b/pages/choose-username.tsx index 6198916..8a5bcaf 100644 --- a/pages/choose-username.tsx +++ b/pages/choose-username.tsx @@ -70,8 +70,8 @@ export default function Subscribe() {

Feel free to reach out to us at{" "} - - hello@linkwarden.app + + support@linkwarden.app {" "} in case of any issues.

diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx index 1c9dd20..0dbbba7 100644 --- a/pages/subscribe.tsx +++ b/pages/subscribe.tsx @@ -44,8 +44,8 @@ export default function Subscribe() {

Feel free to reach out to us at{" "} - - hello@linkwarden.app + + support@linkwarden.app {" "} in case of any issues.