Added location element
Fixed TTL in DB to match maxAge of session Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
d8b15e50af
commit
cf83d2b95b
5
.env
5
.env
@ -1,3 +1,6 @@
|
||||
HTTPS=true
|
||||
SSL_CRT_FILE=/etc/letsencrypt/live/ketrenos.com/cert.pem
|
||||
SSL_KEY_FILE=/etc/letsencrypt/live/ketrenos.com/privkey.pem
|
||||
REACT_APP_basePath="/"
|
||||
NODE_CONFIG_ENV='production'
|
||||
LOG_LINE=1
|
||||
LOG_LINE=1
|
||||
|
@ -32,7 +32,7 @@
|
||||
"web-vitals": "^2.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "HTTPS=true react-scripts start",
|
||||
"start": "export $(cat ../.env | xargs) && react-scripts start",
|
||||
"build": "export $(cat ../.env | xargs) && react-scripts build",
|
||||
"test": "export $(cat ../.env | xargs) && react-scripts test",
|
||||
"eject": "export $(cat ../.env | xargs) && react-scripts eject"
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
import './Group.css';
|
||||
import { GlobalContext } from "./GlobalContext.js";
|
||||
import { base } from "./Common.js";
|
||||
import { Location } from "./Location.js";
|
||||
|
||||
function Group() {
|
||||
const { csrfToken, user, setUser } = useContext(GlobalContext);
|
||||
@ -40,36 +41,7 @@ function Group() {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
setLocations(data.map(location => {
|
||||
const fields = Object.getOwnPropertyNames(location)
|
||||
.map(field => <div key={field}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
width: '100%'
|
||||
}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignSelf: 'flex-start',
|
||||
fontWeight: 'bold',
|
||||
minWidth: '8rem'
|
||||
}}>{field}</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignSelf: 'flex-start',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
{location[field]}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <div key={location.id} style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center'
|
||||
}}>{ fields }</div>;
|
||||
}));
|
||||
setLocations(data);
|
||||
};
|
||||
effect();
|
||||
}, [user, setGroup, groupId, csrfToken]);
|
||||
@ -114,7 +86,8 @@ function Group() {
|
||||
{ !error && <>
|
||||
<div>Group: {groupId}</div>
|
||||
<div>Locations</div>
|
||||
{ locations }
|
||||
{ locations.map(location =>
|
||||
<Location location={location} key={location.id}/>) }
|
||||
</> }
|
||||
</GlobalContext.Provider>
|
||||
</Paper>
|
||||
|
4
client/src/Location.css
Normal file
4
client/src/Location.css
Normal file
@ -0,0 +1,4 @@
|
||||
.Location {
|
||||
text-align: center;
|
||||
}
|
||||
|
94
client/src/Location.js
Normal file
94
client/src/Location.js
Normal file
@ -0,0 +1,94 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import Paper from '@mui/material/Paper';
|
||||
import {
|
||||
useParams,
|
||||
useNavigate
|
||||
} from "react-router-dom";
|
||||
|
||||
import './Location.css';
|
||||
import { GlobalContext } from "./GlobalContext.js";
|
||||
import { base } from "./Common.js";
|
||||
|
||||
function Location(props) {
|
||||
const propLocation = props.location;
|
||||
const { csrfToken } = useContext(GlobalContext);
|
||||
const [ location, setLocation ] = useState(
|
||||
typeof propLocation === 'object' ? propLocation : undefined);
|
||||
const locationId =
|
||||
typeof propLocation === 'number' ? propLocation : undefined;
|
||||
const [ error, setError ] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!csrfToken && (location || !locationId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const effect = async () => {
|
||||
const res = await window.fetch(
|
||||
`${base}/api/v1/locations/${locationId}`, {
|
||||
method: 'GET',
|
||||
cache: 'no-cache',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'CSRF-Token': csrfToken
|
||||
}
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.status >= 400) {
|
||||
setError(data.message ? data.message : res.statusText);
|
||||
return;
|
||||
}
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
setLocation(data);
|
||||
}
|
||||
effect();
|
||||
}, [locationId, csrfToken, location]);
|
||||
|
||||
const createLocation = (location) => {
|
||||
const fields = Object.getOwnPropertyNames(location)
|
||||
.map(field => <div key={field}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
width: '100%'
|
||||
}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignSelf: 'flex-start',
|
||||
fontWeight: 'bold',
|
||||
minWidth: '8rem'
|
||||
}}>{field}</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignSelf: 'flex-start',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
{location[field]}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return <div key={location.id} style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center'
|
||||
}}>{fields}</div>;
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper className="Location" style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}}>
|
||||
{ error && <div>{error}</div>}
|
||||
{ !error && <>
|
||||
{ createLocation(location) }
|
||||
</> }
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
export { Location };
|
@ -26,30 +26,40 @@ require('./console-line.js'); /* Monkey-patch console.log with line numbers */
|
||||
app.set('trust proxy', true);
|
||||
app.use(session({
|
||||
secret: 'm@g1x!c00k13$',
|
||||
maxAge: 14 * 24 * 60 * 60 * 1000, /* 2 weeks */
|
||||
resave: true,
|
||||
saveUninitialized: false,
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000, /* 1 month */
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
cookie: { secure: true },
|
||||
store: new SqliteStore({
|
||||
driver: sqlite3.Database,
|
||||
path: config.get('sessions.db'),
|
||||
ttl: 5000,
|
||||
ttl: 30 * 24 * 60 * 60 * 1000, /* 1 month */
|
||||
cleanupInterval: 300000
|
||||
}),
|
||||
}));
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use((req, res, next) => {
|
||||
const csrfDebug = (req) => {
|
||||
console.log('CSRF debug: ', {
|
||||
token: req.header('CSRF-Token'),
|
||||
method: req.method
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
token: req.header('CSRF-Token'),
|
||||
csrf: req.csrfToken ? req.csrfToken() : 'CSRF not initialized',
|
||||
user: (req.session && req.session.userId)
|
||||
? req.session.userId
|
||||
: 'Not logged in'
|
||||
});
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(csrf({
|
||||
cookie: true
|
||||
}));
|
||||
app.use((req, res, next) => {
|
||||
csrfDebug(req);
|
||||
next();
|
||||
});
|
||||
app.use(bodyParser.json());
|
||||
|
||||
//const ws = require('express-ws')(app, server);
|
||||
@ -84,11 +94,7 @@ goodTimesDB.init().then((db) => {
|
||||
app.use(methodOverride());
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.use((err, req, res, _next) => {
|
||||
console.log('CSRF debug: ', {
|
||||
token: req.header('CSRF-Token'),
|
||||
csrf: req.csrfToken(),
|
||||
method: req.method
|
||||
});
|
||||
csrfDebug(req);
|
||||
console.error(err);
|
||||
res.status(err.status || 500).json({
|
||||
message: err.message,
|
||||
|
@ -5,7 +5,6 @@ const router = express.Router();
|
||||
|
||||
const originalLocations = require('../location-data.js');
|
||||
|
||||
|
||||
router.put('/', (req, res) => {
|
||||
const location = req.body;
|
||||
location.id = originalLocations.length;
|
||||
@ -20,9 +19,9 @@ router.get('/:locationId?', (req, res) => {
|
||||
item => item.id === locationId
|
||||
);
|
||||
if (!location) {
|
||||
res.status(404).send({ message: `Location ${locationId} not found.`});
|
||||
return res.status(404).send({ message: `Location ${locationId} not found.`});
|
||||
}
|
||||
res.status(200).send([ location ]);
|
||||
return res.status(200).send([ location ]);
|
||||
}
|
||||
|
||||
return res.status(200).send(originalLocations);
|
||||
|
@ -77,6 +77,8 @@ router.put('/password', async (req, res) => {
|
||||
|
||||
router.get('/csrf', (req, res) => {
|
||||
const token = req.csrfToken();
|
||||
console.log(
|
||||
`${req.method} ${req.path} - token`, token);
|
||||
res.json({ csrfToken: token });
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user