-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
86 lines (71 loc) · 2.26 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const express = require("express");
const Database = require("better-sqlite3");
const ssbValidate = require("ssb-validate");
const app = express();
const db = new Database("db.sqlite");
const host = "localhost";
const port = 3000;
const externalHost = `http://${host}:${port}`;
const hmacKey = null;
let state = ssbValidate.initial();
db.prepare(
"CREATE TABLE IF NOT EXISTS messages (value TEXT, author TEXT, sequence INTEGER)"
).run();
// TODO: Check for race condition.
// While this is running I think we might validate a duplicate message.
// I don't think it's a security problem, but it's not a best practice either.
db.prepare("SELECT value FROM messages")
.all()
.forEach((row) => {
ssbValidate.append(state, hmacKey, JSON.parse(row.value));
});
// JSON support.
app.use(express.json({ limit: "16MB" }));
// Return all messages.
app.get("/", (req, res) => {
const rows = db
.prepare(
"SELECT author, MAX(sequence) as sequence FROM messages GROUP BY author"
)
.all();
const rowsWithLink = rows.map((row) => {
row.link = `${externalHost}/author/${encodeURIComponent(row.author)}`;
return row;
});
res.send(rowsWithLink);
});
app.get("/author/:id", (req, res) => {
const rows = db
.prepare("SELECT value FROM messages WHERE author = ?")
.all(req.params.id);
res.send(rows.map((row) => JSON.parse(row.value)));
});
// Accept new messages.
app.post("/", function (req, res) {
// Handles each message being written. Success returns true, otherwise false.
const write = (input) => {
const value = input.value != null ? input.value : input;
try {
state = ssbValidate.append(state, hmacKey, value);
const stringValue = JSON.stringify(value);
db.prepare(
"INSERT INTO messages (value, author, sequence) VALUES (?, ?, ?)"
).run(stringValue, value.author, value.sequence);
return true;
} catch (err) {
// console.log(err);
return false;
}
};
// Return number of successful writes.
let rowsWritten;
if (Array.isArray(req.body)) {
rowsWritten = req.body.filter(write).length;
} else {
rowsWritten = Number(write(req.body));
}
res.send(`${rowsWritten}\n`);
});
app.listen(port, () =>
console.log(`Example app listening at http://localhost:${port}`)
);