2024-04-20 18:18:38 +00:00
|
|
|
import { Hono } from "https://deno.land/x/hono@v4.2.5/mod.ts";
|
2024-04-20 18:32:52 +00:00
|
|
|
import {
|
|
|
|
serveStatic,
|
|
|
|
logger,
|
|
|
|
} from "https://deno.land/x/hono@v4.2.5/middleware.ts";
|
2024-04-20 18:18:38 +00:00
|
|
|
|
|
|
|
const cache = await Deno.openKv();
|
|
|
|
const app = new Hono();
|
2024-04-20 18:32:52 +00:00
|
|
|
app.use(logger());
|
2024-04-20 18:18:38 +00:00
|
|
|
|
|
|
|
// .well-known for matrix
|
|
|
|
app.get("/.well-known/matrix/client", (c) =>
|
|
|
|
c.json({
|
|
|
|
"m.homeserver": {
|
|
|
|
base_url: "https://matrix.chat.tjo.space",
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
app.get("/.well-known/matrix/server", (c) =>
|
|
|
|
c.json({
|
|
|
|
"m.server": "matrix.chat.tjo.space:443",
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
app.get("/.well-known/matrix/support", (c) =>
|
|
|
|
c.json({
|
|
|
|
contacts: [
|
|
|
|
{
|
|
|
|
matrix_id: "@tine:tjo.space",
|
|
|
|
email_address: "tine@tjo.space",
|
|
|
|
role: "m.role.admin",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
// .well-known for webfinger - tailscale
|
|
|
|
app.get("/.well-known/webfinger", (c) => {
|
|
|
|
const resource = c.req.query("resource");
|
|
|
|
if (!resource) {
|
|
|
|
c.status(400);
|
|
|
|
return c.json({ error: "Missing resource query parameter" });
|
|
|
|
}
|
|
|
|
|
|
|
|
const [scheme] = resource.split(":");
|
|
|
|
if (scheme !== "acct") {
|
|
|
|
c.status(400);
|
|
|
|
return c.json({ error: "Only acct scheme is supported" });
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.json({
|
|
|
|
subject: resource,
|
|
|
|
links: [
|
|
|
|
{
|
2024-04-20 18:43:14 +00:00
|
|
|
rel: "http://openid.net/specs/connect/1.0/issuer",
|
2024-04-20 18:18:38 +00:00
|
|
|
href: `https://id.tjo.space/application/o/tailscalecom/`,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// Serve plausible analytics
|
|
|
|
app.get("/js/script.js", async (c) => {
|
|
|
|
c.header("Content-Type", "text/javascript");
|
|
|
|
|
|
|
|
// Check if we have the script cached
|
|
|
|
const cachedScript = await cache.get<string>(["plausible", "script"]);
|
|
|
|
if (cachedScript.value) {
|
|
|
|
return c.body(cachedScript.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
const response = await fetch("https://plausible.io/js/plausible.js");
|
|
|
|
const script = await response.text();
|
|
|
|
|
|
|
|
// Cache for 24 hours if we got the script
|
|
|
|
if (response.status === 200) {
|
|
|
|
await cache.set(["plausible", "script"], script, {
|
|
|
|
expireIn: 1000 * 60 * 60 * 24,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.body(script);
|
|
|
|
});
|
2024-04-22 17:39:04 +00:00
|
|
|
app.post("/api/event", (c) => {
|
2024-04-20 18:18:38 +00:00
|
|
|
const request = new Request(c.req.raw);
|
|
|
|
request.headers.delete("Cookie");
|
|
|
|
request.headers.set("X-Forwarded-For", c.req.header("host") || "");
|
|
|
|
return fetch("https://plausible.io/api/event", request);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Serve website
|
|
|
|
app.use("*", serveStatic({ root: "./web" }));
|
|
|
|
|
|
|
|
// Start server
|
|
|
|
Deno.serve({ port: 8080, hostname: "0.0.0.0" }, app.fetch);
|