AstroCol/src/pages/api/auth/generateAccessToken.ts

70 lines
2.1 KiB
TypeScript

import { randomBytes, createHash } from "crypto";
import type { APIRoute } from "astro";
import type AccessToken from "../../../types/AccessToken";
import { createAccessToken } from "../../../lib/accessTokens";
export const POST: APIRoute = async({ request }) => {
const data = await request.json().catch(() => {return new Response(
JSON.stringify({
code: 400,
message: "Bad Request",
error: "Invalid JSON"
})
)});
if(!data.username) return new Response(
JSON.stringify({
code: 400,
message: "Bad Request",
error: "Username is required"
})
)
const header = request.headers.get("Authorization");
const token = header?.split(" ")[1];
if(!token) return new Response(
JSON.stringify({
code: 401,
message: "Unauthorized",
error: "Access Token is required"
})
)
if(token !== import.meta.env.MASTER_ACCESSTOKEN) return new Response(
JSON.stringify({
code: 401,
message: "Unauthorized",
error: "Invalid Access Token"
})
)
else {
const now = new Date();
const timestamp = Buffer.from(String(Date.now())).toString('base64url');
const username = Buffer.from(data.username).toString('base64url');
const random = randomBytes(16).toString("base64url");
const randomHashed = createHash("sha256").update(random).digest("hex");
const expiresIn = (data.duration ?? 86400) * 1000;
const tokenString = `A.${timestamp}.${username}.${random}`;
const accessToken: AccessToken = {
type: "A",
username: data.username,
entropy: randomHashed.toString(),
createdAt: now,
expiresAt: new Date(now.getTime() + expiresIn),
createdFrom: data.createdFrom ?? null
};
await createAccessToken(accessToken);
return new Response(
JSON.stringify({
code: 200,
message: "OK",
accessToken: tokenString
})
);
}
}