diff --git a/.env.development b/.env.development index 342ec895..ecdbcfa9 100644 --- a/.env.development +++ b/.env.development @@ -23,3 +23,4 @@ NEXT_PUBLIC_APP_MEASUREMENT_ID=G-7ZNKM9VFN2 NEXT_PUBLIC_TERM_URL=https://file-system-run-qi6ms4rtoa-ue.a.run.app/ NEXT_PUBLIC_APP_STRIPE_KEY=pk_test_51NyMUrJJ9Dbjmm7hji7JsdifB3sWmgPKQhfRsG7pEPjvwyYe0huU1vLeOwbUe5j5dmPWkS0EqB6euANw2yJ2yQn000lHnTXis7 NEXT_PUBLIC_KANA_SERVER_URL=kana-server.ctfguide.com +NEXT_PUBLIC_GOOGLE_CLIENT_ID=166652277588-4uk7g7irqlicacelg1nfgt0ejmskmo9h.apps.googleusercontent.com diff --git a/package.json b/package.json index 7b444865..1b9486ec 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,14 @@ "asciinema-player": "3.6.3", "autoprefixer": "^10.4.12", "babel-plugin-macros": "^3.1.0", + "@react-oauth/google": "^0.12.1", + "jwt-decode": "^4.0.0", "chart.js": "^4.4.1", "clsx": "^1.2.1", "corepack": "^0.17.0", "dotenv": "^16.0.3", "easymde": "^2.18.0", "enable": "^3.4.0", - "firebase": "^9.16.0", "focus-visible": "^5.2.0", "framer-motion": "^10.2.4", "heroicons": "^2.0.13", diff --git a/src/components/AuthPopup.jsx b/src/components/AuthPopup.jsx index e01ee6a2..9ca1c2a7 100644 --- a/src/components/AuthPopup.jsx +++ b/src/components/AuthPopup.jsx @@ -1,24 +1,10 @@ import { useState, useEffect } from 'react'; import Link from 'next/link'; -import { getAuth, onAuthStateChanged } from 'firebase/auth'; +//import { getAuth, onAuthStateChanged } from 'firebase/auth'; export function AuthPopup() { // check if firebase logged in const [user, setUser] = useState(false); - const auth = getAuth(); - useEffect(() => { - const auth = getAuth(); - onAuthStateChanged(auth, (user) => { - if (user) { - // User is signed in, see docs for a list of available properties - // https://firebase.google.com/docs/reference/js/firebase.User - const uid = user.uid; - setUser(false); - } else { - setUser(false); - } - }); - }); if (user) { return
{/*User logged in*/}
; } else { diff --git a/src/components/StandardNav.jsx b/src/components/StandardNav.jsx index 968a1580..a97a5c21 100644 --- a/src/components/StandardNav.jsx +++ b/src/components/StandardNav.jsx @@ -18,10 +18,7 @@ import request from "@/utils/request"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faEllipsis, faSearch } from '@fortawesome/free-solid-svg-icons'; import { faBug, faLock, faUserSecret, faNetworkWired, faBrain, faTerminal } from '@fortawesome/free-solid-svg-icons'; -// Do not remove, even if detected as unused by vscode! -import { app } from '../config/firebaseConfig'; -import { getAuth, onAuthStateChanged, signOut } from 'firebase/auth'; import 'reactjs-popup/dist/index.css'; import Upgrade from './nav/Upgrade'; @@ -34,9 +31,7 @@ function classNames(...classes) { return classes.filter(Boolean).join(' '); } -const auth = getAuth(); const baseUrl = process.env.NEXT_PUBLIC_FRONTEND_URL; - const adminList = ['pranav']; const DEFAULT_NOTIFICATION = { @@ -58,20 +53,15 @@ export function StandardNav({ guestAllowed, alignCenter = true }) { const [showBanner, setShowBanner] = useState(false); const [showSearchModal, setShowSearchModal] = useState(false); const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const [open, setOpen] = useState(true) - const router = useRouter(); function logout() { - signOut(auth) - .then(() => { - window.location.replace('/login'); - }) - .catch((error) => { - console.log(error); - }); + document.cookie = 'idToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + router.push('/login'); } // if user signed out redirect diff --git a/src/components/groups/assignments/create-challenge.jsx b/src/components/groups/assignments/create-challenge.jsx index fafe46db..00fd5d6a 100644 --- a/src/components/groups/assignments/create-challenge.jsx +++ b/src/components/groups/assignments/create-challenge.jsx @@ -7,8 +7,8 @@ import { MarkdownViewer } from '@/components/MarkdownViewer'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import fileApi from '@/utils/file-api'; -import { getAuth } from 'firebase/auth'; -import request from '@/utils/request'; +import request, { getCookie } from '@/utils/request'; +import { jwtDecode } from 'jwt-decode'; const styles = { h1: { fontSize: '2.4rem' }, @@ -19,8 +19,6 @@ const styles = { h6: { fontSize: '1.2rem' }, }; -const auth = getAuth(); - export default function Createchall(props) { const pages = [ @@ -87,7 +85,10 @@ export default function Createchall(props) { await uploadChallenge(''); return; } else { - const token = await auth.currentUser.accessToken; + const cookie = getCookie('idToken'); + const data = jwtDecode(cookie); + + const token = data.id; const fileId = await fileApi(token, selectedFile); if(fileId !== null) { await uploadChallenge(fileId); diff --git a/src/components/groups/assignments/updateChallengeInfo.jsx b/src/components/groups/assignments/updateChallengeInfo.jsx index 5b4e96d5..b7f383b5 100644 --- a/src/components/groups/assignments/updateChallengeInfo.jsx +++ b/src/components/groups/assignments/updateChallengeInfo.jsx @@ -5,14 +5,12 @@ import { StandardNav } from '@/components/StandardNav'; import ClassroomNav from '@/components/groups/classroomNav'; import CreateAssignment from '@/components/groups/assignments/createAssignment'; import { useState, useEffect } from 'react'; -import request from '@/utils/request'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; - import fileApi, { deleteFiles, getFileName, getFile } from '@/utils/file-api'; -import { getAuth } from 'firebase/auth'; -const auth = getAuth(); +import request, { getCookie } from '@/utils/request'; +import { jwtDecode } from 'jwt-decode'; const Editor = (props) => { const [contentPreview, setContentPreview] = useState(''); @@ -55,8 +53,9 @@ const Editor = (props) => { if(!validateNewChallege()) { return; } - - const token = await auth.currentUser.accessToken; + const cookie = getCookie('idToken'); + const data = jwtDecode(cookie); + const token = data.id; setIsCreating(true); let fileIds = []; let idsToDelete = []; diff --git a/src/components/onboarding/DataAsk.jsx b/src/components/onboarding/DataAsk.jsx index 15e53412..3c8f1f49 100644 --- a/src/components/onboarding/DataAsk.jsx +++ b/src/components/onboarding/DataAsk.jsx @@ -1,33 +1,20 @@ -import { Container } from '@/components/Container'; + import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; -import { getCookie } from '@/utils/request'; import AuthFooter from '@/components/auth/AuthFooter'; -import Link from 'next/link'; - import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -import { getAuth, onAuthStateChanged, signOut } from 'firebase/auth'; - - -export function DataAsk({ props }) { +export function DataAsk(props) { const router = useRouter(); const [username, setUsername] = useState(''); const [validationMessage, setValidationMessage] = useState(''); const [isLoading, setIsLoading] = useState(false); const [userHasEdited, setUserHasEdited] = useState(false); // New state to track if the user has edited the input + function logout() { - signOut(auth) - .then(() => { - window.location.replace('/login'); - }) - .catch((error) => { - console.log(error); - }); + router.push('/login'); } - const auth = getAuth(); - useEffect(() => { if (router.query.part == '1') { @@ -37,6 +24,7 @@ export function DataAsk({ props }) { } } }); + useEffect(() => { if (!userHasEdited) return; // Don't validate until the user edits the input @@ -56,7 +44,7 @@ export function DataAsk({ props }) { } }, [username, userHasEdited]); - function submitData() { + async function submitData() { setIsLoading(true); // Generate JSON to send var username = document.getElementById('username').value; @@ -122,55 +110,43 @@ export function DataAsk({ props }) { return; } - // send http request - var xhr = new XMLHttpRequest(); - xhr.open('POST', `${process.env.NEXT_PUBLIC_API_URL}/users`); - xhr.setRequestHeader('Content-Type', 'application/json'); - - let token = getCookie(); - xhr.setRequestHeader('Authorization', 'Bearer ' + token); - - xhr.withCredentials = true; - - xhr.addEventListener('readystatechange', function () { - if (this.readyState === 4 && this.readyState === 201) { - var parsed = JSON.parse(this.responseText); - if (parsed.username) { - // Sign out - // Redirect to login - window.location.href = '/dashboard'; - } - } - - if (this.readyState === 4 && this.readyState != 201) { - var parsed = JSON.parse(this.responseText); - - if (parsed.error === 'undefined' || parsed.error) { - - - setIsLoading(false); - toast.error(parsed.error); + const body = { + email: props.email, + password: props.password, + username, + birthday, + firstName: firstname, + lastName: lastname, + location: "???", + accountType: props.accountType + } - } else { - window.location.href = "./dashboard"; - // window.location.replace('./onboarding?part=1&error=' + parsed.error); - // document.getElementById('error').classList.remove('hidden'); - // document.getElementById('error').innerHTML = parsed.error; - } + try { + const url = `${process.env.NEXT_PUBLIC_API_URL}/account/register`; + const requestOptions = { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }; + + const response = await fetch(url, requestOptions); + const data = await response.json(); + + if(data.success) { + const { token } = data; + setIsLoading(false); + document.cookie = `idToken=${token}; SameSite=None; Secure; Path=/`; + router.push('/dashboard'); + } else { + setIsLoading(false); + toast.error(data.error); } - }); - xhr.send( - JSON.stringify({ - username: localStorage.getItem('username'), - birthday: localStorage.getItem('birthday'), - firstName: localStorage.getItem('firstname'), - lastName: localStorage.getItem('lastname'), - location: "????", - }) - ); + } catch (error) { + console.log(error); + toast.error("An error occurred. Please try again later."); } - + } } @@ -180,40 +156,26 @@ export function DataAsk({ props }) { backgroundRepeat: 'repeat', width: '100%', height: '100%', - }}> + }}> +
+
-
- - - - -
- - - -
+ className=" pb-10 pt-4 px-4 shadow sm:px-10 border-t-4 border-blue-600 bg-neutral-800" + > +
- +
+

+ {' '} + Finish creating your account +

-
-

- {' '} - Finish creating your account -

-
- -
+ adow-sm">
{ - setUsername(e.target.value); - if (!userHasEdited) setUserHasEdited(true); // Set to true on first edit - }} - className="bg-neutral-900 mt-2 block w-full rounded border-0 p-0 py-1 px-4 text-white placeholder-gray-500 focus:ring-0 sm:text-sm" - placeholder="This is what people on CTFGuide will know you as." - /> - {userHasEdited && validationMessage && ( -
- {validationMessage} -
- )} + type="text" + name="name" + id="username" + value={username} + onChange={(e) => { + setUsername(e.target.value); + if (!userHasEdited) setUserHasEdited(true); // Set to true on first edit + }} + className="bg-neutral-900 mt-2 block w-full rounded border-0 p-0 py-1 px-4 text-white placeholder-gray-500 focus:ring-0 sm:text-sm" + placeholder="This is what people on CTFGuide will know you as." + /> + {userHasEdited && validationMessage && ( +
+ {validationMessage} +
+ )}
@@ -319,13 +281,13 @@ export function DataAsk({ props }) { submitData(); }} className="flex w-full justify-center rounded-sm border border-transparent bg-blue-700 hover:bg-blue-700/90 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2" - > + > { isLoading ? ( ) : ( - Start Hacking - ) + Start Hacking + ) } @@ -336,8 +298,8 @@ export function DataAsk({ props }) {
- -
+ +
diff --git a/src/components/onboarding/OnboardingFlow.jsx b/src/components/onboarding/OnboardingFlow.jsx index 087e4501..c5ae51b2 100644 --- a/src/components/onboarding/OnboardingFlow.jsx +++ b/src/components/onboarding/OnboardingFlow.jsx @@ -4,7 +4,7 @@ import { DataAskPart2 } from '@/components/onboarding/DataAskPart2'; import { Demo } from '@/components/onboarding/Demo'; import { useRouter } from 'next/router'; -export function OnboardingFlow() { +export function OnboardingFlow(props) { const router = useRouter(); const [flowState, setFlowState] = useState(router.query.part || '1'); @@ -19,15 +19,13 @@ export function OnboardingFlow() { setFlowState(router.query.part); }, [router.query.part]); - // Read part from URL query parameter - if (flowState === '1') { - return ; + return ; } else if (flowState === '2') { return ; } else if (flowState === '3') { return ; } else { - return ; + return ; } } diff --git a/src/components/studio/forking/editor.jsx b/src/components/studio/forking/editor.jsx index 144196e9..efc37bfe 100644 --- a/src/components/studio/forking/editor.jsx +++ b/src/components/studio/forking/editor.jsx @@ -1,19 +1,18 @@ import React from 'react'; import { MarkdownViewer } from '@/components/MarkdownViewer'; import { useState, useEffect } from 'react'; -import request from '@/utils/request'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -import { useRouter } from 'next/router'; -import { getAuth } from 'firebase/auth'; +//import { useRouter } from 'next/router'; import fileApi, {getNewFileIds, getFileName, getFile } from '@/utils/file-api'; -const auth = getAuth(); +import request, { getCookie } from '@/utils/request'; +import { jwtDecode } from 'jwt-decode'; const Editor = (props) => { - const router = useRouter(); + //const router = useRouter(); const [contentPreview, setContentPreview] = useState(''); const [penalty, setPenalty] = useState([0, 0, 0]); const [hints, setHints] = useState([ @@ -50,7 +49,11 @@ const Editor = (props) => { if(!validateNewChallege()) { return; } - const token = await auth.currentUser.accessToken; + + const cookie = getCookie('idToken'); + const data = jwtDecode(cookie); + const token = data.id; + setIsCreating(true); let fileIds = []; const originalFileIds = existingFiles.filter((file) => file.using).map((file) => file.fileId); diff --git a/src/config/firebaseConfig.js b/src/config/firebaseConfig.js deleted file mode 100644 index dc08ecf0..00000000 --- a/src/config/firebaseConfig.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - © CTFGuide Corporation -*/ - -import { initializeApp } from 'firebase/app'; -//import { getAnalytics } from "firebase/analytics"; - -/* - This code is intended to be public. This is public facing client information. - It isn't some secret key or anything. It's just a way for our auth service (Firebase) to identify the app. -*/ - -// -const firebaseConfig = { - apiKey: process.env.NEXT_PUBLIC_APP_API_KEY, - authDomain: process.env.NEXT_PUBLIC_APP_AUTH_DOMAIN, - projectId: process.env.NEXT_PUBLIC_APP_PROJECT_ID, - storageBucket: process.env.NEXT_PUBLIC_APP_STORAGE_BUCKET, - messagingSenderId: process.env.NEXT_PUBLIC_APP_MESSAGING_SENDER_ID, - appId: process.env.NEXT_PUBLIC_APP_ID, - measurmentId: process.env.NEXT_PUBLIC_APP_MEASURMENT_ID, -}; - -//console.log(firebaseConfig); - -// Initialize Firebase -// const app = initializeApp(firebaseConfig); - - -// const firebaseConfig = { -// apiKey: "AIzaSyBLAN84VP3jSA5dqhrU6Bjmfu5NiUDuNw4", -// authDomain: "cyberjags-8b081.firebaseapp.com", -// databaseURL: "https://cyberjags-8b081.firebaseio.com", -// projectId: "cyberjags-8b081", -// storageBucket: "cyberjags-8b081.appspot.com", -// messagingSenderId: "166652277588", -// appId: "1:166652277588:web:e08b9e19916451e14dcec1", -// measurementId: "G-7ZNKM9VFN2" -// }; -/** -const firebaseConfig = { - apiKey: 'AIzaSyBLAN84VP3jSA5dqhrU6Bjmfu5NiUDuNw4', - authDomain: 'cyberjags-8b081.firebaseapp.com', - databaseURL: 'https://cyberjags-8b081.firebaseio.com', - projectId: 'cyberjags-8b081', - storageBucket: 'cyberjags-8b081.appspot.com', - messagingSenderId: '166652277588', - appId: '1:166652277588:web:e08b9e19916451e14dcec1', - measurementId: 'G-7ZNKM9VFN2', -}; -*/ - -const app = initializeApp(firebaseConfig); - -// make a function to check if the cookie exists -// if it does, then set the auth token to the cookie - -// Initialize Firebase - -//const analytics = getAnalytics(app); diff --git a/src/config/jwt.js b/src/config/jwt.js deleted file mode 100644 index 53ce18f3..00000000 --- a/src/config/jwt.js +++ /dev/null @@ -1,34 +0,0 @@ -import '@/config/firebaseConfig'; - -import { getAuth } from 'firebase/auth'; -const auth = getAuth(); - -const checkAuthToken = () => { - const cookies = document.cookie.split(';').map(cookie => cookie.trim().split('=')[0]); - return cookies.includes('idToken'); -} - -const updateAuthToken = async (auth) => { - try { - - if(auth.currentUser && checkAuthToken()) { - console.log("Generating new token"); - const idToken = await auth.currentUser.getIdToken(true); - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - } - - } catch(err) { - console.log(err); - } -} - -const updateAuthTokenInterval = (auth) => { - const intervalId = setInterval(() => { - updateAuthToken(auth); - }, 10 * 60 * 1000); - return () => { - clearInterval(intervalId); - }; -} - -updateAuthTokenInterval(auth); diff --git a/src/config/lessonConfigs.js b/src/config/lessonConfigs.js index 1ea61115..91637387 100644 --- a/src/config/lessonConfigs.js +++ b/src/config/lessonConfigs.js @@ -12,4 +12,4 @@ const configArray = [{ "navTitles": ["What is Linux?", "Command Basics", "Mastery Task", "Logging into a server"] }]; -export default configArray; \ No newline at end of file +export default configArray; diff --git a/src/middleware.js b/src/middleware.js index a112a212..25c626d3 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -15,8 +15,6 @@ export function middleware(req) { // ensure token is valid // basic request to server to ensure that the token is valid - - if (!idToken) { const url = req.nextUrl.clone(); url.pathname = '/login'; diff --git a/src/pages/_app.jsx b/src/pages/_app.jsx index b3f0b0c2..23780823 100644 --- a/src/pages/_app.jsx +++ b/src/pages/_app.jsx @@ -1,8 +1,10 @@ import 'focus-visible'; import '@/styles/tailwind.css'; import '@tremor/react/dist/esm/tremor.css'; -import '@/config/jwt'; +import { GoogleOAuthProvider } from '@react-oauth/google'; export default function App({ Component, pageProps }) { - return ; + return + ; + } diff --git a/src/pages/create/new.jsx b/src/pages/create/new.jsx index 2234b93a..a48cd8c8 100644 --- a/src/pages/create/new.jsx +++ b/src/pages/create/new.jsx @@ -6,7 +6,8 @@ import { MarkdownViewer } from '@/components/MarkdownViewer'; import fileApi from '@/utils/file-api'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -import request from '@/utils/request'; +import request, { getCookie } from '@/utils/request'; +import { jwtDecode } from 'jwt-decode'; const pages = [ { name: 'Creator Dashboard', href: '../create', current: false }, @@ -17,9 +18,6 @@ const pages = [ }, ]; -import { getAuth } from 'firebase/auth'; -const auth = getAuth(); - const styles = { h1: { fontSize: '2.4rem' }, h2: { fontSize: '2rem' }, @@ -68,7 +66,10 @@ export default function Createchall() { await uploadChallenge(''); return; } else { - const token = await auth.currentUser.accessToken; + const cookie = getCookie('idToken'); + const data = jwtDecode(cookie); + + const token = data.id; const fileId = await fileApi(token, selectedFile); if(fileId !== null) { await uploadChallenge(fileId); diff --git a/src/pages/login.jsx b/src/pages/login.jsx index 6f241a8e..9137dc99 100644 --- a/src/pages/login.jsx +++ b/src/pages/login.jsx @@ -1,262 +1,71 @@ import Head from 'next/head'; import Link from 'next/link'; -import { Button } from '@/components/Button'; -import { TextField } from '@/components/Fields'; -import { Logo } from '@/components/Logo'; -import { Alert } from '@/components/Alert'; -import { useState, useEffect } from 'react'; -import { app } from '../config/firebaseConfig'; +import { useState } from 'react'; import router from 'next/router'; -import { - getAuth, - onAuthStateChanged, - signInWithEmailAndPassword, - GoogleAuthProvider, - OAuthProvider, - signInWithPopup, -} from 'firebase/auth'; - import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import AuthFooter from '@/components/auth/AuthFooter'; - -const provider = new GoogleAuthProvider(); - +import { GoogleLogin } from '@react-oauth/google'; +import { jwtDecode } from 'jwt-decode'; export default function Login() { - const auth = getAuth(); - const [session, setSession] = useState(); - const [logoutUrl, setLogoutUrl] = useState(); const [isLoading, setIsLoading] = useState(false); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); - useEffect(() => { - onAuthStateChanged(auth, (user) => { - // removing the cookie - document.cookie = "idToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; - }); - }, []); - - async function loginUser() { - const email = document.getElementById('username').value; - const password = document.getElementById('password').value; - + async function handleLoginRequest(requestOptions) { setIsLoading(true); - - signInWithEmailAndPassword(auth, email, password) - .then((userCredential) => { - // Fetch ID Token - userCredential.user.getIdToken().then((idToken) => { - - // Send token to backend via HTTPS - var data = new FormData(); - var xhr = new XMLHttpRequest(); - - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - - xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`); - xhr.addEventListener('readystatechange', function () { - if (this.readyState === 4) { - var parsed = JSON.parse(this.responseText); - - // Sotre username - localStorage.setItem('username', parsed.username); - - if (!parsed.email) { - window.location.replace('/onboarding'); - return; - } - - // Store related API endpoints in local storage. - localStorage.setItem('userLikesUrl', parsed.userLikesUrl); - localStorage.setItem( - 'userChallengesUrl', - parsed.userChallengesUrl - ); - - localStorage.setItem('userBadgesUrl', parsed.userBadgesUrl); - localStorage.setItem('notificationsUrl', parsed.notificationsUrl); - localStorage.setItem('role', parsed.role); - - localStorage.setItem('username', parsed.username); - - router.push('/dashboard'); - } - }); - xhr.setRequestHeader('Authorization', 'Bearer ' + idToken); - xhr.send(data); - }); - }) - .catch((error) => { - setIsLoading(false); - const errorCode = error.code; - const errorMessage = error.message; - - let userFriendlyMessage; - switch (errorCode) { - case 'auth/user-not-found': - userFriendlyMessage = 'No user found with this email.'; - break; - case 'auth/wrong-password': - userFriendlyMessage = 'Incorrect password. Please try again.'; - break; - case 'auth/too-many-requests': - userFriendlyMessage = 'Too many attempts. Please try again later.'; - break; - default: - userFriendlyMessage = 'An error occurred. Please try again.'; - } - toast.error(userFriendlyMessage); - - }); + try { + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/account/login`, requestOptions); + let data = await response.json(); + let { success, token, body } = data; + if (success) { + document.cookie = `idToken=${token}; SameSite=None; Secure; Path=/`; + + localStorage.setItem('username', body.username); + localStorage.setItem('firstname', body.firstName); + localStorage.setItem('lastname', body.lastName); + localStorage.setItem('birthday', body.birthday); + + router.push('/dashboard'); + } else { + toast.error(data.message); + } + } catch(error) { + console.log(error); + } + setIsLoading(false); } - async function loginGoogle() { - const auth = getAuth(); - signInWithPopup(auth, provider) - .then((result) => { - // Fetch ID Token - result.user.getIdToken().then((idToken) => { - - // Send token to backend via HTTPS - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - - var data = new FormData(); - var xhr = new XMLHttpRequest(); - - xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`); - xhr.addEventListener('readystatechange', function () { - if (this.readyState === 4) { - try { - var parsed = JSON.parse(this.responseText); - - if (!parsed.email) { - // User hasn't finished onboarding. - window.location.replace('/onboarding'); - return; - } - - // Store related API endpoints in local storage. - localStorage.setItem('userLikesUrl', parsed.userLikesUrl); - localStorage.setItem( - 'userChallengesUrl', - parsed.userChallengesUrl - ); - localStorage.setItem('userBadgesUrl', parsed.userBadgesUrl); - localStorage.setItem( - 'notificationsUrl', - parsed.notificationsUrl - ); - - localStorage.setItem('role', parsed.role); - localStorage.setItem('username', parsed.username); - - // addthing the token to cookies - - router.push('/dashboard'); - - } catch (error) { - console.log('Error parsing JSON data:', error); - } - } - }); - xhr.setRequestHeader('Authorization', 'Bearer ' + idToken); - xhr.send(data); - }); - }) - .catch((error) => { - // Handle Errors here. - const errorCode = error.code; - const errorMessage = error.message; - - const credential = GoogleAuthProvider.credentialFromError(error); - // basic cleaned errormeSSAGE to send back - - let userFriendlyMessage; - switch (errorCode) { - case 'auth/user-not-found': - userFriendlyMessage = 'No user found with this email.'; - break; - case 'auth/wrong-password': - userFriendlyMessage = 'Incorrect password. Please try again.'; - break; - case 'auth/too-many-requests': - userFriendlyMessage = 'Too many attempts. Please try again later.'; - break; - default: - userFriendlyMessage = 'An error occurred. Please try again.'; - } - toast.error(userFriendlyMessage); - - }); + const handleLogin = async (e) => { + e.preventDefault(); + const requestOptions = { + method: 'POST', + body: JSON.stringify({ email, password, accountType: 'EMAIL'}), + headers: { 'Content-Type': 'application/json' } + }; + await handleLoginRequest(requestOptions); } - const loginMicrosoft = () => { - // Microsoft login logic here - const provider2 = new OAuthProvider('microsoft.com'); - signInWithPopup(auth, provider2) - .then((result) => { - result.user.getIdToken().then((idToken) => { - - // Send token to backend via HTTPS - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - - var data = new FormData(); - var xhr = new XMLHttpRequest(); - - xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`); - xhr.addEventListener('readystatechange', function () { - if (this.readyState === 4) { - try { - var parsed = JSON.parse(this.responseText); - - if (!parsed.email) { - // User hasn't finished onboarding. - window.location.replace('/onboarding'); - return; - } - - // Store related API endpoints in local storage. - localStorage.setItem('userLikesUrl', parsed.userLikesUrl); - localStorage.setItem( - 'userChallengesUrl', - parsed.userChallengesUrl - ); - localStorage.setItem('userBadgesUrl', parsed.userBadgesUrl); - localStorage.setItem( - 'notificationsUrl', - parsed.notificationsUrl - ); - - localStorage.setItem('role', parsed.role); - localStorage.setItem('username', parsed.username); - - // addthing the token to cookies - - router.push('/dashboard'); + // do the same for google auth login + async function handleSuccess(data) { + console.log("Setting account by google"); + const { credential } = data; + const decode = jwtDecode(credential); + const { email } = decode; + const requestOptions = { + method: 'POST', + body: JSON.stringify({ email, password: null, accountType: 'GOOGLE'}), + headers: { 'Content-Type': 'application/json' } + }; + await handleLoginRequest(requestOptions); + } - } catch (error) { - console.log('Error parsing JSON data:', error); - } - } - }); - xhr.setRequestHeader('Authorization', 'Bearer ' + idToken); - xhr.send(data); - }); - }).catch((error) => { - // Handle Errors here. - console.log(error) - const errorCode = error.code; - const errorMessage = error.message; - // The email of the user's account used. - const email = error.email; - // The MicrosoftAuthProvider credential to access the Microsoft API. - const credential = error.credential; - // Display error message - document.getElementById('error').classList.remove('hidden'); - document.getElementById('errorMessage').innerHTML = errorMessage; - }); - }; + async function handleError(data) { + console.log(data); + toast.error('Google login failed. Please try again later.'); + } return ( <> @@ -277,6 +86,8 @@ export default function Login() { style={{ fontFamily: 'Poppins, sans-serif' }} className="flex min-h-full flex-col justify-center py-12 sm:px-6 lg:px-8 animate__animated animate__fadeIn " > +
+
@@ -328,6 +139,7 @@ export default function Login() { style={{ backgroundColor: '#161716', borderWidth: '0px' }} id="username" name="email" + onChange={(e) => setEmail(e.target.value)} type="text" autoComplete="email" required @@ -348,6 +160,7 @@ export default function Login() { style={{ backgroundColor: '#161716', borderWidth: '0px' }} id="password" name="password" + onChange={(e) => setPassword(e.target.value)} type="password" autoComplete="current-password" required @@ -370,7 +183,7 @@ export default function Login() {
+
- -
+
diff --git a/src/pages/register.jsx b/src/pages/register.jsx index 23c701b1..d8492dc4 100644 --- a/src/pages/register.jsx +++ b/src/pages/register.jsx @@ -1,36 +1,54 @@ import Head from 'next/head'; import Link from 'next/link'; import { useState, useEffect } from 'react'; -import { - getAuth, - createUserWithEmailAndPassword, - GoogleAuthProvider, - signInWithPopup, -} from 'firebase/auth'; -import { app } from '../config/firebaseConfig'; import AuthFooter from '../components/auth/AuthFooter'; -const provider = new GoogleAuthProvider(); - import { ToastContainer, toast } from 'react-toastify'; +import { OnboardingFlow } from '@/components/onboarding/OnboardingFlow'; import 'react-toastify/dist/ReactToastify.css'; +import { GoogleLogin } from '@react-oauth/google'; +import { jwtDecode } from 'jwt-decode'; -export default function Register() { +function Register() { const [validationMessage, setValidationMessage] = useState(''); const [validationMessage2, setValidationMessage2] = useState(''); - const [userHasEdited, setUserHasEdited] = useState(false); // New state to track if the user has edited the input const [password, setPassword] = useState(''); + const [email, setEmail] = useState(''); const [cpassword, setCPassword] = useState(''); - const [isLoading, setIsLoading] = useState(false); + const [showOnboarding, setShowOnboarding] = useState(false); + const [accountType, setAccountType] = useState('EMAIL'); + + async function emailExists(emailData) { + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/account/check-email`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + email: emailData + }), + } + ); + const data = await response.json(); + return data.success; + } catch (error) { + console.error('Error checking email:', error); + return false; + } + } + useEffect(() => { if (!userHasEdited) return; // Don't validate until the user edits the input - + if (password !== cpassword) { setValidationMessage2('Passwords do not match.'); } else { if (cpassword !== "") { - setValidationMessage2('Looks good!'); + setValidationMessage2('Looks good!'); } else { setValidationMessage2(''); } @@ -41,365 +59,293 @@ export default function Register() { return; } // some password safety - if (password.length < 8) { - setValidationMessage('Password must be at least 8 characters long.'); - } else if (!/[A-Z]/.test(password)) { - setValidationMessage('Password must contain at least one uppercase letter.'); - } else if (!/[a-z]/.test(password)) { - setValidationMessage('Password must contain at least one lowercase letter.'); - } else if (!/[0-9]/.test(password)) { - setValidationMessage('Password must contain at least one number.'); - } else if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) { - setValidationMessage('Password must contain at least one special character.'); - } else { - setValidationMessage('Looks good!'); - // make message green - - } - - + if (password.length < 8) { + setValidationMessage('Password must be at least 8 characters long.'); + } else if (!/[A-Z]/.test(password)) { + setValidationMessage('Password must contain at least one uppercase letter.'); + } else if (!/[a-z]/.test(password)) { + setValidationMessage('Password must contain at least one lowercase letter.'); + } else if (!/[0-9]/.test(password)) { + setValidationMessage('Password must contain at least one number.'); + } else if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) { + setValidationMessage('Password must contain at least one special character.'); + } else { + setValidationMessage('Looks good!'); + // make message green + } }, [password, cpassword, userHasEdited]); - async function loginGoogle() { - const auth = getAuth(); - signInWithPopup(auth, provider) - .then((result) => { - // Fetch ID Token - result.user.getIdToken().then((idToken) => { - //console.log("We are making a register"); - // Send token to backend via HTTPS - var data = new FormData(); - var xhr = new XMLHttpRequest(); - xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`); - xhr.addEventListener('readystatechange', function () { - if (this.readyState === 4) { - try { - var parsed = JSON.parse(this.responseText); - - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - if (!parsed.email) { - // User hasn't finished onboarding. - window.location.replace('/onboarding'); - return; - } - - // Store related API endpoints in local storage. - localStorage.setItem('userLikesUrl', parsed.userLikesUrl); - localStorage.setItem( - 'userChallengesUrl', - parsed.userChallengesUrl - ); - localStorage.setItem('userBadgesUrl', parsed.userBadgesUrl); - localStorage.setItem( - 'notificationsUrl', - parsed.notificationsUrl - ); - localStorage.setItem('role', parsed.role); - - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - window.location.replace('/dashboard'); - } catch (error) { - console.log('Error parsing JSON data:', error); - } - } - }); - xhr.setRequestHeader('Authorization', 'Bearer ' + idToken); - xhr.send(data); - }); - }) - .catch((error) => { - // Handle Errors here. - const errorCode = error.code; - const errorMessage = error.message; - - const credential = GoogleAuthProvider.credentialFromError(error); - - toast.error(errorMessage); - }); + + async function registerUser(e) { + setAccountType('EMAIL'); + e.preventDefault(); + if(email == "" || password == "" || cpassword == "") { + toast.error('Please fill in all fields.'); + return; + } + if(password.length < 8) { + toast.error('Password must be at least 8 characters long.'); + return; + } + if (document.getElementById('password').value !== document.getElementById('cpassword').value) { + toast.error('Passwords do not match.'); + return; + } + const exists = await emailExists(email); + if(!exists) { + toast.error('Email already exists.'); + return; + } + setShowOnboarding(true); + console.log('Registering user...'); } - async function registerUser() { - const auth = getAuth(); - - if ( - document.getElementById('password').value === - document.getElementById('cpassword').value - ) { - createUserWithEmailAndPassword( - auth, - document.getElementById('email-address').value, - document.getElementById('cpassword').value - ) - .then((userCredential) => { - // Signed in - const user = userCredential.user; - userCredential.user.getIdToken().then((idToken) => { - - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - var xhr = new XMLHttpRequest(); - xhr.open('GET', `${process.env.NEXT_PUBLIC_API_URL}/account`); - xhr.addEventListener('readystatechange', function () { - if (this.readyState === 4) { - var parsed = JSON.parse(this.responseText); - document.cookie = `idToken=${idToken}; SameSite=None; Secure; Path=/`; - window.location.replace('/onboarding'); - } - }); - xhr.setRequestHeader('Authorization', `Bearer ${idToken}`); - xhr.send(); - }); - }) - .catch((error) => { - const errorCode = error.code; - const errorMessage = error.message; - // handle each error - if (errorCode === 'auth/invalid-credential') { - toast.error('Invalid credentials.'); - } - if (errorCode === 'auth/invalid-email') { - toast.error('Invalid email.'); - } - if (errorCode === 'auth/invalid-password') { - toast.error('Invalid password.'); - } - - - }); - } else { - toast.error("Passwords do not match."); + async function handleSuccess(data) { + console.log("Setting account by google"); + setAccountType('GOOGLE'); + const { credential } = data; + const decode = jwtDecode(credential); + setEmail(decode.email); + const exists = await emailExists(decode.email); + if(!exists) { + toast.error('Email already exists.'); + return; } + setPassword(''); + setShowOnboarding(true); + } + + async function handleError(data) { + console.log(data); + toast.error('Account failed to create.'); } + return ( <> - - Sign Up - CTFGuide - - - - - - -
-
-
- -
- -
-
-
-
-
-

- Something went wrong. -

-
-
-
- -

Get started on

- - CTFGuide -

CTFGuide

- -
-

- + + Dashboard - CTFGuide + + +

+
+ +
+
+ + ) : ( + <> + + Sign Up - CTFGuide + + + +
+
- Already have an account? - -

- -
- -
-
- -
- -
- - - - { - setPassword(e.target.value); - if (!userHasEdited) setUserHasEdited(true); // Set to true on first edit - }} - className="block w-full appearance-none rounded-sm border border-gray-300 px-3 py-2 text-white placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm" - /> - {userHasEdited && validationMessage && ( -
- {validationMessage} -
- )} - - -
-
+
+
+
+
- -
- { - setCPassword(e.target.value); - }} - className="block w-full appearance-none rounded-sm border border-gray-300 px-3 py-2 text-white placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm" - /> - {userHasEdited && validationMessage2 && ( -
- {validationMessage2} -
- )} -
-
+
+
+
+

+ Something went wrong. +

+
+
+
+ +

Get started on

+ + CTFGuide +

CTFGuide

+ +
+

+ + Already have an account? + +

+ +
+ setEmail(e.target.value)} + name="email" + type="text" + autoComplete="email" + required + className="block w-full appearance-none rounded-sm border border-gray-300 px-3 py-2 text-white placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm" + /> +
+
+ +
+ +
+ + { + setPassword(e.target.value); + if (!userHasEdited) setUserHasEdited(true); // Set to true on first edit + }} + className="block w-full appearance-none rounded-sm border border-gray-300 px-3 py-2 text-white placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm" + /> + {userHasEdited && validationMessage && ( +
+ {validationMessage} +
+ )} + + +
+
+ + +
+ +
+ { + setCPassword(e.target.value); + }} + className="block w-full appearance-none rounded-sm border border-gray-300 px-3 py-2 text-white placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm" + /> + {userHasEdited && validationMessage2 && ( +
+ {validationMessage2} +
+ )} +
+
+ + +
+ +
+
+ +
+
+
+ handleSuccess(data)} + onFailure={(data) => handleError(data)} + text="signup_with" // Custom button text + theme="filled_black" // Optional: Choose between "default", "dark", or "light" themes + width="370" // Optional: Custom button width + /> +
+ +
+
+ + +
+ + - -
-
-
- - +
+
- - -
- -
-
-
- - + + + ) + } ); } +export default Register; diff --git a/src/pages/users/[user].jsx b/src/pages/users/[user].jsx index 4229118d..ef2fa6a4 100644 --- a/src/pages/users/[user].jsx +++ b/src/pages/users/[user].jsx @@ -1,19 +1,8 @@ -import firebase from 'firebase/app'; -// import { storage } from '../../config/firebaseConfig.js'; -import { - getStorage, - ref, - uploadBytesResumable, - getDownloadURL, -} from 'firebase/storage'; -import { app } from '../../config/firebaseConfig.js'; - import Markdown from 'react-markdown'; - // Kshitij import { Tooltip } from 'react-tooltip'; -import 'firebase/storage'; +// import 'firebase/storage'; import Head from 'next/head'; import React from 'react'; @@ -27,8 +16,6 @@ import PieChart from '@/components/profile/PieChart.jsx'; import Badge from '@/components/profile/Badge.jsx'; import Skeleton from 'react-loading-skeleton'; -import { Router } from 'react-router-dom'; -import { useRouter } from 'next/router'; import { Transition, Dialog } from '@headlessui/react'; import { Fragment } from 'react'; @@ -88,9 +75,7 @@ export default function Users() { const [openBio, setOpenBio] = useState(false); const [bioBanner, bannerState] = useState(false); const [tempBio, setTempBio] = useState(''); - const [badges, setbadges] = useState(null); - const [selectedBanner, setSelectedBanner] = useState(null); const [isBannerPopupOpen, setIsBannerPopupOpen] = useState(false); const [banner, setBanner] = useState( @@ -298,33 +283,6 @@ export default function Users() { fetchData(); }, [user]); - // check to see if user is logged in - useEffect(() => { - try { - fetch(`${process.env.NEXT_PUBLIC_API_URL}/account`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer ' + localStorage.getItem('idToken'), - }, - }) - .then((response) => response.json()) - .then((data) => { - if (data.error || !data.username) { - console.log('debug| user not logged in :('); - setIsLoggedIn(false); - } else { - setIsLoggedIn(true); - } - }) - .catch((err) => { - console.log(err); - console.log('debug| user not logged in :('); - setIsLoggedIn(false); - }); - } catch { } - }, []); - // Follower useEffect useEffect(() => { if (!user) { diff --git a/yarn.lock b/yarn.lock index 33b30d29..38d902f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -284,378 +284,6 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@firebase/analytics-compat@0.2.6": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.2.6.tgz#50063978c42f13eb800e037e96ac4b17236841f4" - integrity sha512-4MqpVLFkGK7NJf/5wPEEP7ePBJatwYpyjgJ+wQHQGHfzaCDgntOnl9rL2vbVGGKCnRqWtZDIWhctB86UWXaX2Q== - dependencies: - "@firebase/analytics" "0.10.0" - "@firebase/analytics-types" "0.8.0" - "@firebase/component" "0.6.4" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/analytics-types@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.8.0.tgz#551e744a29adbc07f557306530a2ec86add6d410" - integrity sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw== - -"@firebase/analytics@0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.10.0.tgz#9c6986acd573c6c6189ffb52d0fd63c775db26d7" - integrity sha512-Locv8gAqx0e+GX/0SI3dzmBY5e9kjVDtD+3zCFLJ0tH2hJwuCAiL+5WkHuxKj92rqQj/rvkBUCfA1ewlX2hehg== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/installations" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/app-check-compat@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.3.7.tgz#e150f61d653a0f2043a34dcb995616a717161839" - integrity sha512-cW682AxsyP1G+Z0/P7pO/WT2CzYlNxoNe5QejVarW2o5ZxeWSSPAiVEwpEpQR/bUlUmdeWThYTMvBWaopdBsqw== - dependencies: - "@firebase/app-check" "0.8.0" - "@firebase/app-check-types" "0.5.0" - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/app-check-interop-types@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz#b27ea1397cb80427f729e4bbf3a562f2052955c4" - integrity sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg== - -"@firebase/app-check-types@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check-types/-/app-check-types-0.5.0.tgz#1b02826213d7ce6a1cf773c329b46ea1c67064f4" - integrity sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ== - -"@firebase/app-check@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.8.0.tgz#b531ec40900af9c3cf1ec63de9094a0ddd733d6a" - integrity sha512-dRDnhkcaC2FspMiRK/Vbp+PfsOAEP6ZElGm9iGFJ9fDqHoPs0HOPn7dwpJ51lCFi1+2/7n5pRPGhqF/F03I97g== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/app-compat@0.2.13": - version "0.2.13" - resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.2.13.tgz#c42d392f45f2c9fef1631cb3ae36d53296aa6407" - integrity sha512-j6ANZaWjeVy5zg6X7uiqh6lM6o3n3LD1+/SJFNs9V781xyryyZWXe+tmnWNWPkP086QfJoNkWN9pMQRqSG4vMg== - dependencies: - "@firebase/app" "0.9.13" - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/app-types@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.9.0.tgz#35b5c568341e9e263b29b3d2ba0e9cfc9ec7f01e" - integrity sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q== - -"@firebase/app@0.9.13": - version "0.9.13" - resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.9.13.tgz#b1d3ad63d52f235a0d70a9b4261cabb3a24690d7" - integrity sha512-GfiI1JxJ7ecluEmDjPzseRXk/PX31hS7+tjgBopL7XjB2hLUdR+0FTMXy2Q3/hXezypDvU6or7gVFizDESrkXw== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - idb "7.1.1" - tslib "^2.1.0" - -"@firebase/auth-compat@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.4.2.tgz#cb65edc2fbd5f72fff32310409f2fd702b5145e7" - integrity sha512-Q30e77DWXFmXEt5dg5JbqEDpjw9y3/PcP9LslDPR7fARmAOTIY9MM6HXzm9KC+dlrKH/+p6l8g9ifJiam9mc4A== - dependencies: - "@firebase/auth" "0.23.2" - "@firebase/auth-types" "0.12.0" - "@firebase/component" "0.6.4" - "@firebase/util" "1.9.3" - node-fetch "2.6.7" - tslib "^2.1.0" - -"@firebase/auth-interop-types@0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz#78884f24fa539e34a06c03612c75f222fcc33742" - integrity sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg== - -"@firebase/auth-types@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.12.0.tgz#f28e1b68ac3b208ad02a15854c585be6da3e8e79" - integrity sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA== - -"@firebase/auth@0.23.2": - version "0.23.2" - resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.23.2.tgz#9e6d8dd550a28053c1825fb98c7dc9b37119254d" - integrity sha512-dM9iJ0R6tI1JczuGSxXmQbXAgtYie0K4WvKcuyuSTCu9V8eEDiz4tfa1sO3txsfvwg7nOY3AjoCyMYEdqZ8hdg== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - node-fetch "2.6.7" - tslib "^2.1.0" - -"@firebase/component@0.6.4": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.6.4.tgz#8981a6818bd730a7554aa5e0516ffc9b1ae3f33d" - integrity sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA== - dependencies: - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/database-compat@0.3.4": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-0.3.4.tgz#4e57932f7a5ba761cd5ac946ab6b6ab3f660522c" - integrity sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/database" "0.14.4" - "@firebase/database-types" "0.10.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/database-types@0.10.4": - version "0.10.4" - resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.10.4.tgz#47ba81113512dab637abace61cfb65f63d645ca7" - integrity sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ== - dependencies: - "@firebase/app-types" "0.9.0" - "@firebase/util" "1.9.3" - -"@firebase/database@0.14.4": - version "0.14.4" - resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.14.4.tgz#9e7435a16a540ddfdeb5d99d45618e6ede179aa6" - integrity sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ== - dependencies: - "@firebase/auth-interop-types" "0.2.1" - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - faye-websocket "0.11.4" - tslib "^2.1.0" - -"@firebase/firestore-compat@0.3.12": - version "0.3.12" - resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.3.12.tgz#c08b24c76da7af75598f3c28432b6eb22f959b56" - integrity sha512-mazuNGAx5Kt9Nph0pm6ULJFp/+j7GSsx+Ncw1GrnKl+ft1CQ4q2LcUssXnjqkX2Ry0fNGqUzC1mfIUrk9bYtjQ== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/firestore" "3.13.0" - "@firebase/firestore-types" "2.5.1" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/firestore-types@2.5.1": - version "2.5.1" - resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-2.5.1.tgz#464b2ee057956599ca34de50eae957c30fdbabb7" - integrity sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw== - -"@firebase/firestore@3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-3.13.0.tgz#f924a3bb462bc3ac666dc5d375f3f8c4e1a72345" - integrity sha512-NwcnU+madJXQ4fbLkGx1bWvL612IJN/qO6bZ6dlPmyf7QRyu5azUosijdAN675r+bOOJxMtP1Bv981bHBXAbUg== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - "@firebase/webchannel-wrapper" "0.10.1" - "@grpc/grpc-js" "~1.7.0" - "@grpc/proto-loader" "^0.6.13" - node-fetch "2.6.7" - tslib "^2.1.0" - -"@firebase/functions-compat@0.3.5": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.3.5.tgz#7a532d3a9764c6d5fbc1ec5541a989a704326647" - integrity sha512-uD4jwgwVqdWf6uc3NRKF8cSZ0JwGqSlyhPgackyUPe+GAtnERpS4+Vr66g0b3Gge0ezG4iyHo/EXW/Hjx7QhHw== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/functions" "0.10.0" - "@firebase/functions-types" "0.6.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/functions-types@0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.6.0.tgz#ccd7000dc6fc668f5acb4e6a6a042a877a555ef2" - integrity sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw== - -"@firebase/functions@0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.10.0.tgz#c630ddf12cdf941c25bc8d554e30c3226cd560f6" - integrity sha512-2U+fMNxTYhtwSpkkR6WbBcuNMOVaI7MaH3cZ6UAeNfj7AgEwHwMIFLPpC13YNZhno219F0lfxzTAA0N62ndWzA== - dependencies: - "@firebase/app-check-interop-types" "0.3.0" - "@firebase/auth-interop-types" "0.2.1" - "@firebase/component" "0.6.4" - "@firebase/messaging-interop-types" "0.2.0" - "@firebase/util" "1.9.3" - node-fetch "2.6.7" - tslib "^2.1.0" - -"@firebase/installations-compat@0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@firebase/installations-compat/-/installations-compat-0.2.4.tgz#b5557c897b4cd3635a59887a8bf69c3731aaa952" - integrity sha512-LI9dYjp0aT9Njkn9U4JRrDqQ6KXeAmFbRC0E7jI7+hxl5YmRWysq5qgQl22hcWpTk+cm3es66d/apoDU/A9n6Q== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/installations" "0.6.4" - "@firebase/installations-types" "0.5.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/installations-types@0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.5.0.tgz#2adad64755cd33648519b573ec7ec30f21fb5354" - integrity sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg== - -"@firebase/installations@0.6.4": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.6.4.tgz#20382e33e6062ac5eff4bede8e468ed4c367609e" - integrity sha512-u5y88rtsp7NYkCHC3ElbFBrPtieUybZluXyzl7+4BsIz4sqb4vSAuwHEUgCgCeaQhvsnxDEU6icly8U9zsJigA== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/util" "1.9.3" - idb "7.0.1" - tslib "^2.1.0" - -"@firebase/logger@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.4.0.tgz#15ecc03c452525f9d47318ad9491b81d1810f113" - integrity sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA== - dependencies: - tslib "^2.1.0" - -"@firebase/messaging-compat@0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.2.4.tgz#323ca48deef77065b4fcda3cfd662c4337dffcfd" - integrity sha512-lyFjeUhIsPRYDPNIkYX1LcZMpoVbBWXX4rPl7c/rqc7G+EUea7IEtSt4MxTvh6fDfPuzLn7+FZADfscC+tNMfg== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/messaging" "0.12.4" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/messaging-interop-types@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz#6056f8904a696bf0f7fdcf5f2ca8f008e8f6b064" - integrity sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ== - -"@firebase/messaging@0.12.4": - version "0.12.4" - resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.12.4.tgz#ccb49df5ab97d5650c9cf5b8c77ddc34daafcfe0" - integrity sha512-6JLZct6zUaex4g7HI3QbzeUrg9xcnmDAPTWpkoMpd/GoSVWH98zDoWXMGrcvHeCAIsLpFMe4MPoZkJbrPhaASw== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/installations" "0.6.4" - "@firebase/messaging-interop-types" "0.2.0" - "@firebase/util" "1.9.3" - idb "7.0.1" - tslib "^2.1.0" - -"@firebase/performance-compat@0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.4.tgz#95cbf32057b5d9f0c75d804bc50e6ed3ba486274" - integrity sha512-nnHUb8uP9G8islzcld/k6Bg5RhX62VpbAb/Anj7IXs/hp32Eb2LqFPZK4sy3pKkBUO5wcrlRWQa6wKOxqlUqsg== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/performance" "0.6.4" - "@firebase/performance-types" "0.2.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/performance-types@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.2.0.tgz#400685f7a3455970817136d9b48ce07a4b9562ff" - integrity sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA== - -"@firebase/performance@0.6.4": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.6.4.tgz#0ad766bfcfab4f386f4fe0bef43bbcf505015069" - integrity sha512-HfTn/bd8mfy/61vEqaBelNiNnvAbUtME2S25A67Nb34zVuCSCRIX4SseXY6zBnOFj3oLisaEqhVcJmVPAej67g== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/installations" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/remote-config-compat@0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.2.4.tgz#1f494c81a6c9560b1f9ca1b4fbd4bbbe47cf4776" - integrity sha512-FKiki53jZirrDFkBHglB3C07j5wBpitAaj8kLME6g8Mx+aq7u9P7qfmuSRytiOItADhWUj7O1JIv7n9q87SuwA== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/remote-config" "0.4.4" - "@firebase/remote-config-types" "0.3.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/remote-config-types@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz#689900dcdb3e5c059e8499b29db393e4e51314b4" - integrity sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA== - -"@firebase/remote-config@0.4.4": - version "0.4.4" - resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.4.4.tgz#6a496117054de58744bc9f382d2a6d1e14060c65" - integrity sha512-x1ioTHGX8ZwDSTOVp8PBLv2/wfwKzb4pxi0gFezS5GCJwbLlloUH4YYZHHS83IPxnua8b6l0IXUaWd0RgbWwzQ== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/installations" "0.6.4" - "@firebase/logger" "0.4.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/storage-compat@0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.3.2.tgz#51a97170fd652a516f729f82b97af369e5a2f8d7" - integrity sha512-wvsXlLa9DVOMQJckbDNhXKKxRNNewyUhhbXev3t8kSgoCotd1v3MmqhKKz93ePhDnhHnDs7bYHy+Qa8dRY6BXw== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/storage" "0.11.2" - "@firebase/storage-types" "0.8.0" - "@firebase/util" "1.9.3" - tslib "^2.1.0" - -"@firebase/storage-types@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.8.0.tgz#f1e40a5361d59240b6e84fac7fbbbb622bfaf707" - integrity sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg== - -"@firebase/storage@0.11.2": - version "0.11.2" - resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.11.2.tgz#c5e0316543fe1c4026b8e3910f85ad73f5b77571" - integrity sha512-CtvoFaBI4hGXlXbaCHf8humajkbXhs39Nbh6MbNxtwJiCqxPy9iH3D3CCfXAvP0QvAAwmJUTK3+z9a++Kc4nkA== - dependencies: - "@firebase/component" "0.6.4" - "@firebase/util" "1.9.3" - node-fetch "2.6.7" - tslib "^2.1.0" - -"@firebase/util@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.9.3.tgz#45458dd5cd02d90e55c656e84adf6f3decf4b7ed" - integrity sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA== - dependencies: - tslib "^2.1.0" - -"@firebase/webchannel-wrapper@0.10.1": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.1.tgz#60bb2aaf129f9e00621f8d698722ddba6ee1f8ac" - integrity sha512-Dq5rYfEpdeel0bLVN+nfD1VWmzCkK+pJbSjIawGE+RY4+NIJqhbUDDQjvV0NUK84fMfwxvtFoCtEe70HfZjFcw== - "@floating-ui/core@^1.5.3": version "1.5.3" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.3.tgz#b6aa0827708d70971c8679a16cf680a515b8a52a" @@ -741,36 +369,6 @@ dependencies: type-fest "^4.1.0" -"@grpc/grpc-js@~1.7.0": - version "1.7.3" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.7.3.tgz#f2ea79f65e31622d7f86d4b4c9ae38f13ccab99a" - integrity sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog== - dependencies: - "@grpc/proto-loader" "^0.7.0" - "@types/node" ">=12.12.47" - -"@grpc/proto-loader@^0.6.13": - version "0.6.13" - resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.13.tgz#008f989b72a40c60c96cd4088522f09b05ac66bc" - integrity sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g== - dependencies: - "@types/long" "^4.0.1" - lodash.camelcase "^4.3.0" - long "^4.0.0" - protobufjs "^6.11.3" - yargs "^16.2.0" - -"@grpc/proto-loader@^0.7.0": - version "0.7.8" - resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.8.tgz#c050bbeae5f000a1919507f195a1b094e218036e" - integrity sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA== - dependencies: - "@types/long" "^4.0.1" - lodash.camelcase "^4.3.0" - long "^4.0.0" - protobufjs "^7.2.4" - yargs "^17.7.2" - "@headlessui/react@^1.7.2": version "1.7.15" resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.15.tgz#53ef6ae132af81b8f188414767b6e79ebf8dc73f" @@ -1131,59 +729,6 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - "@puppeteer/browsers@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.0.0.tgz#3646d2a465c112eac21510d43b21c828612118f9" @@ -1197,6 +742,11 @@ unbzip2-stream "1.4.3" yargs "17.7.2" +"@react-oauth/google@^0.12.1": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@react-oauth/google/-/google-0.12.1.tgz#b76432c3a525e9afe076f787d2ded003fcc1bee9" + integrity sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg== + "@react-spring/animated@~9.7.3": version "9.7.3" resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.3.tgz#4211b1a6d48da0ff474a125e93c0f460ff816e0f" @@ -1379,11 +929,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== - "@types/marked@^4.0.7": version "4.3.1" resolved "https://registry.yarnpkg.com/@types/marked/-/marked-4.3.1.tgz#45fb6dfd47afb595766c71ed7749ead23f137de3" @@ -1408,11 +953,6 @@ dependencies: undici-types "~5.26.4" -"@types/node@>=12.12.47", "@types/node@>=13.7.0": - version "20.4.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" - integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== - "@types/node@>=8.1.0": version "20.8.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.3.tgz#c4ae2bb1cfab2999ed441a95c122bbbe1567a66d" @@ -1902,15 +1442,6 @@ client-only@0.0.1, client-only@^0.0.1: resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -2733,13 +2264,6 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -faye-websocket@0.11.4: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -2774,38 +2298,6 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -firebase@^9.16.0: - version "9.23.0" - resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.23.0.tgz#71fea60d704bfed8e92162911544fd6564a04d0e" - integrity sha512-/4lUVY0lUvBDIaeY1q6dUYhS8Sd18Qb9CgWkPZICUo9IXpJNCEagfNZXBBFCkMTTN5L5gx2Hjr27y21a9NzUcA== - dependencies: - "@firebase/analytics" "0.10.0" - "@firebase/analytics-compat" "0.2.6" - "@firebase/app" "0.9.13" - "@firebase/app-check" "0.8.0" - "@firebase/app-check-compat" "0.3.7" - "@firebase/app-compat" "0.2.13" - "@firebase/app-types" "0.9.0" - "@firebase/auth" "0.23.2" - "@firebase/auth-compat" "0.4.2" - "@firebase/database" "0.14.4" - "@firebase/database-compat" "0.3.4" - "@firebase/firestore" "3.13.0" - "@firebase/firestore-compat" "0.3.12" - "@firebase/functions" "0.10.0" - "@firebase/functions-compat" "0.3.5" - "@firebase/installations" "0.6.4" - "@firebase/installations-compat" "0.2.4" - "@firebase/messaging" "0.12.4" - "@firebase/messaging-compat" "0.2.4" - "@firebase/performance" "0.6.4" - "@firebase/performance-compat" "0.2.4" - "@firebase/remote-config" "0.4.4" - "@firebase/remote-config-compat" "0.2.4" - "@firebase/storage" "0.11.2" - "@firebase/storage-compat" "0.3.2" - "@firebase/util" "1.9.3" - flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -3085,11 +2577,6 @@ hoist-non-react-statics@^3.3.1: dependencies: react-is "^16.7.0" -http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - http-proxy-agent@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" @@ -3106,16 +2593,6 @@ https-proxy-agent@^7.0.2: agent-base "^7.0.2" debug "4" -idb@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.1.tgz#d2875b3a2f205d854ee307f6d196f246fea590a7" - integrity sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg== - -idb@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" - integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== - ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -3409,6 +2886,11 @@ jsonfile@^4.0.0: object.assign "^4.1.4" object.values "^1.1.6" +jwt-decode@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" + integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== + kleur@^4.0.3: version "4.1.5" resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" @@ -3451,11 +2933,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -3466,16 +2943,6 @@ lodash@^4.17.19, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@^5.0.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" - integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== - loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -3860,13 +3327,6 @@ next@^14.0.2: "@next/swc-win32-ia32-msvc" "14.0.4" "@next/swc-win32-x64-msvc" "14.0.4" -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - node-fetch@^2.6.12: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -4200,43 +3660,6 @@ property-information@^6.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d" integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== -protobufjs@^6.11.3: - version "6.11.3" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" - integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^4.0.0" - -protobufjs@^7.2.4: - version "7.2.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.4.tgz#3fc1ec0cdc89dd91aef9ba6037ba07408485c3ae" - integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/node" ">=13.7.0" - long "^5.0.0" - proxy-agent@6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.3.1.tgz#40e7b230552cf44fd23ffaf7c59024b692612687" @@ -4699,11 +4122,6 @@ safe-array-concat@^1.0.0: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@>=5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -5153,7 +4571,7 @@ tslib@^2.0.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tslib@^2.1.0, tslib@^2.4.0: +tslib@^2.4.0: version "2.6.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== @@ -5401,20 +4819,6 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== -websocket-driver@>=0.5.1: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -5506,17 +4910,12 @@ yaml@^2.1.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@17.7.2, yargs@^17.7.2: +yargs@17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -5529,19 +4928,6 @@ yargs@17.7.2, yargs@^17.7.2: y18n "^5.0.5" yargs-parser "^21.1.1" -yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"