Upload files to "api/src"

master
Joseph 2024-10-31 17:05:05 +00:00
parent 8a7f7d12d5
commit 6c0d061023
3 changed files with 289 additions and 0 deletions

211
api/src/index.ts 100644
View File

@ -0,0 +1,211 @@
import { Router, IRequest } from "itty-router";
import { StoredRequest, RequestBin, ReturnedRequest } from "./types";
import { mapRequest, randomString, json } from "./utils";
export interface Env {
DB: D1Database;
}
const router = Router<IRequest, [env: Env, ctx: ExecutionContext]>();
router.post("/create", async (req, env: Env) => {
const id = randomString(10);
const result = await env.DB.prepare("INSERT INTO bins (id) values (?)").bind(id).run();
if (!result.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
return json({
success: true,
bin: {
id
}
});
});
router.all("/-/:id/*", async (request, env: Env) => {
const { params, method, headers, url } = request;
const { id } = params;
const result = await env.DB.prepare("SELECT * FROM bins WHERE id = ?").bind(id).first<string>("id");
if (!result) {
return json({
success: false,
message: "A request bin could not be found with the ID provided"
}, { status: 404 });
}
const headersObject: {[k: string]: string} = {};
let ip = "";
for (const [key, value] of headers) {
headersObject[key] = value;
if (key === "cf-connecting-ip")
ip = value;
}
const requestId = randomString(10);
const body = await request.arrayBuffer();
const insertResult = await env.DB
.prepare("INSERT INTO requests (id, ip, method, url, timestamp, headers, body, bin_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
.bind(requestId, ip, method, url, Date.now(), JSON.stringify(headersObject), body, id)
.run();
if (!insertResult.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
return json({ success: true });
});
router.delete("/:id", async ({ params }, env: Env) => {
const { id } = params;
let result = await env.DB.prepare("DELETE FROM requests WHERE bin_id = ?").bind(id).run();
if (!result.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
result = await env.DB.prepare("DELETE FROM bins WHERE id = ?").bind(id).run();
if (!result.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
return json({ success: true });
});
router.delete("/:id/all", async ({ params }, env: Env) => {
const { id } = params;
const binResult = await env.DB.prepare("SELECT * FROM bins WHERE id = ?").bind(id).first<string>("id");
if (!binResult) {
return json({
success: false,
message: "A request bin could not be found with the ID provided"
}, { status: 404 });
}
const result = await env.DB.prepare("DELETE FROM requests WHERE bin_id = ?").bind(id).run();
if (!result.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
return json({ success: true });
});
router.delete("/:id/:requestId", async ({ params }, env: Env) => {
const { id, requestId } = params;
const binResult = await env.DB.prepare("SELECT * FROM bins WHERE id = ?").bind(id).first<string>("id");
if (!binResult) {
return json({
success: false,
message: "A request bin could not be found with the ID provided"
}, { status: 404 });
}
const result = await env.DB.prepare("DELETE FROM requests WHERE bin_id = ? AND id = ?").bind(id, requestId).run();
if (!result.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
return json({ success: true });
});
router.get("/:id", async ({ params }, env: Env) => {
const { id } = params;
const result = await env.DB.prepare("SELECT * FROM bins WHERE id = ?").bind(id).first<string>("id");
if (!result) {
return json({
success: false,
message: "A request bin could not be found with the ID provided"
}, { status: 404 });
}
const requestsResult = await env.DB.prepare("SELECT * FROM requests WHERE bin_id = ?").bind(id).all<StoredRequest>();
if (!requestsResult.success) {
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
}
const requestMap: {[key: string]: ReturnedRequest} = {};
for (const r of requestsResult.results)
requestMap[r.id] = mapRequest(r);
return json({
success: true,
bin: <RequestBin>{
id,
requests: requestMap
}
});
});
router.get("/:id/:requestId", async ({ params }, env: Env) => {
const { id, requestId } = params;
const result = await env.DB.prepare("SELECT * FROM bins WHERE id = ?").bind(id).first<string>("id");
if (!result) {
return json({
success: false,
message: "A request bin could not be found with the ID provided"
}, { status: 404 });
}
const request = await env.DB.prepare("SELECT * FROM requests WHERE bin_id = ? AND id = ?").bind(id, requestId).first<StoredRequest>();
if (!request) {
return json({
success: false,
message: "A request could not be found in this bin with the ID provided"
}, { status: 404 });
}
return json({ success: true, request: mapRequest(request) });
});
router.all("*", () => {
return json({ success: false, message: "Endpoint not found" }, { status: 404 });
});
export default {
fetch(req: Request, env: Env, ctx: ExecutionContext) {
return router.handle(req, env, ctx).catch(e => {
console.error(e);
return json({
success: false,
message: "An unknown error occurred"
}, { status: 500 });
});
}
};

33
api/src/types.ts 100644
View File

@ -0,0 +1,33 @@
export interface Headers {
[key: string]: string
}
export interface StoredRequest {
id: string;
bin_id: string
ip: string
method: string
url: string
timestamp: number
headers: string
body?: ArrayBuffer
}
export interface ReturnedRequest {
id: string
ip: string
method: string
url: string
timestamp: number
headers: Headers
body?: ArrayBuffer
}
export interface Requests {
[key: string]: ReturnedRequest
}
export interface RequestBin {
id: string
requests: Requests
}

45
api/src/utils.ts 100644
View File

@ -0,0 +1,45 @@
import { Headers, ReturnedRequest, StoredRequest } from "./types";
const DEFAULT_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
export const randomString = (length: number, characters?: string): string => {
let charactersToUse = DEFAULT_CHARACTERS;
if (characters)
charactersToUse = characters;
let result = "";
for (let i = 0; i < length; i++)
result += charactersToUse.charAt(Math.floor(Math.random() * charactersToUse.length));
return result;
};
export const mapRequest = (storedRequest: StoredRequest): ReturnedRequest => {
return {
id: storedRequest.id,
method: storedRequest.method,
ip: storedRequest.ip,
url: storedRequest.url,
timestamp: storedRequest.timestamp,
headers: JSON.parse(storedRequest.headers) as Headers,
body: storedRequest.body
};
};
export const json = (body: object, options: ResponseInit = {}): Response => {
const { headers = {}, ...rest } = options;
return new Response(JSON.stringify(body), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,HEAD,TRACE,CONNECT,OPTIONS",
...headers
},
...rest
});
};