From b1faacd312f0d821a291dcc56ef3b16a327a15ba Mon Sep 17 00:00:00 2001 From: Aditya Sankaran Date: Sun, 29 Sep 2019 19:07:35 -0400 Subject: [PATCH 01/10] backend and frontend connect in progress --- functions/handlers/post.js | 14 +++++++++----- twistter-frontend/src/Writing_Microblogs.js | 9 ++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/functions/handlers/post.js b/functions/handlers/post.js index 71b97eb..3a27c1a 100644 --- a/functions/handlers/post.js +++ b/functions/handlers/post.js @@ -1,3 +1,4 @@ +const admin = require('firebase-admin'); /* eslint-disable promise/always-return */ exports.putPost = (req, res) => { if (req.body.body.trim() === '') { @@ -6,18 +7,21 @@ exports.putPost = (req, res) => { const newPost = { body: req.body.body, - userHandle: req.user.handle, - userImage: req.user.imageUrl, + userHandle: req.body.userHandle, + userImage: req.body.userImage, + title: req.body.title, createdAt: new Date().toISOString(), likeCount: 0, - commentCount: 0 + commentCount: 0, + }; - db.collection('post').add(newPost) - .then((doc) => { + admin.firestore().collection('posts').add(newPost) + .then((doc) => { const resPost = newPost; resPost.postId = doc.id; res.json(resPost); + }) .catch((err) => { res.status(500).json({ error: 'something is wrong'}); diff --git a/twistter-frontend/src/Writing_Microblogs.js b/twistter-frontend/src/Writing_Microblogs.js index eca41d4..4769a9a 100644 --- a/twistter-frontend/src/Writing_Microblogs.js +++ b/twistter-frontend/src/Writing_Microblogs.js @@ -1,6 +1,7 @@ import React, { Component } from "react"; import { BrowserRouter as Router } from 'react-router-dom'; import Route from 'react-router-dom/Route'; +import axios from 'axios'; class Writing_Microblogs extends Component { @@ -25,7 +26,13 @@ class Writing_Microblogs extends Component { } handleSubmit(event) { - alert('A title for the microblog was inputted: ' + this.state.title + '\nA microblog was posted: ' + this.state.value); + // alert('A title for the microblog was inputted: ' + this.state.title + '\nA microblog was posted: ' + this.state.value); + const response = await axios.post( + 'http://localhost:5001/twistter-e4649/us-central1/api/putPost', + { }, + { headers: { 'Content-Type': 'application/json'} } + ) + console.log(response.data); event.preventDefault(); } From 55dc62e57e9907993a9725ca1c9b07245a2dc896 Mon Sep 17 00:00:00 2001 From: Aditya Sankaran Date: Mon, 30 Sep 2019 18:06:23 -0400 Subject: [PATCH 02/10] connected backend to frontend for writing microblogs --- functions/handlers/post.js | 6 ++---- functions/index.js | 3 ++- twistter-frontend/src/App.js | 2 ++ twistter-frontend/src/Userline.js | 24 +++++++++++++++++++++ twistter-frontend/src/Writing_Microblogs.js | 11 ++++++++-- 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 twistter-frontend/src/Userline.js diff --git a/functions/handlers/post.js b/functions/handlers/post.js index 3a27c1a..68ac37c 100644 --- a/functions/handlers/post.js +++ b/functions/handlers/post.js @@ -1,15 +1,13 @@ const admin = require('firebase-admin'); /* eslint-disable promise/always-return */ exports.putPost = (req, res) => { - if (req.body.body.trim() === '') { - return res.status(400).json({ body: 'Body must not be empty!'}); - } + const newPost = { body: req.body.body, userHandle: req.body.userHandle, userImage: req.body.userImage, - title: req.body.title, + microBlogTitle: req.body.microBlogTitle, createdAt: new Date().toISOString(), likeCount: 0, commentCount: 0, diff --git a/functions/index.js b/functions/index.js index 7d0498a..b4dbbcd 100644 --- a/functions/index.js +++ b/functions/index.js @@ -19,7 +19,8 @@ const { // post routes -app.post('/putPost', FBauth, putPost); +//app.post('/putPost', FBauth, putPost); +app.post('/putPost', putPost); // users routes app.get('/getUser/:handle', getUserDetails); diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index 3b0a077..1fea229 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -12,6 +12,7 @@ import register from './Register.js'; import login from './Login.js'; import user from './pages/user'; import writeMicroblog from './Writing_Microblogs.js'; +import userLine from './Userline.js'; class App extends Component { render() { @@ -25,6 +26,7 @@ class App extends Component { + diff --git a/twistter-frontend/src/Userline.js b/twistter-frontend/src/Userline.js new file mode 100644 index 0000000..af4ba7a --- /dev/null +++ b/twistter-frontend/src/Userline.js @@ -0,0 +1,24 @@ +import React, { Component } from "react"; +import { BrowserRouter as Router } from 'react-router-dom'; +import Route from 'react-router-dom/Route'; +import axios from 'axios'; + +class Userline extends Component { + + constructor(props) + { + super(props); + this.state = { + + } + } + + render() { + return ( +

Hi

+ ) + } + +} + +export default Userline; \ No newline at end of file diff --git a/twistter-frontend/src/Writing_Microblogs.js b/twistter-frontend/src/Writing_Microblogs.js index 4769a9a..d9cbb1e 100644 --- a/twistter-frontend/src/Writing_Microblogs.js +++ b/twistter-frontend/src/Writing_Microblogs.js @@ -27,12 +27,19 @@ class Writing_Microblogs extends Component { handleSubmit(event) { // alert('A title for the microblog was inputted: ' + this.state.title + '\nA microblog was posted: ' + this.state.value); - const response = await axios.post( + + const response = axios.post( 'http://localhost:5001/twistter-e4649/us-central1/api/putPost', - { }, + { body: this.state.value, + userHandle: "new user", + userImage: "bing-url", + microBlogTitle: this.state.title + + }, { headers: { 'Content-Type': 'application/json'} } ) console.log(response.data); + event.preventDefault(); } From b1cfcda948db174b5a334753d7cb212c36c7338b Mon Sep 17 00:00:00 2001 From: Aaron Sun Date: Mon, 30 Sep 2019 22:26:28 -0400 Subject: [PATCH 03/10] Clean baseline --- twistter-frontend/package.json | 3 +-- twistter-frontend/src/Login.js | 2 -- twistter-frontend/src/Register.js | 2 -- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/twistter-frontend/package.json b/twistter-frontend/package.json index b18ef34..9971045 100644 --- a/twistter-frontend/package.json +++ b/twistter-frontend/package.json @@ -28,6 +28,5 @@ "last 1 firefox version", "last 1 safari version" ] - }, - "proxy": "https://us-central1-socialape-2619.cloudfunctions.net/api" + } } diff --git a/twistter-frontend/src/Login.js b/twistter-frontend/src/Login.js index 86c8d98..50ecfdc 100644 --- a/twistter-frontend/src/Login.js +++ b/twistter-frontend/src/Login.js @@ -4,8 +4,6 @@ import './App.css'; import logo from './twistter-logo.png'; import TextField from '@material-ui/core/TextField'; -import axios from 'axios'; - class Login extends Component { render() { return ( diff --git a/twistter-frontend/src/Register.js b/twistter-frontend/src/Register.js index a04dde4..8828204 100644 --- a/twistter-frontend/src/Register.js +++ b/twistter-frontend/src/Register.js @@ -4,8 +4,6 @@ import './App.css'; import logo from './twistter-logo.png'; import TextField from '@material-ui/core/TextField'; -//import axios from 'axios'; - class Register extends Component { render() { return ( From 201f5d894936297ef3de2d85a97a0d5bde5e202e Mon Sep 17 00:00:00 2001 From: Aaron Sun Date: Mon, 30 Sep 2019 23:04:37 -0400 Subject: [PATCH 04/10] Reconciled my code with master --- .firebaserc | 2 +- firebase.json | 55 +++--- functions/index.js | 223 +++++++++++++++++++-- functions/package-lock.json | 385 +++++++++++++++++++++++++----------- functions/package.json | 5 +- 5 files changed, 499 insertions(+), 171 deletions(-) diff --git a/.firebaserc b/.firebaserc index 0b3cf99..2e9e776 100644 --- a/.firebaserc +++ b/.firebaserc @@ -5,4 +5,4 @@ "Twistter1": "twistter-6a42d", "SuperTiger69": "twistter-e4649" } -} \ No newline at end of file +} diff --git a/firebase.json b/firebase.json index 896c687..0e2c6a7 100644 --- a/firebase.json +++ b/firebase.json @@ -1,29 +1,30 @@ { - "database": { - "rules": "database.rules.json" - }, - "firestore": { - "rules": "firestore.rules", - "indexes": "firestore.indexes.json" - }, - "functions": { - "predeploy": [ - "npm --prefix \"$RESOURCE_DIR\" run lint" - ] - }, - "hosting": { - "public": "public", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [{ - "source": "/feed", - "destination": "/feed.html" - }] - }, - "storage": { - "rules": "storage.rules" + "database": { + "rules": "database.rules.json" + }, + "firestore": { + "rules": "firestore.rules", + "indexes": "firestore.indexes.json" + }, + "functions": { + "predeploy": [ + "npm --prefix \"$RESOURCE_DIR\" run lint" + ] + }, + "hosting": { + "public": "public", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ], + "rewrites": [{ + "source": "/feed", + "destination": "/feed.html" + }] + }, + "storage": { + "rules": "storage.rules" + } } -} + \ No newline at end of file diff --git a/functions/index.js b/functions/index.js index 9130d2f..4b2edf2 100644 --- a/functions/index.js +++ b/functions/index.js @@ -5,7 +5,7 @@ const app = require('express')(); admin.initializeApp(); const db = admin.firestore(); -const firebaseConfig = { +var config = { apiKey: "AIzaSyCvsWetg4qFdsPGfJ3LCw_QaaYzoan7Q34", authDomain: "twistter-e4649.firebaseapp.com", databaseURL: "https://twistter-e4649.firebaseio.com", @@ -15,40 +15,221 @@ const firebaseConfig = { appId: "1:20131817365:web:633c95fb08b16d4526b89c" }; + const firebase = require('firebase'); -firebase.initializeApp(firebaseConfig); +firebase.initializeApp(config); // Acts as a middleman between the client and any function that you use it with // The function will only execute if the user is logged in, or rather, they have // a valid token -const FBAuth = (req, resp, next) => { +const firebaseAuth = (req, res, next) => { let idToken; if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) { idToken = req.headers.authorization.split('Bearer ')[1]; } else { console.error('No token found'); - return resp.status(403).json({ error: 'Unauthorized' }); + return res.status(403).json({ error: 'Unauthorized' }); } admin.auth().verifyIdToken(idToken) - .then(decodedToken => { - req.user = decodedToken; - console.log(decodedToken); - return db.collection('users') - .where('userId', '==', req.user.uid) - .limit(1) - .get(); - }) - .then(data => { - req.user.handle = data.docs[0].data().handle; - return next(); - }) - .catch(err => { - console.error('Error verifying token', err); - return res.status(403).json(err); - }) -} + .then(decodedToken => { + req.user = decodedToken; + console.log(decodedToken); + return db.collection('users') + .where('userId', '==', req.user.uid) + .limit(1) + .get(); + }) + .then(data => { + req.user.username = data.docs[0].data().username; + return next(); + }) + .catch(err => { + console.error("Token verfication failed.", err); + return res.status(403).json(err); + }); +}; + +app.post('/scream', firebaseAuth, (req, res) => { + const newScream = { + username: req.user.username, + body: req.body.body, + numLikes: 0, + numComments: 0, + time: new Date().toISOString() + }; + + let invalidCred = {}; + + //Body check + if(req.body.body.trim() === '') { + invalidCred.body = 'Body must not be blank'; + } + + //Overall check + if(Object.keys(invalidCred).length > 0) { + return res.status(400).json(errors); + } + + db + .collection('screams') + .add(newScream) + .then(doc => { + res.json({ message: `Document ${doc.id} created successfully!` }); + }) + .catch(err => { + console.error(err); + return res.status(500).json({ error: 'Someting went wrong.' }); + }); +}); + +app.get('/screams', (req, res) => { + db + .collection('screams') + .orderBy('time', 'desc') + .get() + .then(data => { + let screams = []; + data.forEach(doc => { + screams.push({ + username: doc.data().username, + body: doc.data().body, + numLikes: doc.data().numLikes, + numComments: doc.data().numComments, + time: doc.data().time, + screamId: doc.id + }); + }); + return res.json(screams); + }) + .catch(err => { + console.error(err); + return res.status(500).json({ error: err.code }); + }); +}); + +app.post('/signup', (req, res) => { + const newUser = { + email: req.body.email, + username: req.body.username, + password: req.body.password, + confirmPassword: req.body.confirmPassword, + time: new Date().toISOString() + }; + + let invalidCred = {}; + + const emailRegEx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + + //Email check + if(newUser.email.trim() === '') { + invalidCred.email = 'Email must not be blank.'; + } + else if(!newUser.email.match(emailRegEx)) { + invalidCred.email = 'Email is invalid.'; + } + + //Username check + if(newUser.username.trim() === '') { + invalidCred.username = 'Username must not be blank.'; + } + else if(newUser.username.length < 4 || newUser.username.length > 30) { + invalidCred.username = 'Username must be between 4-30 characters long.'; + } + + //Password check + if(newUser.password.trim() === '') { + invalidCred.password = 'Password must not be blank.'; + } + else if(newUser.password.length < 8 || newUser.password.length > 20) { + invalidCred.password = 'Password must be between 8-20 characters long.'; + } + + //Confirm password check + if(newUser.confirmPassword !== newUser.password) { + invalidCred.confirmPassword = 'Passwords must match.'; + } + + //Overall check + if(Object.keys(invalidCred).length > 0) { + return res.status(400).json(errors); + } + + let idToken, userId; + + db.doc(`/users/${newUser.username}`).get() + .then(doc => { + if(doc.exists) { + return res.status(400).json({ username: 'This username is already taken.' }); + } + return firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password); + }) + .then(data => { + userId = data.user.uid; + return data.user.getIdToken(); + }) + .then(token => { + idToken = token; + const userCred = { + email: req.body.email, + username: newUser.username, + time: newUser.time, + userId + } + return db.doc(`/users/${newUser.username}`).set(userCred); + }) + .then(() => { + return res.status(201).json({ idToken }); + }) + .catch(err => { + console.error(err); + if(err.code === 'auth/email-already-in-use') { + return res.status(500).json({ email: 'This email is already taken.' }); + } + return res.status(500).json({ error: err.code }); + }); +}); + +app.post('/login', (req, res) => { + const user = { + email: req.body.email, + password: req.body.password + } + + //Auth validation + let invalidCred = {}; + + //Email check + if(user.email.trim() === '') { + invalidCred.email = 'Email must not be blank.'; + } + + //Password check + if(user.password.trim() === '') { + invalidCred.password = 'Password must not be blank.'; + } + + //Overall check + if(Object.keys(invalidCred).length > 0) { + return res.status(400).json(errors); + } + + firebase.auth().signInWithEmailAndPassword(user.email, user.password) + .then(data => { + return data.user.getIdToken(); + }) + .then(token => { + return res.json({token}); + }) + .catch(err => { + console.error(err); + if(err.code === 'auth/wrong-password') { + return res.status(403).json({ general: 'Invalid credentials. Please try again.' }); + } + return res.status(500).json({ error: err.code }); + }); +}); app.get('/getUsers', (req, res) => { admin.firestore().collection('users').get().then(data => { diff --git a/functions/package-lock.json b/functions/package-lock.json index a23d4aa..2b7397c 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -24,16 +24,31 @@ } }, "@firebase/app": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.4.16.tgz", + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.4.17.tgz", "integrity": "sha512-4aa6ixQlV6xQxj4HbwFKrfYZnnKk8AtB/vEEuIaBCGQYBvV287OVNCozXd4CC4Q4I4Vtkzrc+kggahYFl8nDWQ==", "requires": { "@firebase/app-types": "0.4.3", - "@firebase/logger": "0.1.24", - "@firebase/util": "0.2.27", + "@firebase/logger": "0.1.25", + "@firebase/util": "0.2.28", "dom-storage": "2.1.0", "tslib": "1.10.0", "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "@firebase/logger": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.25.tgz", + "integrity": "sha512-/lRhuepVcCCnQ2jcO5Hr08SYdmZDTQU9fdPdzg+qXJ9k/QnIrD2RbswXQcL6mmae3uPpX7fFXQAoScJ9pzp50w==" + }, + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } + } } }, "@firebase/app-types": { @@ -55,8 +70,8 @@ "integrity": "sha512-foQHhvyB0RR+mb/+wmHXd/VOU+D8fruFEW1k79Q9wzyTPpovMBa1Mcns5fwEWBhUfi8bmoEtaGB8RSAHnTFzTg==" }, "@firebase/database": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.2.tgz", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.3.tgz", "integrity": "sha512-LnXKRE1AmjlS+iRF7j8vx+Ni8x85CmLP5u5Pw5rDKhKLn2eTR1tJKD937mUeeGEtDHwR1rrrkLYOqRR2cSG3hQ==", "requires": { "@firebase/database-types": "0.4.3", @@ -75,17 +90,32 @@ } }, "@firebase/firestore": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.5.2.tgz", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.5.3.tgz", "integrity": "sha512-CPYLvkGZBKE47oQC9a0q13UMVRj3LvnSbB1nOerktE3CGRHKy44LxDumamN8Kj067hV/80mKK9FdbeUufwO/Rg==", "requires": { "@firebase/firestore-types": "1.5.0", - "@firebase/logger": "0.1.24", - "@firebase/util": "0.2.27", + "@firebase/logger": "0.1.25", + "@firebase/util": "0.2.28", "@firebase/webchannel-wrapper": "0.2.26", "@grpc/proto-loader": "^0.5.0", "grpc": "1.23.3", "tslib": "1.10.0" + }, + "dependencies": { + "@firebase/logger": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.25.tgz", + "integrity": "sha512-/lRhuepVcCCnQ2jcO5Hr08SYdmZDTQU9fdPdzg+qXJ9k/QnIrD2RbswXQcL6mmae3uPpX7fFXQAoScJ9pzp50w==" + }, + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } + } } }, "@firebase/firestore-types": { @@ -94,9 +124,9 @@ "integrity": "sha512-VhRHNbEbak+R2iK8e1ir2Lec7eaHMZpGTRy6LMtzATYthlkwNHF9tO8JU8l6d1/kYkI4+DWzX++i3HhTziHEWA==" }, "@firebase/functions": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.17.tgz", - "integrity": "sha512-heWMXrR3hgvQNe1JEZMUeY7a0QFLMVwVS+lzLq/lzk06bj22X9bJy7Yct+/P9P1ftnsCGLrhk3jAEuL78seoqg==", + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.18.tgz", + "integrity": "sha512-N/ijwpxJy26kOErYIi5QS8pQgMZEuEMF/zDaNmgqcoN3J8P52NhBnVQZnIl+U4W96nQfNiURhSwXEERHFyvSZQ==", "requires": { "@firebase/functions-types": "0.3.8", "@firebase/messaging-types": "0.3.2", @@ -110,14 +140,24 @@ "integrity": "sha512-9hajHxA4UWVCGFmoL8PBYHpamE3JTNjObieMmnvZw3cMRTP2EwipMpzZi+GPbMlA/9swF9yHCY/XFAEkwbvdgQ==" }, "@firebase/installations": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.2.6.tgz", - "integrity": "sha512-hkuKmBtnsmqIfWxt9KyaN+cP574pfTcB81IG5tnmVcgP1xQ4hyQ9LRP0M7jDTGWMw272TInBzUuaM05xw9GMnA==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.2.7.tgz", + "integrity": "sha512-67tzowHVwRBtEuB1HLMD+fCdoRyinOQlMKBes7UwrtZIVd0CPDUqAKxNqup5EypWZb7O2tqFtRzK7POajfSNMA==", "requires": { "@firebase/installations-types": "0.1.2", - "@firebase/util": "0.2.27", + "@firebase/util": "0.2.28", "idb": "3.0.2", "tslib": "1.10.0" + }, + "dependencies": { + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } + } } }, "@firebase/installations-types": { @@ -131,13 +171,23 @@ "integrity": "sha512-wPwhWCepEjWiTIqeC9U+7Hcw4XwezKPdXmyXbYSPiWNDcVekNgMPkntwSK+/2ufJO/1nMwAL2n6fL12oQG/PpQ==" }, "@firebase/messaging": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.4.10.tgz", - "integrity": "sha512-WqtSqlulV2ix4MZ3r1HwGAEj0DiEWtpNCSPh5wOXZsj8Kd01Q2QPTLUtUWmwXSV9WCQWnowfE2x8wjq5388ixw==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.4.11.tgz", + "integrity": "sha512-KYt479yio6ThkV7Pb9LRB1KPIBio+OR4RozwyoLC1ZSVQdTIrd/sVEuDSzYY88Wh/6Kg6ejdu2z6mfWG9l1ZaQ==", "requires": { "@firebase/messaging-types": "0.3.2", - "@firebase/util": "0.2.27", + "@firebase/util": "0.2.28", "tslib": "1.10.0" + }, + "dependencies": { + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } + } } }, "@firebase/messaging-types": { @@ -146,15 +196,30 @@ "integrity": "sha512-2qa2qNKqpalmtwaUV3+wQqfCm5myP/dViIBv+pXF8HinemIfO1IPQtr9pCNfsSYyus78qEhtfldnPWXxUH5v0w==" }, "@firebase/performance": { - "version": "0.2.18", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.2.18.tgz", - "integrity": "sha512-PcN+nTPaMGqODfwAXgwbaCvcxXH+YzvK6UpZzm0Bl9wmW28/oJipnUxF3cYbVGCiaLAaByIPVSIF22XhTOjUtA==", + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.2.19.tgz", + "integrity": "sha512-dINWwR/XcSiSnFNNX7QWfec8bymiXk1Zp6mPyPN+R9ONMrpDbygQUy06oT/6r/xx9nHG4Za6KMUJag3sWNKqnQ==", "requires": { - "@firebase/installations": "0.2.6", - "@firebase/logger": "0.1.24", + "@firebase/installations": "0.2.7", + "@firebase/logger": "0.1.25", "@firebase/performance-types": "0.0.3", - "@firebase/util": "0.2.27", + "@firebase/util": "0.2.28", "tslib": "1.10.0" + }, + "dependencies": { + "@firebase/logger": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.25.tgz", + "integrity": "sha512-/lRhuepVcCCnQ2jcO5Hr08SYdmZDTQU9fdPdzg+qXJ9k/QnIrD2RbswXQcL6mmae3uPpX7fFXQAoScJ9pzp50w==" + }, + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } + } } }, "@firebase/performance-types": { @@ -163,9 +228,9 @@ "integrity": "sha512-RuC63nYJPJU65AsrNMc3fTRcRgHiyNcQLh9ufeKUT1mEsFgpxr167gMb+tpzNU4jsbvM6+c6nQAFdHpqcGkRlQ==" }, "@firebase/polyfill": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.21.tgz", - "integrity": "sha512-2mqS3FQHMhCGyfMGRsaZEypHSBD8hVmp9ZBnZSkn8hq5sSOLiNTFSC0FsvNu5z99GNsPQJFTui8bxcZl5cHQbw==", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.22.tgz", + "integrity": "sha512-PYbEqDHJhJJoF2Q5IB/oP0Tz6O2vSUPtODy9kUQibi+T0bK1gkTaySPwz8GAgHfIpFNENj1kK+7Xpf87R8bYbw==", "requires": { "core-js": "3.2.1", "promise-polyfill": "8.1.3", @@ -180,13 +245,23 @@ } }, "@firebase/storage": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.11.tgz", - "integrity": "sha512-Q2ffXE+X62gFy5mZkg7qhzAC7+kqaNZWpgS+297h/hWr/cFBDyC8eBPmnI509eKi2okixmOMbWnNluZkNYNSfw==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.12.tgz", + "integrity": "sha512-8hXt3qPZlVH+yPF4W9Dc15/gBiTPGUJUgYs3dH9WnO41QWl1o4aNlZpZK/pdnpCIO1GmN0+PxJW9TCNb0H0Hqw==", "requires": { "@firebase/storage-types": "0.3.3", - "@firebase/util": "0.2.27", + "@firebase/util": "0.2.28", "tslib": "1.10.0" + }, + "dependencies": { + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } + } } }, "@firebase/storage-types": { @@ -208,9 +283,9 @@ "integrity": "sha512-VlTurkvs4v7EVFWESBZGOPghFEokQhU5au5CP9WqA8B2/PcQRDsaaQlQCA6VATuEnW+vtSiSBvTiOc4004f8xg==" }, "@google-cloud/common": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.2.0.tgz", - "integrity": "sha512-ArSNbbuMOWVhrSasxECEYRcjMzkPgTfXJHQE5gccyDaoBv0oKqG9S2lse2KAgHpRADRna7wKiX9PWOpeB19VvA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.2.2.tgz", + "integrity": "sha512-AgMdDgLeYlEG17tXtMCowE7mplm907pcugtfJYYAp06HNe9RDnunUIY5KMnn9yikYl7NXNofARC+hwG77Zsa4g==", "optional": true, "requires": { "@google-cloud/projectify": "^1.0.0", @@ -256,7 +331,8 @@ "@google-cloud/promisify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-1.0.2.tgz", - "integrity": "sha512-7WfV4R/3YV5T30WRZW0lqmvZy9hE2/p9MvpI34WuKa2Wz62mLu5XplGTFEMK6uTbJCLWUxTcZ4J4IyClKucE5g==" + "integrity": "sha512-7WfV4R/3YV5T30WRZW0lqmvZy9hE2/p9MvpI34WuKa2Wz62mLu5XplGTFEMK6uTbJCLWUxTcZ4J4IyClKucE5g==", + "optional": true }, "@google-cloud/storage": { "version": "3.2.1", @@ -443,6 +519,7 @@ "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, "requires": { "event-target-shim": "^5.0.0" } @@ -472,6 +549,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "optional": true, "requires": { "es6-promisify": "^5.0.0" } @@ -497,7 +575,7 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { @@ -526,7 +604,8 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true }, "ascli": { "version": "1.0.1", @@ -552,12 +631,14 @@ "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "optional": true }, "bignumber.js": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", + "optional": true }, "body-parser": { "version": "1.19.0", @@ -705,28 +786,28 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } } }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } +}, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -853,7 +934,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true }, "cors": { "version": "2.8.5", @@ -901,6 +983,7 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "optional": true, "requires": { "ms": "^2.1.1" } @@ -984,6 +1067,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "optional": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -994,12 +1078,14 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1013,12 +1099,14 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -1061,6 +1149,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "optional": true, "requires": { "once": "^1.4.0" } @@ -1074,12 +1163,14 @@ "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "optional": true }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "optional": true, "requires": { "es6-promise": "^4.0.3" } @@ -1242,7 +1333,8 @@ "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==" + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true }, "express": { "version": "4.17.1", @@ -1304,7 +1396,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true }, "external-editor": { "version": "3.1.0", @@ -1338,7 +1431,8 @@ "fast-text-encoding": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", - "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" + "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==", + "optional": true }, "faye-websocket": { "version": "0.11.3", @@ -1396,42 +1490,55 @@ } }, "firebase": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-6.6.1.tgz", - "integrity": "sha512-iXbHPIBRt04xYSjWffnARqZbc3vUc0RTnOHsMtAqaT7pqDWicaghEwj2WbCJ0+JLAiKnLNK7fTjW73zfKQSSoQ==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-6.6.2.tgz", + "integrity": "sha512-uL9uNbutC0T8GAxrGgOCC35Ven3QKJqzJozNoVIpBuiWrB9ifm9aKOxn44h6o5ouviax3LVvoiG2jLkLkdQq4A==", "requires": { - "@firebase/app": "0.4.16", + "@firebase/app": "0.4.17", "@firebase/app-types": "0.4.3", "@firebase/auth": "0.12.0", - "@firebase/database": "0.5.3", - "@firebase/firestore": "1.5.2", - "@firebase/functions": "0.4.17", - "@firebase/installations": "0.2.6", - "@firebase/messaging": "0.4.10", - "@firebase/performance": "0.2.18", - "@firebase/polyfill": "0.3.21", - "@firebase/storage": "0.3.11", - "@firebase/util": "0.2.27" + "@firebase/database": "0.5.4", + "@firebase/firestore": "1.5.3", + "@firebase/functions": "0.4.18", + "@firebase/installations": "0.2.7", + "@firebase/messaging": "0.4.11", + "@firebase/performance": "0.2.19", + "@firebase/polyfill": "0.3.22", + "@firebase/storage": "0.3.12", + "@firebase/util": "0.2.28" }, "dependencies": { "@firebase/database": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.3.tgz", - "integrity": "sha512-TFjQ/M0T4jO24jAMU5cZAHNk3ndNfeNtGKe5PL4o/YrGYJHg3XaE2LKzU/vFrXUFLnLxqbETzXjFa4hTA6cDUg==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.4.tgz", + "integrity": "sha512-Hz1Bi3fzIcNNocE4EhvvwoEQGurG2BGssWD3/6a2bzty+K1e57SLea2Ied8QYNBUU1zt/4McHfa3Y71EQIyn/w==", "requires": { "@firebase/database-types": "0.4.3", - "@firebase/logger": "0.1.24", - "@firebase/util": "0.2.27", + "@firebase/logger": "0.1.25", + "@firebase/util": "0.2.28", "faye-websocket": "0.11.3", "tslib": "1.10.0" } + }, + "@firebase/logger": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.25.tgz", + "integrity": "sha512-/lRhuepVcCCnQ2jcO5Hr08SYdmZDTQU9fdPdzg+qXJ9k/QnIrD2RbswXQcL6mmae3uPpX7fFXQAoScJ9pzp50w==" + }, + "@firebase/util": { + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.28.tgz", + "integrity": "sha512-ZQMAWtXj8y5kvB6izs0aTM/jG+WO8HpqhXA/EwD6LckJ+1P5LnAhaLZt1zR4HpuCE+jeP5I32Id5RJ/aifFs6A==", + "requires": { + "tslib": "1.10.0" + } } } }, "firebase-admin": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.5.0.tgz", - "integrity": "sha512-rvgCj5Z1iFOT6K6uW37VRl4PKNpAcBFu/FIQ4Nl5bFnqbHSxf+QxzsqdsUtIxdqZU1yh2DTs2t+s5qORx/T9+g==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.6.0.tgz", + "integrity": "sha512-+JqOinU5bYUkg434LqEBXrHMrIBhL/+HwWEgbZpS1sBKHQRJK7LlcBrayqxvQKwJzgh5xs/JTInTmkozXk7h1w==", "requires": { "@firebase/database": "^0.5.1", "@google-cloud/firestore": "^2.0.0", @@ -1530,12 +1637,14 @@ "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": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "optional": true }, "gaxios": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.0.1.tgz", "integrity": "sha512-c1NXovTxkgRJTIgB2FrFmOFg4YIV6N/bAa4f/FZ4jIw13Ql9ya/82x69CswvotJhbV3DiGnlTZwoq2NVXk2Irg==", + "optional": true, "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -1544,9 +1653,10 @@ } }, "gcp-metadata": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-2.0.2.tgz", - "integrity": "sha512-dxPXBvjyfz5qFEBXzEwNmuZXwsGYfuASGYeg3CKZDaQRXdiWti9J3/Ezmtyon1OrCNpDO2YekyoSjEqMtsrcXw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.0.0.tgz", + "integrity": "sha512-WP5/TZWri9TrD41jNr8ukY9dKYLL+8jwQVwbtUbmprjWuyybdnJNkbXbwqD2sdbXIVXD1WCqzfj7QftSLB6K8Q==", + "optional": true, "requires": { "gaxios": "^2.0.1", "json-bigint": "^0.3.0" @@ -1587,15 +1697,16 @@ "dev": true }, "google-auth-library": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.2.1.tgz", - "integrity": "sha512-p9vO6UcRIK/zD3PxoMijaUfFYu6tvzaQwvag1K/82O42NBeAnmllyQUgqaBhcAh9FzFAVlN4bQIaO8+prpE7Vg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.2.2.tgz", + "integrity": "sha512-0vzniXbjD5SE9aenAMqhjVR99wvqLpyd5Fw6zC3WxJ15GIMGx96tq+Cu1WRviqsnQqhrmnad6T69kv6qkj/w2Q==", + "optional": true, "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", "fast-text-encoding": "^1.0.0", "gaxios": "^2.0.0", - "gcp-metadata": "^2.0.0", + "gcp-metadata": "^3.0.0", "gtoken": "^4.0.0", "jws": "^3.1.5", "lru-cache": "^5.0.0" @@ -1626,6 +1737,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.2.tgz", "integrity": "sha512-UfnEARfJKI6pbmC1hfFFm+UAcZxeIwTiEcHfqKe/drMsXD/ilnVjF7zgOGpHXyhuvX6jNJK3S8A0hOQjwtFxEw==", + "optional": true, "requires": { "node-forge": "^0.9.0" }, @@ -1633,7 +1745,8 @@ "node-forge": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==" + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "optional": true } } }, @@ -2076,6 +2189,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.0.0.tgz", "integrity": "sha512-XaRCfHJxhj06LmnWNBzVTAr85NfAErq0W1oabkdqwbq3uL/QTB1kyvGog361Uu2FMG/8e3115sIy/97Rnd4GjQ==", + "optional": true, "requires": { "gaxios": "^2.0.0", "google-p12-pem": "^2.0.0", @@ -2131,7 +2245,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true }, "string_decoder": { "version": "1.1.1", @@ -2209,6 +2324,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "optional": true, "requires": { "agent-base": "^4.3.0", "debug": "^3.1.0" @@ -2246,7 +2362,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "optional": true }, "inflight": { "version": "1.0.6", @@ -2261,7 +2378,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "optional": true }, "inquirer": { "version": "6.5.2", @@ -2326,8 +2444,10 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-obj": { "version": "2.0.0", @@ -2364,7 +2484,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "optional": true }, "isarray": { "version": "0.0.1", @@ -2418,6 +2539,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", + "optional": true, "requires": { "bignumber.js": "^7.0.0" } @@ -2559,6 +2681,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "optional": true, "requires": { "yallist": "^3.0.2" } @@ -2590,7 +2713,8 @@ "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "optional": true }, "mime-db": { "version": "1.41.0", @@ -2679,7 +2803,8 @@ "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "optional": true }, "node-forge": { "version": "0.7.4", @@ -2705,7 +2830,8 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "optional": true }, "on-finished": { "version": "2.3.0", @@ -2719,6 +2845,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "optional": true, "requires": { "wrappy": "1" } @@ -2826,7 +2953,8 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "optional": true }, "progress": { "version": "2.0.3", @@ -2879,6 +3007,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "optional": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -2888,6 +3017,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.0.tgz", "integrity": "sha512-ieN9HmpFPt4J4U4qnjN4BxrnqpPPXJyp3qFErxfwBtFOec6ewpIHdS2eu3TkmGW6S+RzFGEOGpm5ih/X/onRPQ==", + "optional": true, "requires": { "duplexify": "^4.1.1", "inherits": "^2.0.3", @@ -2898,6 +3028,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "optional": true, "requires": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", @@ -2909,6 +3040,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "optional": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2919,6 +3051,7 @@ "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, "requires": { "safe-buffer": "~5.2.0" } @@ -3073,7 +3206,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true }, "send": { "version": "0.17.1", @@ -3156,7 +3290,8 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "optional": true }, "slice-ansi": { "version": "2.1.0", @@ -3190,6 +3325,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, "requires": { "stubs": "^3.0.0" } @@ -3197,7 +3333,8 @@ "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "optional": true }, "streamsearch": { "version": "0.1.2", @@ -3207,9 +3344,9 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { + "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } @@ -3223,7 +3360,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -3238,7 +3375,8 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "optional": true }, "supports-color": { "version": "5.5.0", @@ -3318,6 +3456,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "optional": true, "requires": { "readable-stream": "2 || 3" }, @@ -3326,6 +3465,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "optional": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3336,6 +3476,7 @@ "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, "requires": { "safe-buffer": "~5.2.0" } @@ -3420,7 +3561,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "optional": true }, "utils-merge": { "version": "1.0.1", @@ -3529,7 +3671,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true }, "write": { "version": "1.0.3", @@ -3555,7 +3698,8 @@ "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "optional": true }, "xmlhttprequest": { "version": "1.8.0", @@ -3575,7 +3719,8 @@ "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "optional": true }, "yargs": { "version": "3.32.0", diff --git a/functions/package.json b/functions/package.json index 200b47a..a4d52a8 100644 --- a/functions/package.json +++ b/functions/package.json @@ -10,10 +10,11 @@ "logs": "firebase functions:log" }, "engines": { - "node": "8" + "node": "10" }, "dependencies": { - "firebase": "^6.6.1", + "express": "^4.17.1", + "firebase": "^6.6.2", "firebase-admin": "^8.0.0", "firebase-functions": "^3.1.0" }, From 022f440cb92127d88b55d76d63c961cdb357e1a2 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 1 Oct 2019 12:44:47 -0400 Subject: [PATCH 05/10] added Navigation bar to home page --- functions/handlers/users.js | 1 + 1 file changed, 1 insertion(+) diff --git a/functions/handlers/users.js b/functions/handlers/users.js index 240bfdd..df7465a 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -1,3 +1,4 @@ +/* eslint-disable promise/catch-or-return */ const {db} = require('../util/admin'); const {validateUpdateProfileInfo} = require('../util/validator'); From 60d1d76839194e8a8d1b0c2408a1739d64f7c551 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 1 Oct 2019 12:56:34 -0400 Subject: [PATCH 06/10] Added nav bar --- twistter-frontend/src/App.js | 5 ++++- twistter-frontend/src/components/layout/NavBar.js | 8 +++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index 1fea229..e6efa6c 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -6,6 +6,7 @@ import './App.css'; import { BrowserRouter as Router } from 'react-router-dom'; import Route from 'react-router-dom/Route'; +import NavBar, { Navbar } from './components/layout/NavBar'; import home from './Home.js'; import register from './Register.js'; @@ -18,7 +19,9 @@ class App extends Component { render() { return ( - +
+ +
diff --git a/twistter-frontend/src/components/layout/NavBar.js b/twistter-frontend/src/components/layout/NavBar.js index 9a7d6eb..e4ee5c5 100644 --- a/twistter-frontend/src/components/layout/NavBar.js +++ b/twistter-frontend/src/components/layout/NavBar.js @@ -10,8 +10,8 @@ export class Navbar extends Component { return ( - - + ) From 754c2f2d75fc1511f44072258bff2bf5be7bae0e Mon Sep 17 00:00:00 2001 From: Aditya Sankaran Date: Tue, 1 Oct 2019 14:03:15 -0400 Subject: [PATCH 07/10] added get request userline function --- functions/handlers/post.js | 17 +++++++++++++ functions/index.js | 3 ++- twistter-frontend/src/Userline.js | 27 +++++++++++++++------ twistter-frontend/src/Writing_Microblogs.js | 4 ++- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/functions/handlers/post.js b/functions/handlers/post.js index 79fcc4a..d15ea33 100644 --- a/functions/handlers/post.js +++ b/functions/handlers/post.js @@ -26,3 +26,20 @@ exports.putPost = (req, res) => { }); }; +exports.getallPostsforUser = (req, res) => { + + admin.firestore().collection('posts').where('userHandle', '==', 'user' ).get() + .then((data) => { + let posts = []; + data.forEach(function(doc) { + posts.push(doc.data()); + }); + return res.status(200).json(posts); + }) + .catch((err) => { + console.error(err); + return res.status(500).json({error: 'Failed to fetch all posts written by specific user.'}) + }) + } + + diff --git a/functions/index.js b/functions/index.js index 15c9020..f93af4c 100644 --- a/functions/index.js +++ b/functions/index.js @@ -24,8 +24,9 @@ app.post('/updateProfileInfo', updateProfileInfo); /*------------------------------------------------------------------* * handlers/post.js * *------------------------------------------------------------------*/ -const {putPost} = require('./handlers/post'); +const {putPost, getallPostsforUser} = require('./handlers/post'); +app.get('/getallPostsforUser', getallPostsforUser); // Adds one post to the database app.post('/putPost', fbAuth, putPost); diff --git a/twistter-frontend/src/Userline.js b/twistter-frontend/src/Userline.js index af4ba7a..51d74f4 100644 --- a/twistter-frontend/src/Userline.js +++ b/twistter-frontend/src/Userline.js @@ -9,16 +9,29 @@ class Userline extends Component { { super(props); this.state = { - + microBlogs : [] } + } - render() { + componentDidMount() { + + axios.get('http://localhost:5001/twistter-e4649/us-central1/api/getallPostsforUser') + .then(res => { + const post = res.data; + this.setState({microBlogs : post}) + + }) + + + } + + render() { return ( -

Hi

+
    + { this.state.microBlogs.map(microBlog =>

    {microBlog.body}

    )} +
) - } - + } } - -export default Userline; \ No newline at end of file +export default Userline; diff --git a/twistter-frontend/src/Writing_Microblogs.js b/twistter-frontend/src/Writing_Microblogs.js index d9cbb1e..1858193 100644 --- a/twistter-frontend/src/Writing_Microblogs.js +++ b/twistter-frontend/src/Writing_Microblogs.js @@ -37,10 +37,11 @@ class Writing_Microblogs extends Component { }, { headers: { 'Content-Type': 'application/json'} } + ) console.log(response.data); - event.preventDefault(); + this.setState({value: '', title: '',characterCount: 10}) } handleChangeforPost(event) { @@ -51,6 +52,7 @@ class Writing_Microblogs extends Component { const charCount = event.target.value.length const charRemaining = 10 - charCount this.setState({characterCount: charRemaining }) + } From cc98fa788433ebdcc5c5bf5b00670cd696f2e94e Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Tue, 1 Oct 2019 15:27:24 -0400 Subject: [PATCH 08/10] Fixed index.js and refactored it. --- functions/handlers/users.js | 133 ++++++++++++++++++++- functions/index.js | 232 ++---------------------------------- 2 files changed, 143 insertions(+), 222 deletions(-) diff --git a/functions/handlers/users.js b/functions/handlers/users.js index 6c5941f..70d6cbd 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -1,7 +1,138 @@ /* eslint-disable promise/catch-or-return */ -const {db} = require('../util/admin'); +const {admin, db} = require('../util/admin'); +const config = require('../util/config'); + const {validateUpdateProfileInfo} = require('../util/validator'); +const firebase = require('firebase'); +firebase.initializeApp(config); + + + +exports.signup = (req, res) => { + const newUser = { + email: req.body.email, + handle: req.body.handle, + password: req.body.password, + confirmPassword: req.body.confirmPassword, + time: new Date().toISOString() + }; + + // console.log(newUser); + + let errors = {}; + + const emailRegEx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + + //Email check + if(newUser.email.trim() === '') { + errors.email = 'Email must not be blank.'; + } + else if(!newUser.email.match(emailRegEx)) { + errors.email = 'Email is invalid.'; + } + + //handle check + if(newUser.handle.trim() === '') { + errors.handle = 'Username must not be blank.'; + } + else if(newUser.handle.length < 4 || newUser.handle.length > 30) { + errors.handle = 'Username must be between 4-30 characters long.'; + } + + //Password check + if(newUser.password.trim() === '') { + errors.password = 'Password must not be blank.'; + } + else if(newUser.password.length < 8 || newUser.password.length > 20) { + errors.password = 'Password must be between 8-20 characters long.'; + } + + //Confirm password check + if(newUser.confirmPassword !== newUser.password) { + errors.confirmPassword = 'Passwords must match.'; + } + + //Overall check + if(Object.keys(errors).length > 0) { + return res.status(400).json(errors); + } + + let idToken, userId; + + db.doc(`/users/${newUser.handle}`).get() + .then(doc => { + if(doc.exists) { + return res.status(400).json({ handle: 'This username is already taken.' }); + } + return firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password); + }) + .then(data => { + userId = data.user.uid; + return data.user.getIdToken(); + }) + .then(token => { + idToken = token; + const userCred = { + email: req.body.email, + handle: newUser.handle, + time: newUser.time, + userId + } + return db.doc(`/users/${newUser.handle}`).set(userCred); + }) + .then(() => { + return res.status(201).json({ idToken }); + }) + .catch(err => { + console.error(err); + if(err.code === 'auth/email-already-in-use') { + return res.status(500).json({ email: 'This email is already taken.' }); + } + return res.status(500).json({ error: err.code }); + }); +}; + +exports.login = (req, res) => { + const user = { + email: req.body.email, + password: req.body.password + } + + //Auth validation + let invalidCred = {}; + + //Email check + if(user.email.trim() === '') { + invalidCred.email = 'Email must not be blank.'; + } + + //Password check + if(user.password.trim() === '') { + invalidCred.password = 'Password must not be blank.'; + } + + //Overall check + if(Object.keys(invalidCred).length > 0) { + return res.status(400).json(errors); + } + + firebase.auth().signInWithEmailAndPassword(user.email, user.password) + .then(data => { + return data.user.getIdToken(); + }) + .then(token => { + return res.json({token}); + }) + .catch(err => { + console.error(err); + if(err.code === 'auth/wrong-password') { + return res.status(403).json({ general: 'Invalid credentials. Please try again.' }); + } + return res.status(500).json({ error: err.code }); + }); + }; + exports.getProfileInfo = (req, res) => { // FIXME: Delete this after login is implemented req.user = {}; diff --git a/functions/index.js b/functions/index.js index 6ff3bd3..04d3b4e 100644 --- a/functions/index.js +++ b/functions/index.js @@ -4,236 +4,26 @@ const app = require('express')(); const cors = require('cors'); app.use(cors()); -var config = { - apiKey: "AIzaSyCvsWetg4qFdsPGfJ3LCw_QaaYzoan7Q34", - authDomain: "twistter-e4649.firebaseapp.com", - databaseURL: "https://twistter-e4649.firebaseio.com", - projectId: "twistter-e4649", - storageBucket: "twistter-e4649.appspot.com", - messagingSenderId: "20131817365", - appId: "1:20131817365:web:633c95fb08b16d4526b89c" -}; +const fbAuth = require('./util/fbAuth'); -const firebase = require('firebase'); -firebase.initializeApp(config); +const {db} = require('./util/admin'); -// Acts as a middleman between the client and any function that you use it with -// The function will only execute if the user is logged in, or rather, they have -// a valid token -const firebaseAuth = (req, res, next) => { - let idToken; +// const firebase = require('firebase'); +// firebase.initializeApp(config); - if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) { - idToken = req.headers.authorization.split('Bearer ')[1]; - } else { - console.error('No token found'); - return res.status(403).json({ error: 'Unauthorized' }); - } - admin.auth().verifyIdToken(idToken) - .then(decodedToken => { - req.user = decodedToken; - console.log(decodedToken); - return db.collection('users') - .where('userId', '==', req.user.uid) - .limit(1) - .get(); - }) - .then(data => { - req.user.username = data.docs[0].data().username; - return next(); - }) - .catch(err => { - console.error("Token verfication failed.", err); - return res.status(403).json(err); - }); -}; -app.post('/scream', firebaseAuth, (req, res) => { - const newScream = { - username: req.user.username, - body: req.body.body, - numLikes: 0, - numComments: 0, - time: new Date().toISOString() - }; - let invalidCred = {}; - - //Body check - if(req.body.body.trim() === '') { - invalidCred.body = 'Body must not be blank'; - } - - //Overall check - if(Object.keys(invalidCred).length > 0) { - return res.status(400).json(errors); - } - - db - .collection('screams') - .add(newScream) - .then(doc => { - res.json({ message: `Document ${doc.id} created successfully!` }); - }) - .catch(err => { - console.error(err); - return res.status(500).json({ error: 'Someting went wrong.' }); - }); -}); - -app.get('/screams', (req, res) => { - db - .collection('screams') - .orderBy('time', 'desc') - .get() - .then(data => { - let screams = []; - data.forEach(doc => { - screams.push({ - username: doc.data().username, - body: doc.data().body, - numLikes: doc.data().numLikes, - numComments: doc.data().numComments, - time: doc.data().time, - screamId: doc.id - }); - }); - return res.json(screams); - }) - .catch(err => { - console.error(err); - return res.status(500).json({ error: err.code }); - }); -}); - -app.post('/signup', (req, res) => { - const newUser = { - email: req.body.email, - username: req.body.username, - password: req.body.password, - confirmPassword: req.body.confirmPassword, - time: new Date().toISOString() - }; - - let invalidCred = {}; - - const emailRegEx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - - //Email check - if(newUser.email.trim() === '') { - invalidCred.email = 'Email must not be blank.'; - } - else if(!newUser.email.match(emailRegEx)) { - invalidCred.email = 'Email is invalid.'; - } - - //Username check - if(newUser.username.trim() === '') { - invalidCred.username = 'Username must not be blank.'; - } - else if(newUser.username.length < 4 || newUser.username.length > 30) { - invalidCred.username = 'Username must be between 4-30 characters long.'; - } - - //Password check - if(newUser.password.trim() === '') { - invalidCred.password = 'Password must not be blank.'; - } - else if(newUser.password.length < 8 || newUser.password.length > 20) { - invalidCred.password = 'Password must be between 8-20 characters long.'; - } - - //Confirm password check - if(newUser.confirmPassword !== newUser.password) { - invalidCred.confirmPassword = 'Passwords must match.'; - } - - //Overall check - if(Object.keys(invalidCred).length > 0) { - return res.status(400).json(errors); - } - - let idToken, userId; - - db.doc(`/users/${newUser.username}`).get() - .then(doc => { - if(doc.exists) { - return res.status(400).json({ username: 'This username is already taken.' }); - } - return firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password); - }) - .then(data => { - userId = data.user.uid; - return data.user.getIdToken(); - }) - .then(token => { - idToken = token; - const userCred = { - email: req.body.email, - username: newUser.username, - time: newUser.time, - userId - } - return db.doc(`/users/${newUser.username}`).set(userCred); - }) - .then(() => { - return res.status(201).json({ idToken }); - }) - .catch(err => { - console.error(err); - if(err.code === 'auth/email-already-in-use') { - return res.status(500).json({ email: 'This email is already taken.' }); - } - return res.status(500).json({ error: err.code }); - }); -}); - -app.post('/login', (req, res) => { - const user = { - email: req.body.email, - password: req.body.password - } - - //Auth validation - let invalidCred = {}; - - //Email check - if(user.email.trim() === '') { - invalidCred.email = 'Email must not be blank.'; - } - - //Password check - if(user.password.trim() === '') { - invalidCred.password = 'Password must not be blank.'; - } - - //Overall check - if(Object.keys(invalidCred).length > 0) { - return res.status(400).json(errors); - } - - firebase.auth().signInWithEmailAndPassword(user.email, user.password) - .then(data => { - return data.user.getIdToken(); - }) - .then(token => { - return res.json({token}); - }) - .catch(err => { - console.error(err); - if(err.code === 'auth/wrong-password') { - return res.status(403).json({ general: 'Invalid credentials. Please try again.' }); - } - return res.status(500).json({ error: err.code }); - }); -}); /*------------------------------------------------------------------* - * handlers/users.js * - *------------------------------------------------------------------*/ -const {getUserDetails, getProfileInfo, updateProfileInfo} = require('./handlers/users'); +* handlers/users.js * +*------------------------------------------------------------------*/ +const {getUserDetails, getProfileInfo, updateProfileInfo, signup, login} = require('./handlers/users'); + +app.post('/signup', signup); + +app.post('/login', login); app.get('/getUser/:handle', getUserDetails); From c5bec46b52794c9133ef716e37504242942bc7cf Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Tue, 1 Oct 2019 16:08:53 -0400 Subject: [PATCH 09/10] Fix fbAuth function not extracting 'Bearer ' --- functions/util/fbAuth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions/util/fbAuth.js b/functions/util/fbAuth.js index 04d71ed..a9243cc 100644 --- a/functions/util/fbAuth.js +++ b/functions/util/fbAuth.js @@ -7,8 +7,8 @@ module.exports = (req, res, next) => { let idToken; // Checking that the token exists in the header of the request - if (req.headers.authorization) { - idToken = req.headers.authorization; + if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) { + idToken = req.headers.authorization.split('Bearer ')[1]; } else { console.error('No token found'); return res.status(403).json({ error: 'Unauthorized'}); From eb945fa0cfcc9b52b4c01eedb7dcc2cfd319dfe7 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Tue, 1 Oct 2019 16:31:37 -0400 Subject: [PATCH 10/10] Finished fixing login and signup backend. --- functions/handlers/users.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/functions/handlers/users.js b/functions/handlers/users.js index 70d6cbd..54dcf00 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -15,7 +15,7 @@ exports.signup = (req, res) => { handle: req.body.handle, password: req.body.password, confirmPassword: req.body.confirmPassword, - time: new Date().toISOString() + createdAt: new Date().toISOString() }; // console.log(newUser); @@ -76,7 +76,7 @@ exports.signup = (req, res) => { const userCred = { email: req.body.email, handle: newUser.handle, - time: newUser.time, + createdAt: newUser.createdAt, userId } return db.doc(`/users/${newUser.handle}`).set(userCred); @@ -100,20 +100,20 @@ exports.login = (req, res) => { } //Auth validation - let invalidCred = {}; + let errors = {}; //Email check if(user.email.trim() === '') { - invalidCred.email = 'Email must not be blank.'; + errors.email = 'Email must not be blank.'; } //Password check if(user.password.trim() === '') { - invalidCred.password = 'Password must not be blank.'; + errors.password = 'Password must not be blank.'; } //Overall check - if(Object.keys(invalidCred).length > 0) { + if(Object.keys(errors).length > 0) { return res.status(400).json(errors); }