From 3c44eeebf3ecc7a87a9d50e5a07c8d44b8974b38 Mon Sep 17 00:00:00 2001 From: alyssadev Date: Tue, 19 Sep 2023 12:01:14 +1000 Subject: [PATCH] Added upload type checking, default name/type, optional metrics, browser auth prompt --- package.json | 2 +- src/index.js | 67 +++++++++++++++++++++++++++++++++++++--------------- test.py | 7 +----- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 604d0e7..36534ee 100644 --- a/package.json +++ b/package.json @@ -9,4 +9,4 @@ "devDependencies": { "wrangler": "^3.0.0" } -} \ No newline at end of file +} diff --git a/src/index.js b/src/index.js index 1ad6119..13ad1ad 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,17 @@ // vim: tabstop=4 shiftwidth=4 expandtab +async function isAsciiFile(buf) { + var isAscii = true; + const view = new Uint8Array(buf) + for (var i=0, len=view.byteLength; i 127) { + isAscii=false + break + } + } + return isAscii +} + function makeid(length) { let result = ''; const characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; @@ -15,6 +27,7 @@ function makeid(length) { async function checkAuth(request) { const auth = request.headers.get("Authorization"); const auth_check = await AUTH.get(auth) + console.log(auth, auth_check) return Boolean(auth_check); } @@ -23,27 +36,35 @@ function getHost(request) { } function create_response(request, body, metadata) { - METRICS.writeDataPoint({ - indexes: [ - metadata.status - ], - blobs: [ - request.method, - request.cf.country, - request.cf.asn, - request.cf.timezone, - new Date().toISOString(), - request.headers.get("cf-connecting-ip"), - request.headers.get("referer") - ] - }) + try { + METRICS.writeDataPoint({ + indexes: [ + metadata.status + ], + blobs: [ + request.method, + request.cf.country, + request.cf.asn, + request.cf.timezone, + new Date().toISOString(), + request.headers.get("cf-connecting-ip"), + request.headers.get("referer") + ] + }) + } catch (e) { + // Metrics disabled + if (!(e instanceof ReferenceError)) { + throw e + } + } + return new Response(body, metadata) } async function add(request,host,path) { const auth = await checkAuth(request) if (!auth) - return create_response(request, "Only GET requests allowed to unauthed users", {status:403}); + return create_response(request, "Auth required", {status:401,headers:{"www-authenticate":"Basic"}}); if (!request.headers.get("content-type")) return create_response(request, "No data provided", {status:400}) if (!path) return create_response(request, "No path provided",{status:400}) @@ -59,7 +80,7 @@ async function add(request,host,path) { } path = path.toLowerCase() - // URL shortening + const req_clone = request.clone() const data = await request.formData() const dest = data.get("u") try { @@ -74,10 +95,18 @@ async function add(request,host,path) { } catch (e) { if (e instanceof TypeError) { if (!dest) return create_response(request, "No file provided", {status:400}) + const buf = await req_clone.arrayBuffer() + var name = dest.name + var type = dest.type + if (!name || !type) { + const is_ascii = await isAsciiFile(buf) + if (!name) name = is_ascii ? "paste.txt" : "paste.bin" + if (!type) type = is_ascii ? "text/plain" : "application/octet-stream" + } await FILES.put(path, dest, { httpMetadata: { - contentType: dest.type, - contentDisposition: `inline; filename="${dest.name}"` + contentType: type, + contentDisposition: `inline; filename="${name}"` } }) await KV.delete(path) @@ -92,7 +121,7 @@ async function add(request,host,path) { async function remove(request,host,path) { const auth = await checkAuth(request) if (!auth) - return create_response(request, "Only GET requests allowed to unauthed users", {status:403}); + return create_response(request, "Auth required", {status:401,headers:{"www-authenticate":"Basic"}}); if (!path) return create_response(request, "No path provided",{status:400}) path = path.toLowerCase() await KV.delete(path) diff --git a/test.py b/test.py index 53a6240..cc43a80 100644 --- a/test.py +++ b/test.py @@ -22,17 +22,12 @@ try: # unauth requests to auth methods reqs = put(host),post(host),delete(host) - assert all(req.status_code == 403 for req in reqs) # unauth requests to auth methods + assert all(req.status_code == 401 for req in reqs) # unauth requests to auth methods # auth put wo data req = put(host + "/devtestpath",data={},headers=auth) assert req.status_code == 400 # auth put wo data -# # auth put invalid url -# req = put(host + "/devtestpath",data={"u": "golf sale"},headers=auth) -# assert req.status_code == 400 # auth put invalid url -# # invalid urls would now be stored as files instead - # auth put wo path req = put(host,data={"u": "http://www.example.com"},headers=auth) assert req.status_code == 400 # auth put wo path