diff --git a/routes/upload.sh.ts b/routes/upload.sh.ts index df01727..d8a945f 100644 --- a/routes/upload.sh.ts +++ b/routes/upload.sh.ts @@ -1,24 +1,7 @@ // routes/upload.sh.ts import { Handlers } from '$fresh/server.ts' -const script = `#!/bin/bash -if [ "$#" -ne 1 ]; then - echo "Usage: $0 " - exit 1 -fi - -FILENAME=$(basename "$1") -KEY=$(openssl rand -hex 32) -IV=$(openssl rand -hex 16) -ENCODED_FILENAME=$(echo -n "$FILENAME" | xxd -plain | tr -d '\n' | sed 's/\\(.\\{2\\}\\)/%\\1/g') - -# Use key as hash for storage -openssl enc -aes-256-cbc -in "$1" -K "$KEY" -iv "$IV" | \\ -curl -s -X PUT "https://cryptsend.thingylabs.io/\${KEY}.enc" \\ - -H "Content-Type: application/octet-stream" \\ - --data-binary @- > /dev/null && \\ -echo "https://cryptsend.thingylabs.io/d/#\${KEY}\${IV}\${ENCODED_FILENAME}" -` +const script = Deno.readTextFile("../upload.sh") export const handler: Handlers = { GET() { diff --git a/upload.sh b/upload.sh new file mode 100644 index 0000000..d8fa814 --- /dev/null +++ b/upload.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +set -euo pipefail + +# max file size of 100MB +MAX_SIZE="100000000" + +# arguments +declare -a ARGS +ARGS[0]="${0}" + +usage() { + local err="${1:-1}" + local opt="${2:-}" + case "${err}" in + 1) + echo "Usage: ${ARGS[0]} " + ;; + 2) + echo "${opt} is required!" + ;; + 3) + echo "File to big! $(numfmt --to=iec "${opt}") of max $(numfmt --to=iec "${MAX_SIZE}")" + ;; + esac + exit "${err}" +} + +prerequisites() { + # one argument required + [[ "${#}" -eq 1 ]] || usage + + local -r item="${1}" + # needs to be a file + [[ -f "${item}" || -d "${item}" ]] || usage + ARGS[1]="${item}" + + command -v openssl @>/dev/null || usage 2 "openssl" + command -v curl @>/dev/null || usage 2 "curl" + command -v sed @>/dev/null || usage 2 "sed" + command -v tar @>/dev/null || usage 2 "tar" +} + +confirm() { + local text="${1}" + + read -p "${text} [yY] " -n 1 -r + echo + [[ "${REPLY,,}" = "y" ]] || return 1 +} + +file() { + local item="${ARGS[1]}" + + # if so zip after confirmation + if [[ -d "${item}" ]]; then + local tarfile + tarfile="$(mktemp)" + TRAP 'rm -f "${tarfile}"' EXIT + + # todo: we can add an -q flag to not promt this + confirm "Zip and upload folder '$(basename "${item}")'?" || exit 0 + tar -czvf "${tarfile}" "${item}" + item="${tarfile}" + fi + + # check max size + local size + size="$( + # linux || osx || bsd || yolo + stat -c"%s" "${item}" || + stat -s "${item}" || + stat -f"%z" "${item}" || + echo "0" + )" + ( size < MAX_SIZE ) || usage 3 "${size}" + + echo "${item}" +} + +upload() { + local file="${1}" + local filename encoded_filename key iv + + filename="$(basename "${file}")" + key="$(openssl rand -hex 32)" + iv="$(openssl rand -hex 16)" + encoded_filename="$( + echo -n "${filename}" | xxd -plain | tr -d '\n' | sed 's/\\(.\\{2\\}\\)/%\\1/g') + )" + + # Use key as hash for storage + openssl \\ + enc -aes-256-cbc -in "${file}" -K "${key}" -iv "${iv}" \ + | curl -s -X PUT "https://cryptsend.thingylabs.io/${key}.enc" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @- > /dev/null + + echo "https://cryptsend.thingylabs.io/d/#${key}${iv}${encoded_filename}" +} + +prerequisites "${@}" +upload "$(file)" \ No newline at end of file