2025-03-20 23:45:29 +01:00
|
|
|
import { SQL } from "bun";
|
2025-02-28 22:59:07 +01:00
|
|
|
import {API} from "osu-api-v2-js";
|
2025-03-06 22:18:15 +01:00
|
|
|
import type { Handler } from "..";
|
2025-02-28 22:59:07 +01:00
|
|
|
|
2025-03-20 23:45:29 +01:00
|
|
|
const allowed_services = ["osu", "umami"];
|
|
|
|
|
2025-02-28 22:59:07 +01:00
|
|
|
export interface Token {
|
|
|
|
access_token: string;
|
2025-03-20 23:45:29 +01:00
|
|
|
expires: number;
|
|
|
|
service: string;
|
2025-02-28 22:59:07 +01:00
|
|
|
}
|
|
|
|
|
2025-03-06 22:18:15 +01:00
|
|
|
export const token: Handler = async (params) => {
|
|
|
|
const service = params.get("service");
|
2025-03-20 23:45:29 +01:00
|
|
|
if (!service || !allowed_services.includes(service)) {
|
2025-03-06 22:18:15 +01:00
|
|
|
return new Response("Bad Request", {status: 400});
|
|
|
|
}
|
2025-02-28 22:59:07 +01:00
|
|
|
|
2025-03-20 23:45:29 +01:00
|
|
|
const db = new SQL({
|
|
|
|
username: "postgres"
|
|
|
|
});
|
|
|
|
await db.connect();
|
|
|
|
await db.begin(sql => sql`
|
|
|
|
CREATE TABLE IF NOT EXISTS tokens (
|
|
|
|
access_token text,
|
|
|
|
expires bigserial,
|
|
|
|
service text
|
|
|
|
)
|
|
|
|
`);
|
|
|
|
|
|
|
|
const tokens: Token[] = await db.begin(sql => sql`
|
|
|
|
SELECT * FROM tokens
|
|
|
|
WHERE service = ${service}
|
|
|
|
`);
|
|
|
|
|
|
|
|
const now = Number(new Date());
|
2025-02-28 22:59:07 +01:00
|
|
|
const token = tokens.find((t) => t.expires > now);
|
|
|
|
const expiredTokens = tokens.filter((t) => now > t.expires);
|
|
|
|
|
|
|
|
const promises: Promise<void>[] = [];
|
|
|
|
|
|
|
|
if (!token) {
|
|
|
|
promises.push(new Promise(async (resolve, reject) => {
|
|
|
|
console.log(`Setting a new token for ${service}...`);
|
2025-03-20 23:45:29 +01:00
|
|
|
let new_tokens: Token[] = [];
|
2025-02-28 22:59:07 +01:00
|
|
|
|
|
|
|
if (service === "osu") {
|
2025-03-06 22:18:15 +01:00
|
|
|
const api = await API.createAsync(11451, process.env["API_OSU"]!);
|
2025-03-20 23:45:29 +01:00
|
|
|
new_tokens = await db.begin(sql => sql`
|
|
|
|
INSERT INTO tokens (access_token, expires, service)
|
|
|
|
VALUES (${api.access_token}, ${Number(api.expires)}, ${service})
|
|
|
|
RETURNING *
|
|
|
|
`);
|
2025-02-28 22:59:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
else if (service === "umami") {
|
|
|
|
const response = await fetch("https://visitors.taevas.xyz/api/auth/login", {
|
|
|
|
method: "POST",
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
|
|
},
|
2025-03-06 22:18:15 +01:00
|
|
|
body: `username=${process.env["USERNAME_UMAMI"]}&password=${process.env["PASSWORD_UMAMI"]}`
|
2025-02-28 22:59:07 +01:00
|
|
|
});
|
|
|
|
const json: {token: string} = await response.json();
|
|
|
|
|
|
|
|
// Assume it expires in one day
|
|
|
|
const date = new Date();
|
|
|
|
date.setHours(date.getHours() + 24);
|
2025-03-20 23:45:29 +01:00
|
|
|
new_tokens = await db.begin(sql => sql`
|
|
|
|
INSERT INTO tokens (access_token, expires, service)
|
|
|
|
VALUES (${json.token}, ${Number(date)}, ${service})
|
|
|
|
RETURNING *
|
|
|
|
`);
|
2025-02-28 22:59:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
console.error(`Service "${service}" doesn't exist! Unable to set a new token...`);
|
|
|
|
return reject();
|
|
|
|
}
|
|
|
|
|
2025-03-20 23:45:29 +01:00
|
|
|
new_tokens.forEach((token) => {
|
|
|
|
console.log(`New ${service} token in the database, it'll expire on`, new Date(Number(token.expires)));
|
|
|
|
});
|
2025-02-28 22:59:07 +01:00
|
|
|
resolve();
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (expiredTokens.length) {
|
|
|
|
promises.push(new Promise(async (resolve) => {
|
|
|
|
console.log(`Deleting old tokens for ${service}...`);
|
|
|
|
await Promise.all(expiredTokens.map(async (t) => {
|
|
|
|
return new Promise<void>(async (resolve) => {
|
2025-03-20 23:45:29 +01:00
|
|
|
await db.begin(sql => sql`
|
|
|
|
DELETE FROM tokens
|
|
|
|
WHERE access_token = ${t.access_token}
|
|
|
|
`);
|
|
|
|
console.log(`Old ${service} token that expired on`, new Date(Number(t.expires)), "has been deleted");
|
2025-02-28 22:59:07 +01:00
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
resolve();
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
await Promise.all(promises);
|
|
|
|
|
2025-03-06 22:18:15 +01:00
|
|
|
return new Response(null, {status: 200});
|
2025-02-28 22:59:07 +01:00
|
|
|
};
|