70 lines
2.1 KiB
TypeScript
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
|
|
})
|
|
);
|
|
}
|
|
} |