typescript(multiplayer-backend): 😁 Fixed the auth route!
typescript(multiplayer-backend): (the login one is still broken) typescript(multiplayer-backend): typescript(multiplayer-backend): Started refactoring the auth and fixing the folder structure! Signed-off-by: prescientmoon <git@moonythm.dev>
This commit is contained in:
parent
3740397789
commit
6fb7143528
2017
typescript/multiplayer-backend/package-lock.json
generated
2017
typescript/multiplayer-backend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@
|
|||
"devDependencies": {
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/connect-mongo": "0.0.41",
|
||||
"@types/cors": "^2.8.5",
|
||||
"@types/dotenv": "^6.1.1",
|
||||
"@types/express": "^4.16.1",
|
||||
"@types/express-session": "^1.15.12",
|
||||
|
@ -32,13 +32,10 @@
|
|||
"dependencies": {
|
||||
"bcryptjs": "^2.4.3",
|
||||
"chalk": "^2.4.2",
|
||||
"connect-mongo": "^2.0.3",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^7.0.0",
|
||||
"express": "^4.16.4",
|
||||
"express-session": "^1.16.1",
|
||||
"express-validator": "^5.3.1",
|
||||
"firebase-admin": "^7.2.0",
|
||||
"firestore-store": "^1.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"mongoose": "^5.5.7",
|
||||
"morgan": "^1.9.1",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * from "./preventGlobalError"
|
|
@ -0,0 +1,15 @@
|
|||
import { Request, Response } from "express";
|
||||
|
||||
export const preventGlobalErrors = (func: (req: Request, res: Response) => any) => {
|
||||
return async (req: Request, res: Response) => {
|
||||
try {
|
||||
await func(req,res)
|
||||
}
|
||||
catch (err) {
|
||||
res.json({
|
||||
succes: false,
|
||||
errors: [err]
|
||||
}).status(400)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from "./respond"
|
10
typescript/multiplayer-backend/src/common/respond/respond.ts
Normal file
10
typescript/multiplayer-backend/src/common/respond/respond.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { Response } from "express";
|
||||
|
||||
export const respond = (res:Response, succes = true, data: any = {},
|
||||
errors:any[] = [], status = 200) => {
|
||||
res.json({
|
||||
succes,
|
||||
data,
|
||||
errors
|
||||
}).status(status)
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
import * as express from "express"
|
||||
import chalk from "chalk";
|
||||
import * as cors from "cors"
|
||||
|
||||
import { staticRoutes } from "../config";
|
||||
import { routes } from "./routes"
|
||||
import { urlencoded } from "body-parser";
|
||||
import { json } from "body-parser";
|
||||
import { morganChalk } from "./middleware/morgan";
|
||||
import { sessionMiddleware } from "./middleware/sessions"
|
||||
|
||||
|
@ -18,7 +19,12 @@ export const setupServer = (): Promise<serverSetupResults> =>
|
|||
//create express app
|
||||
const app = express()
|
||||
|
||||
app.use(urlencoded({ extended: true }), morganChalk, sessionMiddleware)
|
||||
app.use(
|
||||
cors(),
|
||||
json(),
|
||||
morganChalk,
|
||||
sessionMiddleware
|
||||
)
|
||||
|
||||
//load static routes
|
||||
staticRoutes.forEach(route => {
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
import { Request, Response } from "express"
|
||||
import { whiteList } from "../../config"
|
||||
import { includes } from "lodash"
|
||||
|
||||
const urls = whiteList.map(urlObject => urlObject.url)
|
||||
|
||||
//TODO: remove from here
|
||||
const defaultMethods = "GET, POST, OPTIONS, PUT, PATCH, DELETE"
|
||||
|
||||
/**
|
||||
* used to fix the cors errors things
|
||||
* @param url the url to allow
|
||||
* @param methods the methods to allow the url to do
|
||||
*/
|
||||
export const corsErrorFixer = (req: Request, res: Response, next: any) => {
|
||||
const host = req.get("host")
|
||||
const methods: any = whiteList.find(value => value.url == host) || { methods: undefined }
|
||||
|
||||
if (!includes(urls, host))
|
||||
return next()
|
||||
|
||||
res.setHeader('Access-Control-Allow-Origin', host) // Website you wish to allow to connect
|
||||
res.setHeader('Access-Control-Allow-Methods', methods.methods || defaultMethods) //// Request methods you wish to allow
|
||||
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type') // Request headers you wish to allow
|
||||
|
||||
// Pass to next layer of middleware
|
||||
next();
|
||||
}
|
|
@ -12,6 +12,7 @@ const getToken = (req: Request) => {
|
|||
// Handle token presented as a cookie parameter
|
||||
return req.cookies.token;
|
||||
}
|
||||
|
||||
// If we return null, we couldn't find a token.
|
||||
// In this case, the JWT middleware will return a 401 (unauthorized) to the client for this request
|
||||
return null;
|
||||
|
@ -60,11 +61,5 @@ export const sessionMiddleware = async (req: Request, res: Response, next: Funct
|
|||
})
|
||||
}
|
||||
|
||||
req.session.rainbow = "unicorn"
|
||||
|
||||
//TODO: remove types for express-session
|
||||
//@ts-ignore expects callback
|
||||
req.session.save()
|
||||
|
||||
next()
|
||||
}
|
|
@ -1,134 +1,66 @@
|
|||
import { Router, Response, Request } from "express"
|
||||
import { reddirect } from "../../middleware/reddirect";
|
||||
import * as validator from "express-validator"
|
||||
import { generateUid, encodePassword } from "../../services/auth/signup";
|
||||
import { savePassword } from "../../services/auth/signup";
|
||||
import { corsErrorFixer } from "../../middleware/corsErrorMiddleware";
|
||||
import { config } from "dotenv"
|
||||
import { compare } from "bcryptjs";
|
||||
import { User, UserDoc } from "../../models/User";
|
||||
import { Passsord } from "../../models/Password";
|
||||
import { preventGlobalErrors } from "../../common/preventGlobalError";
|
||||
import { respond } from "../../common/respond";
|
||||
|
||||
//extract env variables
|
||||
config()
|
||||
|
||||
const router = Router()
|
||||
|
||||
router.get("/test", (req, res) => {
|
||||
res.send("just a test")
|
||||
const authHandler = preventGlobalErrors(async (req: Request, res: Response) => {
|
||||
//if already logged in return the uid
|
||||
if (req.session.uid)
|
||||
return respond(res, true, { uid: req.session.uid })
|
||||
|
||||
//get data from body
|
||||
const { password, email, name } = req.body
|
||||
|
||||
//check if the email isnt used
|
||||
if (await User.findOne({ email }))
|
||||
return respond(res, false, { email }, ["email is already used"], 400)
|
||||
|
||||
//validate
|
||||
req.check("email", "email isnt valid").isEmail()
|
||||
const errors = req.validationErrors() as any[]
|
||||
|
||||
if (errors)
|
||||
return respond(res, false, {}, errors, 400)
|
||||
|
||||
//generate an uid
|
||||
const uid = await generateUid()
|
||||
|
||||
const user = new User({
|
||||
email, name, uid,
|
||||
friends: [],
|
||||
photo: process.env.DEFAULTPROFILEPIC
|
||||
} as UserDoc) //used for my editor to help me
|
||||
|
||||
//save things in session
|
||||
req.session.uid = uid
|
||||
req.session.save(() => { })
|
||||
|
||||
await Promise.all([
|
||||
encodePassword(password).then(result => savePassword(uid, result)),
|
||||
user.save()
|
||||
])
|
||||
|
||||
//send uid back
|
||||
return respond(res,true,{ uid })
|
||||
})
|
||||
|
||||
const loginHtml = (req: Request, res: Response) => {
|
||||
res.send(`
|
||||
<form action="/auth/login" method=post>
|
||||
<div>
|
||||
<label for=email>email</label>
|
||||
<input type=text id=email name=email>
|
||||
</div>
|
||||
<div>
|
||||
<label for=password>password</label>
|
||||
<input type=password id=password name=password>
|
||||
</div>
|
||||
<div>
|
||||
<label for=name>name</label>
|
||||
<input type=name id=name name=name>
|
||||
</div>
|
||||
<button type=submit>Submit</button>
|
||||
</form>
|
||||
<button onclick="
|
||||
fetch('/',{
|
||||
headers: {
|
||||
authorization: 'do u see this?'
|
||||
}
|
||||
})">send</button>
|
||||
`)
|
||||
}
|
||||
|
||||
|
||||
const sayHello = (req: Request, res: Response) => {
|
||||
res.send(`
|
||||
<form action="/auth" method=post>
|
||||
<div>
|
||||
<label for=email>email</label>
|
||||
<input type=text id=email name=email>
|
||||
</div>
|
||||
<div>
|
||||
<label for=password>password</label>
|
||||
<input type=password id=password name=password>
|
||||
</div>
|
||||
<div>
|
||||
<label for=name>name</label>
|
||||
<input type=name id=name name=name>
|
||||
</div>
|
||||
<button type=submit>Submit</button>
|
||||
</form>
|
||||
`)
|
||||
}
|
||||
|
||||
const authHandler = async (req: Request, res: Response) => {
|
||||
try {
|
||||
//if already logged in return the uid
|
||||
if (req.session.uid)
|
||||
return res.redirect("auth/account")
|
||||
|
||||
//get data from body
|
||||
const { password, email, name } = req.body
|
||||
|
||||
//check if the email isnt used
|
||||
if (await User.findOne({ name }))
|
||||
res.redirect("login")
|
||||
|
||||
//validate
|
||||
req.check("email", "email isnt valid").isEmail()
|
||||
const errors = req.validationErrors()
|
||||
|
||||
if (errors)
|
||||
res.json({ error: `${req.body.email} is not a valid email` })
|
||||
|
||||
//generate an uid
|
||||
const uid = await generateUid()
|
||||
|
||||
const user = new User({
|
||||
email,
|
||||
friends: [],
|
||||
name,
|
||||
photo: process.env.DEFAULTPROFILEPIC,
|
||||
uid
|
||||
} as UserDoc) //used for my editor to help me
|
||||
|
||||
encodePassword(password)
|
||||
|
||||
//save the password and the user in the db
|
||||
await Promise.all([
|
||||
encodePassword(password).then(result => savePassword(uid, result)),
|
||||
user.save()
|
||||
])
|
||||
|
||||
//save things in session
|
||||
req.session.uid = uid
|
||||
|
||||
//save in the session
|
||||
req.session.save(() => { })
|
||||
|
||||
//send uid back
|
||||
res.json({
|
||||
succes: true,
|
||||
data: {
|
||||
uid
|
||||
}
|
||||
}).status(200)
|
||||
}
|
||||
catch (errors) {
|
||||
//send erros to clinet
|
||||
res.json({ errors })
|
||||
}
|
||||
}
|
||||
|
||||
const account = async (req: Request, res: Response) => {
|
||||
try {
|
||||
if (!req.session.uid)
|
||||
res.json({
|
||||
succes: false,
|
||||
data: {},
|
||||
errors: ["uid doesnt exist"]
|
||||
}).status(203)
|
||||
|
||||
|
@ -139,9 +71,9 @@ const account = async (req: Request, res: Response) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
catch (errors) {
|
||||
catch (err) {
|
||||
//send erros to clinet
|
||||
res.json({ errors })
|
||||
res.json({ succes: false, errors: [err] })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,12 +134,10 @@ const logout = async (req: Request, res: Response) => {
|
|||
res.send({ succes: true })
|
||||
}
|
||||
|
||||
router.use("*", validator(), corsErrorFixer)
|
||||
router.use("*", validator())
|
||||
|
||||
router
|
||||
.get("/", sayHello)
|
||||
.post("/", authHandler)
|
||||
.get("/login", loginHtml)
|
||||
.post("/login", login)
|
||||
.get("/account", account)
|
||||
.get("/logout", logout)
|
||||
|
@ -218,6 +148,4 @@ router
|
|||
res.send(await generateUid())
|
||||
})
|
||||
|
||||
router.use("/*", reddirect("/auth"))
|
||||
|
||||
export const auth = router
|
|
@ -1,7 +1,6 @@
|
|||
import * as bcrypt from "bcryptjs"
|
||||
import { promisify } from "util";
|
||||
import { randomBytes } from "crypto";
|
||||
import { database } from "../db/firestore";
|
||||
import { Passsord, PasswordDoc } from "../../models/Password";
|
||||
import { User } from "../../models/User";
|
||||
|
||||
|
@ -38,8 +37,9 @@ export function savePassword(uid: string, password: string) {
|
|||
|
||||
export async function getPassword(uid: string) {
|
||||
//get doc
|
||||
const doc = await database.doc(`passwords/${uid}`).get()
|
||||
// const doc = await database.doc(`passwords/${uid}`).get()
|
||||
|
||||
//return result
|
||||
return doc.data()
|
||||
// return doc.data()
|
||||
return "train"
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import * as admin from "firebase-admin"
|
||||
|
||||
export const firebase = admin.initializeApp({
|
||||
credential: admin.credential.cert('firebase-admin.json'),
|
||||
databaseURL: 'https://planets-io.firebaseio.com'
|
||||
});
|
||||
|
||||
export const database = firebase.firestore()
|
Loading…
Reference in a new issue