211 lines
No EOL
5.7 KiB
JavaScript
211 lines
No EOL
5.7 KiB
JavaScript
import express from "express";
|
|
import { config as dotenvConfig } from "dotenv";
|
|
import path from "path";
|
|
import SQLite from 'better-sqlite3';
|
|
import { Kysely, SqliteDialect } from 'kysely';
|
|
import { nanoid } from "nanoid";
|
|
import { JSDOM } from "jsdom";
|
|
|
|
dotenvConfig();
|
|
|
|
const __dirname = import.meta.dirname;
|
|
|
|
const rawDB = new SQLite('abtmtr.db');
|
|
|
|
const db = new Kysely({
|
|
dialect: new SqliteDialect({
|
|
database: rawDB,
|
|
})
|
|
});
|
|
|
|
rawDB.exec(`CREATE TABLE IF NOT EXISTS blurbs( 'id' TEXT, 'site' TEXT, 'blurb' TEXT, 'verified' INTEGER, 'time' INTEGER );`);
|
|
|
|
const app = express();
|
|
|
|
app.set('view engine', 'ejs');
|
|
app.use('/assets', express.static('assets'));
|
|
app.set('views', path.join(__dirname, "views", "pages"));
|
|
|
|
// app.use(async (req, res, next) => {
|
|
// const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json")
|
|
// .catch(() => res.status(500).send())
|
|
// .then((res) => res.json())
|
|
// .catch(() => res.status(500).send());
|
|
// const followingJson = await fetch("https://cdn.abtmtr.link/site_content/following.json")
|
|
// .catch(() => res.status(500).send())
|
|
// .then((res) => res.json())
|
|
// .catch(() => res.status(500).send());
|
|
// app.locals.buttons = buttonsJson;
|
|
// app.locals.following = followingJson;
|
|
// next();
|
|
// })
|
|
|
|
app.get('/', async (req, res) => {
|
|
const statusesJson = await fetch("https://cdn.abtmtr.link/site_content/v13/statuses.json")
|
|
.catch(() => res.status(500).send())
|
|
.then((res) => res.json());
|
|
|
|
res.render('index', {
|
|
statuses: statusesJson
|
|
});
|
|
})
|
|
|
|
app.get('/servers', async (req, res) => {
|
|
const servicesJson = await fetch("https://cdn.abtmtr.link/site_content/v13/services.json")
|
|
.catch(() => res.status(500).send())
|
|
.then((res) => res.json());
|
|
const computersJson = await fetch("https://cdn.abtmtr.link/site_content/v13/computers.json")
|
|
.catch(() => res.status(500).send())
|
|
.then((res) => res.json());
|
|
|
|
res.render('servers', {
|
|
services: servicesJson,
|
|
computers: computersJson,
|
|
visibility: [
|
|
"for domain performance",
|
|
"for personal use",
|
|
"for use by friends of abtmtr.link's webmaster(s)",
|
|
"for restricted public use",
|
|
"for public use"
|
|
]
|
|
});
|
|
});
|
|
|
|
app.get('/about', async (req, res) => {
|
|
const linksJson = await fetch("https://cdn.abtmtr.link/site_content/v13/links.json")
|
|
.catch(() => res.status(500).send())
|
|
.then((res) => res.json());
|
|
|
|
res.render('about', {
|
|
links: linksJson
|
|
});
|
|
});
|
|
|
|
app.get('/sites', async (req, res) => {
|
|
const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json")
|
|
.catch(() => res.status(500).send())
|
|
.then((res) => res.json())
|
|
.catch(() => res.status(500).send());
|
|
const followingJson = await fetch("https://cdn.abtmtr.link/site_content/following.json")
|
|
.catch(() => res.status(500).send())
|
|
.then((res) => res.json())
|
|
.catch(() => res.status(500).send());
|
|
|
|
res.render('sites', {
|
|
b: buttonsJson, f: followingJson
|
|
});
|
|
});
|
|
|
|
app.get('/blurbs', async (req, res) => {
|
|
const data = await db
|
|
.selectFrom('blurbs')
|
|
.selectAll()
|
|
.where('verified', '=', 1)
|
|
.orderBy('time', "desc")
|
|
.execute();
|
|
res.render('blurbs', { data });
|
|
});
|
|
|
|
// brbrleibbghbelsbbsbuuebbuubsubss
|
|
async function cleanupBlurbles() {
|
|
const timeNow = Date.now() - 86400000;
|
|
await db
|
|
.deleteFrom('blurbs')
|
|
.where('time', '<', timeNow)
|
|
.where('verified', '=', 0)
|
|
.execute()
|
|
}
|
|
|
|
app.get('/blurbs/testsend', async (req, res) => {
|
|
|
|
res.render('blurbsent', { id: "THISISATESTLOL" });
|
|
});
|
|
|
|
app.get('/blurbs/send', async (req, res) => {
|
|
const body = req.query;
|
|
const errors = [];
|
|
|
|
if (body.site == null) errors.push("Site domain required");
|
|
else {
|
|
const status = await fetch(body.site).then(x => x.status).catch(_ => _);
|
|
if (status != 200) errors.push("Site must be online");
|
|
}
|
|
if (body.text == null) errors.push("Blurb text required");
|
|
else {
|
|
if (body.text.length < 1) errors.push("Blurb text must not be blank");
|
|
if (body.text.length > 140) errors.push("Blurb text must not exceed 140 characters");
|
|
}
|
|
|
|
if (errors.length > 0) return res.status(400).json({
|
|
error: "Bad Request",
|
|
message: errors.join(", ")
|
|
});
|
|
|
|
const postId = nanoid(32);
|
|
|
|
try {
|
|
await db.insertInto('blurbs')
|
|
.values({
|
|
id: postId,
|
|
site: body.site,
|
|
blurb: body.text,
|
|
verified: 0,
|
|
time: Date.now()
|
|
})
|
|
.executeTakeFirstOrThrow();
|
|
} catch (err) {
|
|
console.log(err)
|
|
return res.status(500).send('Internal Server Error');
|
|
}
|
|
|
|
cleanupBlurbles();
|
|
|
|
res.render('blurbsent', { id: postId });
|
|
});
|
|
|
|
app.get('/blurbs/check', async (req, res) => {
|
|
const body = req.query;
|
|
const blurbFromId = await db
|
|
.selectFrom('blurbs')
|
|
.selectAll()
|
|
.where('id', '=', body.id)
|
|
.executeTakeFirst();
|
|
|
|
if (blurbFromId == null) return res.redirect("/blurbs/");
|
|
|
|
const site = await fetch(blurbFromId.site).then(x => x.text()).catch(_ => _);
|
|
const dom = new JSDOM(site);
|
|
const relationLink = dom.window.document.querySelector(
|
|
`[rel=me][href="https://abtmtr.link/blurbs/#${blurbFromId.id}"]`
|
|
);
|
|
if (relationLink != null) await db
|
|
.updateTable('blurbs')
|
|
.set({
|
|
verified: 1
|
|
})
|
|
.where('id', '=', body.id)
|
|
.executeTakeFirst();
|
|
else {
|
|
await db
|
|
.updateTable('blurbs')
|
|
.set({
|
|
verified: 0
|
|
})
|
|
.where('id', '=', body.id)
|
|
.executeTakeFirst();
|
|
}
|
|
|
|
cleanupBlurbles();
|
|
|
|
res.redirect("/blurbs/");
|
|
});
|
|
|
|
app.get("/favicon.ico", (req, res) => {
|
|
res.redirect("https://cdn.abtmtr.link/site_content/favicon.ico")
|
|
})
|
|
|
|
app.listen(process.env.PORT, () => {
|
|
const url = new URL("http://localhost/");
|
|
url.port = process.env.PORT;
|
|
console.log(`Example app listening on ${url.toString()}`);
|
|
}); |