parent
32913d582a
commit
5a7021b674
@ -0,0 +1,29 @@ |
|||||||
|
import { useState, createContext, useContext } from "react"; |
||||||
|
import { postLogIn, postLogOut } from './apiTools.jsx'; |
||||||
|
|
||||||
|
const LogInContext = createContext(false); |
||||||
|
export const LogInStatusUpdateEscapeTool = {}; |
||||||
|
|
||||||
|
function AuthProvider({children}) { |
||||||
|
let [loggedIn, setLoggedIn] = useState(localStorage.getItem("loggedIn") == "true"); |
||||||
|
|
||||||
|
function logOneWay (yeah) { |
||||||
|
localStorage.setItem("loggedIn", yeah); |
||||||
|
setLoggedIn(yeah); |
||||||
|
} |
||||||
|
|
||||||
|
LogInStatusUpdateEscapeTool.loggedIn = loggedIn; |
||||||
|
LogInStatusUpdateEscapeTool.setLoggedIn = logOneWay; |
||||||
|
|
||||||
|
return ( |
||||||
|
<LogInContext.Provider value={ loggedIn }> |
||||||
|
{children} |
||||||
|
</LogInContext.Provider> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export function useLoggedIn() { |
||||||
|
return useContext(LogInContext); |
||||||
|
} |
||||||
|
|
||||||
|
export default AuthProvider; |
@ -1,31 +1,31 @@ |
|||||||
import { useForm } from "react-hook-form"; |
import { useForm } from "react-hook-form"; |
||||||
import { useNavigate } from 'react-router-dom'; |
import { useNavigate } from 'react-router-dom'; |
||||||
import { logIn } from '../apiTools.jsx'; |
import { postLogIn } from '../apiTools.jsx'; |
||||||
|
|
||||||
function LogIn() { |
function LogIn() { |
||||||
const { register, handleSubmit } = useForm(); |
const { register, handleSubmit } = useForm(); |
||||||
const navigate = useNavigate(); |
const navigate = useNavigate(); |
||||||
|
|
||||||
const onSubmit = (d) => { |
const onSubmit = (d) => { |
||||||
logIn(d) |
postLogIn(d).then( () => navigate('/') ); |
||||||
.then(() => navigate('/')) |
|
||||||
.catch((error) => console.log('error logging in: ', error)); |
|
||||||
}; |
}; |
||||||
|
|
||||||
return ( |
return ( |
||||||
<form onSubmit={handleSubmit(onSubmit)}> |
<div className="main-column"> |
||||||
<label> |
<form onSubmit={handleSubmit(onSubmit)}> |
||||||
User name: |
<label> |
||||||
<input {...register("name")} /> |
User name: |
||||||
<br/> |
<input {...register("name")} /> |
||||||
</label> |
<br/> |
||||||
<label> |
</label> |
||||||
Password: |
<label> |
||||||
<input {...register("password")} /> |
Password: |
||||||
<br/> |
<input type="password" {...register("password")} /> |
||||||
</label> |
<br/> |
||||||
<button type="submit">Log right in, buckaroo!</button> |
</label> |
||||||
</form> |
<button type="submit">Log right in, buckaroo!</button> |
||||||
|
</form> |
||||||
|
</div> |
||||||
); |
); |
||||||
} |
} |
||||||
|
|
||||||
|
@ -0,0 +1,52 @@ |
|||||||
|
import { useEffect } from 'react'; |
||||||
|
import { useForm } from "react-hook-form"; |
||||||
|
import { useNavigate } from 'react-router-dom'; |
||||||
|
import { fetchProfile } from '../apiTools.jsx'; |
||||||
|
import { useLoggedIn } from '../AuthProvider.jsx'; |
||||||
|
import { useQuery } from '@tanstack/react-query'; |
||||||
|
|
||||||
|
function Profile() { |
||||||
|
const { register, handleSubmit } = useForm(); |
||||||
|
const navigate = useNavigate(); |
||||||
|
const loggedIn = useLoggedIn(); |
||||||
|
|
||||||
|
const { isPending, isError, error, data } = useQuery({ // fetch the currrent values |
||||||
|
queryKey: ['profile'], |
||||||
|
queryFn: fetchProfile, |
||||||
|
retry: 1 |
||||||
|
}); |
||||||
|
|
||||||
|
//useEffect(() => { if (!loggedIn) navigate('/'); }, [loggedIn]); |
||||||
|
|
||||||
|
const { name, favoriteColor, leastFavoriteColor } = (data || {}); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="main-column"> |
||||||
|
<section className="page-contents"> |
||||||
|
<p>the page {isPending ? "is" : "isn't"} pending</p> |
||||||
|
<p>there {isError ? "is" : "isn't"} an error</p> |
||||||
|
<p>error is {error?.message}</p> |
||||||
|
<form onSubmit={handleSubmit(() => {})}> |
||||||
|
<label> |
||||||
|
User name: |
||||||
|
<input {...register("name")} value={name}/> |
||||||
|
<br/> |
||||||
|
</label> |
||||||
|
<label> |
||||||
|
Favorite Color: |
||||||
|
<input {...register("favoriteColor")} value={favoriteColor}/> |
||||||
|
<br/> |
||||||
|
</label> |
||||||
|
<label> |
||||||
|
Least Favorite Color: |
||||||
|
<input {...register("leastFavoriteColor")} value={leastFavoriteColor}/> |
||||||
|
<br/> |
||||||
|
</label> |
||||||
|
<button type="submit">Change those settings, bucko!!</button> |
||||||
|
</form> |
||||||
|
</section> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export default Profile; |
@ -1,122 +0,0 @@ |
|||||||
const express = require('express'); |
|
||||||
const showdown = require('showdown'); |
|
||||||
const argon2 = require('argon2'); |
|
||||||
|
|
||||||
const { query } = require('./dbHelper.js'); |
|
||||||
const { graphFromList } = require('./graphStuff.js'); |
|
||||||
|
|
||||||
const app = express.Router(); |
|
||||||
const converter = new showdown.Converter(); |
|
||||||
|
|
||||||
const sqlite = require("better-sqlite3"); |
|
||||||
const db = new sqlite('the_big_db.db', { verbose: console.log }); |
|
||||||
console.log(db); |
|
||||||
|
|
||||||
app.get('/pages', (req, res) => { |
|
||||||
try { |
|
||||||
const pages = db.prepare('select id, title from pages').all(); |
|
||||||
res.status(200).json(pages); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
}
|
|
||||||
}); |
|
||||||
|
|
||||||
app.post('/page/new', (req, res) => { |
|
||||||
try { |
|
||||||
const newPage = db.prepare('insert into pages (title, description) values (?, ?) returning id') |
|
||||||
.get("new page", "this page is new!"); |
|
||||||
res.status(200).json(newPage); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
app.get('/page/:id', (req, res) => { |
|
||||||
try { |
|
||||||
const page = db.prepare('select * from pages where id=:id').get(req.params); |
|
||||||
if (page === undefined) res.status(404).json({"error": "page not found"}); |
|
||||||
else res.status(200).json(page); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
app.post('/page/:id', (req, res) => { |
|
||||||
try { |
|
||||||
const html = converter.makeHtml(req.body.description); |
|
||||||
const changes = db.prepare('replace into pages (id, title, descriptioon, html) values (?, ?, ?, ?)') |
|
||||||
.run(req.params.id, req.body.title, req.body.description, html); |
|
||||||
res.status(200).json(changes); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
app.delete('/page/:id', (req, res) => { |
|
||||||
try { |
|
||||||
const changes = db.prepare('delete from pages where id = ?').run(req.params.id); |
|
||||||
res.status(200).json({id: req.params.id}); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
} |
|
||||||
}) |
|
||||||
|
|
||||||
app.get('/graph', (req, res) => { |
|
||||||
try { |
|
||||||
const rows = db.prepare('select id, html from pages').all(); |
|
||||||
const graph = graphFromList(rows); |
|
||||||
res.status(200).json(graph); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
// auth stuff
|
|
||||||
app.post('/register', async (req, res) => { |
|
||||||
const {name, password, nonce} = req.body; |
|
||||||
|
|
||||||
const oldUser = db.prepare('select name from users where name=?').get(name); |
|
||||||
if (oldUser) return res.status(500).json({"error": "user name already in use"}); |
|
||||||
|
|
||||||
// check if the nonce password is correctt
|
|
||||||
if (nonce != "a softer birdsong") return res.status(500).json({"error": "wrong nonce"}); |
|
||||||
|
|
||||||
try { |
|
||||||
// i'm told argon2 is the good one nowatimes
|
|
||||||
const hash = await argon2.hash(password); |
|
||||||
const inserted = db.prepare('insert into users (name, password) values (?, ?)').run(name, hash); |
|
||||||
res.status(200).json(inserted); |
|
||||||
} catch (error) { |
|
||||||
res.status(500).json({"error": error}); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
app.post('/login', async (req, res) => { |
|
||||||
if (req.session.name) { |
|
||||||
return res.status(200).json({message: "already logged in", name: req.session.name}); |
|
||||||
} |
|
||||||
|
|
||||||
const {name, password} = req.body; |
|
||||||
|
|
||||||
// fetch username and passswords from the db
|
|
||||||
const storedUser = db.prepare('select name, password from users where name = ?').get(name); |
|
||||||
if (!storedUser) { |
|
||||||
return res.status(401).json({"error": "password/username combo not found in database"}); |
|
||||||
} |
|
||||||
|
|
||||||
//check if the passss hashes mattch and log in
|
|
||||||
if (!(await argon2.verify(storedUser.password, password))) { |
|
||||||
return res.status(401).json({"error": "password/username combo not found in database"}); |
|
||||||
} |
|
||||||
|
|
||||||
// set the session cookie and rreturn 200!
|
|
||||||
req.session.name = name; |
|
||||||
return res.status(200).json({message: "successfully logged in!", name: name}); |
|
||||||
}); |
|
||||||
|
|
||||||
app.post('/logout', (req, res) => { |
|
||||||
req.session.destroy(); |
|
||||||
res.status(200).json({message: "successfully logged out"}); |
|
||||||
}); |
|
||||||
|
|
||||||
module.exports = app; |
|
@ -0,0 +1,10 @@ |
|||||||
|
function loginRequired(req, res, next) { |
||||||
|
console.log("checkinig on req.session for auhetnticaion: ", req.session); |
||||||
|
if (!req.session.name) { |
||||||
|
return res.status(401).json({"error": "need to be logged in for that bucko"}); |
||||||
|
} |
||||||
|
|
||||||
|
next(); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { loginRequired }; |
@ -0,0 +1,25 @@ |
|||||||
|
const { graphFromList } = require('../graphStuff.js'); |
||||||
|
|
||||||
|
const sqlite = require('better-sqlite3'); |
||||||
|
const db = new sqlite('the_big_db.db', { verbose: console.log }); |
||||||
|
|
||||||
|
const express = require('express'); |
||||||
|
const app = express.Router(); |
||||||
|
|
||||||
|
const page_routes = require('./pages.js'); |
||||||
|
app.use(page_routes); |
||||||
|
|
||||||
|
const user_routes = require('./users.js'); |
||||||
|
app.use(user_routes); |
||||||
|
|
||||||
|
app.get('/graph', (req, res) => { |
||||||
|
try { |
||||||
|
const rows = db.prepare('select id, html from pages').all(); |
||||||
|
const graph = graphFromList(rows); |
||||||
|
res.status(200).json(graph); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
module.exports = app; |
@ -0,0 +1,62 @@ |
|||||||
|
const express = require('express'); |
||||||
|
const app = express.Router(); |
||||||
|
|
||||||
|
const sqlite = require('better-sqlite3'); |
||||||
|
const db = new sqlite('../the_big_db.db', { verbose: console.log }); |
||||||
|
|
||||||
|
const { loginRequired } = require('../authStuff.js'); |
||||||
|
|
||||||
|
const showdown = require('showdown'); |
||||||
|
const converter = new showdown.Converter(); |
||||||
|
|
||||||
|
app.get('/pages', (req, res) => { |
||||||
|
try { |
||||||
|
const pages = db.prepare('select id, title from pages').all(); |
||||||
|
res.status(200).json(pages); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
}
|
||||||
|
}); |
||||||
|
|
||||||
|
app.post('/page/new', loginRequired, (req, res) => { |
||||||
|
try { |
||||||
|
const newPage = db.prepare('insert into pages (title, description) values (?, ?) returning id') |
||||||
|
.get("new page", "this page is new!"); |
||||||
|
res.status(200).json(newPage); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
app.get('/page/:id', (req, res) => { |
||||||
|
try { |
||||||
|
const page = db.prepare('select * from pages where id=:id').get(req.params); |
||||||
|
if (page === undefined) res.status(404).json({"error": "page not found"}); |
||||||
|
else res.status(200).json(page); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
app.post('/page/:id', loginRequired, (req, res) => { |
||||||
|
try { |
||||||
|
const html = converter.makeHtml(req.body.description); |
||||||
|
const changes = db.prepare('replace into pages (id, title, description, html) values (?, ?, ?, ?)') |
||||||
|
.run(req.params.id, req.body.title, req.body.description, html); |
||||||
|
res.status(200).json(changes); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
app.delete('/page/:id', loginRequired, (req, res) => { |
||||||
|
try { |
||||||
|
const changes = db.prepare('delete from pages where id = ?').run(req.params.id); |
||||||
|
res.status(200).json({id: req.params.id}); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
module.exports = app; |
@ -0,0 +1,68 @@ |
|||||||
|
const express = require('express'); |
||||||
|
const app = express.Router(); |
||||||
|
|
||||||
|
const sqlite = require('better-sqlite3'); |
||||||
|
const db = new sqlite('../the_big_db.db', { verbose: console.log }); |
||||||
|
|
||||||
|
const argon2 = require('argon2'); |
||||||
|
|
||||||
|
const { loginRequired } = require('../authStuff.js'); |
||||||
|
|
||||||
|
// auth stuff
|
||||||
|
app.post('/register', async (req, res) => { |
||||||
|
const {name, password, nonce} = req.body; |
||||||
|
|
||||||
|
const oldUser = db.prepare('select name from users where name=?').get(name); |
||||||
|
if (oldUser) return res.status(500).json({"error": "user name already in use"}); |
||||||
|
|
||||||
|
// check if the nonce password is correctt
|
||||||
|
if (nonce != "a softer birdsong") return res.status(500).json({"error": "wrong nonce"}); |
||||||
|
|
||||||
|
try { |
||||||
|
// i'm told argon2 is the good one nowatimes
|
||||||
|
const hash = await argon2.hash(password); |
||||||
|
const inserted = db.prepare('insert into users (name, password) values (?, ?)').run(name, hash); |
||||||
|
res.status(200).json(inserted); |
||||||
|
} catch (error) { |
||||||
|
res.status(500).json({"error": error}); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
app.post('/login', async (req, res) => { |
||||||
|
if (req.session.name) { |
||||||
|
return res.status(200).json({message: "already logged in", name: req.session.name}); |
||||||
|
} |
||||||
|
|
||||||
|
const {name, password} = req.body; |
||||||
|
|
||||||
|
// fetch username and passswords from the db
|
||||||
|
const storedUser = db.prepare('select name, password from users where name = ?').get(name); |
||||||
|
if (!storedUser) { |
||||||
|
return res.status(401).json({"error": "password/username combo not found in database"}); |
||||||
|
} |
||||||
|
|
||||||
|
//check if the passss hashes mattch and log in
|
||||||
|
if (!(await argon2.verify(storedUser.password, password))) { |
||||||
|
return res.status(401).json({"error": "password/username combo not found in database"}); |
||||||
|
} |
||||||
|
|
||||||
|
// set the session cookie and rreturn 200!
|
||||||
|
req.session.name = name; |
||||||
|
console.log('setting req.session.name! : ', req.session); |
||||||
|
return res.status(200).json({message: "successfully logged in!", name: name}); |
||||||
|
}); |
||||||
|
|
||||||
|
app.post('/logout', (req, res) => { |
||||||
|
req.session.destroy(); |
||||||
|
res.status(200).json({message: "successfully logged out"}); |
||||||
|
}); |
||||||
|
|
||||||
|
app.get('/user', loginRequired, (req, res) => { |
||||||
|
res.status(200).json({ |
||||||
|
"name": req.session.name, |
||||||
|
"favoriteColor": "red", |
||||||
|
"leastFavoriteColor": "also red" |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
module.exports = app; |
Loading…
Reference in new issue