diff --git a/packages/play-node-go/public/reset.css b/packages/play-node-go/public/reset.css
index e91c47f..170a2f5 100644
--- a/packages/play-node-go/public/reset.css
+++ b/packages/play-node-go/public/reset.css
@@ -51,3 +51,8 @@ table {
border-collapse: collapse;
border-spacing: 0;
}
+
+button {
+ background: none;
+ border: none;
+}
\ No newline at end of file
diff --git a/packages/play-node-go/src/components/Button/Guest/Guest.js b/packages/play-node-go/src/components/Button/Guest/Guest.js
new file mode 100644
index 0000000..7989092
--- /dev/null
+++ b/packages/play-node-go/src/components/Button/Guest/Guest.js
@@ -0,0 +1,34 @@
+import React from "react";
+import authServices from "../../../services/authServices";
+
+const Guest = ({ dispatch }) => {
+ const handleClick = async (e) => {
+ e.preventDefault();
+ // dispatch to guest endpoint
+ const guestResponse = await authServices.guestService();
+
+ if (guestResponse.errors) {
+ const authError = guestResponse.errors[0].auth;
+ return dispatch({
+ type: "ERR",
+ message: "AUTH_ERROR",
+ body: { authError },
+ });
+ }
+
+ return dispatch({
+ type: "AUTH",
+ message: "GUEST",
+ body: guestResponse,
+ });
+ };
+ return (
+ <>
+
+ >
+ );
+};
+
+export default Guest;
diff --git a/packages/play-node-go/src/components/Form/Auth/Auth.js b/packages/play-node-go/src/components/Form/Auth/Auth.js
index 87d0234..c567db6 100644
--- a/packages/play-node-go/src/components/Form/Auth/Auth.js
+++ b/packages/play-node-go/src/components/Form/Auth/Auth.js
@@ -1,45 +1,49 @@
-import React, { useState } from 'react';
+import React, { useState } from "react";
-import Login from '../Login/Login';
-import Signup from '../Signup/Signup';
+import Login from "../Login/Login";
+import Signup from "../Signup/Signup";
+import Guest from "../../Button/Guest/Guest";
const Auth = (props) => {
- const [ showForm, setShowForm ] = useState('login')
+ const [showForm, setShowForm] = useState("login");
const { state, dispatch } = props;
return (
<>
-
{setShowForm('login')}}
+
{
+ setShowForm("login");
+ }}
>
-
Login
+
Login
- {
- showForm === 'login'
- ?
- : <>>
- }
+ {showForm === "login" ? (
+
+ ) : (
+ <>>
+ )}
{setShowForm('signup')}}
+ className="nav__section nav__section--auth"
+ onClick={() => {
+ setShowForm("signup");
+ }}
>
-
Signup
+
Signup
- {
- showForm === 'signup'
- ?
- : <>>
- }
+ {showForm === "signup" ? (
+
+ ) : (
+ <>>
+ )}
+
+
+
>
);
-}
+};
export default Auth;
diff --git a/packages/play-node-go/src/pages/Layout/MainWrapper/MainWrapper.scss b/packages/play-node-go/src/pages/Layout/MainWrapper/MainWrapper.scss
index 6dbe9e0..b31fc93 100644
--- a/packages/play-node-go/src/pages/Layout/MainWrapper/MainWrapper.scss
+++ b/packages/play-node-go/src/pages/Layout/MainWrapper/MainWrapper.scss
@@ -1,4 +1,5 @@
@import '../../../../public/stylesheets/partials/mixins';
+@import '../../../../public/stylesheets/partials/variables';
div.main-wrapper {
display: flex;
@@ -33,4 +34,15 @@ div.main-wrapper {
height: 100%;
}
}
+}
+
+button {
+ color:map-get($colors, 'sidebar_link');
+ cursor: pointer;
+ font-family: inherit;
+ font-size: 110%;
+ font-weight: bold;
+ margin-bottom: .5em;
+ padding: 0;
+ text-decoration: none;
}
\ No newline at end of file
diff --git a/packages/play-node-go/src/pages/Layout/NavBar/NavBar.js b/packages/play-node-go/src/pages/Layout/NavBar/NavBar.js
index 02da86e..c3e0f82 100644
--- a/packages/play-node-go/src/pages/Layout/NavBar/NavBar.js
+++ b/packages/play-node-go/src/pages/Layout/NavBar/NavBar.js
@@ -1,29 +1,36 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
-import './NavBar.scss';
-import Logo from '../../../components/Display/Logo/Logo';
-
-const NavBar = (props) => {
+import React from "react";
+import { Link } from "react-router-dom";
+import "./NavBar.scss";
+import Logo from "../../../components/Display/Logo/Logo";
+const NavBar = ({ state }) => {
return (
-
-
+
+
+
+
-
-
+
+
-
+
-
+
-
{props.user ? props.user.username : <>>}
+
+ {state.user.username ? state.user.username : <>>}
+
);
-}
+};
-export default NavBar;
\ No newline at end of file
+export default NavBar;
diff --git a/packages/play-node-go/src/reducers/auth/reducer.auth.js b/packages/play-node-go/src/reducers/auth/reducer.auth.js
index ce220de..9152c95 100644
--- a/packages/play-node-go/src/reducers/auth/reducer.auth.js
+++ b/packages/play-node-go/src/reducers/auth/reducer.auth.js
@@ -1,20 +1,23 @@
export const authReducer = (state, action) => {
switch (action.message) {
- case 'LOGIN':
- return loginReducer(state, action);
-
- case 'SIGNUP':
+ case "LOGIN":
return loginReducer(state, action);
- case 'LOGOUT':
+ case "SIGNUP":
+ return loginReducer(state, action);
+
+ case "GUEST":
+ return loginReducer(state, action);
+
+ case "LOGOUT":
return state;
default:
return state;
- }
-}
+ }
+};
function loginReducer(state, action) {
const newUser = action.body;
- return {...state, user: newUser };
-}
\ No newline at end of file
+ return { ...state, user: newUser };
+}
diff --git a/packages/play-node-go/src/services/authServices.js b/packages/play-node-go/src/services/authServices.js
index 2ecbb52..261aa77 100644
--- a/packages/play-node-go/src/services/authServices.js
+++ b/packages/play-node-go/src/services/authServices.js
@@ -1,43 +1,58 @@
-import config from '../config';
+import config from "../config";
const authEndpoint = config.authAddress;
-const signupEndpoint = `${authEndpoint}/signup`
-const loginEndpoint = `${authEndpoint}/login`
+const signupEndpoint = `${authEndpoint}/signup`;
+const loginEndpoint = `${authEndpoint}/login`;
+const guestEndpoint = `${authEndpoint}/guest`;
var headers = new Headers();
-headers.append('Content-Type', 'application/json');
-headers.append('Accept', 'application/json');
-headers.append('Sec-Fetch-Site', 'cross-site')
+headers.append("Content-Type", "application/json");
+headers.append("Accept", "application/json");
+headers.append("Sec-Fetch-Site", "cross-site");
-const loginService = async(formData) => {
+const loginService = async (formData) => {
const response = await fetch(loginEndpoint, {
- method: 'POST',
- credentials: 'include',
+ method: "POST",
+ credentials: "include",
body: JSON.stringify(formData),
- headers: headers
+ headers: headers,
})
- .then(res => res.text())
- .then(text => JSON.parse(text))
- .catch(err => err);
-
+ .then((res) => res.text())
+ .then((text) => JSON.parse(text))
+ .catch((err) => err);
+
return response;
-}
+};
const signupService = async (formData) => {
const response = await fetch(signupEndpoint, {
- method: 'POST',
- credentials: 'include',
+ method: "POST",
+ credentials: "include",
body: JSON.stringify(formData),
- headers: headers
+ headers: headers,
})
- .then(res => res.text())
- .then(text => JSON.parse(text))
- .catch(err => err);
+ .then((res) => res.text())
+ .then((text) => JSON.parse(text))
+ .catch((err) => err);
return response;
-}
+};
+
+const guestService = async () => {
+ const response = await fetch(guestEndpoint, {
+ method: "POST",
+ credentials: "include",
+ headers,
+ })
+ .then((res) => res.text())
+ .then((text) => JSON.parse(text))
+ .catch((err) => err);
+
+ return response;
+};
export default {
loginService,
- signupService
-}
\ No newline at end of file
+ signupService,
+ guestService,
+};
diff --git a/packages/server/controllers/auth.js b/packages/server/controllers/auth.js
index 77091ba..fab82bb 100644
--- a/packages/server/controllers/auth.js
+++ b/packages/server/controllers/auth.js
@@ -1,15 +1,16 @@
-const { validationResult } = require('express-validator');
+const { validationResult } = require("express-validator");
-const userQueries = require('../data/queries/user');
-const { hashPassword, compareHash } = require('../services/bcrypt');
-const signToken = require('../services/signToken');
+const userQueries = require("../data/queries/user");
+const { hashPassword, compareHash } = require("../services/bcrypt");
+const signToken = require("../services/signToken");
+const guestServices = require("../services/guestServices");
const checkValidationErrors = (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
-}
+};
const signup = async (req, res, next) => {
checkValidationErrors(req, res);
@@ -20,51 +21,68 @@ const signup = async (req, res, next) => {
const hashedPassword = await hashPassword(user.password);
const secureUser = { ...user, password: hashedPassword };
if (existingUser.length) {
- return res.status(409).json({errors: [{auth: 'User already exists!'}]})
+ return res
+ .status(409)
+ .json({ errors: [{ auth: "User already exists!" }] });
}
const newUser = await userQueries.insertUser(secureUser);
- signToken(res, newUser)
- res.status(201).json({...newUser});
- }
-
- catch (err) {
+ signToken(res, newUser);
+ res.status(201).json({ ...newUser });
+ } catch (err) {
res.status(500).json(err);
}
-}
+};
const login = async (req, res, next) => {
checkValidationErrors(req, res);
const user = req.body;
-
+
try {
const queryResults = await userQueries.findUserByNameOrEmail(user);
const savedUser = queryResults[0] || null;
-
+
if (!savedUser) {
- return res.status(401).send({errors: 'bad credentials'});
+ return res.status(401).send({ errors: "bad credentials" });
}
-
+
const hashedPassword = savedUser.password;
const passwordMatch = await compareHash(user.password, hashedPassword);
if (!passwordMatch) {
- return res.status(401).send({errors: 'bad credentials'});
+ return res.status(401).send({ errors: "bad credentials" });
}
-
- const authorizedUser = {...savedUser};
+
+ const authorizedUser = { ...savedUser };
delete authorizedUser.password;
-
+
signToken(res, authorizedUser);
- res.send({...authorizedUser}).status(200);
+ res.send({ ...authorizedUser }).status(200);
+ } catch (e) {
+ res.status(500).send({ errors: e });
}
-
- catch (err) {
- res.status(500).send({errors: err});
+};
+
+const guest = async (req, res, next) => {
+ try {
+ // username generator returns `Guest-${num}`
+ const { username, password } = guestServices.generateGuest();
+ // generateGuestUser();
+ const email = null;
+ // id generator returns `
+ const id = null;
+ const user = { username, email, id, password };
+ signToken(res, user);
+ delete user.password;
+ res.send(user);
+ } catch (e) {
+ console.log(e);
+ res.status(500).send({ errors: e });
}
-}
+};
module.exports = {
signup,
- login
-}
\ No newline at end of file
+ login,
+ guest,
+};
diff --git a/packages/server/routes/auth.js b/packages/server/routes/auth.js
index dfa96f9..6f1f2fb 100644
--- a/packages/server/routes/auth.js
+++ b/packages/server/routes/auth.js
@@ -1,10 +1,20 @@
-const express = require('express');
+const express = require("express");
const router = express.Router();
-const app = require('../server');
-const authController = require('../controllers/auth');
-const { signupValidationRules, loginValidationRules, validate } = require('../middleware/userValidator');
+const app = require("../server");
+const authController = require("../controllers/auth");
+const {
+ signupValidationRules,
+ loginValidationRules,
+ validate,
+} = require("../middleware/userValidator");
-router.post('/signup', signupValidationRules(), validate, authController.signup);
-router.post('/login', loginValidationRules(), validate, authController.login);
+router.post(
+ "/signup",
+ signupValidationRules(),
+ validate,
+ authController.signup
+);
+router.post("/login", loginValidationRules(), validate, authController.login);
+router.post("/guest", authController.guest);
module.exports = router;
diff --git a/packages/server/services/guestServices.js b/packages/server/services/guestServices.js
new file mode 100644
index 0000000..ca52616
--- /dev/null
+++ b/packages/server/services/guestServices.js
@@ -0,0 +1,25 @@
+const generateRandomPassword = () => {
+ const minLength = 8,
+ maxLength = 16,
+ minUTF = 33,
+ maxUTF = 126;
+ const randomize = (min, max) => Math.floor(Math.random() * (max - min) + min);
+ return Array(randomize(minLength, maxLength))
+ .fill(0)
+ .map(() => String.fromCharCode(randomize(minUTF, maxUTF)))
+ .join("");
+};
+
+const guestService = {
+ currentGuest: 0,
+ generateGuest() {
+ // generate unique username
+ const username = `Guest-${String(this.currentGuest++).padStart(6, 0)}`;
+ // generate random "password"
+ // this exists solely to add extra randomness to signed token and is not validated
+ const password = generateRandomPassword();
+ return { username, password };
+ },
+};
+
+module.exports = guestService;