diff --git a/package.json b/package.json index 74a4a342..f14362b6 100644 --- a/package.json +++ b/package.json @@ -34,17 +34,24 @@ "@emotion/styled": "11.11.0", "@prisma/client": "5.5.2", "@willbooster/shared-lib-react": "3.0.0", + "cookie": "0.6.0", "framer-motion": "10.16.4", "next": "14.0.1", + "nextjs-cors": "2.2.0", "pino": "8.16.0", "pino-pretty": "10.2.3", "pm2": "5.3.0", "react": "18.2.0", "react-dom": "18.2.0", + "react-icons": "4.12.0", + "supertokens-auth-react": "0.36.1", + "supertokens-node": "16.6.8", + "supertokens-web-js": "0.8.0", "zod": "3.22.4" }, "devDependencies": { "@chakra-ui/cli": "2.4.1", + "@types/cookie": "^0", "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", "@types/node": "20.8.10", diff --git a/src/app/(home)/layout.tsx b/src/app/(home)/layout.tsx new file mode 100644 index 00000000..aaddf265 --- /dev/null +++ b/src/app/(home)/layout.tsx @@ -0,0 +1,26 @@ +'use client'; + +import { Container, Spinner } from '@chakra-ui/react'; +import React, { Suspense } from 'react'; + +import { DefaultFooter } from '../../components/organisms/DefaultFooter'; +import { DefaultHeader } from '../../components/organisms/DefaultHeader'; +import type { LayoutComponent } from '../../types'; + +const DefaultLayout: LayoutComponent = ({ children }) => { + return ( + <> + + + }> + + {children} + + + + + > + ); +}; + +export default DefaultLayout; diff --git a/src/app/page.tsx b/src/app/(home)/page.tsx similarity index 85% rename from src/app/page.tsx rename to src/app/(home)/page.tsx index eaa75f0e..2e911352 100644 --- a/src/app/page.tsx +++ b/src/app/(home)/page.tsx @@ -2,7 +2,7 @@ import { Button, Heading, Text, VStack } from '@chakra-ui/react'; import type { NextPage } from 'next'; import NextLink from 'next/link'; -import { prisma } from '../infrastructures/prisma'; +import { prisma } from '../../infrastructures/prisma'; const HomePage: NextPage = async () => { const users = await prisma.user.findMany(); @@ -13,7 +13,7 @@ const HomePage: NextPage = async () => { トレーシング力を鍛えよう - + 今すぐはじめる diff --git a/src/app/api/auth/[[...path]]/route.ts b/src/app/api/auth/[[...path]]/route.ts new file mode 100644 index 00000000..24f0dbbb --- /dev/null +++ b/src/app/api/auth/[[...path]]/route.ts @@ -0,0 +1,38 @@ +import type { NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; +import { getAppDirRequestHandler } from 'supertokens-node/nextjs'; + +import { ensureSuperTokensInit } from '../../../../infrastructures/supertokens/backendConfig'; + +ensureSuperTokensInit(); + +const handleCall = getAppDirRequestHandler(NextResponse); + +export async function GET(request: NextRequest): Promise { + const res = await handleCall(request); + if (!res.headers.has('Cache-Control')) { + // This is needed for production deployments with Vercel + res.headers.set('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate'); + } + return res; +} + +export async function POST(request: NextRequest): Promise { + return handleCall(request); +} + +export async function DELETE(request: NextRequest): Promise { + return handleCall(request); +} + +export async function PUT(request: NextRequest): Promise { + return handleCall(request); +} + +export async function PATCH(request: NextRequest): Promise { + return handleCall(request); +} + +export async function HEAD(request: NextRequest): Promise { + return handleCall(request); +} diff --git a/src/app/auth/[[...path]]/page.tsx b/src/app/auth/[[...path]]/page.tsx new file mode 100644 index 00000000..3604ce6b --- /dev/null +++ b/src/app/auth/[[...path]]/page.tsx @@ -0,0 +1,26 @@ +'use client'; + +import type { NextPage } from 'next'; +import { useEffect, useState } from 'react'; +import { redirectToAuth } from 'supertokens-auth-react'; +import { EmailPasswordPreBuiltUI } from 'supertokens-auth-react/recipe/emailpassword/prebuiltui'; +import SuperTokens from 'supertokens-auth-react/ui'; + +const AuthPage: NextPage = () => { + // if the user visits a page that is not handled by us (like /auth/random), then we redirect them back to the auth page. + const [loaded, setLoaded] = useState(false); + + useEffect(() => { + if (SuperTokens.canHandleRoute([EmailPasswordPreBuiltUI])) { + setLoaded(true); + } else { + void redirectToAuth({ redirectBack: false }); + } + }, []); + + if (loaded) { + return SuperTokens.getRoutingComponent([EmailPasswordPreBuiltUI]); + } +}; + +export default AuthPage; diff --git a/src/app/courses/page.tsx b/src/app/courses/page.tsx new file mode 100644 index 00000000..118e722d --- /dev/null +++ b/src/app/courses/page.tsx @@ -0,0 +1,14 @@ +import type { NextPage } from 'next'; + +import { HomePage } from '../../components/pages/homePage'; + +const CoursePage: NextPage = async () => { + return ( + + Courses + + + ); +}; + +export default CoursePage; diff --git a/src/app/sessionUtils.ts b/src/app/sessionUtils.ts new file mode 100644 index 00000000..9d371205 --- /dev/null +++ b/src/app/sessionUtils.ts @@ -0,0 +1,139 @@ +import { serialize } from 'cookie'; +import { cookies, headers } from 'next/headers'; +import type { NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; +import { PreParsedRequest, CollectingResponse } from 'supertokens-node/framework/custom'; +import type { SessionContainer, VerifySessionOptions } from 'supertokens-node/recipe/session'; +import Session from 'supertokens-node/recipe/session'; +import type { HTTPMethod } from 'supertokens-node/types'; + +import { ensureSuperTokensInit } from '../infrastructures/supertokens/backendConfig'; + +ensureSuperTokensInit(); + +interface SSRSession { + session: SessionContainer | undefined; + hasToken: boolean; + /** + * This allows us to protect our routes based on the current session claims. For example + * this will be true if email verification is required but the user has not verified their + * email. + */ + hasInvalidClaims: boolean; + baseResponse: CollectingResponse; + nextResponse?: NextResponse; +} + +export async function getSSRSession(req?: NextRequest, options?: VerifySessionOptions): Promise { + const query = req === undefined ? {} : Object.fromEntries(new URL(req.url).searchParams.entries()); + const parsedCookies: Record = Object.fromEntries( + (req === undefined ? cookies() : req.cookies).getAll().map((cookie) => [cookie.name, cookie.value]) + ); + + /** + * Pre parsed request is a wrapper exposed by SuperTokens. It is used as a helper to detect if the + * original request contains session tokens. We then use this pre parsed request to call `getSession` + * to check if there is a valid session. + */ + const baseRequest = new PreParsedRequest({ + method: req === undefined ? 'get' : (req.method as HTTPMethod), + url: req === undefined ? '' : req.url, + query, + headers: req === undefined ? headers() : req.headers, + cookies: parsedCookies, + getFormBody: () => req!.formData(), + getJSONBody: () => req!.json(), + }); + + /** + * Collecting response is a wrapper exposed by SuperTokens. In this case we are using an empty + * CollectingResponse when calling `getSession`. If the request contains valid session tokens + * the SuperTokens SDK will attach all the relevant tokens to the collecting response object which + * we can then use to return those session tokens in the final result (refer to `withSession` in this file) + */ + const baseResponse = new CollectingResponse(); + + try { + /** + * `getSession` will throw if session is required and there is no valid session. You can use + * `options` to configure whether or not you want to require sessions when calling `getSSRSession` + */ + const session = await Session.getSession(baseRequest, baseResponse, options); + return { + session, + hasInvalidClaims: false, + hasToken: session !== undefined, + baseResponse, + }; + } catch (error) { + if (Session.Error.isErrorFromSuperTokens(error)) { + return { + hasToken: error.type !== Session.Error.UNAUTHORISED, + hasInvalidClaims: error.type === Session.Error.INVALID_CLAIMS, + session: undefined, + baseResponse, + nextResponse: new NextResponse('Authentication required', { + status: error.type === Session.Error.INVALID_CLAIMS ? 403 : 401, + }), + }; + } else { + throw error; + } + } +} + +export async function withSession( + request: NextRequest, + handler: (session: SessionContainer | undefined) => Promise, + options?: VerifySessionOptions +): Promise> { + const { baseResponse, nextResponse, session } = await getSSRSession(request, options); + if (nextResponse) { + return nextResponse; + } + + const userResponse = await handler(session); + + let didAddCookies = false; + let didAddHeaders = false; + + /** + * Base response is the response from SuperTokens that contains all the session tokens. + * We add all cookies and headers in the base response to the final response from the + * API to make sure sessions work correctly. + */ + for (const respCookie of baseResponse.cookies) { + didAddCookies = true; + userResponse.headers.append( + 'Set-Cookie', + serialize(respCookie.key, respCookie.value, { + domain: respCookie.domain, + expires: new Date(respCookie.expires), + httpOnly: respCookie.httpOnly, + path: respCookie.path, + sameSite: respCookie.sameSite, + secure: respCookie.secure, + }) + ); + } + + for (const [value, key] of baseResponse.headers) { + didAddHeaders = true; + userResponse.headers.set(key, value); + } + + /** + * For some deployment services (Vercel for example) production builds can return cached results for + * APIs with older header values. In this case if the session tokens have changed (because of refreshing + * for example) the cached result would still contain the older tokens and sessions would stop working. + * + * As a result, if we add cookies or headers from base response we also set the Cache-Control header + * to make sure that the final result is not a cached version. + */ + if ((didAddCookies || didAddHeaders) && !userResponse.headers.has('Cache-Control')) { + // This is needed for production deployments with Vercel + userResponse.headers.set('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate'); + } + + return userResponse; +} diff --git a/src/components/molecules/HomeClientComponent.tsx b/src/components/molecules/HomeClientComponent.tsx new file mode 100644 index 00000000..a0244ce0 --- /dev/null +++ b/src/components/molecules/HomeClientComponent.tsx @@ -0,0 +1,27 @@ +'use client'; + +import React from 'react'; +import { useSessionContext } from 'supertokens-auth-react/recipe/session'; + +export const HomeClientComponent: React.FC = () => { + const session = useSessionContext(); + + if (session.loading) { + return Loading...; + } + + if (session.doesSessionExist === false) { + return Session does not exist; + } + + return ( + + + + Client side component got userId: {session.userId} + + + + + ); +}; diff --git a/src/components/molecules/SessionAuthForNext.tsx b/src/components/molecules/SessionAuthForNext.tsx new file mode 100644 index 00000000..283402dd --- /dev/null +++ b/src/components/molecules/SessionAuthForNext.tsx @@ -0,0 +1,19 @@ +'use client'; + +import React, { useEffect, useState } from 'react'; +import { SessionAuth } from 'supertokens-auth-react/recipe/session'; + +type Props = Parameters[0] & { + children?: React.ReactNode | undefined; +}; + +export const SessionAuthForNext: React.FC = (props: Props) => { + const [loaded, setLoaded] = useState(false); + useEffect(() => { + setLoaded(true); + }, []); + if (!loaded) { + return props.children; + } + return {props.children}; +}; diff --git a/src/components/molecules/TryRefreshComponent.tsx b/src/components/molecules/TryRefreshComponent.tsx new file mode 100644 index 00000000..98096c10 --- /dev/null +++ b/src/components/molecules/TryRefreshComponent.tsx @@ -0,0 +1,43 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import React, { useEffect, useState } from 'react'; +import SuperTokens from 'supertokens-auth-react'; +import Session from 'supertokens-auth-react/recipe/session'; + +export const TryRefreshComponent: React.FC = () => { + const router = useRouter(); + const [didError, setDidError] = useState(false); + + useEffect(() => { + /** + * `attemptRefreshingSession` will call the refresh token endpoint to try and + * refresh the session. This will throw an error if the session cannot be refreshed. + */ + void Session.attemptRefreshingSession() + .then((hasSession) => { + /** + * If the user has a valid session, we reload the page to restart the flow + * with valid session tokens + */ + if (hasSession) { + router.refresh(); + } else { + SuperTokens.redirectToAuth(); + } + }) + .catch(() => { + setDidError(true); + }); + }, [router]); + + /** + * We add this check to make sure we handle the case where the refresh API fails with + * an unexpected error + */ + if (didError) { + return Something went wrong, please reload the page; + } + + return Loading...; +}; diff --git a/src/components/organisms/DefaultFooter.tsx b/src/components/organisms/DefaultFooter.tsx new file mode 100644 index 00000000..ec0cc833 --- /dev/null +++ b/src/components/organisms/DefaultFooter.tsx @@ -0,0 +1,14 @@ +import type { BoxProps } from '@chakra-ui/react'; +import { Box, HStack } from '@chakra-ui/react'; + +import { APP_AUTHOR } from '../../constants'; + +export const DefaultFooter: React.FC = (props) => { + return ( + + + © {APP_AUTHOR} + + + ); +}; diff --git a/src/components/organisms/DefaultHeader.tsx b/src/components/organisms/DefaultHeader.tsx new file mode 100644 index 00000000..9ea9a786 --- /dev/null +++ b/src/components/organisms/DefaultHeader.tsx @@ -0,0 +1,83 @@ +'use client'; + +import type { BoxProps } from '@chakra-ui/react'; +import { + Box, + Button, + Heading, + HStack, + Icon, + Menu, + MenuButton, + MenuDivider, + MenuItem, + MenuList, +} from '@chakra-ui/react'; +import NextLink from 'next/link'; +import { useRouter } from 'next/navigation'; +import React from 'react'; +import { FaChevronDown, FaSignOutAlt, FaUser, FaCog } from 'react-icons/fa'; +import { signOut, useSessionContext } from 'supertokens-auth-react/recipe/session'; + +import { APP_NAME } from '../../constants'; + +const MENU_ITEMS: readonly [string, string][] = [ + ['/courses', '科目一覧'], + ['/submissions', '提出一覧'], +]; + +export const DefaultHeader: React.FC = (props) => { + const session = useSessionContext(); + + const router = useRouter(); + + return ( + + + + {APP_NAME} + + + {MENU_ITEMS.map(([href, label]) => ( + + {label} + + ))} + + + + {!session.loading && session.doesSessionExist ? ( + + } + rightIcon={} + variant="ghost" + > + {`User ${session.userId.slice(0, 4)}...${session.userId.slice(-4)}`} + + + }> + 設定 + + + } + onClick={async () => { + await signOut(); + router.push('/'); + }} + > + サインアウト + + + + ) : ( + + サインイン + + )} + + + ); +}; diff --git a/src/components/organisms/Providers.tsx b/src/components/organisms/Providers.tsx index fba80e0a..f7edb155 100644 --- a/src/components/organisms/Providers.tsx +++ b/src/components/organisms/Providers.tsx @@ -2,16 +2,24 @@ import { CacheProvider } from '@chakra-ui/next-js'; import { ChakraProvider } from '@chakra-ui/react'; +import { usePathname, useRouter } from 'next/navigation'; +import React from 'react'; +import { SuperTokensWrapper } from 'supertokens-auth-react'; +import { ensureSuperTokensReactInit, setRouter } from '../../infrastructures/supertokens/frontend'; import { theme } from '../../theme'; +ensureSuperTokensReactInit(); + export const Providers: React.FC<{ children: React.ReactNode }> = ({ children }) => { + setRouter(useRouter(), usePathname() || window.location.pathname); + return ( - <> + {/* Chakra UI */} {children} - > + ); }; diff --git a/src/components/pages/homePage.tsx b/src/components/pages/homePage.tsx new file mode 100644 index 00000000..3c64eafd --- /dev/null +++ b/src/components/pages/homePage.tsx @@ -0,0 +1,52 @@ +import type { NextPage } from 'next'; +import { redirect } from 'next/navigation'; + +import { getSSRSession } from '../../app/sessionUtils'; +import { SessionAuthForNext } from '../molecules/SessionAuthForNext'; +import { TryRefreshComponent } from '../molecules/TryRefreshComponent'; + +export const HomePage: NextPage = async () => { + const { hasInvalidClaims, hasToken, session } = await getSSRSession(); + + // `session` will be undefined if it does not exist or has expired + if (!session) { + if (!hasToken) { + /** + * This means that the user is not logged in. If you want to display some other UI in this + * case, you can do so here. + */ + return redirect('/auth'); + } + + /** + * `hasInvalidClaims` indicates that session claims did not pass validation. For example if email + * verification is required but the user's email has not been verified. + */ + return hasInvalidClaims ? ( + /** + * This will make sure that the user is redirected based on their session claims. For example they + * will be redirected to the email verification screen if needed. + * + * We pass in no children in this case to prevent hydration issues and still be able to redirect the + * user. + */ + + ) : ( + /** + * This means that the session does not exist but we have session tokens for the user. In this case + * the `TryRefreshComponent` will try to refresh the session. + */ + + ); + } + + /** + * SessionAuthForNextJS will handle proper redirection for the user based on the different session states. + * It will redirect to the login page if the session does not exist etc. + */ + return ( + + Your user id is: {session.getUserId()} + + ); +}; diff --git a/src/constants.ts b/src/constants.ts index 8716fda0..04e7a611 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,3 @@ -export const APP_AUTHOR = 'WillBooster Inc.'; -export const APP_DESCRIPTION = 'This is an app'; -export const APP_NAME = '無限ドリルβ'; +export const APP_AUTHOR = 'Kazunori Sakamoto'; +export const APP_DESCRIPTION = 'An educational web app for training trace skills'; +export const APP_NAME = 'トレース道場'; diff --git a/src/infrastructures/supertokens/appInfo.ts b/src/infrastructures/supertokens/appInfo.ts new file mode 100644 index 00000000..eff3b5ba --- /dev/null +++ b/src/infrastructures/supertokens/appInfo.ts @@ -0,0 +1,8 @@ +export const appInfo = { + // learn more about this on https://supertokens.com/docs/thirdpartyemailpassword/appinfo + appName: 'TraceDojo', + apiDomain: 'http://localhost:3000', + websiteDomain: 'http://localhost:3000', + apiBasePath: '/api/auth', + websiteBasePath: '/auth', +}; diff --git a/src/infrastructures/supertokens/backendConfig.ts b/src/infrastructures/supertokens/backendConfig.ts new file mode 100644 index 00000000..111df765 --- /dev/null +++ b/src/infrastructures/supertokens/backendConfig.ts @@ -0,0 +1,29 @@ +import SuperTokens from 'supertokens-node'; +import EmailPasswordNode from 'supertokens-node/recipe/emailpassword'; +import SessionNode from 'supertokens-node/recipe/session'; +import type { TypeInput } from 'supertokens-node/types'; + +import { appInfo } from './appInfo'; + +export const backendConfig = (): TypeInput => { + return { + framework: 'custom', + supertokens: { + // https://try.supertokens.com is for demo purposes. Replace this with the address of your core instance (sign up on supertokens.com), or self host a core. + connectionURI: 'https://try.supertokens.com', + // apiKey: , + }, + appInfo, + recipeList: [EmailPasswordNode.init(), SessionNode.init()], + isInServerlessEnv: true, + }; +}; + +let initialized = false; +// This function is used in your APIs to make sure SuperTokens is initialised +export function ensureSuperTokensInit(): void { + if (!initialized) { + SuperTokens.init(backendConfig()); + initialized = true; + } +} diff --git a/src/infrastructures/supertokens/frontend.ts b/src/infrastructures/supertokens/frontend.ts new file mode 100644 index 00000000..181a8be4 --- /dev/null +++ b/src/infrastructures/supertokens/frontend.ts @@ -0,0 +1,39 @@ +import type { useRouter } from 'next/navigation'; +import SuperTokensReact from 'supertokens-auth-react'; +import type { SuperTokensConfig } from 'supertokens-auth-react/lib/build/types'; +import EmailPasswordReact from 'supertokens-auth-react/recipe/emailpassword'; +import SessionReact from 'supertokens-auth-react/recipe/session'; + +import { appInfo } from './appInfo'; + +const routerInfo: { router?: ReturnType; pathName?: string } = {}; + +export function setRouter(router: ReturnType, pathName: string): void { + routerInfo.router = router; + routerInfo.pathName = pathName; +} + +export const frontendConfig = (): SuperTokensConfig => { + return { + appInfo, + recipeList: [EmailPasswordReact.init(), SessionReact.init()], + windowHandler: (original) => ({ + ...original, + location: { + ...original.location, + getPathName: () => routerInfo.pathName!, + assign: (url) => routerInfo.router!.push(url.toString()), + setHref: (url) => routerInfo.router!.push(url.toString()), + }, + }), + }; +}; + +let isInitialized = false; + +export function ensureSuperTokensReactInit(): void { + if (typeof window === 'undefined') return; + if (isInitialized) return; + SuperTokensReact.init(frontendConfig()); + isInitialized = true; +} diff --git a/yarn.lock b/yarn.lock index e0331188..2b206cb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3748,6 +3748,13 @@ __metadata: languageName: node linkType: hard +"@types/cookie@npm:^0": + version: 0.6.0 + resolution: "@types/cookie@npm:0.6.0" + checksum: 5b326bd0188120fb32c0be086b141b1481fec9941b76ad537f9110e10d61ee2636beac145463319c71e4be67a17e85b81ca9e13ceb6e3bb63b93d16824d6c149 + languageName: node + linkType: hard + "@types/eslint@npm:8.44.6": version: 8.44.6 resolution: "@types/eslint@npm:8.44.6" @@ -4180,6 +4187,15 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:6": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: "npm:4" + checksum: dc4f757e40b5f3e3d674bc9beb4f1048f4ee83af189bae39be99f57bf1f48dde166a8b0a5342a84b5944ee8e6ed1e5a9d801858f4ad44764e84957122fe46261 + languageName: node + linkType: hard + "agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": version: 7.1.0 resolution: "agent-base@npm:7.1.0" @@ -4479,6 +4495,13 @@ __metadata: languageName: node linkType: hard +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + "atomic-sleep@npm:^1.0.0": version: 1.0.0 resolution: "atomic-sleep@npm:1.0.0" @@ -4509,6 +4532,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.6.0": + version: 1.6.3 + resolution: "axios@npm:1.6.3" + dependencies: + follow-redirects: "npm:^1.15.0" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: dcc6d982353db33e6893ef01cdf81d0a0548dbd8fba0cb046dc4aee1a6a16226721faa4c2a13b2673d47130509629cdb93bb991b3a2bd4ef17a5ac27a8bba0da + languageName: node + linkType: hard + "axobject-query@npm:^3.2.1": version: 3.2.1 resolution: "axobject-query@npm:3.2.1" @@ -4656,6 +4690,15 @@ __metadata: languageName: node linkType: hard +"browser-tabs-lock@npm:^1.3.0": + version: 1.3.0 + resolution: "browser-tabs-lock@npm:1.3.0" + dependencies: + lodash: "npm:>=4.17.21" + checksum: b1f9cbd221725cf3228daf42360ea6a97f69b29e0475ef734bc5a6bd5c27b61f99db716c49808988a1c735d828207dcaa3a8802e605d0195538fbf9e25d1753b + languageName: node + linkType: hard + "browserslist-generator@npm:^2.1.0": version: 2.1.0 resolution: "browserslist-generator@npm:2.1.0" @@ -4688,6 +4731,13 @@ __metadata: languageName: node linkType: hard +"buffer-equal-constant-time@npm:1.0.1": + version: 1.0.1 + resolution: "buffer-equal-constant-time@npm:1.0.1" + checksum: fb2294e64d23c573d0dd1f1e7a466c3e978fe94a4e0f8183937912ca374619773bef8e2aceb854129d2efecbbc515bbd0cc78d2734a3e3031edb0888531bbc8e + languageName: node + linkType: hard + "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -5042,6 +5092,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + "commander@npm:11.1.0": version: 11.1.0 resolution: "commander@npm:11.1.0" @@ -5102,6 +5161,13 @@ __metadata: languageName: node linkType: hard +"content-type@npm:^1.0.5": + version: 1.0.5 + resolution: "content-type@npm:1.0.5" + checksum: b76ebed15c000aee4678c3707e0860cb6abd4e680a598c0a26e17f0bfae723ec9cc2802f0ff1bc6e4d80603719010431d2231018373d4dde10f9ccff9dadf5af + languageName: node + linkType: hard + "continuation-local-storage@npm:^3.2.1": version: 3.2.1 resolution: "continuation-local-storage@npm:3.2.1" @@ -5126,6 +5192,20 @@ __metadata: languageName: node linkType: hard +"cookie@npm:0.4.0": + version: 0.4.0 + resolution: "cookie@npm:0.4.0" + checksum: 71508a1c8a4e97bb88f42635542ef24ebe7e713f82573ac61e9b289616334d14bfb28210d7979d9ada24b0254f5fb563af938cac13bc8c0c3f60f47a2257f791 + languageName: node + linkType: hard + +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686 + languageName: node + linkType: hard + "copy-to-clipboard@npm:3.3.3": version: 3.3.3 resolution: "copy-to-clipboard@npm:3.3.3" @@ -5158,6 +5238,16 @@ __metadata: languageName: node linkType: hard +"cors@npm:^2.8.5": + version: 2.8.5 + resolution: "cors@npm:2.8.5" + dependencies: + object-assign: "npm:^4" + vary: "npm:^1" + checksum: 373702b7999409922da80de4a61938aabba6929aea5b6fd9096fefb9e8342f626c0ebd7507b0e8b0b311380744cc985f27edebc0a26e0ddb784b54e1085de761 + languageName: node + linkType: hard + "cosmiconfig@npm:^7.0.0": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" @@ -5185,6 +5275,15 @@ __metadata: languageName: node linkType: hard +"cross-fetch@npm:^3.1.6": + version: 3.1.8 + resolution: "cross-fetch@npm:3.1.8" + dependencies: + node-fetch: "npm:^2.6.12" + checksum: 4c5e022ffe6abdf380faa6e2373c0c4ed7ef75e105c95c972b6f627c3f083170b6886f19fb488a7fa93971f4f69dcc890f122b0d97f0bf5f41ca1d9a8f58c8af + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -5205,6 +5304,13 @@ __metadata: languageName: node linkType: hard +"crypto-js@npm:^4.1.1": + version: 4.2.0 + resolution: "crypto-js@npm:4.2.0" + checksum: 8fbdf9d56f47aea0794ab87b0eb9833baf80b01a7c5c1b0edc7faf25f662fb69ab18dc2199e2afcac54670ff0cd9607a9045a3f7a80336cccd18d77a55b9fdf0 + languageName: node + linkType: hard + "css-box-model@npm:1.2.1": version: 1.2.1 resolution: "css-box-model@npm:1.2.1" @@ -5258,7 +5364,7 @@ __metadata: languageName: node linkType: hard -"dayjs@npm:~1.11.5": +"dayjs@npm:^1.11.9, dayjs@npm:~1.11.5": version: 1.11.10 resolution: "dayjs@npm:1.11.10" checksum: 4de9af50639d47df87f2e15fa36bb07e0f9ed1e9c52c6caa1482788ee9a384d668f1dbd00c54f82aaab163db07d61d2899384b8254da3a9184fc6deca080e2fe @@ -5272,7 +5378,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:~4.3.1": +"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.1": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -5340,6 +5446,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + "dequal@npm:^2.0.3": version: 2.0.3 resolution: "dequal@npm:2.0.3" @@ -5416,6 +5529,15 @@ __metadata: languageName: node linkType: hard +"ecdsa-sig-formatter@npm:1.0.11": + version: 1.0.11 + resolution: "ecdsa-sig-formatter@npm:1.0.11" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: ebfbf19d4b8be938f4dd4a83b8788385da353d63307ede301a9252f9f7f88672e76f2191618fd8edfc2f24679236064176fab0b78131b161ee73daa37125408c + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.4.601": version: 1.4.616 resolution: "electron-to-chromium@npm:1.4.616" @@ -6295,7 +6417,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.14.0": +"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.15.0": version: 1.15.3 resolution: "follow-redirects@npm:1.15.3" peerDependenciesMeta: @@ -6324,6 +6446,17 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + mime-types: "npm:^2.1.12" + checksum: cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e + languageName: node + linkType: hard + "framer-motion@npm:10.16.4": version: 10.16.4 resolution: "framer-motion@npm:10.16.4" @@ -6816,6 +6949,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:^5.0.0": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 6dd639f03434003577c62b27cafdb864784ef19b2de430d8ae2a1d45e31c4fd60719e5637b44db1a88a046934307da7089e03d6089ec3ddacc1189d8de8897d1 + languageName: node + linkType: hard + "https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "https-proxy-agent@npm:7.0.2" @@ -6898,6 +7041,13 @@ __metadata: languageName: node linkType: hard +"inflation@npm:^2.0.0": + version: 2.1.0 + resolution: "inflation@npm:2.1.0" + checksum: aadfcb8047a7e00d644e2e195f901dd9d7266c2be2326b7f8f6a99298f14916f1e322d00108a7e2778d6e76a8dc2174ddb9ac14bcdfe4f4866dfd612b695ab5d + languageName: node + linkType: hard + "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -6933,6 +7083,13 @@ __metadata: languageName: node linkType: hard +"intl-tel-input@npm:^17.0.19": + version: 17.0.21 + resolution: "intl-tel-input@npm:17.0.21" + checksum: 2c6c0331046f69fcf880812ab766266e568c3e8b44d50eb628e5bb305e73c2cf4b39965a3422efc54557f46cf983b5b91e9d6c9965ec9513c6eb8c47a790b8c3 + languageName: node + linkType: hard + "invariant@npm:^2.2.4": version: 2.2.4 resolution: "invariant@npm:2.2.4" @@ -7309,6 +7466,13 @@ __metadata: languageName: node linkType: hard +"jose@npm:^4.13.1": + version: 4.15.4 + resolution: "jose@npm:4.15.4" + checksum: ce8b29f84d6172a566b12b599dafa82f3bef0f16278bb76d562490ac1516fcc14017b05a39d20ffad25ed504f4996d4af4c9d3e0273d95b2d5559bf6d1112bc0 + languageName: node + linkType: hard + "joycon@npm:^3.1.1": version: 3.1.1 resolution: "joycon@npm:3.1.1" @@ -7440,6 +7604,24 @@ __metadata: languageName: node linkType: hard +"jsonwebtoken@npm:^9.0.0": + version: 9.0.2 + resolution: "jsonwebtoken@npm:9.0.2" + dependencies: + jws: "npm:^3.2.2" + lodash.includes: "npm:^4.3.0" + lodash.isboolean: "npm:^3.0.3" + lodash.isinteger: "npm:^4.0.4" + lodash.isnumber: "npm:^3.0.3" + lodash.isplainobject: "npm:^4.0.6" + lodash.isstring: "npm:^4.0.1" + lodash.once: "npm:^4.0.0" + ms: "npm:^2.1.1" + semver: "npm:^7.5.4" + checksum: d287a29814895e866db2e5a0209ce730cbc158441a0e5a70d5e940eb0d28ab7498c6bf45029cc8b479639bca94056e9a7f254e2cdb92a2f5750c7f358657a131 + languageName: node + linkType: hard + "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -7452,6 +7634,27 @@ __metadata: languageName: node linkType: hard +"jwa@npm:^1.4.1": + version: 1.4.1 + resolution: "jwa@npm:1.4.1" + dependencies: + buffer-equal-constant-time: "npm:1.0.1" + ecdsa-sig-formatter: "npm:1.0.11" + safe-buffer: "npm:^5.0.1" + checksum: 5c533540bf38702e73cf14765805a94027c66a0aa8b16bc3e89d8d905e61a4ce2791e87e21be97d1293a5ee9d4f3e5e47737e671768265ca4f25706db551d5e9 + languageName: node + linkType: hard + +"jws@npm:^3.2.2": + version: 3.2.2 + resolution: "jws@npm:3.2.2" + dependencies: + jwa: "npm:^1.4.1" + safe-buffer: "npm:^5.0.1" + checksum: e770704533d92df358adad7d1261fdecad4d7b66fa153ba80d047e03ca0f1f73007ce5ed3fbc04d2eba09ba6e7e6e645f351e08e5ab51614df1b0aa4f384dfff + languageName: node + linkType: hard + "keyv@npm:^4.5.3": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -7506,6 +7709,13 @@ __metadata: languageName: node linkType: hard +"libphonenumber-js@npm:^1.9.44": + version: 1.10.53 + resolution: "libphonenumber-js@npm:1.10.53" + checksum: de5630a2c8c3a481fd4e37f2a36b5f199a7079b92f0e802e431124fe437c0401424a793bf3f18bcca151a57a6556d20ff8ccc2deea655a5675e2676ba2775224 + languageName: node + linkType: hard + "lilconfig@npm:3.0.0": version: 3.0.0 resolution: "lilconfig@npm:3.0.0" @@ -7579,6 +7789,48 @@ __metadata: languageName: node linkType: hard +"lodash.includes@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.includes@npm:4.3.0" + checksum: 7ca498b9b75bf602d04e48c0adb842dfc7d90f77bcb2a91a2b2be34a723ad24bc1c8b3683ec6b2552a90f216c723cdea530ddb11a3320e08fa38265703978f4b + languageName: node + linkType: hard + +"lodash.isboolean@npm:^3.0.3": + version: 3.0.3 + resolution: "lodash.isboolean@npm:3.0.3" + checksum: 0aac604c1ef7e72f9a6b798e5b676606042401dd58e49f051df3cc1e3adb497b3d7695635a5cbec4ae5f66456b951fdabe7d6b387055f13267cde521f10ec7f7 + languageName: node + linkType: hard + +"lodash.isinteger@npm:^4.0.4": + version: 4.0.4 + resolution: "lodash.isinteger@npm:4.0.4" + checksum: 4c3e023a2373bf65bf366d3b8605b97ec830bca702a926939bcaa53f8e02789b6a176e7f166b082f9365bfec4121bfeb52e86e9040cb8d450e64c858583f61b7 + languageName: node + linkType: hard + +"lodash.isnumber@npm:^3.0.3": + version: 3.0.3 + resolution: "lodash.isnumber@npm:3.0.3" + checksum: 2d01530513a1ee4f72dd79528444db4e6360588adcb0e2ff663db2b3f642d4bb3d687051ae1115751ca9082db4fdef675160071226ca6bbf5f0c123dbf0aa12d + languageName: node + linkType: hard + +"lodash.isplainobject@npm:^4.0.6": + version: 4.0.6 + resolution: "lodash.isplainobject@npm:4.0.6" + checksum: afd70b5c450d1e09f32a737bed06ff85b873ecd3d3d3400458725283e3f2e0bb6bf48e67dbe7a309eb371a822b16a26cca4a63c8c52db3fc7dc9d5f9dd324cbb + languageName: node + linkType: hard + +"lodash.isstring@npm:^4.0.1": + version: 4.0.1 + resolution: "lodash.isstring@npm:4.0.1" + checksum: 09eaf980a283f9eef58ef95b30ec7fee61df4d6bf4aba3b5f096869cc58f24c9da17900febc8ffd67819b4e29de29793190e88dc96983db92d84c95fa85d1c92 + languageName: node + linkType: hard + "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -7593,7 +7845,14 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.14": +"lodash.once@npm:^4.0.0": + version: 4.1.1 + resolution: "lodash.once@npm:4.1.1" + checksum: 46a9a0a66c45dd812fcc016e46605d85ad599fe87d71a02f6736220554b52ffbe82e79a483ad40f52a8a95755b0d1077fba259da8bfb6694a7abbf4a48f1fc04 + languageName: node + linkType: hard + +"lodash@npm:>=4.17.21, lodash@npm:^4.17.14": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -7731,6 +7990,22 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + "mimic-fn@npm:^2.1.0": version: 2.1.0 resolution: "mimic-fn@npm:2.1.0" @@ -8019,6 +8294,31 @@ __metadata: languageName: node linkType: hard +"nextjs-cors@npm:2.2.0": + version: 2.2.0 + resolution: "nextjs-cors@npm:2.2.0" + dependencies: + cors: "npm:^2.8.5" + peerDependencies: + next: ^8.1.1-canary.54 || ^9.0.0 || ^10.0.0-0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 + checksum: 26b153b59efc514c5860ea9e68bfcc997db3b5b15270920028f2f9108266275531a28e82e9d77f47840a0586bdcf1f9df707ea09520104a9113758ac7560c856 + languageName: node + linkType: hard + +"node-fetch@npm:^2.6.12": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: "npm:^5.0.0" + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8 + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 10.0.1 resolution: "node-gyp@npm:10.0.1" @@ -8046,6 +8346,13 @@ __metadata: languageName: node linkType: hard +"nodemailer@npm:^6.7.2": + version: 6.9.7 + resolution: "nodemailer@npm:6.9.7" + checksum: 5ea7f781782361890d4492dc2412496e89fb04c498814e6c4fe7b168a27d7491a00f725cf90c26768907506e8afb76e8cfe6f6300def9940bc7f7e323405eaa6 + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.0 resolution: "nopt@npm:7.2.0" @@ -8095,7 +8402,7 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.1.1": +"object-assign@npm:^4, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -8516,6 +8823,15 @@ __metadata: languageName: node linkType: hard +"pkce-challenge@npm:^3.0.0": + version: 3.1.0 + resolution: "pkce-challenge@npm:3.1.0" + dependencies: + crypto-js: "npm:^4.1.1" + checksum: 5ff04324159946d1712557103f9cc6484ab0b86078c55049f5da1d709ffd9e1093868b44fb3fa98b162b14a6410f894d19eb09b79a6de0317be0ac9c86408b74 + languageName: node + linkType: hard + "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -8718,7 +9034,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1": +"prop-types@npm:*, prop-types@npm:^15.6.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -8752,6 +9068,13 @@ __metadata: languageName: node linkType: hard +"psl@npm:1.8.0": + version: 1.8.0 + resolution: "psl@npm:1.8.0" + checksum: b5f1956f7530860e1918e7238291689fdc3cab9c2c0cdbc47cde21addcc7f62495d794692cc1e43e54728d273f78037e8e73ac43009509a1a7f823341f4039c8 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -8769,6 +9092,22 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.9.4": + version: 6.11.2 + resolution: "qs@npm:6.11.2" + dependencies: + side-channel: "npm:^1.0.4" + checksum: 4f95d4ff18ed480befcafa3390022817ffd3087fc65f146cceb40fc5edb9fa96cb31f648cae2fa96ca23818f0798bd63ad4ca369a0e22702fcd41379b3ab6571 + languageName: node + linkType: hard + +"querystringify@npm:^2.1.1": + version: 2.2.0 + resolution: "querystringify@npm:2.2.0" + checksum: 3258bc3dbdf322ff2663619afe5947c7926a6ef5fb78ad7d384602974c467fadfc8272af44f5eb8cddd0d011aae8fabf3a929a8eee4b86edcc0a21e6bd10f9aa + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -8842,6 +9181,15 @@ __metadata: languageName: node linkType: hard +"react-icons@npm:4.12.0": + version: 4.12.0 + resolution: "react-icons@npm:4.12.0" + peerDependencies: + react: "*" + checksum: 2170f43031ee7365539f72d4075cbe6c7fbf9a66d6cf4494aa9393b194272da0564f5b19d1b24dbfc567c0ac89f5fe5b8974d92dd83f61e252388dde6a226fb8 + languageName: node + linkType: hard + "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -9102,6 +9450,13 @@ __metadata: languageName: node linkType: hard +"requires-port@npm:^1.0.0": + version: 1.0.0 + resolution: "requires-port@npm:1.0.0" + checksum: b2bfdd09db16c082c4326e573a82c0771daaf7b53b9ce8ad60ea46aa6e30aaf475fe9b164800b89f93b748d2c234d8abff945d2551ba47bf5698e04cd7713267 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -9372,7 +9727,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 @@ -9420,6 +9775,13 @@ __metadata: languageName: node linkType: hard +"scmp@npm:^2.1.0": + version: 2.1.0 + resolution: "scmp@npm:2.1.0" + checksum: 2128efa993cd2e3e10e3ab6d574cc9993ac7aa30430527e5da830ab509ba15eae49d8ca918d6aa934915bbd5b863778b04178227be005b49d801c0ca6063d2e4 + languageName: node + linkType: hard + "secure-json-parse@npm:^2.4.0": version: 2.7.0 resolution: "secure-json-parse@npm:2.7.0" @@ -9917,6 +10279,68 @@ __metadata: languageName: node linkType: hard +"supertokens-auth-react@npm:0.36.1": + version: 0.36.1 + resolution: "supertokens-auth-react@npm:0.36.1" + dependencies: + intl-tel-input: "npm:^17.0.19" + prop-types: "npm:*" + supertokens-js-override: "npm:^0.0.4" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + supertokens-web-js: ^0.8.0 + checksum: b4aaad21bb2f84cdb4962abf01e4a15bebe4e3ee16d63db858d9d809d194410cb3aaa6ba9be951b2bc4ce5a6013580996969357ab938e810ca4182fbd26ece70 + languageName: node + linkType: hard + +"supertokens-js-override@npm:0.0.4, supertokens-js-override@npm:^0.0.4": + version: 0.0.4 + resolution: "supertokens-js-override@npm:0.0.4" + checksum: 75468560e2f9fa0386e38d22f80aea705342f728db877b069623d3cfe070d85977b257508a2c8d3c6439280bfd6f1c7448ba8ac312b9abba6c8927428330028e + languageName: node + linkType: hard + +"supertokens-node@npm:16.6.8": + version: 16.6.8 + resolution: "supertokens-node@npm:16.6.8" + dependencies: + content-type: "npm:^1.0.5" + cookie: "npm:0.4.0" + cross-fetch: "npm:^3.1.6" + debug: "npm:^4.3.3" + inflation: "npm:^2.0.0" + jose: "npm:^4.13.1" + libphonenumber-js: "npm:^1.9.44" + nodemailer: "npm:^6.7.2" + pkce-challenge: "npm:^3.0.0" + psl: "npm:1.8.0" + supertokens-js-override: "npm:^0.0.4" + twilio: "npm:^4.19.3" + checksum: e0ca889b44548a21a56e39a79340dbf8b2556cdbcf760584aa7ee4d75f3ea76f82ef9b35e4a8ddcd345ae7502525189dbb277c66e9e012416c94eb80727831a3 + languageName: node + linkType: hard + +"supertokens-web-js@npm:0.8.0": + version: 0.8.0 + resolution: "supertokens-web-js@npm:0.8.0" + dependencies: + supertokens-js-override: "npm:0.0.4" + supertokens-website: "npm:^17.0.3" + checksum: 7703699d4e7c57404e3a5eaffc3f50c75a47bbabc261d6c1ed1e532b2168b2a3a1b73506a360d20b578a8ed86151fb645c10f68c9f168d7f601ea983714a3eae + languageName: node + linkType: hard + +"supertokens-website@npm:^17.0.3": + version: 17.0.4 + resolution: "supertokens-website@npm:17.0.4" + dependencies: + browser-tabs-lock: "npm:^1.3.0" + supertokens-js-override: "npm:^0.0.4" + checksum: 68811e39f91ef09914c3400a0ca42894ef2014b0dc5c2de0c882fe1ea16e5d213a3e18b49d440fbafa342c618193ceca14675fdd7eaf99e9084aa2e5369c66fa + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -10039,6 +10463,13 @@ __metadata: languageName: node linkType: hard +"tr46@npm:~0.0.3": + version: 0.0.3 + resolution: "tr46@npm:0.0.3" + checksum: 047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11 + languageName: node + linkType: hard + "trace-dojo@workspace:.": version: 0.0.0-use.local resolution: "trace-dojo@workspace:." @@ -10049,6 +10480,7 @@ __metadata: "@emotion/react": "npm:11.11.1" "@emotion/styled": "npm:11.11.0" "@prisma/client": "npm:5.5.2" + "@types/cookie": "npm:^0" "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" "@types/node": "npm:20.8.10" @@ -10060,6 +10492,7 @@ __metadata: "@willbooster/shared-lib-react": "npm:3.0.0" "@willbooster/wb": "npm:6.1.15" build-ts: "npm:11.0.11" + cookie: "npm:0.6.0" eslint: "npm:8.56.0" eslint-config-next: "npm:14.0.4" eslint-config-prettier: "npm:9.1.0" @@ -10075,6 +10508,7 @@ __metadata: lint-staged: "npm:15.2.0" micromatch: "npm:4.0.5" next: "npm:14.0.1" + nextjs-cors: "npm:2.2.0" pino: "npm:8.16.0" pino-pretty: "npm:10.2.3" pinst: "npm:3.0.0" @@ -10083,7 +10517,11 @@ __metadata: prisma: "npm:5.5.2" react: "npm:18.2.0" react-dom: "npm:18.2.0" + react-icons: "npm:4.12.0" sort-package-json: "npm:2.6.0" + supertokens-auth-react: "npm:0.36.1" + supertokens-node: "npm:16.6.8" + supertokens-web-js: "npm:0.8.0" typescript: "npm:5.3.3" zod: "npm:3.22.4" languageName: unknown @@ -10196,6 +10634,22 @@ __metadata: languageName: node linkType: hard +"twilio@npm:^4.19.3": + version: 4.20.0 + resolution: "twilio@npm:4.20.0" + dependencies: + axios: "npm:^1.6.0" + dayjs: "npm:^1.11.9" + https-proxy-agent: "npm:^5.0.0" + jsonwebtoken: "npm:^9.0.0" + qs: "npm:^6.9.4" + scmp: "npm:^2.1.0" + url-parse: "npm:^1.5.9" + xmlbuilder: "npm:^13.0.2" + checksum: deb4d76a103619437292590d81db165826c1b02eab1d10ecd01d5456d1f384df9b71657b58b6611fb2b7e20f110933ca744b6137e4f33401978f74d62f78f05a + languageName: node + linkType: hard + "tx2@npm:~1.0.4": version: 1.0.5 resolution: "tx2@npm:1.0.5" @@ -10434,6 +10888,16 @@ __metadata: languageName: node linkType: hard +"url-parse@npm:^1.5.9": + version: 1.5.10 + resolution: "url-parse@npm:1.5.10" + dependencies: + querystringify: "npm:^2.1.1" + requires-port: "npm:^1.0.0" + checksum: bd5aa9389f896974beb851c112f63b466505a04b4807cea2e5a3b7092f6fbb75316f0491ea84e44f66fed55f1b440df5195d7e3a8203f64fcefa19d182f5be87 + languageName: node + linkType: hard + "use-callback-ref@npm:^1.3.0": version: 1.3.1 resolution: "use-callback-ref@npm:1.3.1" @@ -10498,6 +10962,13 @@ __metadata: languageName: node linkType: hard +"vary@npm:^1": + version: 1.1.2 + resolution: "vary@npm:1.1.2" + checksum: f15d588d79f3675135ba783c91a4083dcd290a2a5be9fcb6514220a1634e23df116847b1cc51f66bfb0644cf9353b2abb7815ae499bab06e46dd33c1a6bf1f4f + languageName: node + linkType: hard + "vizion@npm:~2.2.1": version: 2.2.1 resolution: "vizion@npm:2.2.1" @@ -10520,6 +10991,23 @@ __metadata: languageName: node linkType: hard +"webidl-conversions@npm:^3.0.0": + version: 3.0.1 + resolution: "webidl-conversions@npm:3.0.1" + checksum: 5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db + languageName: node + linkType: hard + +"whatwg-url@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-url@npm:5.0.0" + dependencies: + tr46: "npm:~0.0.3" + webidl-conversions: "npm:^3.0.0" + checksum: 1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5 + languageName: node + linkType: hard + "which-boxed-primitive@npm:^1.0.2": version: 1.0.2 resolution: "which-boxed-primitive@npm:1.0.2" @@ -10670,6 +11158,13 @@ __metadata: languageName: node linkType: hard +"xmlbuilder@npm:^13.0.2": + version: 13.0.2 + resolution: "xmlbuilder@npm:13.0.2" + checksum: e703027bd10808ee93f6626a4ca440e9d295a0b323aed151c39f427f32d23bda0a1af0b9278286fa94c25fc52d46716fa79e17abcda31205fb33bf4bc0ffe575 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8"
+ Client side component got userId: {session.userId} + +