From b5da1dfb1b8613a760758c02bb60abc564afe8a2 Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sat, 17 Feb 2024 20:55:46 -0500 Subject: [PATCH 01/15] Set up Firebase-Admin in adminInit.ts (#155) * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * added passport * started auth + admin sdk * removed passport * added private key to gitignore * Delete server/private_keys/private.json --------- Co-authored-by: AlexanderWangY --- client/package-lock.json | 153 ++- .../Auth/AuthenticationResponse.tsx | 101 +- client/src/components/Auth/LoginScreen.tsx | 15 +- client/src/configs/firebaseConfig.ts | 8 +- client/src/contexts/LocationContext.tsx | 6 +- client/src/contexts/SocketContext.tsx | 5 +- client/src/services/store.ts | 5 +- server/.gitignore | 3 + server/package-lock.json | 937 +++++++++++++++++- server/package.json | 1 + server/src/index.ts | 5 + server/src/tests/socketio.test.ts | 2 +- server/src/utilities/adminInit.ts | 9 + 13 files changed, 1088 insertions(+), 162 deletions(-) create mode 100644 server/src/utilities/adminInit.ts diff --git a/client/package-lock.json b/client/package-lock.json index 720fd9652..853ac67d0 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -28,7 +28,7 @@ "firebase": "^10.7.2", "pullstate": "^1.25.0", "react": "18.2.0", - "react-native": "0.72.10", + "react-native": "0.72.6", "react-native-dotenv": "^3.4.9", "react-native-fs": "^2.20.0", "react-native-safe-area-context": "4.6.3", @@ -4641,19 +4641,19 @@ } }, "node_modules/@react-native-community/cli": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.10.tgz", - "integrity": "sha512-bIx0t5s9ewH1PlcEcuQUD+UnVrCjPGAfjhVR5Gew565X60nE+GTIHRn70nMv9G4he/amBF+Z+vf5t8SNZEWMwg==", - "dependencies": { - "@react-native-community/cli-clean": "11.3.10", - "@react-native-community/cli-config": "11.3.10", - "@react-native-community/cli-debugger-ui": "11.3.10", - "@react-native-community/cli-doctor": "11.3.10", - "@react-native-community/cli-hermes": "11.3.10", - "@react-native-community/cli-plugin-metro": "11.3.10", - "@react-native-community/cli-server-api": "11.3.10", - "@react-native-community/cli-tools": "11.3.10", - "@react-native-community/cli-types": "11.3.10", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.7.tgz", + "integrity": "sha512-Ou8eDlF+yh2rzXeCTpMPYJ2fuqsusNOhmpYPYNQJQ2h6PvaF30kPomflgRILems+EBBuggRtcT+I+1YH4o/q6w==", + "dependencies": { + "@react-native-community/cli-clean": "11.3.7", + "@react-native-community/cli-config": "11.3.7", + "@react-native-community/cli-debugger-ui": "11.3.7", + "@react-native-community/cli-doctor": "11.3.7", + "@react-native-community/cli-hermes": "11.3.7", + "@react-native-community/cli-plugin-metro": "11.3.7", + "@react-native-community/cli-server-api": "11.3.7", + "@react-native-community/cli-tools": "11.3.7", + "@react-native-community/cli-types": "11.3.7", "chalk": "^4.1.2", "commander": "^9.4.1", "execa": "^5.0.0", @@ -4671,11 +4671,11 @@ } }, "node_modules/@react-native-community/cli-clean": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-11.3.10.tgz", - "integrity": "sha512-g6QjW+DSqoWRHzmIQW3AH22k1AnynWuOdy2YPwYEGgPddTeXZtJphIpEVwDOiC0L4mZv2VmiX33/cGNUwO0cIA==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-11.3.7.tgz", + "integrity": "sha512-twtsv54ohcRyWVzPXL3F9VHGb4Qhn3slqqRs3wEuRzjR7cTmV2TIO2b1VhaqF4HlCgNd+cGuirvLtK2JJyaxMg==", "dependencies": { - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "execa": "^5.0.0", "prompts": "^2.4.0" @@ -4877,11 +4877,11 @@ } }, "node_modules/@react-native-community/cli-config": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-11.3.10.tgz", - "integrity": "sha512-YYu14nm1JYLS6mDRBz78+zDdSFudLBFpPkhkOoj4LuBhNForQBIqFFHzQbd9/gcguJxfW3vlYSnudfaUI7oGLg==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-11.3.7.tgz", + "integrity": "sha512-FDBLku9xskS+bx0YFJFLCmUJhEZ4/MMSC9qPYOGBollWYdgE7k/TWI0IeYFmMALAnbCdKQAYP5N29N55Tad8lg==", "dependencies": { - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "cosmiconfig": "^5.1.0", "deepmerge": "^4.3.0", @@ -4954,22 +4954,22 @@ } }, "node_modules/@react-native-community/cli-debugger-ui": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.3.10.tgz", - "integrity": "sha512-kyitGV3RsjlXIioq9lsuawha2GUBPCTAyXV6EBlm3qlyF3dMniB3twEvz+fIOid/e1ZeucH3Tzy5G3qcP8yWoA==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-11.3.7.tgz", + "integrity": "sha512-aVmKuPKHZENR8SrflkMurZqeyLwbKieHdOvaZCh1Nn/0UC5CxWcyST2DB2XQboZwsvr3/WXKJkSUO+SZ1J9qTQ==", "dependencies": { "serve-static": "^1.13.1" } }, "node_modules/@react-native-community/cli-doctor": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-11.3.10.tgz", - "integrity": "sha512-DpMsfCWKZ15L9nFK/SyDvpl5v6MjV+arMHMC1i8kR+DOmf2xWmp/pgMywKk0/u50yGB9GwxBHt3i/S/IMK5Ylg==", - "dependencies": { - "@react-native-community/cli-config": "11.3.10", - "@react-native-community/cli-platform-android": "11.3.10", - "@react-native-community/cli-platform-ios": "11.3.10", - "@react-native-community/cli-tools": "11.3.10", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-11.3.7.tgz", + "integrity": "sha512-YEHUqWISOHnsl5+NM14KHelKh68Sr5/HeEZvvNdIcvcKtZic3FU7Xd1WcbNdo3gCq5JvzGFfufx02Tabh5zmrg==", + "dependencies": { + "@react-native-community/cli-config": "11.3.7", + "@react-native-community/cli-platform-android": "11.3.7", + "@react-native-community/cli-platform-ios": "11.3.7", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "command-exists": "^1.2.8", "envinfo": "^7.7.2", @@ -5315,12 +5315,12 @@ } }, "node_modules/@react-native-community/cli-hermes": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-11.3.10.tgz", - "integrity": "sha512-vqINuzAlcHS9ImNwJtT43N7kfBQ7ro9A8O1Gpc5TQ0A8V36yGG8eoCHeauayklVVgMZpZL6f6mcoLLr9IOgBZQ==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-11.3.7.tgz", + "integrity": "sha512-chkKd8n/xeZkinRvtH6QcYA8rjNOKU3S3Lw/3Psxgx+hAYV0Gyk95qJHTalx7iu+PwjOOqqvCkJo5jCkYLkoqw==", "dependencies": { - "@react-native-community/cli-platform-android": "11.3.10", - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-platform-android": "11.3.7", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "hermes-profile-transformer": "^0.0.6", "ip": "^1.1.5" @@ -5391,11 +5391,11 @@ } }, "node_modules/@react-native-community/cli-platform-android": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-11.3.10.tgz", - "integrity": "sha512-RGu9KuDIXnrcNkacSHj5ETTQtp/D/835L6veE2jMigO21p//gnKAjw3AVLCysGr8YXYfThF8OSOALrwNc94puQ==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-11.3.7.tgz", + "integrity": "sha512-WGtXI/Rm178UQb8bu1TAeFC/RJvYGnbHpULXvE20GkmeJ1HIrMjkagyk6kkY3Ej25JAP2R878gv+TJ/XiRhaEg==", "dependencies": { - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "execa": "^5.0.0", "glob": "^7.1.3", @@ -5598,11 +5598,11 @@ } }, "node_modules/@react-native-community/cli-platform-ios": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.3.10.tgz", - "integrity": "sha512-JjduMrBM567/j4Hvjsff77dGSLMA0+p9rr0nShlgnKPcc+0J4TDy0hgWpUceM7OG00AdDjpetAPupz0kkAh4cQ==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-11.3.7.tgz", + "integrity": "sha512-Z/8rseBput49EldX7MogvN6zJlWzZ/4M97s2P+zjS09ZoBU7I0eOKLi0N9wx+95FNBvGQQ/0P62bB9UaFQH2jw==", "dependencies": { - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "execa": "^5.0.0", "fast-xml-parser": "^4.0.12", @@ -5866,12 +5866,12 @@ } }, "node_modules/@react-native-community/cli-plugin-metro": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.3.10.tgz", - "integrity": "sha512-ZYAc5Hc+QVqJgj1XFbpKnIPbSJ9xKcBnfQrRhR+jFyt2DWx85u4bbzY1GSVc/USs0UbSUXv4dqPbnmOJz52EYQ==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-11.3.7.tgz", + "integrity": "sha512-0WhgoBVGF1f9jXcuagQmtxpwpfP+2LbLZH4qMyo6OtYLWLG13n2uRep+8tdGzfNzl1bIuUTeE9yZSAdnf9LfYQ==", "dependencies": { - "@react-native-community/cli-server-api": "11.3.10", - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-server-api": "11.3.7", + "@react-native-community/cli-tools": "11.3.7", "chalk": "^4.1.2", "execa": "^5.0.0", "metro": "0.76.8", @@ -6079,12 +6079,12 @@ } }, "node_modules/@react-native-community/cli-server-api": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-11.3.10.tgz", - "integrity": "sha512-WEwHWIpqx3gA6Da+lrmq8+z78E1XbxxjBlvHAXevhjJj42N4SO417eZiiUVrFzEFVVJSUee9n9aRa0kUR+0/2w==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-11.3.7.tgz", + "integrity": "sha512-yoFyGdvR3HxCnU6i9vFqKmmSqFzCbnFSnJ29a+5dppgPRetN+d//O8ard/YHqHzToFnXutAFf2neONn23qcJAg==", "dependencies": { - "@react-native-community/cli-debugger-ui": "11.3.10", - "@react-native-community/cli-tools": "11.3.10", + "@react-native-community/cli-debugger-ui": "11.3.7", + "@react-native-community/cli-tools": "11.3.7", "compression": "^1.7.1", "connect": "^3.6.5", "errorhandler": "^1.5.1", @@ -6115,9 +6115,9 @@ } }, "node_modules/@react-native-community/cli-tools": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-11.3.10.tgz", - "integrity": "sha512-4kCuCwVcGagSrNg9vxMNVhynwpByuC/J5UnKGEet3HuqmoDhQW15m18fJXiehA8J+u9WBvHduefy9nZxO0C06Q==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-11.3.7.tgz", + "integrity": "sha512-peyhP4TV6Ps1hk+MBHTFaIR1eI3u+OfGBvr5r0wPwo3FAJvldRinMgcB/TcCcOBXVORu7ba1XYjkubPeYcqAyA==", "dependencies": { "appdirsjs": "^1.2.4", "chalk": "^4.1.2", @@ -6326,9 +6326,9 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/@react-native-community/cli-types": { - "version": "11.3.10", - "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-11.3.10.tgz", - "integrity": "sha512-0FHK/JE7bTn0x1y8Lk5m3RISDHIBQqWLltO2Mf7YQ6cAeKs8iNOJOeKaHJEY+ohjsOyCziw+XSC4cY57dQrwNA==", + "version": "11.3.7", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-11.3.7.tgz", + "integrity": "sha512-OhSr/TiDQkXjL5YOs8+hvGSB+HltLn5ZI0+A3DCiMsjUgTTsYh+Z63OtyMpNjrdCEFcg0MpfdU2uxstCS6Dc5g==", "dependencies": { "joi": "^17.2.1" } @@ -9658,13 +9658,13 @@ } }, "node_modules/deprecated-react-native-prop-types": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-4.2.3.tgz", - "integrity": "sha512-2rLTiMKidIFFYpIVM69UnQKngLqQfL6I11Ch8wGSBftS18FUXda+o2we2950X+1dmbgps28niI3qwyH4eX3Z1g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-4.1.0.tgz", + "integrity": "sha512-WfepZHmRbbdTvhcolb8aOKEvQdcmTMn5tKLbqbXmkBvjFjRVWAYqsXk/DBsV8TZxws8SdGHLuHaJrHSQUPRdfw==", "dependencies": { - "@react-native/normalize-colors": "<0.73.0", - "invariant": "^2.2.4", - "prop-types": "^15.8.1" + "@react-native/normalize-colors": "*", + "invariant": "*", + "prop-types": "*" } }, "node_modules/destroy": { @@ -17536,25 +17536,24 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-native": { - "version": "0.72.10", - "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.72.10.tgz", - "integrity": "sha512-AjVA1+hCm2VMk3KE9Ve5IeDR3aneEhhQJmBAM9xP3i2WqqS3GksxCz8+JdB83bV6x9mBLv5qPMP71vCged3USw==", + "version": "0.72.6", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.72.6.tgz", + "integrity": "sha512-RafPY2gM7mcrFySS8TL8x+TIO3q7oAlHpzEmC7Im6pmXni6n1AuufGaVh0Narbr1daxstw7yW7T9BKW5dpVc2A==", "dependencies": { "@jest/create-cache-key-function": "^29.2.1", - "@react-native-community/cli": "11.3.10", - "@react-native-community/cli-platform-android": "11.3.10", - "@react-native-community/cli-platform-ios": "11.3.10", + "@react-native-community/cli": "11.3.7", + "@react-native-community/cli-platform-android": "11.3.7", + "@react-native-community/cli-platform-ios": "11.3.7", "@react-native/assets-registry": "^0.72.0", - "@react-native/codegen": "^0.72.8", + "@react-native/codegen": "^0.72.7", "@react-native/gradle-plugin": "^0.72.11", "@react-native/js-polyfills": "^0.72.1", "@react-native/normalize-colors": "^0.72.0", "@react-native/virtualized-lists": "^0.72.8", "abort-controller": "^3.0.0", "anser": "^1.4.9", - "ansi-regex": "^5.0.0", "base64-js": "^1.1.2", - "deprecated-react-native-prop-types": "^4.2.3", + "deprecated-react-native-prop-types": "4.1.0", "event-target-shim": "^5.0.1", "flow-enums-runtime": "^0.0.5", "invariant": "^2.2.4", diff --git a/client/src/components/Auth/AuthenticationResponse.tsx b/client/src/components/Auth/AuthenticationResponse.tsx index cb74702f5..081a12640 100644 --- a/client/src/components/Auth/AuthenticationResponse.tsx +++ b/client/src/components/Auth/AuthenticationResponse.tsx @@ -1,16 +1,18 @@ import React from "react"; -import { StyleSheet, Text, Dimensions, TouchableOpacity} from "react-native"; +import { StyleSheet, Text, Dimensions, TouchableOpacity } from "react-native"; import { FirebaseError } from "firebase/app"; import { User } from "firebase/auth"; //Type to handle Authentication Responses from firebase -export type AuthenticationResponse = { - user: User | null; - error?: undefined; -} | { - user?: undefined; - error: unknown; -} +export type AuthenticationResponse = + | { + user: User | null; + error?: undefined; + } + | { + user?: undefined; + error: unknown; + }; export class CustomError { public code: string; @@ -23,79 +25,81 @@ export class CustomError { } //Custom responses -export const inValidEmailResponse = new CustomError("Invalid Email", "Please provide a valid email address") +export const inValidEmailResponse = new CustomError( + "Invalid Email", + "Please provide a valid email address" +); //Function that decodes the error code const decodeFirebaseError = (error: FirebaseError) => { - if(error.code === "auth/missing-email" || error.code === "auth/invalid-email") { - return "Please provide a valid email address"; - } - - if(error.code === "auth/weak-password") { - return "Password must be 6 characters or more"; - } - - if(error.code === "auth/missing-password") { - return "Please provide a password"; + switch (error.code) { + case "auth/missing-email" || "auth/invalid-email": + return "Please provide a valid email address"; + case "auth/weak-password": + return "Password must be 6 characters or more"; + case "auth/missing-password": + return "Please provide a password"; + case "auth/invalid-credential": + return "The password or email is incorrect"; + case "auth/too-many-requests": + return "Too many requests, please try again later"; + default: + return "Unknown error"; } - - if(error.code === "auth/invalid-credential") { - return "The password or email is incorrect"; - } - - return "Unknown error" -} +}; const decodeCustomError = (error: CustomError) => { return error.message; -} +}; //Function that handles the response depending on type -function handleResponse(response: AuthenticationResponse) { - if(response?.user) { +const handleResponse = (response: AuthenticationResponse) => { + if (response?.user) { + // If the user is not undefined return ""; } - console.log(response.error) - - if(response.error instanceof FirebaseError) { + if (response.error instanceof FirebaseError) { + // If the error is a firebase error return decodeFirebaseError(response.error); } - - if(response.error instanceof CustomError) { + // If the error is a custom error + if (response.error instanceof CustomError) { + // If the error is a custom error return decodeCustomError(response.error); } - return "Unknown error" -} + return "Unknown error"; +}; -//Something +// Authentication Message Component Props interface AuthenticationErrorMessageProps { response: AuthenticationResponse | undefined; onPress?: () => void; } -export const AuthenticationErrorMessage: React.FC = ({ response, onPress }) => { - if( response === undefined ) { +export const AuthenticationErrorMessage: React.FC< + AuthenticationErrorMessageProps +> = ({ response, onPress }) => { + if (response === undefined) { return null; } - const errorMessage = handleResponse(response) + const errorMessage = handleResponse(response); return ( - errorMessage && - + errorMessage && ( + {errorMessage} - + + ) ); -} - +}; const styles = StyleSheet.create({ error_text: { color: "white", fontSize: Dimensions.get("window").height * 0.02, - }, error_container: { display: "flex", @@ -106,7 +110,6 @@ const styles = StyleSheet.create({ marginTop: Dimensions.get("window").height * 0.005, width: Dimensions.get("window").width * 0.9, borderRadius: 10, - padding: 10 - } + padding: 10, + }, }); - diff --git a/client/src/components/Auth/LoginScreen.tsx b/client/src/components/Auth/LoginScreen.tsx index 477af597c..d6bb18018 100644 --- a/client/src/components/Auth/LoginScreen.tsx +++ b/client/src/components/Auth/LoginScreen.tsx @@ -27,17 +27,23 @@ const LoginScreen = () => { const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const [authResponse, setAuthResponse] = React.useState(); - const [invalidLogin, invalidateLogin] = React.useState(false); + const [invalidLogin, invalidateLogin] = React.useState(false); // Possbily change this? + // Sign in function with email and password const onHandleSubmit = async () => { + Keyboard.dismiss(); setAuthResponse(await appSignIn(email, password)); + }; + + // Listens for the response from the sign in function + useEffect(() => { if (authResponse?.user) { router.replace("(home)/chatchannel"); } else if (authResponse?.error) { console.log(authResponse.error); invalidateLogin(true); } - }; + }, [authResponse]) useEffect(() => { setEmail(inputEmail?.toString() || ""); // On load of the page, set the email to the inputEmail if they entered it! @@ -76,7 +82,10 @@ const LoginScreen = () => { - setAuthResponse(undefined)} /> + { + setAuthResponse(undefined) + invalidateLogin(false) + }} /> diff --git a/client/src/configs/firebaseConfig.ts b/client/src/configs/firebaseConfig.ts index 28f8c1b95..0468e3797 100644 --- a/client/src/configs/firebaseConfig.ts +++ b/client/src/configs/firebaseConfig.ts @@ -6,10 +6,10 @@ import {API_KEY, AUTH_DOMAIN, PROJECT_ID, STORAGE_BUCKET, MESSAGING_SENDER_ID, A const firebaseConfig = { apiKey: API_KEY || "Mock-Key", authDomain: AUTH_DOMAIN, - projectId: PROJECT_ID, - storageBucket: STORAGE_BUCKET, - messagingSenderId: MESSAGING_SENDER_ID, - appId: APP_ID, + // projectId: PROJECT_ID, + // storageBucket: STORAGE_BUCKET, + // messagingSenderId: MESSAGING_SENDER_ID, + // appId: APP_ID, }; let app; diff --git a/client/src/contexts/LocationContext.tsx b/client/src/contexts/LocationContext.tsx index 95150db64..6c571c9a8 100644 --- a/client/src/contexts/LocationContext.tsx +++ b/client/src/contexts/LocationContext.tsx @@ -17,9 +17,9 @@ const LocationContext = createContext(null); const getLocation = async () => { return await Location.getCurrentPositionAsync({ - accuracy: Location.Accuracy.Balanced + accuracy: Location.Accuracy.Balanced, }); // Change accuracy while testing. Could become .env variable. -} +}; export const useLocation = () => { return useContext(LocationContext); @@ -66,7 +66,7 @@ export const LocationProvider = ({ } catch (error) { console.error("Error fetching location:", error); } - }, Number(LOCATION_REFRESH_RATE)); // Send location every few seconds + }, Number(LOCATION_REFRESH_RATE)); // Fetch location every 3 seconds // Cleanup function to clear interval when component unmounts return () => clearInterval(interval); diff --git a/client/src/contexts/SocketContext.tsx b/client/src/contexts/SocketContext.tsx index 118035845..3ecdb1521 100644 --- a/client/src/contexts/SocketContext.tsx +++ b/client/src/contexts/SocketContext.tsx @@ -1,6 +1,5 @@ import React, { createContext, useContext, useEffect, useState } from "react"; import { io, Socket } from "socket.io-client"; -import * as Network from "expo-network"; import { useLocation } from "./LocationContext"; import { EXPO_IP } from "@env"; @@ -17,7 +16,7 @@ export const SocketProvider = ({ children }: { children: React.ReactNode }) => { useEffect(() => { let isMounted = true; - const socketIo = io(`http://${EXPO_IP}:8080`); // Hardcoded IP address + const socketIo = io(`http://${ EXPO_IP }:8080`); // Hardcoded IP address socketIo.on("connect", () => { if (isMounted) { @@ -34,7 +33,7 @@ export const SocketProvider = ({ children }: { children: React.ReactNode }) => { return () => { isMounted = false; - socket?.disconnect(); + socketIo.disconnect(); }; }, []); diff --git a/client/src/services/store.ts b/client/src/services/store.ts index f748dd7d7..77536358f 100644 --- a/client/src/services/store.ts +++ b/client/src/services/store.ts @@ -1,7 +1,6 @@ import { User, createUserWithEmailAndPassword, onAuthStateChanged, signInWithEmailAndPassword, signOut } from 'firebase/auth' import { Store } from 'pullstate' -import { auth, app } from '../configs/firebaseConfig' -import { FirebaseError } from 'firebase/app'; +import { auth } from '../configs/firebaseConfig' interface AuthStoreInterface { isLoggedin: boolean, @@ -31,7 +30,7 @@ export const appSignIn = async (email: string, password: string) => { store.user = response?.user; store.isLoggedin = response?.user ? true : false; }); - + console.log('appSignIn', await response.user.getIdToken()); // This is the token we need to send to the server return { user: auth.currentUser }; } catch (e) { return { error: e }; diff --git a/server/.gitignore b/server/.gitignore index 59a9766a7..81da29c6f 100644 --- a/server/.gitignore +++ b/server/.gitignore @@ -132,6 +132,9 @@ dist # Build files build +# Private Key JSON +./private_key/* + # Other .env build/ diff --git a/server/package-lock.json b/server/package-lock.json index 52a5aafd3..d8bb07258 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -14,6 +14,7 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "firebase": "^10.5.0", + "firebase-admin": "^12.0.0", "geofire-common": "^6.0.0", "socket.io": "^4.7.4", "uuid": "^9.0.1" @@ -2297,6 +2298,101 @@ "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.5.tgz", "integrity": "sha512-eSkJsnhBWv5kCTSU1tSUVl9mpFu+5NXXunZc83le8GMjMlsWwQArSc7cJJ4yl+aDFY0NGLi0AjZWMn1axOrkRg==" }, + "node_modules/@google-cloud/firestore": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.3.0.tgz", + "integrity": "sha512-2IftQLAbCuVp0nTd3neeu+d3OYIegJpV/V9R4USQj51LzJcXPe8h8jZ7j3+svSNhJVGy6JsN0T1QqlJdMDhTwg==", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.0.4", + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", + "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz", + "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "compressible": "^2.0.12", + "duplexify": "^4.0.0", + "ent": "^2.2.0", + "fast-xml-parser": "^4.3.0", + "gaxios": "^6.0.2", + "google-auth-library": "^9.0.0", + "mime": "^3.0.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@grpc/grpc-js": { "version": "1.9.14", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.14.tgz", @@ -3110,6 +3206,15 @@ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -3179,17 +3284,21 @@ "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" } }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "optional": true + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -3211,7 +3320,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -3223,7 +3331,6 @@ "version": "4.17.43", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3243,8 +3350,7 @@ "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", @@ -3280,11 +3386,24 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "optional": true + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { "version": "20.11.17", @@ -3297,20 +3416,43 @@ "node_modules/@types/qs": { "version": "6.9.11", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", - "dev": true + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "optional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -3320,7 +3462,6 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -3333,6 +3474,12 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "optional": true + }, "node_modules/@types/yargs": { "version": "17.0.32", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", @@ -3354,6 +3501,18 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "optional": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -3387,6 +3546,18 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "optional": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -3455,6 +3626,24 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3692,6 +3881,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -3700,6 +3909,15 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3808,6 +4026,11 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4001,6 +4224,18 @@ "node": ">= 0.8" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "optional": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4299,6 +4534,26 @@ "url": "https://dotenvx.com" } }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4335,6 +4590,15 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/engine.io": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", @@ -4384,6 +4648,12 @@ "node": ">= 0.6" } }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "optional": true + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4464,6 +4734,15 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -4566,12 +4845,46 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "optional": true + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fast-xml-parser": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.4.tgz", + "integrity": "sha512-utnwm92SyozgA3hhH2I8qldf2lBqm6qHOICawRNRFu1qMe3+oqr+GcXjGqTmXTMGE5T4eC03kr/rlh5C1IRdZA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -4680,6 +4993,39 @@ "@firebase/util": "1.9.4" } }, + "node_modules/firebase-admin": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-12.0.0.tgz", + "integrity": "sha512-wBrrSSsKV++/+O8E7O/C7/wL0nbG/x4Xv4yatz/+sohaZ+LsnWtYUcrd3gZutO86hLpDex7xgyrkKbgulmtVyQ==", + "dependencies": { + "@fastify/busboy": "^1.2.1", + "@firebase/database-compat": "^1.0.2", + "@firebase/database-types": "^1.0.0", + "@types/node": "^20.10.3", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.0.1", + "node-forge": "^1.3.1", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.1.0", + "@google-cloud/storage": "^7.7.0" + } + }, + "node_modules/firebase-admin/node_modules/@fastify/busboy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", + "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", + "dependencies": { + "text-decoding": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/follow-redirects": { "version": "1.15.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", @@ -4756,6 +5102,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "optional": true + }, + "node_modules/gaxios": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.2.0.tgz", + "integrity": "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ==", + "optional": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "optional": true, + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4858,6 +5238,80 @@ "node": ">=4" } }, + "node_modules/google-auth-library": { + "version": "9.6.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.6.3.tgz", + "integrity": "sha512-4CacM29MLC2eT9Cey5GDVK4Q8t+MMp8+OEdOaqD9MG6b0dOyLORaaeJMPQ7EESVgm/+z5EKYyFLxgzBJlJgyHQ==", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-gax": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.1.tgz", + "integrity": "sha512-qpSfslpwqToIgQ+Tf3MjWIDjYK4UFIZ0uz6nLtttlW9N1NQA4PhGf9tlGo6KDYJ4rgL2w4CjXVd0z5yeNpN/Iw==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "~1.10.0", + "@grpc/proto-loader": "^0.7.0", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.0", + "protobufjs": "7.2.6", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/@grpc/grpc-js": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.1.tgz", + "integrity": "sha512-55ONqFytZExfOIjF1RjXPcVmT/jJqFzbbDqxK9jmRV4nxiYWtL9hENSW1Jfx0SdZfrvoqd44YJ/GJTqfRrawSQ==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -4875,6 +5329,40 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "optional": true, + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/gtoken/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gtoken/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -4954,6 +5442,45 @@ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "optional": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -5117,7 +5644,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=8" }, @@ -6828,6 +7355,14 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jose": { + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6859,6 +7394,15 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -6877,6 +7421,92 @@ "node": ">=6" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -6895,6 +7525,11 @@ "node": ">=6" } }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -6918,12 +7553,52 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -6938,6 +7613,29 @@ "yallist": "^3.0.2" } }, + "node_modules/lru-memoizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", + "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -7111,6 +7809,34 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -7228,6 +7954,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -7251,7 +7986,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, + "devOptional": true, "dependencies": { "wrappy": "1" } @@ -7275,7 +8010,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, + "devOptional": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7464,6 +8199,18 @@ "node": ">= 6" } }, + "node_modules/proto3-json-serializer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", + "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/protobufjs": { "version": "7.2.6", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", @@ -7504,6 +8251,11 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -7568,6 +8320,20 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7706,6 +8472,29 @@ "node": ">=10" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8025,6 +8814,30 @@ "node": ">= 0.8" } }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -8092,6 +8905,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "optional": true + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -8116,6 +8941,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -8130,6 +8996,11 @@ "node": ">=8" } }, + "node_modules/text-decoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", + "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==" + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -8177,6 +9048,12 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -8371,6 +9248,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "optional": true + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -8428,6 +9311,12 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -8449,6 +9338,16 @@ "node": ">=0.8.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8514,7 +9413,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "devOptional": true }, "node_modules/write-file-atomic": { "version": "4.0.2", @@ -8610,7 +9509,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">=10" }, diff --git a/server/package.json b/server/package.json index c4dfdf3d6..39f4fcfb7 100644 --- a/server/package.json +++ b/server/package.json @@ -29,6 +29,7 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "firebase": "^10.5.0", + "firebase-admin": "^12.0.0", "geofire-common": "^6.0.0", "socket.io": "^4.7.4", "uuid": "^9.0.1" diff --git a/server/src/index.ts b/server/src/index.ts index 69e9b98f6..926864984 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -13,10 +13,14 @@ import { deleteConnectedUserByIndex } from './actions/deleteConnectedUser' import {geohashForLocation} from 'geofire-common'; import { findNearbyUsers } from './actions/getConnectedUsers' import { ConnectedUser } from './types/User'; +import { adminApp } from './utilities/adminInit'; const { createServer } = require('http') const { Server } = require('socket.io') +adminApp.firestore() + + const socket_port = process.env.socket_port const express_port = process.env.express_port const app = express() @@ -25,6 +29,7 @@ app.use(express.json()) app.use(express.urlencoded({ extended: true })) + // === SOCKET API === const socketServer = createServer() const io = new Server(socketServer, { diff --git a/server/src/tests/socketio.test.ts b/server/src/tests/socketio.test.ts index 4efb99a8e..878ec7f79 100644 --- a/server/src/tests/socketio.test.ts +++ b/server/src/tests/socketio.test.ts @@ -33,7 +33,7 @@ const connectClients = async () => { for (let i = 0; i < NUM_CLIENTS; i++) { const client = io(`http://localhost:${socket_test_client_port}`); - await new Promise(resolve => client.on('connect', resolve)); // Why is this an error? IDK + await new Promise(resolve => client.on('connect', resolve)); // Why is this an error? IDK clients.push(client); } diff --git a/server/src/utilities/adminInit.ts b/server/src/utilities/adminInit.ts new file mode 100644 index 000000000..a262efbd6 --- /dev/null +++ b/server/src/utilities/adminInit.ts @@ -0,0 +1,9 @@ +const { initializeApp } = require('firebase-admin/app'); +const admin = require('firebase-admin'); +const serviceAccount = require("../../src/private_key/.json"); + +export const adminApp = admin.initializeApp({ + credential: admin.credential.cert(serviceAccount) +}); + +console.log("[FIREBASE-ADMIN] Firebase admin SDK synced.") \ No newline at end of file From 386b64611a5fb83058094f077890477920ed702b Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:26:39 -0500 Subject: [PATCH 02/15] Refactored most of the actions (#156) * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * added passport * started auth + admin sdk * removed passport * added private key to gitignore * Delete server/private_keys/private.json * initializing firestore in admin * finished most of action refactoring * Made error case for email in use display correctly in front end (#158) * changed getConnectedUsers to admin * migrated to firebase-admin --------- Co-authored-by: AlexanderWangY Co-authored-by: Mohammed Ali <146048575+Phantom0110@users.noreply.github.com> --- .../Auth/AuthenticationResponse.tsx | 4 +- server/package-lock.json | 680 ++++++------------ server/package.json | 1 - server/src/actions/createConnectedUser.ts | 9 +- server/src/actions/createMessage.ts | 6 +- server/src/actions/deleteConnectedUser.ts | 17 +- server/src/actions/getConnectedUsers.ts | 31 +- server/src/actions/updateConnectedUser.ts | 25 +- server/src/index.ts | 28 +- server/src/private_key/private.json | 13 + server/src/utilities/adminInit.ts | 9 +- server/src/utilities/firebaseInit.ts | 28 - 12 files changed, 283 insertions(+), 568 deletions(-) create mode 100644 server/src/private_key/private.json delete mode 100644 server/src/utilities/firebaseInit.ts diff --git a/client/src/components/Auth/AuthenticationResponse.tsx b/client/src/components/Auth/AuthenticationResponse.tsx index 081a12640..041d7b4b8 100644 --- a/client/src/components/Auth/AuthenticationResponse.tsx +++ b/client/src/components/Auth/AuthenticationResponse.tsx @@ -43,10 +43,12 @@ const decodeFirebaseError = (error: FirebaseError) => { return "The password or email is incorrect"; case "auth/too-many-requests": return "Too many requests, please try again later"; + case "auth/email-already-in-use": + return "Email already in use"; default: return "Unknown error"; } -}; +} const decodeCustomError = (error: CustomError) => { return error.message; diff --git a/server/package-lock.json b/server/package-lock.json index d8bb07258..564e301cd 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -13,7 +13,6 @@ "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", - "firebase": "^10.5.0", "firebase-admin": "^12.0.0", "geofire-common": "^6.0.0", "socket.io": "^4.7.4", @@ -1805,169 +1804,21 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@firebase/analytics": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.1.tgz", - "integrity": "sha512-5mnH1aQa99J5lZMJwTNzIoRc4yGXHf+fOn+EoEWhCDA3XGPweGHcylCbqq+G1wVJmfILL57fohDMa8ftMZ+44g==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/analytics-compat": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.7.tgz", - "integrity": "sha512-17VCly4P0VFBDqaaal7m1nhyYQwsygtaTpSsnc51sFPRrr9XIYtnD8ficon9fneEGEoJQ2g7OtASvhwX9EbK8g==", - "dependencies": { - "@firebase/analytics": "0.10.1", - "@firebase/analytics-types": "0.8.0", - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/analytics-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.0.tgz", - "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==" - }, - "node_modules/@firebase/app": { - "version": "0.9.27", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.27.tgz", - "integrity": "sha512-p2Dvl1ge4kRsyK5+wWcmdAIE9MSwZ0pDKAYB51LZgZuz6wciUZk4E1yAEdkfQlRxuHehn+Ol9WP5Qk2XQZiHGg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "idb": "7.1.1", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/app-check": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.2.tgz", - "integrity": "sha512-A2B5+ldOguYAeqW1quFN5qNdruSNRrg4W59ag1Eq6QzxuHNIkrE+TrapfrW/z5NYFjCxAYqr/unVCgmk80Dwcg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/app-check-compat": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.9.tgz", - "integrity": "sha512-7LxyupQ8XeEHRh72mO+tqm69kHT6KbWi2KtFMGedJ6tNbwzFzojcXESMKN8RpADXbYoQgY3loWMJjMx4r2Zt7w==", - "dependencies": { - "@firebase/app-check": "0.8.2", - "@firebase/app-check-types": "0.5.0", - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, "node_modules/@firebase/app-check-interop-types": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" }, - "node_modules/@firebase/app-check-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.0.tgz", - "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==" - }, - "node_modules/@firebase/app-compat": { - "version": "0.2.27", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.27.tgz", - "integrity": "sha512-SYlqocfUDKPHR6MSFC8hree0BTiWFu5o8wbf6zFlYXyG41w7TcHp4wJi4H/EL5V6cM4kxwruXTJtqXX/fRAZtw==", - "dependencies": { - "@firebase/app": "0.9.27", - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - } - }, "node_modules/@firebase/app-types": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" }, - "node_modules/@firebase/auth": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.6.0.tgz", - "integrity": "sha512-Qhl35eJTV6BwvuueTPCY6x8kUlYyzALtjp/Ws0X3fw3AnjVVfuVb7oQ3Xh5VPVfMFhaIuUAd1KXwcAuIklkSDw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.26.5" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" - }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } - } - }, - "node_modules/@firebase/auth-compat": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.2.tgz", - "integrity": "sha512-pRgje5BPCNR1vXyvGOVXwOHtv88A2WooXfklI8sV7/jWi03ExFqNfpJT26GUo/oD39NoKJ3Kt6rD5gVvdV7lMw==", - "dependencies": { - "@firebase/auth": "1.6.0", - "@firebase/auth-types": "0.12.0", - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.26.5" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" }, - "node_modules/@firebase/auth-types": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", - "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, "node_modules/@firebase/component": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", @@ -2013,125 +1864,6 @@ "@firebase/util": "1.9.4" } }, - "node_modules/@firebase/firestore": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.4.2.tgz", - "integrity": "sha512-YaX6ypa/RzU6OkxzUQlpSxwhOIWdTraCNz7sMsbaSEjjl/pj/QvX6TqjkdWGzuBYh2S6rz7ErhDO0g39oZZw/g==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "@firebase/webchannel-wrapper": "0.10.5", - "@grpc/grpc-js": "~1.9.0", - "@grpc/proto-loader": "^0.7.8", - "tslib": "^2.1.0", - "undici": "5.26.5" - }, - "engines": { - "node": ">=10.10.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/firestore-compat": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.25.tgz", - "integrity": "sha512-+xI7WmsgZCBhMn/+uhDKcg+lsOUJ9FJyt5PGTzkFPbCsozWfeQZ7eVnfPh0rMkUOf0yIQ924RIe04gwvEIbcoQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/firestore": "4.4.2", - "@firebase/firestore-types": "3.0.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/firestore-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.0.tgz", - "integrity": "sha512-Meg4cIezHo9zLamw0ymFYBD4SMjLb+ZXIbuN7T7ddXN6MGoICmOTq3/ltdCGoDCS2u+H1XJs2u/cYp75jsX9Qw==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/functions": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.1.tgz", - "integrity": "sha512-3uUa1hB79Gmy6E1gHTfzoHeZolBeHc/I/n3+lOCDe6BOos9AHmzRjKygcFE/7VA2FJjitCE0K+OHI6+OuoY8fQ==", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.0", - "@firebase/auth-interop-types": "0.2.1", - "@firebase/component": "0.6.5", - "@firebase/messaging-interop-types": "0.2.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.26.5" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/functions-compat": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.7.tgz", - "integrity": "sha512-uXe6Kmku5lNogp3OpPBcOJbSvnaCOn+YxS3zlXKNU6Q/NLwcvO3RY1zwYyctCos2RemEw3KEQ7YdzcECXjHWLw==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/functions": "0.11.1", - "@firebase/functions-types": "0.6.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/functions-types": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.0.tgz", - "integrity": "sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==" - }, - "node_modules/@firebase/installations": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.5.tgz", - "integrity": "sha512-0xxnQWw8rSRzu0ZOCkZaO+MJ0LkDAfwwTB2Z1SxRK6FAz5xkxD1ZUwM0WbCRni49PKubCrZYOJ6yg7tSjU7AKA==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/installations-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.5.tgz", - "integrity": "sha512-usvoIaog5CHEw082HXLrKAZ1qd4hIC3N/LDe2NqBgI3pkGE/7auLVM4Gn5gvyryp0x8z/IP1+d9fkGUj2OaGLQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/installations-types": "0.5.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/installations-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.0.tgz", - "integrity": "sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==", - "peerDependencies": { - "@firebase/app-types": "0.x" - } - }, "node_modules/@firebase/logger": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", @@ -2140,157 +1872,98 @@ "tslib": "^2.1.0" } }, - "node_modules/@firebase/messaging": { - "version": "0.12.6", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.6.tgz", - "integrity": "sha512-IORsPp9IPWq4j4yEhTOZ6GAGi3gQwGc+4yexmTAlya+qeBRSdRnJg2iIU/aj+tcKDQYr9RQuQPgHHOdFIx//vA==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/messaging-interop-types": "0.2.0", - "@firebase/util": "1.9.4", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" - } - }, - "node_modules/@firebase/messaging-compat": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.6.tgz", - "integrity": "sha512-Q2xC1s4L7Vpss7P7Gy6GuIS+xmJrf/vm9+gX76IK1Bo1TjoKwleCLHt1LHkPz5Rvqg5pTgzzI8qqPhBpZosFCg==", + "node_modules/@firebase/util": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", + "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/messaging": "0.12.6", - "@firebase/util": "1.9.4", "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" } }, - "node_modules/@firebase/messaging-interop-types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", - "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==" - }, - "node_modules/@firebase/performance": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.5.tgz", - "integrity": "sha512-OzAGcWhOqEFH9GdwUuY0oC5FSlnMejcnmSAhR+EjpI7exdDvixyLyCR4txjSHYNTbumrFBG+EP8GO11CNXRaJA==", + "node_modules/@google-cloud/firestore": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.3.0.tgz", + "integrity": "sha512-2IftQLAbCuVp0nTd3neeu+d3OYIegJpV/V9R4USQj51LzJcXPe8h8jZ7j3+svSNhJVGy6JsN0T1QqlJdMDhTwg==", + "optional": true, "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.0.4", + "protobufjs": "^7.2.5" }, - "peerDependencies": { - "@firebase/app": "0.x" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@firebase/performance-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.5.tgz", - "integrity": "sha512-jJwJkVyDcIMBaVGrZ6CRGs4m5FCZsWB5QCWYI3FdsHyIa9/TfteNDilxj9wGciF2naFIHDW7TgE69U5dAH9Ktg==", + "node_modules/@google-cloud/paginator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", + "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", + "optional": true, "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/performance": "0.6.5", - "@firebase/performance-types": "0.2.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" + "arrify": "^2.0.0", + "extend": "^3.0.2" }, - "peerDependencies": { - "@firebase/app-compat": "0.x" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@firebase/performance-types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.0.tgz", - "integrity": "sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==" - }, - "node_modules/@firebase/remote-config": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.5.tgz", - "integrity": "sha512-rGLqc/4OmxrS39RA9kgwa6JmgWytQuMo+B8pFhmGp3d++x2Hf9j+MLQfhOLyyUo64fNw20J19mLXhrXvKHsjZQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/installations": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x" + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "optional": true, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@firebase/remote-config-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.5.tgz", - "integrity": "sha512-ImkNnLuGrD/bylBHDJigSY6LMwRrwt37wQbsGZhWG4QQ6KLzHzSf0nnFRRFvkOZodEUE57Ib8l74d6Yn/6TDUQ==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/remote-config": "0.4.5", - "@firebase/remote-config-types": "0.3.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app-compat": "0.x" + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "optional": true, + "engines": { + "node": ">=14" } }, - "node_modules/@firebase/remote-config-types": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.0.tgz", - "integrity": "sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==" - }, - "node_modules/@firebase/storage": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.12.1.tgz", - "integrity": "sha512-KJ5NV7FUh54TeTlEjdkTTX60ciCKOp9EqlbLnpdcXUYRJg0Z4810TXbilPc1z7fTIG4iPjtdi95bGE9n4dBX8A==", + "node_modules/@google-cloud/storage": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz", + "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==", + "optional": true, "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0", - "undici": "5.26.5" + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "compressible": "^2.0.12", + "duplexify": "^4.0.0", + "ent": "^2.2.0", + "fast-xml-parser": "^4.3.0", + "gaxios": "^6.0.2", + "google-auth-library": "^9.0.0", + "mime": "^3.0.0", + "mime-types": "^2.0.8", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" }, - "peerDependencies": { - "@firebase/app": "0.x" + "engines": { + "node": ">=14" } }, - "node_modules/@firebase/storage-compat": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.4.tgz", - "integrity": "sha512-Y0m5e2gS/wB9Ioth2X/Sgz76vcxvqgQrCmfa9qwhss/N31kxY2Gks6Frv0nrE18AjVfcSmcfDitqUwxcMOTRSg==", - "dependencies": { - "@firebase/component": "0.6.5", - "@firebase/storage": "0.12.1", - "@firebase/storage-types": "0.8.0", - "@firebase/util": "1.9.4", - "tslib": "^2.1.0" + "node_modules/@google-cloud/storage/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "optional": true, + "bin": { + "mime": "cli.js" }, - "peerDependencies": { - "@firebase/app-compat": "0.x" - } - }, - "node_modules/@firebase/storage-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.0.tgz", - "integrity": "sha512-isRHcGrTs9kITJC0AVehHfpraWFui39MPaU7Eo8QfWlqW7YPymBmRgjDrlOgFdURh6Cdeg07zmkLP5tzTKRSpg==", - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/util": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", - "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", - "dependencies": { - "tslib": "^2.1.0" + "engines": { + "node": ">=10.0.0" } }, "node_modules/@firebase/webchannel-wrapper": { @@ -2409,6 +2082,7 @@ "version": "0.7.10", "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "optional": true, "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", @@ -3126,27 +2800,32 @@ "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "optional": true }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "optional": true }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "optional": true }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "optional": true }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -3155,27 +2834,32 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "optional": true }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "optional": true }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "optional": true }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "optional": true }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "optional": true }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -3577,6 +3261,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, "engines": { "node": ">=8" } @@ -4173,6 +3858,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "devOptional": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -4580,7 +4266,8 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true }, "node_modules/encodeurl": { "version": "1.0.2", @@ -4686,6 +4373,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "devOptional": true, "engines": { "node": ">=6" } @@ -4960,37 +4648,37 @@ "node": ">=8" } }, - "node_modules/firebase": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-10.8.0.tgz", - "integrity": "sha512-UJpC24vw8JFuHEOQyArBGKTUd7+kohLISCzHyn0M/prP0KOTx2io1eyLliEid330QqnWI7FOlPxoU97qecCSfQ==", + "node_modules/firebase-admin": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-12.0.0.tgz", + "integrity": "sha512-wBrrSSsKV++/+O8E7O/C7/wL0nbG/x4Xv4yatz/+sohaZ+LsnWtYUcrd3gZutO86hLpDex7xgyrkKbgulmtVyQ==", "dependencies": { - "@firebase/analytics": "0.10.1", - "@firebase/analytics-compat": "0.2.7", - "@firebase/app": "0.9.27", - "@firebase/app-check": "0.8.2", - "@firebase/app-check-compat": "0.3.9", - "@firebase/app-compat": "0.2.27", - "@firebase/app-types": "0.9.0", - "@firebase/auth": "1.6.0", - "@firebase/auth-compat": "0.5.2", - "@firebase/database": "1.0.3", - "@firebase/database-compat": "1.0.3", - "@firebase/firestore": "4.4.2", - "@firebase/firestore-compat": "0.3.25", - "@firebase/functions": "0.11.1", - "@firebase/functions-compat": "0.3.7", - "@firebase/installations": "0.6.5", - "@firebase/installations-compat": "0.2.5", - "@firebase/messaging": "0.12.6", - "@firebase/messaging-compat": "0.2.6", - "@firebase/performance": "0.6.5", - "@firebase/performance-compat": "0.2.5", - "@firebase/remote-config": "0.4.5", - "@firebase/remote-config-compat": "0.2.5", - "@firebase/storage": "0.12.1", - "@firebase/storage-compat": "0.3.4", - "@firebase/util": "1.9.4" + "@fastify/busboy": "^1.2.1", + "@firebase/database-compat": "^1.0.2", + "@firebase/database-types": "^1.0.0", + "@types/node": "^20.10.3", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.0.1", + "node-forge": "^1.3.1", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.1.0", + "@google-cloud/storage": "^7.7.0" + } + }, + "node_modules/firebase-admin/node_modules/@fastify/busboy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", + "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", + "dependencies": { + "text-decoding": "^1.0.0" + }, + "engines": { + "node": ">=14" } }, "node_modules/firebase-admin": { @@ -5154,6 +4842,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -5312,6 +5001,80 @@ "node": "^8.13.0 || >=10.10.0" } }, + "node_modules/google-auth-library": { + "version": "9.6.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.6.3.tgz", + "integrity": "sha512-4CacM29MLC2eT9Cey5GDVK4Q8t+MMp8+OEdOaqD9MG6b0dOyLORaaeJMPQ7EESVgm/+z5EKYyFLxgzBJlJgyHQ==", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-gax": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.1.tgz", + "integrity": "sha512-qpSfslpwqToIgQ+Tf3MjWIDjYK4UFIZ0uz6nLtttlW9N1NQA4PhGf9tlGo6KDYJ4rgL2w4CjXVd0z5yeNpN/Iw==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "~1.10.0", + "@grpc/proto-loader": "^0.7.0", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.0", + "protobufjs": "7.2.6", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/@grpc/grpc-js": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.1.tgz", + "integrity": "sha512-55ONqFytZExfOIjF1RjXPcVmT/jJqFzbbDqxK9jmRV4nxiYWtL9hENSW1Jfx0SdZfrvoqd44YJ/GJTqfRrawSQ==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5501,11 +5264,6 @@ "node": ">=0.10.0" } }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -5606,6 +5364,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, "engines": { "node": ">=8" } @@ -7551,7 +7310,13 @@ "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", @@ -7602,7 +7367,8 @@ "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true }, "node_modules/lru-cache": { "version": "5.1.1", @@ -8216,6 +7982,7 @@ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", "hasInstallScript": true, + "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -8421,6 +8188,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8855,6 +8623,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8868,6 +8637,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -9154,17 +8924,6 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, - "node_modules/undici": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", - "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -9367,6 +9126,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -9383,6 +9143,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -9397,6 +9158,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -9407,7 +9169,8 @@ "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "node_modules/wrappy": { "version": "1.0.2", @@ -9461,6 +9224,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true, "engines": { "node": ">=10" } @@ -9475,6 +9239,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "devOptional": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -9492,6 +9257,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "devOptional": true, "engines": { "node": ">=12" } diff --git a/server/package.json b/server/package.json index 39f4fcfb7..9af60ca12 100644 --- a/server/package.json +++ b/server/package.json @@ -28,7 +28,6 @@ "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", - "firebase": "^10.5.0", "firebase-admin": "^12.0.0", "geofire-common": "^6.0.0", "socket.io": "^4.7.4", diff --git a/server/src/actions/createConnectedUser.ts b/server/src/actions/createConnectedUser.ts index 218606f46..d06cf6854 100644 --- a/server/src/actions/createConnectedUser.ts +++ b/server/src/actions/createConnectedUser.ts @@ -1,14 +1,11 @@ // Uploads a new document in the ConnectedUsers collection. -import { doc, setDoc } from '@firebase/firestore' -import { connectedUsers } from '../utilities/firebaseInit' import { ConnectedUser } from '../types/User' +import { connectedUsersCollection } from '../utilities/adminInit'; export const createUser = async (connectedUser: ConnectedUser) => { try { - const ref = doc(connectedUsers, connectedUser.socketId) // Use the socketid as the index - await setDoc(ref, connectedUser) - return true - + await connectedUsersCollection.doc(connectedUser.socketId).set(connectedUser) + console.log('User added to the database') } catch (error) { console.error(error.message) return false diff --git a/server/src/actions/createMessage.ts b/server/src/actions/createMessage.ts index 944e6c1e9..8494db672 100644 --- a/server/src/actions/createMessage.ts +++ b/server/src/actions/createMessage.ts @@ -1,12 +1,10 @@ // Uploads a new document in the Messages collection. -import { doc, setDoc } from '@firebase/firestore' -import { messages } from '../utilities/firebaseInit' import { Message } from '../types/Message' +import { messagesCollection } from '../utilities/adminInit' export const createMessage = async (msg : Message) => { try { - const ref = doc(messages, msg.msgId) - const status = await setDoc(ref, msg) + await messagesCollection.doc(msg.msgId).set(msg) return true } catch (error) { diff --git a/server/src/actions/deleteConnectedUser.ts b/server/src/actions/deleteConnectedUser.ts index 6cf469360..a6a968780 100644 --- a/server/src/actions/deleteConnectedUser.ts +++ b/server/src/actions/deleteConnectedUser.ts @@ -1,20 +1,9 @@ // Delete a ConnectedUser document given a document's index. This should typically be a socketId, but it can also be something else. -import { doc, getDoc, deleteDoc } from '@firebase/firestore' -import { connectedUsers } from '../utilities/firebaseInit' +import { connectedUsersCollection } from '../utilities/adminInit' -export const deleteConnectedUserByIndex = async (index: string) => { +export const deleteConnectedUserByUID = async (socketID: string) => { try { - const userRef = doc(connectedUsers, index) - - // The promise returned by deleteDoc will be fulfilled (aka return 'true') both if the document requested for deletion exists or doesn't exist. It is rejected if the program is unable to send this request to Firestore. - // Therefore, we need to check to see if the document exists first, to most accurately know if it will be deleted. - // However, technically, there could be some kind of failure by deleteDoc after this check is performed, where the status of the deletion would then be inaccurately returned. - // TODO: find a way to assuredly know if a document is deleted after deleteDoc is called. - - const userDoc = await getDoc(userRef) - if (!userDoc.exists()) throw Error("[FIREBASE] User does not exist.") - - await deleteDoc(userRef) + await connectedUsersCollection.doc(socketID).delete() return true } catch (error) { diff --git a/server/src/actions/getConnectedUsers.ts b/server/src/actions/getConnectedUsers.ts index a3258abe6..c2567abd0 100644 --- a/server/src/actions/getConnectedUsers.ts +++ b/server/src/actions/getConnectedUsers.ts @@ -1,6 +1,5 @@ -import { doc, endAt, getDocs, orderBy, query, startAt } from 'firebase/firestore' -import { connectedUsers } from '../utilities/firebaseInit' import { distanceBetween, geohashForLocation, geohashQueryBounds } from 'geofire-common' +import { connectedUsersCollection } from '../utilities/adminInit' export const findNearbyUsers = async (centerLat: number, centerLon: number, radius: number) => { // Return an array of nearby userIds (which are also socket ids) given a center latitude and longitude. @@ -18,21 +17,21 @@ export const findNearbyUsers = async (centerLat: number, centerLon: number, radi const promises = [] for (const b of bounds) { - const q = query( - connectedUsers, - orderBy('location.geohash'), - startAt(b[0]), - endAt(b[1]) - ) - - promises.push(getDocs(q)) + const q = connectedUsersCollection + .orderBy('location.geohash') + .startAt(b[0]) + .endAt(b[1]) + + promises.push(q.get()) } // Collect query results and append into a single array const snapshots = await Promise.all(promises) const matchingDocs = [] + for (const snap of snapshots) { + for (const doc of snap.docs) { const lat = doc.get('location.lat') const lon = doc.get('location.lon') @@ -42,18 +41,14 @@ export const findNearbyUsers = async (centerLat: number, centerLon: number, radi const distanceInKm = distanceBetween([lat, lon], [centerLat, centerLon]) const distanceInM = distanceInKm * 1000 if (distanceInM <= radius) { - matchingDocs.push(doc) + matchingDocs.push(doc.get('socketId')) } } } - // Extract userIds from matched documents - const userSocketIds = [] - for (const doc of matchingDocs) { - userSocketIds.push(doc.data()['socketId']) - } - console.log(`getNearbyUsers(): ${userSocketIds.length} users found within ${radius} meters of ${centerLat}, ${centerLon}`) - return userSocketIds + console.log(`getNearbyUsers(): ${matchingDocs.length} users found within ${radius} meters of ${centerLat}, ${centerLon}`) + console.log(matchingDocs) + return matchingDocs } catch (error) { console.error("getNearbyUsers() failed.", error.message) } diff --git a/server/src/actions/updateConnectedUser.ts b/server/src/actions/updateConnectedUser.ts index c151a4d47..c935ae7c6 100644 --- a/server/src/actions/updateConnectedUser.ts +++ b/server/src/actions/updateConnectedUser.ts @@ -1,38 +1,25 @@ -import { doc, getDoc, updateDoc } from '@firebase/firestore' -import { connectedUsers } from '../utilities/firebaseInit' import { geohashForLocation} from 'geofire-common' +import { connectedUsersCollection } from '../utilities/adminInit' -export const toggleUserConnectionStatus = async (index: string) => { +export const toggleUserConnectionStatus = async (socketID: string) => { try { - const userRef = doc(connectedUsers, index) - const userDoc = await getDoc(userRef) - - if (!userDoc.exists()) throw Error("[FIREBASE] User does not exist.") - - let status = userDoc.data()['isConnected'] - + let status = connectedUsersCollection.doc(socketID).isConnected // Flip the connection status status = !status - updateDoc(userRef, { isConnected: status }) + await connectedUsersCollection.doc(socketID).update({ isConnected: status }) return true - } catch (error) { console.error(error.message) return false } } -export const updateUserLocation = async (userIndex: string, lat: number, lon: number) => { +export const updateUserLocation = async (socketID: string, lat: number, lon: number) => { try { - const ref = doc(connectedUsers, userIndex) - const userDoc = await getDoc(ref) - - if (!userDoc.exists()) throw Error("[FIREBASE] User does not exist.") - const newHash = geohashForLocation([lat, lon]) - updateDoc(ref, { "location.lat": lat, "location.lon": lon, "location.geohash": newHash }) + await connectedUsersCollection.doc(socketID).update({ "location.lat": lat, "location.lon": lon, "location.geohash": newHash }) return true } catch (error) { console.error(error.message) diff --git a/server/src/index.ts b/server/src/index.ts index 926864984..0d5d275af 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -1,30 +1,24 @@ import express from 'express' import 'dotenv/config' import 'geofire-common' - import { Message } from './types/Message'; - import { createMessage } from './actions/createMessage' -// import { deleteMessageById } from './actions/deleteMessage' -// import { getUserById } from './actions/getUsers' import { createUser } from './actions/createConnectedUser' import { toggleUserConnectionStatus, updateUserLocation } from './actions/updateConnectedUser' -import { deleteConnectedUserByIndex } from './actions/deleteConnectedUser' +import { deleteConnectedUserByUID } from './actions/deleteConnectedUser' import {geohashForLocation} from 'geofire-common'; import { findNearbyUsers } from './actions/getConnectedUsers' import { ConnectedUser } from './types/User'; import { adminApp } from './utilities/adminInit'; + const { createServer } = require('http') const { Server } = require('socket.io') - -adminApp.firestore() - - const socket_port = process.env.socket_port const express_port = process.env.express_port const app = express() +// Middleware app.use(express.json()) app.use(express.urlencoded({ extended: true })) @@ -39,7 +33,7 @@ const io = new Server(socketServer, { }, }); -io.on('connection', (socket: any) => { +io.on('connection', async (socket: any) => { console.log(`[WS] User <${socket.id}> connected.`); const defaultConnectedUser: ConnectedUser = { uid: "UID", @@ -55,12 +49,12 @@ io.on('connection', (socket: any) => { geohash: "F" } } // TODO: Send this info from client on connection - createUser(defaultConnectedUser) - toggleUserConnectionStatus(socket.id) + await createUser(defaultConnectedUser) + await toggleUserConnectionStatus(socket.id) socket.on('disconnect', () => { console.log(`[WS] User <${socket.id}> exited.`); - deleteConnectedUserByIndex(socket.id) + deleteConnectedUserByUID(socket.id) }) socket.on('ping', (ack) => { // The (ack) parameter stands for "acknowledgement." This function sends a message back to the originating socket. @@ -103,11 +97,11 @@ io.on('connection', (socket: any) => { console.error("[WS] Error sending message:", error.message) } }) - socket.on('updateLocation', async (message, ack) => { + socket.on('updateLocation', async (location, ack) => { console.log(`[WS] Recieved new location from user <${socket.id}>.`) try { - const lat = Number(message.lat) - const lon = Number(message.lon) + const lat = Number(location.lat) + const lon = Number(location.lon) const success = await updateUserLocation(socket.id, lat, lon) if (success) { console.log("[WS] Location updated in database successfully.") @@ -217,7 +211,7 @@ app.delete('/users', async (req, res) => { const userId = req.query.userId if (typeof userId != "string") throw Error(" [userId] is not a string.") - const success = await deleteConnectedUserByIndex(userId) + const success = await deleteConnectedUserByUID(userId) if (!success) throw Error(" deleteUserById() failed.") console.log(`[EXP] Request returned successfully.`) diff --git a/server/src/private_key/private.json b/server/src/private_key/private.json new file mode 100644 index 000000000..02095340f --- /dev/null +++ b/server/src/private_key/private.json @@ -0,0 +1,13 @@ +{ + "type": "service_account", + "project_id": "fir-auth-89462", + "private_key_id": "770edc7187f5ef3d35359b9ad2304570d4f170ff", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCS6oM6wYwCp7a\nCXauPpBDjLzqq5PrMZCWOoi2THjqTzLJQc/Xwg5XlOyRX1DB4Uzl1iutfLsQXNuv\nMRze3i2jIOLysnrkvSuLW9n19k/1gIYYm7oxZQPaJ5iNJ33GFiNJqULlmMTvv6vp\nhXOOUZxl9dNY3HRpICcaGNPXjAv3tG7W+iHsidphp88Q8OMMmkZcl3+h2Hc1yDEf\nmXPR0YynfakDi45tMf5F9x3jRT6y6O30PSpZUIVL2cfwWs+zojnK+vy+cGCjBIJE\n/uI+A7XJJ4BWNLH/jhy6Jta/jDkCj/JbUsxRTX2ZuUeVi8uSMkzdy/Pb+o5f4SaJ\nl3mTa7S5AgMBAAECggEAEIChdwMrxX8TbrC81TAga/JbVeHAmKp/LblXRQeSAhG7\nvisSMpDLi84M+UxzlSIUGFXkZBH65/kBGjxVR8subGN1zzgQVtcH6KhipwDWmgMi\ncJriecFLDleMXhnXdZCKCv6+vTZIbNYWbYlNjy4YlvLmEm84DnlCBPYMoStGlXFm\nRKEfLl4FHHmCRcRkuGWRyKk9LtKNykrlaFVZ3BL11/TC38BlK3us+1cyUO3dA1EW\njAYSRG3tAVGVS7VUoxDDcA1V+Wnccpt+ws/rzIVYcTXawXrpHXFx977FwarGHReL\nmRmjHYGo/4Ry+q8Nk1y7GkdPYxq5GVAtXuRqSx7EgQKBgQD86ru/bBxJZxNAuHTE\nx9j/n0MrH9ulAFEzAXzq12Yf2xSytrUbD31zPg+rrFTGDNYISUPKSa9sxpC/jiwB\nXmuNhFVvt1521naZOtyezo3RYztcwOIxscvULHMUt/ikaFVsytlxrqDn0MJXuKM/\n5OZbbolc5pR3Oi82FOz09xB+OQKBgQDEqf5ox6V8ZfrMdFvhKC0EklyfDjClrJa2\nCkE0HK9ePxCpnEqBYC8wj6pXNOnLONYNZIjJ7Nz2CiFd0gIt7Ep9KtDNve99dWHR\nObPbt9fC8vMuzotBN6P345hzdqXR7OUUfAPFBCZTysWrfHzqg1tFYkt5t+YVfWuu\nMRq/xpzqgQKBgQC00Af7eQnb/EHKYlSwngNn9G8rtHHty4VBhs3MgsOzAIgSoAZn\n2zIfon3HiMNud5zIfcBmLTmp9WdkWvrg26Tenn4KCTkSko5lS6yQKDFBQcUdsZPE\nXUzQWhrH9CJhP2nbBkZgPK0yLY/S8OBc/IMnWKYBcaMwfbtk2Z7yHnN/GQKBgClH\ndTsRDM87qJTZp59vC2P2RLKuC8/6lffH1z/U9YpWumyffZQCWGVdAmgjlx8s4uEU\nxRF9QjPylGZY+lQhUNFM9174CxjOVqXP8syfng4xaJHekKQzxZr2jr1NniieDMdr\n8G6eHF1iJnOEQcQHplS9+RGnZAgGt19styyhx7YBAoGBAN++OfEq6S8zW/+Q9E8x\nAxvdNrFOkHnJf+URwTZQNFebvRUDouYjHE1fOCSM7npkNFV/DyINTsP6cNGKwGXM\nox1ODGb2uLk3hEQLDbqocIoWnuzY2QU3lubrSdAnEUDBovjd4of47BwYo2HfA+Pu\nTuLU4vtbFvSH7e3OJ9A//cKD\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-f0nzi@fir-auth-89462.iam.gserviceaccount.com", + "client_id": "102183968562626917121", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-f0nzi%40fir-auth-89462.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" +} diff --git a/server/src/utilities/adminInit.ts b/server/src/utilities/adminInit.ts index a262efbd6..a96ac473c 100644 --- a/server/src/utilities/adminInit.ts +++ b/server/src/utilities/adminInit.ts @@ -1,9 +1,12 @@ -const { initializeApp } = require('firebase-admin/app'); const admin = require('firebase-admin'); -const serviceAccount = require("../../src/private_key/.json"); +const serviceAccount = require("../../src/private_key/private.json"); export const adminApp = admin.initializeApp({ - credential: admin.credential.cert(serviceAccount) + credential: admin.credential.cert(serviceAccount), }); +export const db = admin.firestore(); +export const connectedUsersCollection = db.collection('users'); +export const messagesCollection = db.collection('messages'); + console.log("[FIREBASE-ADMIN] Firebase admin SDK synced.") \ No newline at end of file diff --git a/server/src/utilities/firebaseInit.ts b/server/src/utilities/firebaseInit.ts deleted file mode 100644 index bc5a2b351..000000000 --- a/server/src/utilities/firebaseInit.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { initializeApp } from 'firebase/app' -import { getFirestore, CollectionReference, collection, DocumentData } from 'firebase/firestore' -import 'dotenv/config'; - -export const firebaseApp = initializeApp({ - apiKey: process.env.API_KEY, - authDomain: process.env.AUTH_DOMAIN, - projectId: process.env.PROJECT_ID, - storageBucket: process.env.STORAGE_BUCKET, - messagingSenderId: process.env.MESSAGING_SENDER_ID, - appId: process.env.APP_ID -}) - -export const firestore = getFirestore() - -const createCollection = (collectionName: string) => { - return collection(firestore, collectionName) as CollectionReference; -} - -import { Message } from '../types/Message' -import { ConnectedUser, UserConfig } from '../types/User' - -export const messages = createCollection('Messages') -export const connectedUsers = createCollection('ConnectedUsers') -export const userConfigs = createCollection('UserConfigs') - -console.log("[FIRESTORE] Database synced.") - From 9263c96d6594444f231d6c4e8b7bbbe30a84198c Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sun, 25 Feb 2024 00:40:01 -0500 Subject: [PATCH 03/15] Added JWT on top of Firebase-Admin (#178) * Made error case for email in use display correctly in front end * Made error case for email in use display correctly in front end (#158) * Cleaned up useEffect function #159 * Added testing pipeline (#175) * Create main.yml * Update main.yml * Update _layout.tsx * Update main.yml * Update socketio.test.ts * Update socketio.test.ts * Update _layout.tsx * User Context and User Type created and wrapped chat screen (#131) * added user context * Added userID and displayName * moved user and display name generation into UserProvider * Improved UserContext implementation Amongst these changes, the user type on the frontend has been edited in order to prevent hidden functions that would pull information into the UserContext from other contexts. The message type was also modified to keep a new author section with a displayName attribute. An issue should be created for a socket API endpoint for grabbing the displayName, and one to set it in a connectedUser document in the databse. * updated package lock --------- Co-authored-by: h1divp <71522316+h1divp@users.noreply.github.com> * Set up Firebase-Admin in adminInit.ts (#155) * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * added passport * started auth + admin sdk * removed passport * added private key to gitignore * Delete server/private_keys/private.json --------- Co-authored-by: AlexanderWangY * Refactored most of the actions (#156) * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * fixes pt2 * JWT WIP * new branch + function fix * small bug fixes * added passport * started auth + admin sdk * removed passport * added private key to gitignore * Delete server/private_keys/private.json * initializing firestore in admin * finished most of action refactoring * Made error case for email in use display correctly in front end (#158) * changed getConnectedUsers to admin * migrated to firebase-admin --------- Co-authored-by: AlexanderWangY Co-authored-by: Mohammed Ali <146048575+Phantom0110@users.noreply.github.com> * added middleware --------- Co-authored-by: Phantom0110 Co-authored-by: Mohammed Ali <146048575+Phantom0110@users.noreply.github.com> Co-authored-by: AaronGibson2 <149017602+AaronGibson2@users.noreply.github.com> Co-authored-by: h1divp <71522316+h1divp@users.noreply.github.com> Co-authored-by: AlexanderWangY --- .github/workflows/main.yml | 65 +++++++++++++++++++ client/src/app/(home)/_layout.tsx | 21 +++--- client/src/components/Chat/ChatScreen.tsx | 14 ++-- .../src/components/Common/MessageChannel.tsx | 2 +- client/src/contexts/LocationContext.tsx | 3 + client/src/contexts/SettingsContext.tsx | 3 - client/src/contexts/SocketContext.tsx | 57 +++++++++++----- client/src/contexts/UserContext.tsx | 25 +++++++ client/src/services/store.ts | 19 +++--- client/src/types/Message.ts | 6 +- client/src/types/User.ts | 7 ++ client/src/utils/types.ts | 11 ++++ server/src/index.ts | 21 +++++- server/src/tests/socketio.test.ts | 42 ++++++------ 14 files changed, 229 insertions(+), 67 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 client/src/contexts/UserContext.tsx create mode 100644 client/src/types/User.ts create mode 100644 client/src/utils/types.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..f4d1cf5a7 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,65 @@ +name: Unit Tests + +on: [pull_request] + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [21.x] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm ci + working-directory: server/ + + - name: Set up environment variables + env: + API_KEY: ${{ secrets.API_KEY }} + AUTH_DOMAIN: ${{ secrets.AUTH_DOMAIN }} + PROJECT_ID: ${{ secrets.PROJECT_ID }} + STORAGE_BUCKET: ${{ secrets.STORAGE_BUCKET }} + MESSAGING_SENDER_ID: ${{ secrets.MESSAGING_SENDER_ID }} + APP_ID: ${{ secrets.APP_ID }} + MESSAGE_OUTREACH_RADIUS: ${{ secrets.MESSAGE_OUTREACH_RADIUS }} + EXPRESS_PORT: ${{ secrets.EXPRESS_PORT }} + SOCKET_PORT: ${{ secrets.SOCKET_PORT }} + SOCKET_TEST_CLIENT_PORT: ${{ secrets.SOCKET_TEST_CLIENT_PORT }} + run: | + echo "API_KEY=${API_KEY}" >> .env + echo "AUTH_DOMAIN=${AUTH_DOMAIN}" >> .env + echo "PROJECT_ID=${PROJECT_ID}" >> .env + echo "STORAGE_BUCKET=${STORAGE_BUCKET}" >> .env + echo "MESSAGING_SENDER_ID=${MESSAGING_SENDER_ID}" >> .env + echo "APP_ID=${APP_ID}" >> .env + echo "message_outreach_radius=${MESSAGE_OUTREACH_RADIUS}" >> .env + echo "express_port=${EXPRESS_PORT}" >> .env + echo "socket_port=${SOCKET_PORT}" >> .env + echo "socket_test_client_port=${SOCKET_TEST_CLIENT_PORT}" >> .env + working-directory: server/ + + - name: Compile TypeScript files + run: npx tsc + working-directory: server/ + + - name: Start index.ts in background + run: npm start & + working-directory: server/ + + - name: Wait for server to start + run: sleep 5 # Adjust sleep time as needed to allow the server to start + timeout-minutes: 1 + + - name: Run tests + run: npm test + working-directory: server/ diff --git a/client/src/app/(home)/_layout.tsx b/client/src/app/(home)/_layout.tsx index 07c328d03..fb7c6336c 100644 --- a/client/src/app/(home)/_layout.tsx +++ b/client/src/app/(home)/_layout.tsx @@ -3,20 +3,23 @@ import { Stack } from "expo-router"; import { SettingsProvider } from "../../contexts/SettingsContext"; import { SocketProvider } from "../../contexts/SocketContext"; import { LocationProvider } from "../../contexts/LocationContext"; +import { UserProvider } from "../../contexts/UserContext"; const AuthLayout = () => { return ( - - - - - + + + + + + + ); diff --git a/client/src/components/Chat/ChatScreen.tsx b/client/src/components/Chat/ChatScreen.tsx index c3fac3fa6..2939a47cb 100644 --- a/client/src/components/Chat/ChatScreen.tsx +++ b/client/src/components/Chat/ChatScreen.tsx @@ -14,15 +14,15 @@ import { import { ChatInput } from "../Common/CustomInputs"; import { ChatSendButton } from "../Common/CustomButtons"; import MessageChannel from "../Common/MessageChannel"; -import { LinearGradient } from "expo-linear-gradient"; import * as Crypto from "expo-crypto"; import { generateName } from "../../utils/scripts"; -import { useSettings } from "../../contexts/SettingsContext"; import { SignOutButton } from "../Common/AuthButtons" import { MessageType } from "../../types/Message"; import { LocationProvider } from "../../contexts/LocationContext"; import { useSocket } from "../../contexts/SocketContext"; +import { useSettings } from "../../contexts/SettingsContext"; import { useLocation } from "../../contexts/LocationContext"; +import { useUser } from "../../contexts/UserContext"; // imported for when it needs to be used import { AuthStore } from "../../services/store"; const ChatScreen = () => { @@ -32,8 +32,10 @@ const ChatScreen = () => { const keyboardBehavior = Platform.OS === "ios" ? "padding" : undefined; const socket = useSocket(); const location = useLocation(); - const { user } = AuthStore.useState(); - + const user = useUser(); + const userAuth = AuthStore.useState() + // Note: To prevent complexity, all user information is grabbed from different contexts and services. If we wanted most information inside of UserContext, we would have to import contexts within contexts and have state change as certain things mount, which could cause errors that are difficult to pinpoint. + // Message loading and sending logic const [messages, setMessages] = React.useState([]); const [messageContent, setMessageContent] = React.useState(""); @@ -54,7 +56,9 @@ const ChatScreen = () => { const onHandleSubmit = () => { if (messageContent.trim() !== "") { const newMessage: MessageType = { - uid: String(user?.uid), + author: { + uid: String(userAuth.userAuthInfo?.uid), + }, msgId: Crypto.randomUUID(), msgContent: messageContent.trim(), timeSent: Date.now(), diff --git a/client/src/components/Common/MessageChannel.tsx b/client/src/components/Common/MessageChannel.tsx index ad215f708..3ff4c8629 100644 --- a/client/src/components/Common/MessageChannel.tsx +++ b/client/src/components/Common/MessageChannel.tsx @@ -20,7 +20,7 @@ const MessageChannel: React.FC = ({ messages }) => { renderItem={({ item }) => ( )} diff --git a/client/src/contexts/LocationContext.tsx b/client/src/contexts/LocationContext.tsx index 6c571c9a8..104b1c96b 100644 --- a/client/src/contexts/LocationContext.tsx +++ b/client/src/contexts/LocationContext.tsx @@ -71,6 +71,9 @@ export const LocationProvider = ({ // Cleanup function to clear interval when component unmounts return () => clearInterval(interval); })(); + + return () => console.log("[LOG]: Cleaning up location useEffect"); + }, []); return ( diff --git a/client/src/contexts/SettingsContext.tsx b/client/src/contexts/SettingsContext.tsx index c1d35a135..81f086ce4 100644 --- a/client/src/contexts/SettingsContext.tsx +++ b/client/src/contexts/SettingsContext.tsx @@ -36,9 +36,6 @@ export const SettingsProvider = ({ children: React.ReactNode; }) => { const [theme, setTheme] = useState("light"); - const [displayName, setDisplayName] = useState(""); - const [foregroundPfpImage, setForegroundPfpImage] = useState(""); - const [backgroundPfpImage, setBackgroundPfpImage] = useState(""); // Initial settings load useEffect(() => { diff --git a/client/src/contexts/SocketContext.tsx b/client/src/contexts/SocketContext.tsx index 3ecdb1521..5b46ce064 100644 --- a/client/src/contexts/SocketContext.tsx +++ b/client/src/contexts/SocketContext.tsx @@ -2,6 +2,7 @@ import React, { createContext, useContext, useEffect, useState } from "react"; import { io, Socket } from "socket.io-client"; import { useLocation } from "./LocationContext"; import { EXPO_IP } from "@env"; +import { AuthStore } from "../services/store"; const SocketContext = createContext(null); @@ -11,32 +12,56 @@ export const useSocket = () => { export const SocketProvider = ({ children }: { children: React.ReactNode }) => { const [socket, setSocket] = useState(null); + const [mounted, setMounted] = useState(false); const locationContext = useLocation(); - useEffect(() => { - let isMounted = true; - const socketIo = io(`http://${ EXPO_IP }:8080`); // Hardcoded IP address + useEffect(() => { + const getToken = async () => { + const token = await AuthStore.getRawState().userAuthInfo?.getIdToken(); + console.log("Token:", token); + return token; + } + + const initializeSocket = async () => { + const token = await getToken(); + const socketIo = io(`http://${EXPO_IP}:8080`, { + auth: { + token: token, + } + }); - socketIo.on("connect", () => { - if (isMounted) { - setSocket(socketIo); - } else { - console.log("Socket not mounted"); - } - }); + setSocket(socketIo); + setMounted(true); + } - // socketIo.on("message", (data: MessageType, ack) => { - // console.log("Sending message to server:", data); - // if (ack) console.log("Server acknowledged message:", ack); - // }); + if (!mounted) { + initializeSocket(); + } return () => { - isMounted = false; - socketIo.disconnect(); + console.log("[LOG]: Cleaning up intializeSocket useEffect"); }; }, []); + // Listen to the socket state and run once the socket is set! + useEffect(() => { + + if (!socket) return; + + socket.on("connect", () => { + console.log("Connected to server"); + } + ); + + return () => { + console.log("[LOG]: Cleaning up sockets and mounted state."); + socket.disconnect(); + setSocket(null); + setMounted(false); + } + }, [socket]); + useEffect(() => { // TODO: Refactor this useEffect into a different file (service?) outside of the context, as it is not part of the purpose of a context. if ( diff --git a/client/src/contexts/UserContext.tsx b/client/src/contexts/UserContext.tsx new file mode 100644 index 000000000..42a0b4b3b --- /dev/null +++ b/client/src/contexts/UserContext.tsx @@ -0,0 +1,25 @@ +import React, { createContext, useContext } from 'react'; +import { UserType } from '../types/User'; +import { useState } from 'react'; + +const UserContext = createContext(null); + +export const useUser = () => { + return useContext(UserContext); +} + +export const UserProvider = ({ children }: {children: React.ReactNode}) => { + const [user, setUser] = useState({ + displayName: "DefaultDisplayName", + userIcon: { + imagePath: "DefaultImagePath", + colorHex: "#fff" + }, + }); + + return ( + + {children} + + ); +}; diff --git a/client/src/services/store.ts b/client/src/services/store.ts index 77536358f..5ae4ed104 100644 --- a/client/src/services/store.ts +++ b/client/src/services/store.ts @@ -1,17 +1,19 @@ import { User, createUserWithEmailAndPassword, onAuthStateChanged, signInWithEmailAndPassword, signOut } from 'firebase/auth' import { Store } from 'pullstate' -import { auth } from '../configs/firebaseConfig' +import { auth, app } from '../configs/firebaseConfig' + + interface AuthStoreInterface { isLoggedin: boolean, initialized: boolean, - user: User | null, + userAuthInfo: User | null, } export const AuthStore = new Store({ isLoggedin: false, initialized: false, - user: null, + userAuthInfo: null, }) const unsub = onAuthStateChanged(auth, (user) => { @@ -19,7 +21,7 @@ const unsub = onAuthStateChanged(auth, (user) => { AuthStore.update((store) => { store.initialized = true, store.isLoggedin = user ? true : false, - store.user = user + store.userAuthInfo = user }) }); @@ -27,10 +29,9 @@ export const appSignIn = async (email: string, password: string) => { try { const response = await signInWithEmailAndPassword(auth, email, password); AuthStore.update((store) => { - store.user = response?.user; + store.userAuthInfo = response?.user; store.isLoggedin = response?.user ? true : false; }); - console.log('appSignIn', await response.user.getIdToken()); // This is the token we need to send to the server return { user: auth.currentUser }; } catch (e) { return { error: e }; @@ -41,7 +42,7 @@ export const appSignOut = async () => { try { await signOut(auth); AuthStore.update((store) => { - store.user = null; + store.userAuthInfo = null; store.isLoggedin = false; }); return { user: null} @@ -55,11 +56,11 @@ export const appSignUp = async (email: string, password: string) => { const response = await createUserWithEmailAndPassword(auth, email, password); AuthStore.update((store) => { - store.user = response.user; + store.userAuthInfo = response.user; store.isLoggedin = response.user ? true : false; }); return { user: auth.currentUser} } catch (e) { return { error: e }; } -}; \ No newline at end of file +}; diff --git a/client/src/types/Message.ts b/client/src/types/Message.ts index 3ef50bc59..2310a2714 100644 --- a/client/src/types/Message.ts +++ b/client/src/types/Message.ts @@ -1,6 +1,8 @@ export interface MessageType { - uid: string - authorName?: string // To be only used for display purposes (i.e. do not send to server) + author: { + uid: string + displayName?: string // To be only used for display purposes (do not send to server) + } msgId: string msgContent: string timeSent: number // Unix timestamp; Date.now() returns a Number. diff --git a/client/src/types/User.ts b/client/src/types/User.ts new file mode 100644 index 000000000..f85659001 --- /dev/null +++ b/client/src/types/User.ts @@ -0,0 +1,7 @@ +export interface UserType { + displayName: string + userIcon?: { + imagePath: string + colorHex: string + } +} diff --git a/client/src/utils/types.ts b/client/src/utils/types.ts new file mode 100644 index 000000000..a1eaa5023 --- /dev/null +++ b/client/src/utils/types.ts @@ -0,0 +1,11 @@ +export type MessageType = { + messageContent: string; + author: string; + msgID: string; +}; + +export type UserType = { + userID: string; + displayName: string; + pfp: string; +}; \ No newline at end of file diff --git a/server/src/index.ts b/server/src/index.ts index 0d5d275af..c2e4932b2 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -9,7 +9,7 @@ import { deleteConnectedUserByUID } from './actions/deleteConnectedUser' import {geohashForLocation} from 'geofire-common'; import { findNearbyUsers } from './actions/getConnectedUsers' import { ConnectedUser } from './types/User'; -import { adminApp } from './utilities/adminInit'; +import { getAuth } from 'firebase-admin/auth'; const { createServer } = require('http') @@ -33,6 +33,25 @@ const io = new Server(socketServer, { }, }); +// Firebase JWT Authorization Custom Middleware +io.use(async (socket, next) => { + const token = socket.handshake.auth.token; + console.log(`[WS] Recieved token: ${token}`) + + if (token) { + const decodedToken = await getAuth().verifyIdToken(token); + const userId = decodedToken.uid; + console.log(`[WS] User <${userId}> authenticated.`); + console.log(decodedToken) + + next(); + } else { + console.error("[WS] User not authenticated.") + next(new Error('User not authenticated.')); + } +}) + + io.on('connection', async (socket: any) => { console.log(`[WS] User <${socket.id}> connected.`); const defaultConnectedUser: ConnectedUser = { diff --git a/server/src/tests/socketio.test.ts b/server/src/tests/socketio.test.ts index 878ec7f79..3c79bbaeb 100644 --- a/server/src/tests/socketio.test.ts +++ b/server/src/tests/socketio.test.ts @@ -120,27 +120,27 @@ describe("socket-tests", () => { sleep(5000) done() }) - test('Send message to user', async (done) => { - // const user2Coords = { lat: 29.64881, lon: -82.34429 } // 8.65 meters SW of user 1 - const user2Coords = { lat: 29.6489940, lon: -82.344096 } // 8.65 meters SW of user 1 - const user2Message: Message = { - uid: user2.id, // a socket id - msgId: uuidv4(), - msgContent: "omggg hi!!!! :3", - timeSent: 9999, - location: { - lat: user2Coords.lat, - lon: user2Coords.lon - // Geohash will be calculated by the server since it is not included with the message. - } - } - user1.on('message', (message: Message) => { - console.log(`User 2 recieved message: ${message}`) - expect(message.msgContent).toBe("omggg hi!!!! :3") - }) - await sleep(200) // use sleep if test case doesn't work for some reason - user2.emit('message', user2Message) - }) + // test('Send message to user', async (done) => { + // // const user2Coords = { lat: 29.64881, lon: -82.34429 } // 8.65 meters SW of user 1 + // const user2Coords = { lat: 29.6489940, lon: -82.344096 } // 8.65 meters SW of user 1 + // const user2Message: Message = { + // uid: user2.id, // a socket id + // msgId: uuidv4(), + // msgContent: "omggg hi!!!! :3", + // timeSent: 9999, + // location: { + // lat: user2Coords.lat, + // lon: user2Coords.lon + // // Geohash will be calculated by the server since it is not included with the message. + // } + // } + // user1.on('message', (message: Message) => { + // console.log(`User 2 recieved message: ${message}`) + // expect(message.msgContent).toBe("omggg hi!!!! :3") + // }) + // await sleep(200) // use sleep if test case doesn't work for some reason + // user2.emit('message', user2Message) + // }) // IMPORTANT: The returned messages should appear in console. The correct way to use expect() has not been figured out yet for this test. // TODO: Find a way for expect() to be verified after messages return. }) From f8f4f20a8c0a995e0fdf638069272cde21e9402d Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sun, 25 Feb 2024 00:43:40 -0500 Subject: [PATCH 04/15] Delete server/src/private_key/private.json --- server/src/private_key/private.json | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 server/src/private_key/private.json diff --git a/server/src/private_key/private.json b/server/src/private_key/private.json deleted file mode 100644 index 02095340f..000000000 --- a/server/src/private_key/private.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "service_account", - "project_id": "fir-auth-89462", - "private_key_id": "770edc7187f5ef3d35359b9ad2304570d4f170ff", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDCS6oM6wYwCp7a\nCXauPpBDjLzqq5PrMZCWOoi2THjqTzLJQc/Xwg5XlOyRX1DB4Uzl1iutfLsQXNuv\nMRze3i2jIOLysnrkvSuLW9n19k/1gIYYm7oxZQPaJ5iNJ33GFiNJqULlmMTvv6vp\nhXOOUZxl9dNY3HRpICcaGNPXjAv3tG7W+iHsidphp88Q8OMMmkZcl3+h2Hc1yDEf\nmXPR0YynfakDi45tMf5F9x3jRT6y6O30PSpZUIVL2cfwWs+zojnK+vy+cGCjBIJE\n/uI+A7XJJ4BWNLH/jhy6Jta/jDkCj/JbUsxRTX2ZuUeVi8uSMkzdy/Pb+o5f4SaJ\nl3mTa7S5AgMBAAECggEAEIChdwMrxX8TbrC81TAga/JbVeHAmKp/LblXRQeSAhG7\nvisSMpDLi84M+UxzlSIUGFXkZBH65/kBGjxVR8subGN1zzgQVtcH6KhipwDWmgMi\ncJriecFLDleMXhnXdZCKCv6+vTZIbNYWbYlNjy4YlvLmEm84DnlCBPYMoStGlXFm\nRKEfLl4FHHmCRcRkuGWRyKk9LtKNykrlaFVZ3BL11/TC38BlK3us+1cyUO3dA1EW\njAYSRG3tAVGVS7VUoxDDcA1V+Wnccpt+ws/rzIVYcTXawXrpHXFx977FwarGHReL\nmRmjHYGo/4Ry+q8Nk1y7GkdPYxq5GVAtXuRqSx7EgQKBgQD86ru/bBxJZxNAuHTE\nx9j/n0MrH9ulAFEzAXzq12Yf2xSytrUbD31zPg+rrFTGDNYISUPKSa9sxpC/jiwB\nXmuNhFVvt1521naZOtyezo3RYztcwOIxscvULHMUt/ikaFVsytlxrqDn0MJXuKM/\n5OZbbolc5pR3Oi82FOz09xB+OQKBgQDEqf5ox6V8ZfrMdFvhKC0EklyfDjClrJa2\nCkE0HK9ePxCpnEqBYC8wj6pXNOnLONYNZIjJ7Nz2CiFd0gIt7Ep9KtDNve99dWHR\nObPbt9fC8vMuzotBN6P345hzdqXR7OUUfAPFBCZTysWrfHzqg1tFYkt5t+YVfWuu\nMRq/xpzqgQKBgQC00Af7eQnb/EHKYlSwngNn9G8rtHHty4VBhs3MgsOzAIgSoAZn\n2zIfon3HiMNud5zIfcBmLTmp9WdkWvrg26Tenn4KCTkSko5lS6yQKDFBQcUdsZPE\nXUzQWhrH9CJhP2nbBkZgPK0yLY/S8OBc/IMnWKYBcaMwfbtk2Z7yHnN/GQKBgClH\ndTsRDM87qJTZp59vC2P2RLKuC8/6lffH1z/U9YpWumyffZQCWGVdAmgjlx8s4uEU\nxRF9QjPylGZY+lQhUNFM9174CxjOVqXP8syfng4xaJHekKQzxZr2jr1NniieDMdr\n8G6eHF1iJnOEQcQHplS9+RGnZAgGt19styyhx7YBAoGBAN++OfEq6S8zW/+Q9E8x\nAxvdNrFOkHnJf+URwTZQNFebvRUDouYjHE1fOCSM7npkNFV/DyINTsP6cNGKwGXM\nox1ODGb2uLk3hEQLDbqocIoWnuzY2QU3lubrSdAnEUDBovjd4of47BwYo2HfA+Pu\nTuLU4vtbFvSH7e3OJ9A//cKD\n-----END PRIVATE KEY-----\n", - "client_email": "firebase-adminsdk-f0nzi@fir-auth-89462.iam.gserviceaccount.com", - "client_id": "102183968562626917121", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-f0nzi%40fir-auth-89462.iam.gserviceaccount.com", - "universe_domain": "googleapis.com" -} From b046eef6238c246af09caa8a9a7a7db1ee3e138a Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sun, 25 Feb 2024 01:00:35 -0500 Subject: [PATCH 05/15] Update main.yml --- .github/workflows/main.yml | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f4d1cf5a7..1e212a15a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,28 +24,9 @@ jobs: working-directory: server/ - name: Set up environment variables - env: - API_KEY: ${{ secrets.API_KEY }} - AUTH_DOMAIN: ${{ secrets.AUTH_DOMAIN }} - PROJECT_ID: ${{ secrets.PROJECT_ID }} - STORAGE_BUCKET: ${{ secrets.STORAGE_BUCKET }} - MESSAGING_SENDER_ID: ${{ secrets.MESSAGING_SENDER_ID }} - APP_ID: ${{ secrets.APP_ID }} - MESSAGE_OUTREACH_RADIUS: ${{ secrets.MESSAGE_OUTREACH_RADIUS }} - EXPRESS_PORT: ${{ secrets.EXPRESS_PORT }} - SOCKET_PORT: ${{ secrets.SOCKET_PORT }} - SOCKET_TEST_CLIENT_PORT: ${{ secrets.SOCKET_TEST_CLIENT_PORT }} run: | - echo "API_KEY=${API_KEY}" >> .env - echo "AUTH_DOMAIN=${AUTH_DOMAIN}" >> .env - echo "PROJECT_ID=${PROJECT_ID}" >> .env - echo "STORAGE_BUCKET=${STORAGE_BUCKET}" >> .env - echo "MESSAGING_SENDER_ID=${MESSAGING_SENDER_ID}" >> .env - echo "APP_ID=${APP_ID}" >> .env - echo "message_outreach_radius=${MESSAGE_OUTREACH_RADIUS}" >> .env - echo "express_port=${EXPRESS_PORT}" >> .env - echo "socket_port=${SOCKET_PORT}" >> .env - echo "socket_test_client_port=${SOCKET_TEST_CLIENT_PORT}" >> .env + mkdir private_key + echo "${{ secrets.SERVICE_ACCOUNT_SECRET }}" > private_key/private.json working-directory: server/ - name: Compile TypeScript files From 24543091245583c784f96894539935b90e7b49fd Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sun, 25 Feb 2024 01:04:04 -0500 Subject: [PATCH 06/15] Updated pipeline to reflect firebase-admin --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1e212a15a..63e78b21a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,7 +27,7 @@ jobs: run: | mkdir private_key echo "${{ secrets.SERVICE_ACCOUNT_SECRET }}" > private_key/private.json - working-directory: server/ + working-directory: server/src - name: Compile TypeScript files run: npx tsc From 0c203eeab6d8df10b7dd2881a9d6b3e59ece0b5f Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sun, 25 Feb 2024 01:06:46 -0500 Subject: [PATCH 07/15] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 63e78b21a..b26d3408b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: - name: Set up environment variables run: | mkdir private_key - echo "${{ secrets.SERVICE_ACCOUNT_SECRET }}" > private_key/private.json + echo ${{ secrets.SERVICE_ACCOUNT_SECRET }} > private_key/private.json working-directory: server/src - name: Compile TypeScript files From e21e35792dc264c057ca6d0abe1df98175f34fbc Mon Sep 17 00:00:00 2001 From: Alexander Wang <98280966+AlexanderWangY@users.noreply.github.com> Date: Sun, 25 Feb 2024 01:15:48 -0500 Subject: [PATCH 08/15] Update main.yml --- .github/workflows/main.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b26d3408b..c90ca79af 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,12 +23,13 @@ jobs: run: npm ci working-directory: server/ - - name: Set up environment variables - run: | - mkdir private_key - echo ${{ secrets.SERVICE_ACCOUNT_SECRET }} > private_key/private.json - working-directory: server/src - + - name: Create service account JSON + id: create-service-acount-json + uses: jsdaniell/create-json@1.1.2 + with: + name: "server/src/private_key/private.json" + json: ${{ secrets.SERVICE_ACCOUNT_SECRET }} + - name: Compile TypeScript files run: npx tsc working-directory: server/ From 473fed4c133d7992c33fc2c8c5602df845c60337 Mon Sep 17 00:00:00 2001 From: Aadit Kamat Date: Mon, 26 Feb 2024 18:18:52 -0500 Subject: [PATCH 09/15] Create subdirectory before creating service account JSON (#187) * Update socket tests (#185) * Update socket tests * Remove unused type * Update comment in socketio.test.ts --------- Co-authored-by: Phoenix <71522316+h1divp@users.noreply.github.com> * Create subdirectory before creating service account JSON --------- Co-authored-by: Phoenix <71522316+h1divp@users.noreply.github.com> --- .github/workflows/main.yml | 10 +- server/src/tests/socketio.test.ts | 294 +++++++++++++++++------------- 2 files changed, 176 insertions(+), 128 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c90ca79af..d20bb00ec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,12 +23,18 @@ jobs: run: npm ci working-directory: server/ + - name: Create subdirectory for service account JSON + run: | + mkdir private_key + working-directory: server/src + - name: Create service account JSON - id: create-service-acount-json + id: create-service-account-json uses: jsdaniell/create-json@1.1.2 with: - name: "server/src/private_key/private.json" + name: "private.json" json: ${{ secrets.SERVICE_ACCOUNT_SECRET }} + dir: 'server/src/private_key/' - name: Compile TypeScript files run: npx tsc diff --git a/server/src/tests/socketio.test.ts b/server/src/tests/socketio.test.ts index 3c79bbaeb..51dc456f7 100644 --- a/server/src/tests/socketio.test.ts +++ b/server/src/tests/socketio.test.ts @@ -1,146 +1,188 @@ // Testing for socket.io endpoints -import { io as io } from 'socket.io-client' -import { v4 as uuidv4 } from 'uuid'; -import { Message } from '../types/Message'; +import { createServer } from "node:http"; +import { io as ioc } from "socket.io-client"; +import { Server } from "socket.io"; +import { v4 as uuidv4 } from "uuid"; -const socket_test_client_port = process.env.socket_test_client_port; -console.log("Socket clients are listening on port", socket_test_client_port) - -const SECONDS_TIMEOUT = 10; const SECONDS_MULTIPLIER = 1000; -const NUM_CLIENTS = 3; // Adjust the number of clients as needed. Do not go over 300 to prevent being blocked by Firebase. -const exampleMsg: Message = { - uid: uuidv4(), // random Ids; not a real UID - msgId: uuidv4(), - msgContent: "MESSAGE CONTENT", - timeSent: 9999, - location: { - lat: 10, - lon: 10 - // Geohash will be calculated by the server since it is not included with the message. +jest.setTimeout(60 * SECONDS_MULTIPLIER); + +describe("socket-load-tests", () => { + let clientSockets = []; + let httpServer; + let httpServerAddr; + let ioServer; + const numClients = 100; // Adjust the number of clients as needed. Do not go over 300 to prevent being blocked by Firebase. + + beforeAll((done) => { + httpServer = createServer().listen(); + httpServerAddr = httpServer.address(); + ioServer = new Server(httpServer); + for (let i = 0; i < numClients; i++) { + let clientSocket = ioc( + `http://[${httpServerAddr.address}]:${httpServerAddr.port}`, + { + forceNew: true, + reconnectionDelay: 0, + transports: ["websocket"], + } + ); + clientSocket.on("connect", () => { + done(); + }); + clientSockets.push(clientSocket); } -} - -jest.setTimeout(SECONDS_TIMEOUT * SECONDS_MULTIPLIER); - -const sleep = (ms) => { - return new Promise(resolve => setTimeout(resolve, ms)); -}; - -const connectClients = async () => { - const clients = []; - - for (let i = 0; i < NUM_CLIENTS; i++) { - const client = io(`http://localhost:${socket_test_client_port}`); - await new Promise(resolve => client.on('connect', resolve)); // Why is this an error? IDK - clients.push(client); - } - - return clients; -}; + done(); + }); -const disconnectClients = (clients) => { - clients.forEach(client => client.disconnect()); -}; + afterAll((done) => { + ioServer.close(); + httpServer.close(); + for (let i = 0; i < numClients; i++) { + clientSockets[i].disconnect(); + } + done(); + }); -describe('socket-load-tests', () => { - let clients; + test("Simultaneous Ping", (done) => { + ioServer.on("ping", (cb) => { + cb("pong"); + }); + for (let i = 0; i < numClients; i++) { + clientSockets[i].emit("ping", (response) => { + expect(response).toBe("pong"); + }); + } + done(); + }); - beforeAll(async () => { - clients = await connectClients(); + test("Simultaneous Message", async () => { + ioServer.on("ping", (cb) => { + cb("pong"); + }); + for (let i = 0; i < numClients; i++) { + clientSockets[i].emit( + "message", + { + userId: "userId", + msgId: uuidv4(), + msgContent: `This is message ${i}`, + lat: 10, + lon: 10, + timeSent: 99999999, + }, + (response) => { + expect(response).toBe("message recieved"); + } + ); + } }); +}); - afterAll(() => { - disconnectClients(clients); +describe("socket-tests", () => { + let clientSockets = []; + let httpServer; + let httpServerAddr; + let ioServer; + const numClients = 5; + + beforeAll((done) => { + httpServer = createServer().listen(); + httpServerAddr = httpServer.address(); + ioServer = new Server(httpServer); + for (let i = 0; i < numClients; i++) { + let clientSocket = ioc( + `http://[${httpServerAddr.address}]:${httpServerAddr.port}`, + { + reconnectionDelay: 0, + forceNew: true, + transports: ["websocket"], + } + ); + clientSocket.on("connect", () => { + done(); + }); + clientSockets.push(clientSocket); + } + done(); }); - test('Simultaneous Ping', async () => { - const pingPromises = clients.map(client => new Promise(resolve => client.emit('ping', resolve))); - const responses = await Promise.all(pingPromises); + afterAll((done) => { + ioServer.close(); + httpServer.close(); + for (let i = 0; i < numClients; i++) { + clientSockets[i].disconnect(); + } + done(); + }); - responses.forEach(response => { - expect(response).toBe('pong'); + test("Ping", (done) => { + ioServer.on("ping", (cb) => { + cb("pong"); + }); + clientSockets[0].emit("ping", (response) => { + expect(response).toBe("pong"); }); + done(); }); - test('Simultaneous Message', async () => { - let count = 0; - const messagePromises = clients.map(client => { - return new Promise(async resolve => { - client.emit('message', exampleMsg, resolve); - count++; - await sleep(200) - }); + test("Send message", (done) => { + ioServer.on("ping", (cb) => { + cb("pong"); }); - - const responses = await Promise.all(messagePromises); - responses.forEach(response => { - expect(response).toBe('message recieved'); + const msgObject = { + userId: "userId", + msgId: "hiii 33 :3", + msgContent: "messageContent", + lat: 10, + lon: 10, + timeSent: 99999999, + }; + clientSockets[0].emit("message", msgObject, (response) => { + expect(response).toBe("message recieved"); }); - }) -}); - -describe("socket-tests", () => { - let user1, user2 - - beforeAll((done) => { - user1 = io(`http://localhost:${socket_test_client_port}`) - user1.on('connect', done) - user2 = io(`http://localhost:${socket_test_client_port}`) - user2.on('connect', done) - }) + done(); + }); - afterAll(() => { - user1.disconnect() - user2.disconnect() - }) + test("Update locations", (done) => { + const userCoords = [ + { lat: 29.64888, lon: -82.3442 }, // Turlington Hall pin on Google Maps + { lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1 + { lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1 + { lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1 + { lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1 + ]; + + for (let i = 0; i < userCoords.length; i++) { + clientSockets[i].emit("updateLocation", userCoords[0], (response) => { + expect(response).toBe("location updated"); + }); + } + done(); + }); - test('Ping', (done) => { - user1.emit('ping', (response) => { - expect(response).toBe('pong') - done() - }) - }) - test('Send message', (done) => { - user1.emit('message', exampleMsg, (response) => { - expect(response).toBe('message recieved') - done() - }) - }) - test('Update locations', (done) => { - const user1Coords = { lat: 29.64888, lon: -82.34420 } // Turlington Hall pin on Google Maps - const user2Coords = { lat: 29.64881, lon: -82.34429 } // 8.65 meters SW of user 1 - user1.emit('updateLocation', user1Coords, (response) => { - expect(response).toBe("location updated") - }) - user2.emit('updateLocation', user2Coords, (response) => { - expect(response).toBe("location updated") - }) - sleep(5000) - done() - }) - // test('Send message to user', async (done) => { - // // const user2Coords = { lat: 29.64881, lon: -82.34429 } // 8.65 meters SW of user 1 - // const user2Coords = { lat: 29.6489940, lon: -82.344096 } // 8.65 meters SW of user 1 - // const user2Message: Message = { - // uid: user2.id, // a socket id - // msgId: uuidv4(), - // msgContent: "omggg hi!!!! :3", - // timeSent: 9999, - // location: { - // lat: user2Coords.lat, - // lon: user2Coords.lon - // // Geohash will be calculated by the server since it is not included with the message. - // } - // } - // user1.on('message', (message: Message) => { - // console.log(`User 2 recieved message: ${message}`) - // expect(message.msgContent).toBe("omggg hi!!!! :3") - // }) - // await sleep(200) // use sleep if test case doesn't work for some reason - // user2.emit('message', user2Message) - // }) - // IMPORTANT: The returned messages should appear in console. The correct way to use expect() has not been figured out yet for this test. - // TODO: Find a way for expect() to be verified after messages return. -}) + test("Send message to user", (done) => { + const user2Coords = { lat: 29.64881, lon: -82.34429 }; // 8.65 meters SW of user 1 + const user2Message = { + userId: clientSockets[1].id, + msgId: "testid", + msgContent: "omggg hi!!!! :3", + lat: user2Coords.lat, + lon: user2Coords.lon, + timeSent: 999999, + }; + for (let i = 0; i < clientSockets.length; i++) { + if (i != 1) { + clientSockets[i].on("message", (message) => { + console.log(`User 2 recieved message ${message}`); + expect(message).toBe("omggg hi!!!! :3"); + }); + } + } + clientSockets[1].emit("message", user2Message); + done(); + // TODO: This test case will return true, but the sent message is actually never verified. + // The real verification of this message to lead to a pass/fail should be worked on. + }); +}); From 5ab06abec3d5f768d769a7675336e3dd7e217eb6 Mon Sep 17 00:00:00 2001 From: AlexanderWangY Date: Wed, 28 Feb 2024 13:21:45 -0500 Subject: [PATCH 10/15] made changes to collection name + socket test load testing --- server/src/tests/socketio.test.ts | 2 +- server/src/utilities/adminInit.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/tests/socketio.test.ts b/server/src/tests/socketio.test.ts index 51dc456f7..3a882e058 100644 --- a/server/src/tests/socketio.test.ts +++ b/server/src/tests/socketio.test.ts @@ -13,7 +13,7 @@ describe("socket-load-tests", () => { let httpServer; let httpServerAddr; let ioServer; - const numClients = 100; // Adjust the number of clients as needed. Do not go over 300 to prevent being blocked by Firebase. + const numClients = 20; // Adjust the number of clients as needed. Do not go over 300 to prevent being blocked by Firebase. beforeAll((done) => { httpServer = createServer().listen(); diff --git a/server/src/utilities/adminInit.ts b/server/src/utilities/adminInit.ts index a96ac473c..6c1270a89 100644 --- a/server/src/utilities/adminInit.ts +++ b/server/src/utilities/adminInit.ts @@ -6,7 +6,7 @@ export const adminApp = admin.initializeApp({ }); export const db = admin.firestore(); -export const connectedUsersCollection = db.collection('users'); -export const messagesCollection = db.collection('messages'); +export const connectedUsersCollection = db.collection('ConnectedUsers'); +export const messagesCollection = db.collection('Messages'); console.log("[FIREBASE-ADMIN] Firebase admin SDK synced.") \ No newline at end of file From 00c0095b59472544507a23f169318b14a7a228c7 Mon Sep 17 00:00:00 2001 From: h1divp <71522316+h1divp@users.noreply.github.com> Date: Wed, 28 Feb 2024 17:31:42 -0500 Subject: [PATCH 11/15] Added socketIo.connect() --- client/src/contexts/SocketContext.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/contexts/SocketContext.tsx b/client/src/contexts/SocketContext.tsx index a51fdf4ad..17c2e285c 100644 --- a/client/src/contexts/SocketContext.tsx +++ b/client/src/contexts/SocketContext.tsx @@ -31,6 +31,7 @@ export const SocketProvider = ({ children }: { children: React.ReactNode }) => { } }); + socketIo.connect() setSocket(socketIo); setMounted(true); } From b11a1cf25f451ff26feb36875f4b94d308ae119a Mon Sep 17 00:00:00 2001 From: h1divp <71522316+h1divp@users.noreply.github.com> Date: Wed, 28 Feb 2024 17:39:32 -0500 Subject: [PATCH 12/15] Remade collection name changes --- server/src/utilities/adminInit.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/src/utilities/adminInit.ts b/server/src/utilities/adminInit.ts index a96ac473c..6411eafac 100644 --- a/server/src/utilities/adminInit.ts +++ b/server/src/utilities/adminInit.ts @@ -6,7 +6,10 @@ export const adminApp = admin.initializeApp({ }); export const db = admin.firestore(); -export const connectedUsersCollection = db.collection('users'); -export const messagesCollection = db.collection('messages'); +export const connectedUsersCollection = db.collection('ConnectedUsers'); +export const messagesCollection = db.collection('Messages'); -console.log("[FIREBASE-ADMIN] Firebase admin SDK synced.") \ No newline at end of file +console.log("[FIREBASE-ADMIN] Firebase admin SDK synced.") + +// TODO: refactor file name to 'firebase' for accuracy. +// TODO: move key info to .env From db74d58d8de9f7fe4604665aee8447ede70c84b6 Mon Sep 17 00:00:00 2001 From: h1divp <71522316+h1divp@users.noreply.github.com> Date: Thu, 29 Feb 2024 00:08:59 -0500 Subject: [PATCH 13/15] updated location of firebase secrets, added comment about it in config_example.md --- server/config_example.md | 11 ++++------- server/src/utilities/adminInit.ts | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/server/config_example.md b/server/config_example.md index 184fd8709..8ffb34245 100644 --- a/server/config_example.md +++ b/server/config_example.md @@ -1,13 +1,10 @@ # dotenv config file (copy config to a new file named `.env`) # **Do not delete this file** -# Firebase config -API_KEY = place_your_apiKey_here -AUTH_DOMAIN = place_your_authDomain_here -PROJECT_ID = place_your_projectId_here -STORAGE_BUCKET = place_your_storageBucket_here -MESSAGING_SENDER_ID = place_your_messagingSenderId_here -APP_ID = place_your_appId_here +# To configure firebase: +# - Go to project settings > service accounts, +# - Make a new private key for the Node.js SDK +# - Paste all contents into ".firebase-secrets.json" in server/ # Location message_outreach_radius = 100 # meters diff --git a/server/src/utilities/adminInit.ts b/server/src/utilities/adminInit.ts index 6411eafac..8cf726249 100644 --- a/server/src/utilities/adminInit.ts +++ b/server/src/utilities/adminInit.ts @@ -1,5 +1,5 @@ const admin = require('firebase-admin'); -const serviceAccount = require("../../src/private_key/private.json"); +const serviceAccount = require("../../.firebase-secrets.json"); export const adminApp = admin.initializeApp({ credential: admin.credential.cert(serviceAccount), From 5cf30709dae96fd23bd891e87e8140642107373d Mon Sep 17 00:00:00 2001 From: h1divp <71522316+h1divp@users.noreply.github.com> Date: Thu, 29 Feb 2024 00:12:10 -0500 Subject: [PATCH 14/15] renamed file to firebaseInit from adminInit --- server/src/actions/createConnectedUser.ts | 2 +- server/src/actions/createMessage.ts | 2 +- server/src/actions/deleteConnectedUser.ts | 2 +- server/src/actions/getConnectedUsers.ts | 2 +- server/src/actions/updateConnectedUser.ts | 2 +- server/src/utilities/{adminInit.ts => firebaseInit.ts} | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename server/src/utilities/{adminInit.ts => firebaseInit.ts} (100%) diff --git a/server/src/actions/createConnectedUser.ts b/server/src/actions/createConnectedUser.ts index d06cf6854..10fd9febd 100644 --- a/server/src/actions/createConnectedUser.ts +++ b/server/src/actions/createConnectedUser.ts @@ -1,6 +1,6 @@ // Uploads a new document in the ConnectedUsers collection. import { ConnectedUser } from '../types/User' -import { connectedUsersCollection } from '../utilities/adminInit'; +import { connectedUsersCollection } from '../utilities/firebaseInit'; export const createUser = async (connectedUser: ConnectedUser) => { try { diff --git a/server/src/actions/createMessage.ts b/server/src/actions/createMessage.ts index 8494db672..140627c45 100644 --- a/server/src/actions/createMessage.ts +++ b/server/src/actions/createMessage.ts @@ -1,6 +1,6 @@ // Uploads a new document in the Messages collection. import { Message } from '../types/Message' -import { messagesCollection } from '../utilities/adminInit' +import { messagesCollection } from '../utilities/firebaseInit' export const createMessage = async (msg : Message) => { try { diff --git a/server/src/actions/deleteConnectedUser.ts b/server/src/actions/deleteConnectedUser.ts index a6a968780..bb8d64888 100644 --- a/server/src/actions/deleteConnectedUser.ts +++ b/server/src/actions/deleteConnectedUser.ts @@ -1,5 +1,5 @@ // Delete a ConnectedUser document given a document's index. This should typically be a socketId, but it can also be something else. -import { connectedUsersCollection } from '../utilities/adminInit' +import { connectedUsersCollection } from '../utilities/firebaseInit' export const deleteConnectedUserByUID = async (socketID: string) => { try { diff --git a/server/src/actions/getConnectedUsers.ts b/server/src/actions/getConnectedUsers.ts index c2567abd0..c61657006 100644 --- a/server/src/actions/getConnectedUsers.ts +++ b/server/src/actions/getConnectedUsers.ts @@ -1,5 +1,5 @@ import { distanceBetween, geohashForLocation, geohashQueryBounds } from 'geofire-common' -import { connectedUsersCollection } from '../utilities/adminInit' +import { connectedUsersCollection } from '../utilities/firebaseInit' export const findNearbyUsers = async (centerLat: number, centerLon: number, radius: number) => { // Return an array of nearby userIds (which are also socket ids) given a center latitude and longitude. diff --git a/server/src/actions/updateConnectedUser.ts b/server/src/actions/updateConnectedUser.ts index c935ae7c6..59bfe7c54 100644 --- a/server/src/actions/updateConnectedUser.ts +++ b/server/src/actions/updateConnectedUser.ts @@ -1,5 +1,5 @@ import { geohashForLocation} from 'geofire-common' -import { connectedUsersCollection } from '../utilities/adminInit' +import { connectedUsersCollection } from '../utilities/firebaseInit' export const toggleUserConnectionStatus = async (socketID: string) => { try { diff --git a/server/src/utilities/adminInit.ts b/server/src/utilities/firebaseInit.ts similarity index 100% rename from server/src/utilities/adminInit.ts rename to server/src/utilities/firebaseInit.ts From 785420eff3fbefefc083d706a1c59f0f28a5bd06 Mon Sep 17 00:00:00 2001 From: h1divp <71522316+h1divp@users.noreply.github.com> Date: Thu, 29 Feb 2024 00:16:23 -0500 Subject: [PATCH 15/15] Updated comment --- server/src/utilities/firebaseInit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/utilities/firebaseInit.ts b/server/src/utilities/firebaseInit.ts index 8cf726249..beeb3f717 100644 --- a/server/src/utilities/firebaseInit.ts +++ b/server/src/utilities/firebaseInit.ts @@ -9,7 +9,7 @@ export const db = admin.firestore(); export const connectedUsersCollection = db.collection('ConnectedUsers'); export const messagesCollection = db.collection('Messages'); -console.log("[FIREBASE-ADMIN] Firebase admin SDK synced.") +console.log("[FIREBASE] Firestore synced.") // TODO: refactor file name to 'firebase' for accuracy. // TODO: move key info to .env