1
0

Remove use of sessionParser and build cookies directly

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-03-13 14:08:32 -07:00
parent 94eb98ee37
commit 5db9139b5c
4 changed files with 62 additions and 119 deletions

View File

@ -225,6 +225,7 @@ const Table = () => {
});
}, [ gameId, setGameId ]);
/* Once a game id is known, create the sole WebSocket connection
* to the backend. This WebSocket is then shared with any component
* that performs game state updates. Those components should
@ -319,6 +320,39 @@ const Table = () => {
};
const App = () => {
const [playerId, setPlayerId] = useState(undefined);
const [error, setError] = useState(undefined);
useEffect(() => {
if (playerId) {
return;
}
window.fetch(`${base}/api/v1/games/`, {
method: 'GET',
cache: 'no-cache',
credentials: 'same-origin', /* include cookies */
headers: {
'Content-Type': 'application/json'
},
}).then((res) => {
if (res.status >= 400) {
const error = `Unable to connect to Ketr Ketran game server! ` +
`Try refreshing your browser in a few seconds.`;
console.error(error);
setError(error);
}
console.log(res.headers);
return res.json();
}).then((data) => {
setPlayerId(data.player);
}).catch((error) => {
});
}, [playerId, setPlayerId]);
if (!playerId) {
return <>{ error }</>;
}
return (
<Router>
<Routes>

View File

@ -8,22 +8,14 @@ const express = require("express"),
bodyParser = require("body-parser"),
config = require("config"),
session = require('express-session'),
hb = require("handlebars"),
SQLiteStore = require('connect-sqlite3')(session),
basePath = require("./basepath"),
cookieParser = require("cookie-parser"),
app = express(),
fs = require('fs');
let server;
const server = require("http").createServer(app);
if (0) {
const key = fs.readFileSync("ssl/server-key.pem", "utf8"),
cert = fs.readFileSync("ssl/server-cert.pem", "utf8"),
credentials = { key, cert };
server = require("https").createServer(credentials, app);
} else {
server = require("http").createServer(app);
}
app.use(cookieParser());
const ws = require('express-ws')(app, server);
@ -38,7 +30,6 @@ let userDB, gameDB;
app.use(bodyParser.json());
/* App is behind an nginx proxy which we trust, so use the remote address
* set in the headers */
app.set("trust proxy", true);
@ -49,39 +40,6 @@ app.use(basePath, require("./routes/basepath.js"));
/* Handle static files first so excessive logging doesn't occur */
app.use(basePath, express.static(frontendPath, { index: false }));
/*
app.use(bodyParser.urlencoded({
extended: false
}));
*/
/* body-parser does not support text/*, so add support for that here */
if (0) app.use(function(req, res, next){
if (!req.is('text/*')) {
return next();
}
req.setEncoding('utf8');
let text = '';
req.on('data', function(chunk) {
text += chunk;
});
req.on('end', function() {
req.text = text;
next();
});
});
const sessionParser = session({
store: new SQLiteStore({ db: config.get("sessions.db") }),
secret: config.get("sessions.store-secret"),
cookie: { maxAge: 21 * 24 * 60 * 60 * 1000 }, // 3 weeks
saveUninitialized: false,
resave: true
});
app.use(sessionParser);
app.locals.sessionParser = sessionParser;
const index = require("./routes/index");
if (config.has("admin")) {
@ -95,7 +53,6 @@ app.use(basePath, index);
/* /games loads the default index */
app.use(basePath + "games", index);
/* Allow access to the 'users' API w/out being logged in */
/*
const users = require("./routes/users");
@ -110,24 +67,6 @@ app.use(function(err, req, res, next) {
});
});
if (0) {
/* Check authentication */
app.use(basePath, function(req, res, next) {
return users.getSessionUser(req).then(function(user) {
if (user.restriction) {
return res.status(401).send(user.restriction);
}
req.user = user;
return next();
}).catch(function(error) {
return res.status(403).send(error);
});
});
}
/* Everything below here requires a successful authentication */
app.use(basePath, express.static(frontendPath, { index: false }));
app.use(`${basePath}api/v1/games`, require("./routes/games"));
/* Declare the "catch all" index route last; the final route is a 404 dynamic router */

View File

@ -14,7 +14,7 @@
"body-parser": "^1.19.2",
"config": "^3.1.0",
"connect-sqlite3": "^0.9.11",
"cookie-parser": "^1.4.4",
"cookie-parser": "^1.4.6",
"core-js": "^3.2.1",
"express": "^4.17.1",
"express-session": "^1.17.1",

View File

@ -437,17 +437,11 @@ const newPlayer = (color) => {
};
}
const getSession = (game, reqSession) => {
const getSession = (game, id) => {
if (!game.sessions) {
game.sessions = {};
}
if (!reqSession.player_id) {
throw Error(`No session id for ${game.id}`);
}
const id = reqSession.player_id;
/* If this session is not yet in the game, add it and set the player's name */
if (!(id in game.sessions)) {
game.sessions[id] = {
@ -2803,7 +2797,7 @@ const ping = (session) => {
}
const wsInactive = (game, req) => {
const session = getSession(game, req.session);
const session = getSession(game, req.cookies.player);
if (session && session.ws) {
console.log(`Closing WebSocket to ${session.name} due to inactivity.`);
@ -3086,19 +3080,6 @@ const sendWarning = (session, warning) => {
session.ws.send(JSON.stringify({ type: 'warning', warning }));
}
router.ws("/ws/:id", (ws, req) => {
/* Connect the WebSocket to the app's sessionParser */
req.app.locals.sessionParser(req, {}, () => {
if (!req.session.player_id) {
req.session.player_id = crypto.randomBytes(16).toString('hex');
console.log(`[${req.session.player_id.substring(0, 8)}]: wss - New session connected`);
} else {
console.log(`[${req.session.player_id.substring(0, 8)}]: wss - Existing session being used`);
}
wsConnect(ws, req);
});
});
const getFilteredPlayers = (game) => {
const filtered = {};
for (let color in game.players) {
@ -3117,13 +3098,16 @@ const getFilteredPlayers = (game) => {
return filtered;
};
const wsConnect = async (ws, req) => {
router.ws("/ws/:id", async (ws, req) => {
if (!req.cookies || !req.cookies.player) {
ws.send({ type: 'error', error: `Unable to set session cookie` });
return;
}
const { id } = req.params;
const gameId = id;
if (!req.session.player_id) {
throw new Error(`player_id not set from http load`);
}
const short = `[${req.session.player_id.substring(0, 8)}]`;
const short = `[${req.cookies.player.substring(0, 8)}]`;
ws.id = short;
console.log(`${short}: Game ${gameId} - New connection from client.`);
@ -3142,7 +3126,7 @@ const wsConnect = async (ws, req) => {
if (!game) {
return;
}
const session = getSession(game, req.session);
const session = getSession(game, req.cookies.player);
session.live = false;
if (session.ws) {
session.ws.close();
@ -3157,7 +3141,7 @@ const wsConnect = async (ws, req) => {
if (!game) {
return;
}
const session = getSession(game, req.session);
const session = getSession(game, req.cookies.player);
if (session.player) {
session.player.live = false;
}
@ -3186,7 +3170,7 @@ const wsConnect = async (ws, req) => {
return;
}
const game = await loadGame(gameId);
const session = getSession(game, req.session);
const session = getSession(game, req.cookies.player);
if (!session.ws) {
session.ws = ws;
}
@ -3504,7 +3488,7 @@ const wsConnect = async (ws, req) => {
return;
}
const session = getSession(game, req.session);
const session = getSession(game, req.cookies.player);
session.ws = ws;
if (session.player) {
session.player.live = true;
@ -3534,7 +3518,7 @@ const wsConnect = async (ws, req) => {
clearTimeout(session.keepAlive);
}
session.keepAlive = setTimeout(() => { ping(session); }, 2500);
};
});
const debugChat = (game, preamble) => {
preamble = `Degug ${preamble.trim()}`;
@ -3825,7 +3809,7 @@ router.post("/", (req, res/*, next*/) => {
} else {
console.log(`[${req.session.player_id.substring(0, 8)}]: https - Existing session being used`);
}
const session = getSession(game, req.session);
const session = getSession(game, req.cookies.player);
saveGame(game);
return res.status(200).send(getFilteredGameForPlayer(game, session));
});
@ -3911,28 +3895,14 @@ const shuffleBoard = (game) => {
game.signature = gameSignature(game);
}
/*
return gameDB.sequelize.query("SELECT " +
"photos.*,albums.path AS path,photohashes.hash,modified,(albums.path || photos.filename) AS filepath FROM photos " +
"LEFT JOIN albums ON albums.id=photos.albumId " +
"LEFT JOIN photohashes ON photohashes.photoId=photos.id " +
"WHERE photos.id=:id", {
replacements: {
id: id
}, type: gameDB.Sequelize.QueryTypes.SELECT,
raw: true
}).then(function(photos) {
if (photos.length == 0) {
return null;
}
*/
if (0) {
router.get("/*", (req, res/*, next*/) => {
return gameDB.sequelize.query(query, {
replacements: replacements, type: gameDB.Sequelize.QueryTypes.SELECT
}).then((photos) => {
});
/* Simple NO-OP to set session cookie so player-id can use it as the
* index */
router.get("/", (req, res/*, next*/) => {
if (!req.cookies.player) {
res.cookie('player', crypto.randomBytes(16).toString('hex'));
}
console.log(`[${req.cookies.player.substring(0, 8)}]: Browser hand-shake has started.`)
return res.status(200).send({ player: req.cookies.player });
});
}
module.exports = router;