mirror of
https://github.com/ClaytonWWilson/CS307-Team24.git
synced 2025-12-16 02:08:47 +00:00
commit
94db3f451d
@ -61,6 +61,7 @@ exports.getallPostsforUser = (req, res) => {
|
||||
};
|
||||
|
||||
exports.getallPosts = (req, res) => {
|
||||
|
||||
var post_query = admin.firestore().collection("posts");
|
||||
post_query
|
||||
.get()
|
||||
@ -170,6 +171,7 @@ exports.quoteWithPost = (req, res) => {
|
||||
return res.status(400).json({ error: "Post has already been quoted." });
|
||||
}
|
||||
})
|
||||
|
||||
.catch(err => {
|
||||
return res.status(500).json({ error: err });
|
||||
});
|
||||
@ -281,6 +283,7 @@ exports.likePost = (req, res) => {
|
||||
return res.status(404).json({ error: "Post not found" });
|
||||
}
|
||||
})
|
||||
|
||||
.then(data => {
|
||||
if (data.empty) {
|
||||
return admin
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/* eslint-disable promise/catch-or-return */
|
||||
/* eslint-disable promise/always-return */
|
||||
|
||||
const { admin, db } = require("../util/admin");
|
||||
const config = require("../util/config");
|
||||
const { validateUpdateProfileInfo } = require("../util/validator");
|
||||
@ -209,7 +210,7 @@ exports.deleteUser = (req, res) => {
|
||||
let errors = {};
|
||||
|
||||
function thenFunction(data) {
|
||||
console.log(`${data} data for ${req.userData.handle} has been deleted.`);
|
||||
console.log(`${data} for ${req.userData.handle} has been deleted.`);
|
||||
}
|
||||
|
||||
function catchFunction(data, err) {
|
||||
@ -217,14 +218,131 @@ exports.deleteUser = (req, res) => {
|
||||
errors[data] = err;
|
||||
}
|
||||
|
||||
function deleteDirectMessages() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const deleteUsername = req.userData.handle;
|
||||
db.doc(`/users/${deleteUsername}`)
|
||||
.get()
|
||||
.then((deleteUserDocSnap) => {
|
||||
const dms = deleteUserDocSnap.data().dms;
|
||||
const dmRecipients = deleteUserDocSnap.data().dmRecipients;
|
||||
|
||||
if (!dms) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over the list of users who this person has DM'd
|
||||
let otherUsersPromises = [];
|
||||
|
||||
// Resolve if they don't have a dmRecipients list
|
||||
if (dmRecipients === undefined || dmRecipients === null || dmRecipients.length === 0) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
dmRecipients.forEach((dmRecipient) => {
|
||||
otherUsersPromises.push(
|
||||
// Get each users data
|
||||
db.doc(`/users/${dmRecipient}`).get()
|
||||
.then((otherUserDocSnap) => {
|
||||
// Get the index of deleteUsername so that we can remove the dangling
|
||||
// reference to the DM document
|
||||
let otherUserDMRecipients = otherUserDocSnap.data().dmRecipients;
|
||||
let otherUserDMs = otherUserDocSnap.data().dms;
|
||||
let index = -1;
|
||||
otherUserDMRecipients.forEach((dmRecip, i) => {
|
||||
if (dmRecip === deleteUsername) {
|
||||
index = i;
|
||||
}
|
||||
})
|
||||
|
||||
if (index !== -1) {
|
||||
// Remove deleteUsername from their dmRecipients list
|
||||
otherUserDMRecipients.splice(index, 1);
|
||||
|
||||
// Remove the DM channel with deleteUsername
|
||||
otherUserDMs.splice(index, 1);
|
||||
|
||||
// Update the users data
|
||||
return otherUserDocSnap.ref.update({
|
||||
dmRecipients: otherUserDMRecipients,
|
||||
dms: otherUserDMs
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
// Wait for the removal of DM data stored on other users to be deleted
|
||||
Promise.all(otherUsersPromises)
|
||||
.then(() => {
|
||||
// Iterate through DM references and delete them from the dm collection
|
||||
let dmRefsPromises = [];
|
||||
dms.forEach((dmRef) => {
|
||||
// Create a delete queue
|
||||
let batch = db.batch();
|
||||
dmRefsPromises.push(
|
||||
// Add the messages to the delete queue
|
||||
db.collection(`/dm/${dmRef.id}/messages`).listDocuments()
|
||||
.then((docs) => {
|
||||
console.log("second")
|
||||
console.log(docs);
|
||||
docs.map((doc) => {
|
||||
batch.delete(doc);
|
||||
})
|
||||
|
||||
// Add the doc that the DM is stored in to the delete queue
|
||||
batch.delete(dmRef);
|
||||
|
||||
// Commit the writes
|
||||
return batch.commit();
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
return Promise.all(dmRefsPromises);
|
||||
})
|
||||
.then(() => {
|
||||
resolve();
|
||||
return;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("error " + err);
|
||||
reject(err);
|
||||
return;
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return res.status(500).json({error: err});
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// Deletes user from authentication
|
||||
let auth = admin.auth().deleteUser(userId);
|
||||
|
||||
// Deletes database data
|
||||
let data = db
|
||||
.collection("users")
|
||||
.doc(`${req.user.handle}`)
|
||||
.delete();
|
||||
let data = new Promise((resolve, reject) => {
|
||||
deleteDirectMessages()
|
||||
.then(() => {
|
||||
return db
|
||||
.collection("users")
|
||||
.doc(`${req.user.handle}`)
|
||||
.delete()
|
||||
})
|
||||
.then(() => {
|
||||
resolve();
|
||||
return;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
reject(err);
|
||||
return;
|
||||
})
|
||||
})
|
||||
|
||||
// Deletes any custom profile image
|
||||
let image;
|
||||
@ -507,6 +625,7 @@ exports.removeSub = (req, res) => {
|
||||
.catch(err => {
|
||||
return res.status(500).json({ err });
|
||||
});
|
||||
|
||||
return res.status(200).json({ message: "ok" });
|
||||
});
|
||||
};
|
||||
|
||||
@ -43,5 +43,5 @@
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"proxy": "http://localhost:5006/twistter-e4649/us-central1/api"
|
||||
"proxy": "http://localhost:5001/twistter-e4649/us-central1/api"
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import React, { Component } from "react";
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import Route from 'react-router-dom/Route';
|
||||
// import { BrowserRouter as Router } from 'react-router-dom';
|
||||
// import Route from 'react-router-dom/Route';
|
||||
import axios from 'axios';
|
||||
import Box from '@material-ui/core/Box'
|
||||
import {borders} from '@material-ui/system';
|
||||
import { sizing } from '@material-ui/system';
|
||||
// import {borders} from '@material-ui/system';
|
||||
// import { sizing } from '@material-ui/system';
|
||||
// var moment = require('moment');
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ class Userline extends Component {
|
||||
<div style={{fontsize: "13px", textAlign: "left", marginLeft: "14px"}}>
|
||||
<p>Userline</p>
|
||||
</div>
|
||||
<Box border={1} width="25%" flex="1" height="auto" m={2} fontSize="13px" textAlign= "left" padding="5px" flexWrap= "wrap" flexDirection= "row" >
|
||||
<Box border={1} width="25%" flex="1" height="auto" m={2} fontSize="13px" textAlign="left" padding="5px" flexWrap="wrap" flexDirection="row" >
|
||||
<div style={{flexWrap: "wrap", flex: "1", flexDirection: "row", wordBreak: "break-word"}}>
|
||||
<p>
|
||||
{sortedPosts.map((microBlog) => <p>Microblog Title: {microBlog.microBlogTitle}
|
||||
@ -50,7 +50,7 @@ class Userline extends Component {
|
||||
<br></br>Number of comments: {microBlog.commentCount}
|
||||
<br></br>Number of likes: {microBlog.likeCount}
|
||||
<br></br>Body of post: {microBlog.body}
|
||||
<br></br>Tagged topics: {microBlog.microBlogTopics.join("," + " ")}
|
||||
<br></br>Tagged topics: {microBlog.microBlogTopics.join(", ")}
|
||||
</p>)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import React, { Component } from "react";
|
||||
import { BrowserRouter as Router } from "react-router-dom";
|
||||
import Route from "react-router-dom/Route";
|
||||
// import { BrowserRouter as Router } from "react-router-dom";
|
||||
// import Route from "react-router-dom/Route";
|
||||
import axios from "axios";
|
||||
|
||||
// Material-UI
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
// import Typography from '@material-ui/core/Typography';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import withStyles from "@material-ui/styles/withStyles";
|
||||
|
||||
@ -127,7 +127,6 @@ class Writing_Microblogs extends Component {
|
||||
fullWidth
|
||||
autoComplete='off'
|
||||
/>
|
||||
|
||||
<TextField
|
||||
id="content"
|
||||
name="content"
|
||||
|
||||
@ -36,7 +36,7 @@ class Home extends Component {
|
||||
axios
|
||||
.get("/getallPosts")
|
||||
.then(res => {
|
||||
console.log(res.data);
|
||||
// console.log(res.data);
|
||||
this.setState({
|
||||
posts: res.data
|
||||
});
|
||||
@ -57,7 +57,7 @@ class Home extends Component {
|
||||
|
||||
let postMarkup = this.state.posts ? (
|
||||
this.state.posts.map(post =>
|
||||
<Card className={classes.card}>
|
||||
<Card className={classes.card} key={post.postId}>
|
||||
<CardContent>
|
||||
<Typography>
|
||||
{
|
||||
@ -85,8 +85,9 @@ class Home extends Component {
|
||||
<p>Loading post...</p>
|
||||
);
|
||||
|
||||
return authenticated ? (
|
||||
<Grid container spacing={16}>
|
||||
return (
|
||||
authenticated ? (
|
||||
<Grid container>
|
||||
<Grid item sm={4} xs={8}>
|
||||
<Writing_Microblogs />
|
||||
</Grid>
|
||||
@ -121,7 +122,7 @@ class Home extends Component {
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,7 +343,7 @@ const mapStateToProps = (state) => ({
|
||||
|
||||
Home.propTypes = {
|
||||
user: PropTypes.object.isRequired,
|
||||
clases: PropTypes.object.isRequired,
|
||||
classes: PropTypes.object.isRequired,
|
||||
UI: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ export class Login extends Component {
|
||||
<Grid item sm>
|
||||
<img src={logo} className="app-logo" alt="logo" />
|
||||
<br></br>
|
||||
<Typography variant="p" className={classes.pageTitle} fontFamily = "Georgia, serif">
|
||||
<Typography variant="h6" className={classes.pageTitle} fontFamily = "Georgia, serif">
|
||||
<b>Log in to Twistter</b>
|
||||
<br></br>
|
||||
</Typography>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import React, { Component } from "react";
|
||||
// import props
|
||||
import { TextField, Button } from "@material-ui/core";
|
||||
// import { TextField, Button } from "@material-ui/core";
|
||||
import TextField from "@material-ui/core/TextField"
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import axios from "axios";
|
||||
import Fuse from "fuse.js";
|
||||
@ -38,7 +39,7 @@ export class Search extends Component {
|
||||
handles: res.data,
|
||||
loading: false
|
||||
}, () => {
|
||||
console.log(res.data);
|
||||
// console.log(res.data);
|
||||
fuse = new Fuse(this.state.handles, fuseOptions); // "list" is the item array
|
||||
})
|
||||
})
|
||||
@ -65,7 +66,7 @@ export class Search extends Component {
|
||||
let result = fuse.search(event.target.value);
|
||||
let parsed = [];
|
||||
result.forEach((res) => {
|
||||
console.log(res)
|
||||
// console.log(res)
|
||||
parsed.push(this.state.handles[res])
|
||||
})
|
||||
this.setState({
|
||||
@ -80,7 +81,7 @@ export class Search extends Component {
|
||||
render() {
|
||||
let resultMarkup = this.state.searchResult && this.state.searchResult !== "No Results" ? (
|
||||
this.state.searchResult.map(res =>
|
||||
<Router>
|
||||
<Router key={res}>
|
||||
<div>
|
||||
<a href={`/user/${res}`}>
|
||||
{res}
|
||||
|
||||
@ -76,7 +76,7 @@ class user extends Component {
|
||||
profile: null,
|
||||
imageUrl: null,
|
||||
topics: null,
|
||||
newTopic: null
|
||||
newTopic: ""
|
||||
};
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ class user extends Component {
|
||||
topic => (
|
||||
<MyChip
|
||||
label={topic}
|
||||
key={topic.id}
|
||||
key={topic}
|
||||
onDelete={key => this.handleDelete(topic)}
|
||||
/>
|
||||
) // console.log({ topic }.topic.id)
|
||||
@ -206,7 +206,7 @@ class user extends Component {
|
||||
|
||||
let postMarkup = this.state.posts ? (
|
||||
this.state.posts.map(post => (
|
||||
<Card className={classes.card}>
|
||||
<Card className={classes.card} key={post.postId}>
|
||||
<CardContent>
|
||||
<Typography>
|
||||
{this.state.imageUrl ? (
|
||||
@ -215,7 +215,7 @@ class user extends Component {
|
||||
<img src={noImage} height="50" width="50" />
|
||||
)}
|
||||
</Typography>
|
||||
<Typography variant="h7">
|
||||
<Typography variant="h6">
|
||||
<b>{post.userHandle}</b>
|
||||
</Typography>
|
||||
<Typography variant="body2" color={"textSecondary"}>
|
||||
@ -285,7 +285,7 @@ class user extends Component {
|
||||
<TextField
|
||||
id="newTopic"
|
||||
label="new topic"
|
||||
defaultValue=""
|
||||
// defaultValue=""
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
value={this.state.newTopic}
|
||||
@ -295,7 +295,7 @@ class user extends Component {
|
||||
className={classes.addCircle}
|
||||
color="primary"
|
||||
// iconStyle={classes.addCircle}
|
||||
clickable
|
||||
clickable="true"
|
||||
onClick={this.handleAddCircle}
|
||||
cursor="pointer"
|
||||
/>
|
||||
@ -321,7 +321,7 @@ const mapStateToProps = state => ({
|
||||
|
||||
user.propTypes = {
|
||||
user: PropTypes.object.isRequired,
|
||||
clases: PropTypes.object.isRequired
|
||||
classes: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(withStyles(styles)(user));
|
||||
|
||||
@ -89,7 +89,7 @@ export class verify extends Component {
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
const { errors, loading } = this.state;
|
||||
const { loading } = this.state;
|
||||
|
||||
return (
|
||||
<Grid container className={classes.form}>
|
||||
|
||||
@ -1,6 +1,18 @@
|
||||
import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED} from '../types';
|
||||
import {
|
||||
SET_USER,
|
||||
SET_ERRORS,
|
||||
CLEAR_ERRORS,
|
||||
LOADING_UI,
|
||||
// SET_AUTHENTICATED,
|
||||
SET_UNAUTHENTICATED
|
||||
} from '../types';
|
||||
import axios from 'axios';
|
||||
|
||||
const setAuthorizationHeader = (token) => {
|
||||
const FBIdToken = `Bearer ${token}`;
|
||||
localStorage.setItem('FBIdToken', FBIdToken);
|
||||
axios.defaults.headers.common['Authorization'] = FBIdToken;
|
||||
}
|
||||
|
||||
export const getUserData = () => (dispatch) => {
|
||||
axios.get('/user')
|
||||
@ -81,9 +93,3 @@ export const deleteUser = () => (dispatch) => {
|
||||
delete axios.defaults.headers.common['Authorization'];
|
||||
dispatch({ type: SET_UNAUTHENTICATED });
|
||||
}
|
||||
|
||||
const setAuthorizationHeader = (token) => {
|
||||
const FBIdToken = `Bearer ${token}`;
|
||||
localStorage.setItem('FBIdToken', FBIdToken);
|
||||
axios.defaults.headers.common['Authorization'] = FBIdToken;
|
||||
}
|
||||
@ -1,4 +1,11 @@
|
||||
import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED} from '../types';
|
||||
import {
|
||||
SET_USER,
|
||||
// SET_ERRORS,
|
||||
// CLEAR_ERRORS,
|
||||
// LOADING_UI,
|
||||
SET_AUTHENTICATED,
|
||||
SET_UNAUTHENTICATED
|
||||
} from '../types';
|
||||
|
||||
const initialState = {
|
||||
authenticated: false,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user