Skip to content

Commit b7bf8c2

Browse files
authored
Merge pull request #50 from TryShape/issue-46-security-features
Issue 46 security features
2 parents bbd75c6 + 2bd0d45 commit b7bf8c2

18 files changed

Lines changed: 524 additions & 136 deletions

File tree

components/core/App.js

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import React, { useEffect, useState } from "react";
2-
import dynamic from "next/dynamic";
32

4-
// harperDb fetch call
5-
import { harperFetch } from "../../utils/HarperFetch";
3+
// axios
4+
import axios from "axios";
65

7-
// Dummy Shape Data
8-
// import { shapes } from "../../data/shapes";
6+
// dynamic from next
7+
import dynamic from "next/dynamic";
98

109
// loader
1110
import Loader from "react-loader-spinner";
@@ -33,36 +32,30 @@ const App = (props) => {
3332
let shapes = [];
3433

3534
if(user.length === 0) {
36-
// User is not logged In. Fetch all the public shapes
37-
shapes = await harperFetch({
38-
operation: "sql",
39-
sql: `SELECT *
40-
FROM tryshape.shapes s
41-
INNER JOIN tryshape.users u
42-
ON s.createdBy=u.email
43-
WHERE s.private=false
44-
ORDER BY s.likes DESC`,
35+
// User is not logged In. Fetch all the public shapes
36+
const response = await axios.get("/api/GET/shapes", {
37+
params: {
38+
type: 'private'
39+
}
4540
});
41+
shapes = response.data;
4642
} else {
4743
// User is logged in. Let's fetch the private shape and other public shapes.
48-
shapes = await harperFetch({
49-
operation: "sql",
50-
sql: `SELECT *
51-
FROM tryshape.shapes s
52-
INNER JOIN tryshape.users u
53-
ON s.createdBy=u.email
54-
WHERE s.private=false
55-
OR createdBy = '${user.email}'
56-
ORDER BY s.likes DESC`,
44+
const response = await axios.get("/api/GET/shapes", {
45+
params: {
46+
type: 'public-logged-in',
47+
email: user.email
48+
}
5749
});
50+
shapes = response.data;
5851

5952
// Fetch the shapes liked by the logged-in user
60-
const likedShapes = await harperFetch({
61-
operation: "sql",
62-
sql: `SELECT *
63-
FROM tryshape.likes
64-
WHERE email = '${user.email}'`,
53+
const likedResponse = await axios.get("/api/GET/likes", {
54+
params: {
55+
email: user.email
56+
}
6557
});
58+
const likedShapes = likedResponse.data;
6659

6760
// If there are liked shapes, take out the shape_id
6861
if (likedShapes.length > 0) {

components/core/CreateShape.js

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import React, { useState, useEffect } from "react";
22

3+
// axios
4+
import axios from "axios";
5+
36
// Bootstrap
47
import Container from "react-bootstrap/Container";
58
import Row from "react-bootstrap/Row";
@@ -13,9 +16,6 @@ import { ShapeForm, ShapePreview } from "..";
1316
// Toast
1417
import toast from "react-hot-toast";
1518

16-
// harperDb fetch call
17-
import { harperFetch } from "../../utils/HarperFetch";
18-
1919
const CreateShape = (props) => {
2020

2121
// Store the default state as a variable so resetting form is easier
@@ -74,7 +74,7 @@ const CreateShape = (props) => {
7474
"name": props.shape.name,
7575
"formula": props.shape.formula,
7676
"vertices": props.shape.vertices,
77-
"private": true,
77+
"private": props.shape.private,
7878
"edges": props.shape.edges,
7979
"notes": props.shape.notes,
8080
"clipPathType": props.shape.type,
@@ -88,8 +88,6 @@ const CreateShape = (props) => {
8888
// Changes shapeInformation when something in ShapeForm or ShapePreview is altered
8989
const handleChange = (event, data, number) => {
9090

91-
// console.log(event, data);
92-
9391
const name = event.target.name || event.type;
9492
const value = event.target.type === "checkbox" ? event.target.checked : event.target.value;
9593

@@ -131,7 +129,25 @@ const CreateShape = (props) => {
131129
...shapeInformation,
132130
"formula": "polygon(10% 10%, 90% 10%, 90% 90%, 10% 80%)",
133131
"vertices": 4,
134-
"edges": 4,
132+
"edges": 4,
133+
"verticeCoordinates" : [
134+
{
135+
"x": "10%",
136+
"y": "10%",
137+
},
138+
{
139+
"x": "90%",
140+
"y": "10%",
141+
},
142+
{
143+
"x": "90%",
144+
"y": "90%",
145+
},
146+
{
147+
"x": "10%",
148+
"y": "80%",
149+
},
150+
]
135151
});
136152
}
137153

@@ -163,7 +179,7 @@ const CreateShape = (props) => {
163179
}
164180

165181
// If DraggableVertice is moved, adjust verticeCoordinates and formula
166-
if (name === "mousemove") {
182+
if (name === "mousemove" || name === "touchmove") {
167183

168184
const newVerticeCoordinates = addNewVerticeCoordinates(data.x, data.y, number);
169185
const newFormula = generateNewFormula(newVerticeCoordinates);
@@ -193,7 +209,8 @@ const CreateShape = (props) => {
193209
}
194210

195211
// If delete button is pressed and passes a number that corresponds to the vertice, remove the corresponding verticeCoordinate and adjust formula
196-
if (event.target.id.includes("deleteButton") && number !== undefined) {
212+
if ((event.target.id.includes("deleteButton")
213+
|| event.target.parentElement.id.includes("deleteButton")) && number !== undefined) {
197214

198215
let newVerticeCoordinates = [];
199216

@@ -302,34 +319,28 @@ const CreateShape = (props) => {
302319
// Editing Shape
303320
if (props.edit) {
304321

305-
const editShape = await harperFetch({
306-
operation: "sql",
307-
sql: `
308-
UPDATE tryshape.shapes
309-
SET
310-
name = '${shapeInformation.name}',
311-
formula = '${shapeInformation.formula}',
312-
vertices = '${shapeInformation.vertices}',
313-
private = '${shapeInformation.private}',
314-
edges = '${shapeInformation.edges}',
315-
notes = '${shapeInformation.notes}',
316-
type = '${shapeInformation.clipPathType}',
317-
backgroundColor = '${shapeInformation.backgroundColor}'
318-
WHERE
319-
shape_id === '${props.shape.shape_id}'
320-
`
322+
const updateShapeResponse = await axios.post('/api/PUT/shape', {
323+
shapeId: props.shape.shape_id,
324+
name: shapeInformation.name,
325+
formula: shapeInformation.formula,
326+
vertices: shapeInformation.vertices,
327+
visibility: shapeInformation.private,
328+
edges: shapeInformation.edges,
329+
notes: shapeInformation.notes,
330+
type: shapeInformation.clipPathType,
331+
backgroundColor: shapeInformation.backgroundColor
321332
});
333+
const editShape = updateShapeResponse.data;
334+
console.log({editShape});
322335

323-
console.log(editShape);
324-
325-
if (editShape["update_hashes"].length > 0) {
336+
if (editShape.data["update_hashes"].length > 0) {
326337
props.handleClose();
327338
toast.success(`Shape ${shapeInformation.name} edited successfully.`);
328339
props.setShapeAction({
329340
...props.shapeAction,
330341
"action": "edit",
331342
"payload": {
332-
"shape_id": editShape['update_hashes']
343+
"shape_id": editShape.data['update_hashes']
333344
}
334345
});
335346
} else {
@@ -340,30 +351,43 @@ const CreateShape = (props) => {
340351
} else {
341352

342353
// Create the shape in the DB
343-
const insertShape = await harperFetch({
344-
operation: "sql",
345-
sql: `INSERT into tryshape.shapes(backgroundColor, createdAt, createdBy, edges, email, formula, likes, name, notes, private, type, vertices)
346-
values('${shapeInformation.backgroundColor}', null, '${props.user.email}', ${shapeInformation.edges}, null, '${shapeInformation.formula}', 0, '${shapeInformation.name}', '${shapeInformation.notes}', ${shapeInformation.private}, '${shapeInformation.clipPathType}', ${shapeInformation.vertices})`,
354+
const insertShapeResponse = await axios.post('/api/POST/shape', {
355+
name: shapeInformation.name,
356+
formula: shapeInformation.formula,
357+
vertices: shapeInformation.vertices,
358+
visibility: shapeInformation.private,
359+
edges: shapeInformation.edges,
360+
notes: shapeInformation.notes,
361+
type: shapeInformation.clipPathType,
362+
backgroundColor: shapeInformation.backgroundColor,
363+
createdBy: props.user.email,
364+
likes: 0
347365
});
366+
const insertShape = insertShapeResponse.data
348367

349-
console.log(insertShape);
368+
console.log({insertShape});
350369

351370
// Create the user in the db
352-
if (insertShape['inserted_hashes'].length > 0) {
371+
if (insertShape.data['inserted_hashes'].length > 0) {
353372
// First check if the user exist
354-
const result = await harperFetch({
355-
operation: "sql",
356-
sql: `SELECT count(*) from tryshape.users WHERE email='${props.user.email}'`,
357-
});
358-
const count = (result[0]['COUNT(*)']);
373+
const userResponse = await axios.get("/api/GET/user", {
374+
params: {
375+
email: props.user.email
376+
}
377+
});
378+
const result = userResponse.data;
379+
const count = result.length;
359380
console.log({count});
381+
360382
// If doesn't exist, create in db
361383
if (count === 0) {
362-
const insertUser = await harperFetch({
363-
operation: "sql",
364-
sql: `INSERT into tryshape.users(email, name, photoURL)
365-
values('${props.user.email}', '${props.user.displayName}', '${props.user.photoURL}')`,
384+
const insertUserResponse = await axios.post('/api/POST/user', {
385+
displayName: props.user.displayName,
386+
email: props.user.email,
387+
photoURL: props.user.photoURL
366388
});
389+
const insertUser = insertUserResponse.data;
390+
console.log({insertUser});
367391
} else {
368392
console.log(`The user ${props.user.email} present in DB`);
369393
}
@@ -378,7 +402,7 @@ const CreateShape = (props) => {
378402
...props.shapeAction,
379403
"action": "add",
380404
"payload": {
381-
"shape_id": insertShape['inserted_hashes']
405+
"shape_id": insertShape.data['inserted_hashes']
382406
}
383407
});
384408

components/core/DeleteShape.js

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import React from "react";
22

3+
// axios
4+
import axios from "axios";
5+
6+
// bootstrap
37
import Modal from "react-bootstrap/Modal";
48
import Button from "react-bootstrap/Button";
59

10+
// toast
611
import toast from "react-hot-toast";
712

8-
import { harperFetch } from "../../utils/HarperFetch";
9-
1013
// Styled Component
1114
import styled from "styled-components";
1215

@@ -46,25 +49,20 @@ const ContentWrapper = styled.div`
4649
const DeleteShape = ({ show, setShow, shape, shapeAction, setShapeAction }) => {
4750

4851
const handleDelete = async() => {
49-
const deleteShape = await harperFetch({
50-
operation: "sql",
51-
sql: `
52-
DELETE FROM tryshape.shapes
53-
WHERE
54-
shape_id === '${shape.shape_id}'
55-
`
52+
const deleteShapeResponse = await axios.post('/api/DELETE/shape', {
53+
shapeId: shape.shape_id
5654
});
55+
const deleteShape = deleteShapeResponse.data;
56+
console.log({deleteShape});
5757

58-
console.log(deleteShape);
59-
60-
if (deleteShape["deleted_hashes"].length > 0) {
58+
if (deleteShape.data["deleted_hashes"].length > 0) {
6159
setShow(false);
6260
toast.success(`Shape ${shape.name} deleted successfully.`);
6361
setShapeAction({
6462
...shapeAction,
6563
"action": "delete",
6664
"payload": {
67-
"shape_id": deleteShape["deleted_hashes"]
65+
"shape_id": deleteShape.data["deleted_hashes"]
6866
}
6967
});
7068
} else {

components/core/Landing.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ const Landing = ({ setOpen, user, setUser }) => {
460460
</p>
461461
<BannerBodyActions>
462462
<Link href="/app"><Button className="banner-action--primary"><FiPenTool/>Try Now</Button></Link>
463-
<Link href="/app"><Button variant="outline-secondary"><FiGithub />GitHub</Button></Link>
463+
<a href="https://github.com/TryShape" target="_blank" rel="noopener noreferrer"><Button variant="outline-secondary"><FiGithub />GitHub</Button></a>
464464
</BannerBodyActions>
465465
</Col>
466466
</Row>
@@ -557,11 +557,11 @@ const Landing = ({ setOpen, user, setUser }) => {
557557
<SectionContact id="contact">
558558
<Container>
559559
<SocialLinks>
560-
<a href="https://github.com/TryShape" target="_blank"><FiGithub /></a>
561-
<a href="https://twitter.com/tapasadhikary" target="_blank"><FiTwitter /></a>
562-
<a href="https://www.linkedin.com/in/tapasadhikary/" target="_blank"><FiLinkedin /></a>
563-
<a href="https://www.youtube.com/c/TapasAdhikary/featured"><FiYoutube /></a>
564-
<a href="mailto:tapas.adhikary@gmail.com"><FiMail /></a>
560+
<a href="https://github.com/TryShape" target="_blank" rel="noopener noreferrer"><FiGithub /></a>
561+
<a href="https://twitter.com/tapasadhikary" target="_blank" rel="noopener noreferrer"><FiTwitter /></a>
562+
<a href="https://www.linkedin.com/in/tapasadhikary/" target="_blank" rel="noopener noreferrer"><FiLinkedin /></a>
563+
<a href="https://www.youtube.com/c/TapasAdhikary/featured" rel="noopener noreferrer"><FiYoutube /></a>
564+
<a href="mailto:tapas.adhikary@gmail.com" rel="noopener noreferrer"><FiMail /></a>
565565
</SocialLinks>
566566
<SectionContactCredits className="text-center"><small>TryShape is an opensource project developed by <a href="https://tapasadhikary.com/" target="_blank">Tapas Adhikary</a> and friends.</small></SectionContactCredits>
567567
</Container>

components/utils/DraggableVertice.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import React, { useRef } from "react";
33
// react-draggable npm
44
import Draggable from "react-draggable";
55

6+
// icon
7+
import { FiDelete } from "react-icons/fi";
8+
69
// Styled Component
710
import styled from "styled-components";
811

@@ -56,14 +59,28 @@ const DraggableVertice = (props) => {
5659
} else {
5760
props.setFocusNumber(-1);
5861
}
59-
}}
62+
}}
63+
onTouchStart={() => {
64+
if (show === false) {
65+
props.setFocusNumber(props.number);
66+
} else {
67+
props.setFocusNumber(-1);
68+
}
69+
}}
6070
ref={target}
6171
/>
6272
</Draggable>
6373

64-
<Overlay target={target.current} show={show} placement="right">
74+
<Overlay target={target.current}
75+
show={show}
76+
placement={x > 250 ? "left" : "right"}>
6577
<Tooltip>
66-
<span id={"deleteButton" + props.number} onMouseUp={handleDelete} style={{ cursor: "pointer" }}>X</span>
78+
<FiDelete
79+
size="24px"
80+
id={"deleteButton" + props.number}
81+
onMouseUp={handleDelete}
82+
style={{ cursor: "pointer" }}
83+
/>
6784
</Tooltip>
6885
</Overlay>
6986
</>

0 commit comments

Comments
 (0)