diff --git a/src/index.ts b/src/index.ts
index 9ce1f09..0889a60 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -16,24 +16,24 @@
* along with this program. If not, see .
*/
-import {AwsClient} from "aws4fetch";
-import {customAlphabet} from "nanoid";
-import {sha256} from "js-sha256";
+import {AwsClient} from 'aws4fetch';
+import {customAlphabet} from 'nanoid';
+import {sha256} from 'js-sha256';
// Constants
-const SERVICE_URL = "pb.nekoul.com"
-const PASTE_INDEX_HTML_URL = "https://raw.githubusercontent.com/rikkaneko/paste/main/paste.html"
-const UUID_LENGTH = 4
+const SERVICE_URL = 'pb.nekoul.com';
+const PASTE_INDEX_HTML_URL = 'https://raw.githubusercontent.com/rikkaneko/paste/main/paste.html';
+const UUID_LENGTH = 4;
export interface Env {
PASTE_INDEX: KVNamespace;
AWS_ACCESS_KEY_ID: string;
AWS_SECRET_ACCESS_KEY: string;
- ENDPOINT: string
+ ENDPOINT: string;
}
const API_SPEC_TEXT =
-`Paste service https://${SERVICE_URL}
+ `Paste service https://${SERVICE_URL}
[API Specification]
GET / Fetch the Web frontpage for uploading text/file [x]
@@ -78,74 +78,74 @@ Last update on 7 June.
`;
const gen_id = customAlphabet(
- "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", UUID_LENGTH);
+ '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', UUID_LENGTH);
export default {
async fetch(
request: Request,
env: Env,
- ctx: ExecutionContext
+ ctx: ExecutionContext,
): Promise {
const {url, method, headers} = request;
const {pathname} = new URL(url);
- const path = pathname.replace(/\/+$/, "") || "/";
+ const path = pathname.replace(/\/+$/, '') || '/';
let cache = caches.default;
const s3 = new AwsClient({
accessKeyId: env.AWS_ACCESS_KEY_ID,
- secretAccessKey: env.AWS_SECRET_ACCESS_KEY
+ secretAccessKey: env.AWS_SECRET_ACCESS_KEY,
});
// Special path
- if (path === "/favicon.ico" && method == "GET") {
+ if (path === '/favicon.ico' && method == 'GET') {
return new Response(null, {
headers: {
- "cache-control": "public, max-age=172800",
+ 'cache-control': 'public, max-age=172800',
},
- status: 404
- })
+ status: 404,
+ });
}
- if (path === "/api" && method == "GET") {
+ if (path === '/api' && method == 'GET') {
return new Response(API_SPEC_TEXT);
}
- if (path === "/") {
+ if (path === '/') {
switch (method) {
// Fetch the HTML for uploading text/file
- case "GET": {
+ case 'GET': {
return await fetch(PASTE_INDEX_HTML_URL, {
cf: {
- cacheEverything: true
- }
+ cacheEverything: true,
+ },
}).then(value => {
let res = new Response(value.body, value);
// Add the correct content-type to response header
- res.headers.set("content-type", "text/html; charset=UTF-8;");
+ res.headers.set('content-type', 'text/html; charset=UTF-8;');
// Remove the default CSP header
- res.headers.delete("content-security-policy");
+ res.headers.delete('content-security-policy');
return res;
- })
+ });
}
// Create new paste
- case "POST":
+ case 'POST':
const uuid = gen_id();
let buffer: ArrayBuffer;
let title: string | undefined;
// Handle content-type
- const content_type = headers.get("content-type") || "";
+ const content_type = headers.get('content-type') || '';
let mime_type: string | undefined;
let password: string | undefined;
let read_limit: number | undefined;
// Content-Type: multipart/form-data
- if (content_type.includes("form")) {
+ if (content_type.includes('form')) {
const formdata = await request.formData();
- const data = formdata.get("u");
+ const data = formdata.get('u');
if (data === null) {
- return new Response("Invalid request.\n", {
- status: 422
- })
+ return new Response('Invalid request.\n', {
+ status: 422,
+ });
}
// File
if (data instanceof File) {
@@ -155,29 +155,29 @@ export default {
buffer = await data.arrayBuffer();
// Text
} else {
- buffer = new TextEncoder().encode(data)
- mime_type = "text/plain; charset=UTF-8;"
+ buffer = new TextEncoder().encode(data);
+ mime_type = 'text/plain; charset=UTF-8;';
}
// Set password
- const pass = formdata.get("pass");
- if (typeof pass === "string") {
+ const pass = formdata.get('pass');
+ if (typeof pass === 'string') {
password = pass || undefined;
}
- const count = formdata.get("read-limit");
- if (typeof count === "string" && !isNaN(+count)) {
+ const count = formdata.get('read-limit');
+ if (typeof count === 'string' && !isNaN(+count)) {
read_limit = Number(count) || undefined;
}
// Raw body
} else {
- if (headers.has("x-title")) {
- title = headers.get("x-title") || "";
+ if (headers.has('x-title')) {
+ title = headers.get('x-title') || '';
}
- mime_type = headers.get("content-type") || mime_type;
- password = headers.get("x-pass") || undefined;
- const count = headers.get("x-read-limit") || undefined;
+ mime_type = headers.get('content-type') || mime_type;
+ password = headers.get('x-pass') || undefined;
+ const count = headers.get('x-read-limit') || undefined;
if (count !== undefined && !isNaN(+count)) {
read_limit = Number(count) || undefined;
}
@@ -186,30 +186,30 @@ export default {
// Check password rules
if (password && !check_password_rules(password)) {
- return new Response("Invalid password. " +
- "Password must contain alphabets and digits only, and has a length of 4 or more.", {
- status: 422
- })
+ return new Response('Invalid password. ' +
+ 'Password must contain alphabets and digits only, and has a length of 4 or more.', {
+ status: 422,
+ });
}
// Check request.body size <= 10MB
const size = buffer.byteLength;
if (size > 10485760) {
- return new Response("Paste size must be under 10MB.\n", {
- status: 422
+ return new Response('Paste size must be under 10MB.\n', {
+ status: 422,
});
}
// Check request.body size not empty
if (buffer.byteLength == 0) {
- return new Response("Paste cannot be empty.\n", {
- status: 422
+ return new Response('Paste cannot be empty.\n', {
+ status: 422,
});
}
const res = await s3.fetch(`${env.ENDPOINT}/${uuid}`, {
- method: "PUT",
- body: buffer
+ method: 'PUT',
+ body: buffer,
});
if (res.ok) {
@@ -217,18 +217,18 @@ export default {
const descriptor: PasteIndexEntry = {
title: title ?? undefined,
last_modified: Date.now(),
- password: password? sha256(password).slice(0, 16): undefined,
+ password: password ? sha256(password).slice(0, 16) : undefined,
size,
read_count_remain: read_limit,
- mime_type
+ mime_type,
};
// Key will be expired after 28 day if unmodified
ctx.waitUntil(env.PASTE_INDEX.put(uuid, JSON.stringify(descriptor), {expirationTtl: 100800}));
return new Response(get_paste_info(uuid, descriptor));
} else {
- return new Response("Unable to upload the paste.\n", {
- status: 500
+ return new Response('Unable to upload the paste.\n', {
+ status: 500,
});
}
@@ -236,38 +236,38 @@ export default {
} else if (path.length >= UUID_LENGTH + 1) {
// RegExpr to match //