moving to server/db sameness and express-session
This commit is contained in:
parent
ee5402ab44
commit
32913d582a
16
client/package-lock.json
generated
16
client/package-lock.json
generated
@ -20,6 +20,7 @@
|
||||
"graphology-layout-force": "^0.2.4",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-hook-form": "^7.53.0",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-sigma": "^1.2.35",
|
||||
"sigma": "^3.0.0-beta.29",
|
||||
@ -3088,6 +3089,21 @@
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-hook-form": {
|
||||
"version": "7.53.0",
|
||||
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.0.tgz",
|
||||
"integrity": "sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/react-hook-form"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"graphology-layout-force": "^0.2.4",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-hook-form": "^7.53.0",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-sigma": "^1.2.35",
|
||||
"sigma": "^3.0.0-beta.29",
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import Landing from '/src/landing/Landing.jsx'
|
||||
import PageView from '/src/page/PageView.jsx'
|
||||
import PageEdit from '/src/page/PageEdit.jsx'
|
||||
import Landing from '/src/landing/Landing.jsx';
|
||||
import PageView from '/src/page/PageView.jsx';
|
||||
import PageEdit from '/src/page/PageEdit.jsx';
|
||||
import LogIn from '/src/login/LogIn.jsx';
|
||||
import Register from '/src/login/Register.jsx';
|
||||
|
||||
import './App.css'
|
||||
import './App.css';
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@ -14,6 +16,8 @@ function App() {
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={<Landing/>}/>
|
||||
<Route path="/login" element={<LogIn/>}/>
|
||||
<Route path="/register" element={<Register/>}/>
|
||||
<Route path="/:pagenumber" element={<PageView/>}/>
|
||||
<Route path="/:pagenumber/edit" element={<PageEdit/>}/>
|
||||
</Routes>
|
||||
|
@ -4,8 +4,19 @@ import Graph from 'graphology';
|
||||
|
||||
export const apiUrl = `${window.location.origin}/api`;
|
||||
|
||||
|
||||
//lil helper to throw errorrs from the promise when we get not-ok results
|
||||
export const shoofetch = (url, config) => fetch(url, {...config, ...defaults})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(`got an error from the server: ${await res.text()}`);
|
||||
}
|
||||
return res.json();
|
||||
});
|
||||
|
||||
const defaults = {
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
credentials: 'include'
|
||||
};
|
||||
|
||||
export async function postNewPage() {
|
||||
@ -41,7 +52,6 @@ export async function postPage({id, title, description}) {
|
||||
export async function deletePage(id) {
|
||||
return fetch(`${apiUrl}/page/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
...defaults
|
||||
})
|
||||
}
|
||||
@ -56,4 +66,22 @@ export async function fetchGraph() {
|
||||
graph.import(serialized);
|
||||
return graph;
|
||||
})
|
||||
}
|
||||
|
||||
export async function createAccount({name, password, nonce}) {
|
||||
return shoofetch(`${apiUrl}/register`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({name: name, password: password, nonce: nonce})
|
||||
})
|
||||
}
|
||||
|
||||
export async function logIn({name, password}) {
|
||||
return shoofetch(`${apiUrl}/login`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({name: name, password: password})
|
||||
})
|
||||
}
|
||||
|
||||
export async function logOut() {
|
||||
return shoofetch(`${apiUrl}/logout`, { method: 'POST' });
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App.jsx';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
|
||||
@ -9,9 +8,4 @@ root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
);
|
@ -1,7 +1,8 @@
|
||||
|
||||
.landing-page {
|
||||
padding-left:10rem;
|
||||
padding-right: 10rem;
|
||||
width: 76ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-top: 3rem;
|
||||
color: white;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useNavigate, Link } from 'react-router-dom'
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { fetchPageList, postNewPage } from '../apiTools.jsx';
|
||||
import { fetchPageList, postNewPage, logOut } from '../apiTools.jsx';
|
||||
import { useFixLinks } from '../clientStuff.jsx';
|
||||
|
||||
import PageList from './PageList.jsx';
|
||||
@ -37,9 +37,10 @@ function Landing() {
|
||||
<PageList />
|
||||
</section>
|
||||
<section className="landing-section">
|
||||
<button>Sign up</button><br/>
|
||||
<button>Log in</button><br/>
|
||||
<button onClick={makeNewPage.mutate} >Dig new room!</button><br/>
|
||||
<button onClick={() => navigate('/register')}>Sign up</button><br/>
|
||||
<button onClick={() => navigate('/login')}>Log in</button><br/>
|
||||
<button onClick={makeNewPage.mutate}>Dig new room!</button><br/>
|
||||
<button onClick={logOut}>Log Out</button><br/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1 +1,32 @@
|
||||
LogIn.jsx
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { logIn } from '../apiTools.jsx';
|
||||
|
||||
function LogIn() {
|
||||
const { register, handleSubmit } = useForm();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onSubmit = (d) => {
|
||||
logIn(d)
|
||||
.then(() => navigate('/'))
|
||||
.catch((error) => console.log('error logging in: ', error));
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<label>
|
||||
User name:
|
||||
<input {...register("name")} />
|
||||
<br/>
|
||||
</label>
|
||||
<label>
|
||||
Password:
|
||||
<input {...register("password")} />
|
||||
<br/>
|
||||
</label>
|
||||
<button type="submit">Log right in, buckaroo!</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default LogIn;
|
37
client/src/login/Register.jsx
Normal file
37
client/src/login/Register.jsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { createAccount } from "../apiTools.jsx";
|
||||
|
||||
function Register() {
|
||||
const { register, handleSubmit } = useForm();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onSubmit = (d) => {
|
||||
createAccount(d)
|
||||
.then(() => navigate("/login"))
|
||||
.catch((error) => console.log("error: ", error));
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<label>
|
||||
User name:
|
||||
<input {...register("name")} />
|
||||
<br/>
|
||||
</label>
|
||||
<label>
|
||||
Password:
|
||||
<input {...register("password")} />
|
||||
<br/>
|
||||
</label>
|
||||
<label>
|
||||
Nonce password from shoofle:
|
||||
<input {...register("nonce")} />
|
||||
<br/>
|
||||
</label>
|
||||
<button type="submit">Request Account!</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default Register;
|
@ -1,7 +1,8 @@
|
||||
|
||||
.page-container {
|
||||
padding-left:10rem;
|
||||
padding-right: 10rem;
|
||||
width: 76ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-top: 3rem;
|
||||
color: white;
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
@ -10,6 +10,18 @@ create table if not exists pages (
|
||||
)
|
||||
`;
|
||||
|
||||
const createUsers = `
|
||||
create table if not exists users (
|
||||
name varchar(64) primary key,
|
||||
password varchar(128)
|
||||
)
|
||||
`;
|
||||
|
||||
const createTokens = `
|
||||
create table if not exists tokens (
|
||||
)
|
||||
`;
|
||||
|
||||
async function initDb() {
|
||||
const config = {
|
||||
url: "http://127.0.0.1:8000"
|
||||
@ -19,6 +31,7 @@ async function initDb() {
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
|
||||
console.log("creating page table")
|
||||
console.log(await db.execute(createPages));
|
||||
|
||||
console.log("finding pages that havent been rendered");
|
||||
@ -35,7 +48,11 @@ async function initDb() {
|
||||
sql: `replace into pages (id, title, description, html) values (?, ?, ?, ?)`,
|
||||
args: [id, title, description, renderedPage]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
console.log("creating user table");
|
||||
console.log(await db.execute(createUsers));
|
||||
}
|
||||
|
||||
initDb();
|
128
server/api.js
128
server/api.js
@ -1,72 +1,122 @@
|
||||
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) => {
|
||||
query('select id, title from pages', [])
|
||||
.then((r) => r.rows)
|
||||
.then((row) => row.map(([id, title]) => {return {"id": id, "title": title};}))
|
||||
.then((pages) => res.status(200).json(pages))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
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) => {
|
||||
query('insert into pages (title, description) values (?, ?) returning id',
|
||||
["new page", "this page is new!"])
|
||||
.then((r) => r.rows[0])
|
||||
.then((row) => res.status(200).json({id: row[0]}))
|
||||
.catch((error) => res.status(500).json({"error": error}))
|
||||
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) => {
|
||||
query('select * from pages where id=?', [req.params.id])
|
||||
.then((r) => {
|
||||
if (r.rows.length == 0) res.status(404).json({"error": "page not found in db"});
|
||||
else return r.rows[0];
|
||||
}).then((row) => res.status(200).json(row))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
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) => {
|
||||
const html = converter.makeHtml(req.body.description);
|
||||
query('replace into pages (id, title, description, html) values (?, ?, ?, ?)',
|
||||
[req.params.id, req.body.title, req.body.description, html])
|
||||
.then(() => res.status(200).json({}))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
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) => {
|
||||
query('delete from pages where id = ?', [req.params.id])
|
||||
.then(() => res.status(200).json({id: req.params.id}))
|
||||
.catch((error) => res.status(500).json({"error": error}))
|
||||
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) => {
|
||||
query('select id, html from pages', [])
|
||||
.then((r) => r.rows)
|
||||
.then((stuff) => graphFromList(stuff))
|
||||
.then((graph) => res.json(graph))
|
||||
.catch((error) => res.status(500).json({"error": error}));
|
||||
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', (req, res) => {
|
||||
// parse the body, which miight be url-encoded?
|
||||
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
|
||||
// hash the password
|
||||
// add tthe user to the users database
|
||||
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', (req, res) => {
|
||||
// hash the password
|
||||
// check if the user/hashed pass matches
|
||||
// if not, throw an error
|
||||
// create a valid ttoken?
|
||||
// return token
|
||||
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;
|
@ -1,19 +0,0 @@
|
||||
// helper function(s?) to make a query to the database
|
||||
|
||||
const db_url = 'http://127.0.0.1:8000'
|
||||
|
||||
async function query(q, params) {
|
||||
return fetch(db_url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
statements: [{
|
||||
q: q,
|
||||
params: params
|
||||
}]
|
||||
})
|
||||
}).then((res) => res.json())
|
||||
.then((data) => data[0].results);
|
||||
}
|
||||
|
||||
module.exports = { query: query };
|
31
server/db_scripts/copy_db.js
Normal file
31
server/db_scripts/copy_db.js
Normal file
@ -0,0 +1,31 @@
|
||||
const sqlite = require("better-sqlite3");
|
||||
const sqlite3_db = new sqlite('./the_big_db.db', { verbose: console.log });
|
||||
|
||||
const libsql = require("@libsql/client");
|
||||
const config = {url: "http://127.0.0.1:8000"};
|
||||
const libsql_db = libsql.createClient(config);
|
||||
|
||||
async function copyPages() {
|
||||
console.log("copying everythting from hte old db");
|
||||
const pages = (await libsql_db.execute(`select id, title, description, html from pages`)).rows;
|
||||
|
||||
const insertPage = sqlite3_db.prepare(`replace into pages (id, title, description, html) values (:id, :title, :description, :html)`);
|
||||
pages.forEach((page) => {
|
||||
console.log(`inserting page ${page.id}`)
|
||||
insertPage.run(page);
|
||||
});
|
||||
}
|
||||
|
||||
async function copyUsers() {
|
||||
console.log("copying users now");
|
||||
const users = (await libsql_db.execute(`select name, password from users`)).rows;
|
||||
|
||||
const insertUser = sqlite3_db.prepare(`replace into users (name, password) values (:name, :password)`);
|
||||
users.forEach((user) => {
|
||||
console.log(`inserting ${user.name}, ${user.password}`);
|
||||
insertUser.run(user);
|
||||
});
|
||||
}
|
||||
|
||||
copyPages();
|
||||
copyUsers();
|
48
server/db_scripts/initialize_db.js
Normal file
48
server/db_scripts/initialize_db.js
Normal file
@ -0,0 +1,48 @@
|
||||
const sqlite = require("better-sqlite3");
|
||||
const showdown = require("showdown");
|
||||
const db = new sqlite('./the_big_db.db', { verbose: console.log });
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
|
||||
const createPages = db.prepare(`
|
||||
create table if not exists pages (
|
||||
id integer primary key,
|
||||
title varchar(255),
|
||||
description text,
|
||||
html text
|
||||
)
|
||||
`);
|
||||
|
||||
const createUsers = db.prepare(`
|
||||
create table if not exists users (
|
||||
name varchar(64) primary key,
|
||||
password varchar(128)
|
||||
)
|
||||
`);
|
||||
|
||||
|
||||
function initDb() {
|
||||
console.log("creating page table")
|
||||
console.log(createPages.run());
|
||||
|
||||
console.log("finding pages that havent been rendered");
|
||||
rows = db.prepare(`select * from pages where html is null`).all();
|
||||
console.log(rows);
|
||||
|
||||
const insertPage = db.prepare(`replace into pages (id, title, description, html) values (:id, :title, :description, :html)`);
|
||||
|
||||
rows.forEach((pageData) => {
|
||||
const {id, title, description, html} = pageData;
|
||||
console.log(`rendering page number ${id}`)
|
||||
console.log(`${id}. ${title}: ${description} ( ${html} )`);
|
||||
|
||||
const renderedPage = converter.makeHtml(description);
|
||||
|
||||
insertPage.run({...pageData, html: renderedPage});
|
||||
});
|
||||
|
||||
console.log("creating user table");
|
||||
console.log(createUsers.run());
|
||||
}
|
||||
|
||||
initDb();
|
4
server/db_scripts/list_tables.js
Normal file
4
server/db_scripts/list_tables.js
Normal file
@ -0,0 +1,4 @@
|
||||
const sqlite = require("better-sqlite3");
|
||||
const db = new sqlite('./the_big_db.db', { verbose: console.log });
|
||||
|
||||
console.log(db.prepare("select name from sqlite_master where type='table'").all());
|
@ -4,12 +4,12 @@ const { circular } = require('graphology-layout');
|
||||
|
||||
function graphFromList(allTheStuff) {
|
||||
const graph = new graphology.Graph();
|
||||
for (const {id, html} of allTheStuff) {
|
||||
|
||||
for (const [id, html] of allTheStuff) {
|
||||
graph.addNode(id);
|
||||
}
|
||||
|
||||
for (const [id, html] of allTheStuff) {
|
||||
for (const {id, html} of allTheStuff) {
|
||||
const { document } = (new JSDOM(html)).window;
|
||||
const links = document.querySelectorAll('a');
|
||||
links.forEach((link) => {
|
||||
|
818
server/package-lock.json
generated
818
server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,13 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@libsql/client": "^0.14.0",
|
||||
"argon2": "^0.41.1",
|
||||
"better-sqlite3": "^11.3.0",
|
||||
"better-sqlite3-session-store": "^0.1.0",
|
||||
"client-sessions": "^0.8.0",
|
||||
"express": "^4.21.0",
|
||||
"express-session": "^1.18.0",
|
||||
"graphology": "^0.25.4",
|
||||
"graphology-layout": "^0.6.1",
|
||||
"graphology-layout-force": "^0.2.4",
|
||||
|
@ -1,11 +1,28 @@
|
||||
const express = require('express');
|
||||
const session = require('express-session');
|
||||
const sqlite = require('better-sqlite3');
|
||||
|
||||
const apiRoutes = require('./api.js');
|
||||
|
||||
const port = process.env.PORT || 3001; // Use the port provided by the host or default to 3000
|
||||
const db = new sqlite('the_big_db.db', { verbose: console.log });
|
||||
const SqliteStore = require('better-sqlite3-session-store')(session);
|
||||
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
app.use(session({
|
||||
store: new SqliteStore({
|
||||
client: db,
|
||||
expired: {
|
||||
clear: true,
|
||||
intervalMs: 15*60*1000
|
||||
}
|
||||
}),
|
||||
secret: "dno'tt check me into versino control",
|
||||
resave: false
|
||||
}));
|
||||
|
||||
app.use("/api", apiRoutes);
|
||||
|
||||
app.listen(port, () => {
|
||||
|
Loading…
Reference in New Issue
Block a user