diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | backend/api/api.go | 4 | ||||
| -rw-r--r-- | backend/api/routes.go | 8 | ||||
| -rw-r--r-- | frontend/package.json | 1 | ||||
| -rw-r--r-- | frontend/src/components/Inputs.js | 1 | ||||
| -rw-r--r-- | frontend/src/components/PasteArea.js | 54 |
7 files changed, 85 insertions, 7 deletions
@@ -12,4 +12,6 @@ docker-push: fe-run: cd frontend && yarn start fe-build: - cd frontend && yarn build
\ No newline at end of file + cd frontend && yarn build +all: + make -j 2 run fe-run
\ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..220680b --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# ctrl-v source +### a modern, open-source pastebin with latex and markdown rendering support + +Frontend is in React and backend is in Go. + +## developing +#### Common +`make all` — starts React development server on `:3000` and backend on `:8080` + +#### Frontend +`make fe-run` — starts React development server on `:3000` +`make fe-build` — builds development release of frontend in `frontend/build` + +#### Backend +`make run` — starts backend on `:8080` +`make lint` — lints all Go files +`make docker-build` — builds Docker image of current backend +`make docker-run` — runs built Docker image on `:8080` +`make docker-all` — builds and runs built Docker image on `:8080` +`make docker-push` — pushes build Docker image to Dockerhub
\ No newline at end of file diff --git a/backend/api/api.go b/backend/api/api.go index c197774..59242ef 100644 --- a/backend/api/api.go +++ b/backend/api/api.go @@ -30,8 +30,8 @@ func Serve(port int) { // Define Mux Router r := mux.NewRouter() r.HandleFunc("/health", healthCheckFunc) - r.HandleFunc("/api", insertFunc).Methods("POST") - r.HandleFunc("/api/{hash}", getHashFunc).Methods("GET") + r.HandleFunc("/api", insertFunc).Methods("POST", "OPTIONS") + r.HandleFunc("/api/{hash}", getHashFunc).Methods("GET", "OPTIONS") http.Handle("/", r) diff --git a/backend/api/routes.go b/backend/api/routes.go index f41505b..7fb2114 100644 --- a/backend/api/routes.go +++ b/backend/api/routes.go @@ -18,6 +18,10 @@ func healthCheckFunc(w http.ResponseWriter, r *http.Request) { } func insertFunc(w http.ResponseWriter, r *http.Request) { + + // Allow CORS + w.Header().Set("Access-Control-Allow-Origin", "*") + // get content _ = r.ParseMultipartForm(0) expiry := r.FormValue("expiry") @@ -48,6 +52,10 @@ func insertFunc(w http.ResponseWriter, r *http.Request) { } func getHashFunc(w http.ResponseWriter, r *http.Request) { + + // Allow CORS + w.Header().Set("Access-Control-Allow-Origin", "*") + hash := mux.Vars(r)["hash"] paste, err := cache.C.Get(hash) diff --git a/frontend/package.json b/frontend/package.json index 26a63d5..d32e1cc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", + "axios": "^0.19.2", "d3-scale": "^3.2.1", "rc-slider": "^9.2.4", "react": "^16.13.1", diff --git a/frontend/src/components/Inputs.js b/frontend/src/components/Inputs.js index aa68a70..110d5bd 100644 --- a/frontend/src/components/Inputs.js +++ b/frontend/src/components/Inputs.js @@ -52,6 +52,7 @@ class PasteInput extends React.Component { placeholder="Paste your text here" value={this.props.content} id={this.props.id} + required onChange={this.props.onChange} className="lt-shadow" /> <CharLimit diff --git a/frontend/src/components/PasteArea.js b/frontend/src/components/PasteArea.js index 4232c7f..bd08fc1 100644 --- a/frontend/src/components/PasteArea.js +++ b/frontend/src/components/PasteArea.js @@ -1,6 +1,7 @@ import React from 'react'; import { TitleInput, PasteInput } from './Inputs' import OptionsContainer from './Options' +import axios from 'axios'; class PasteArea extends React.Component { constructor(props) { @@ -33,11 +34,56 @@ class PasteArea extends React.Component { }); } + parseExpiry(e) { + var cur = new Date(); + var inSeconds = 0 + switch (e) { + case '5 years': + inSeconds = 600 * 6 * 24 * 7 * 4 * 12 * 5 + break; + case '1 year': + inSeconds = 600 * 6 * 24 * 7 * 4 * 12 + break; + case '1 month': + inSeconds = 600 * 6 * 24 * 7 * 4 + break; + case '1 day': + inSeconds = 600 * 6 * 24 + break; + case '1 hour': + inSeconds = 600 * 6 + break; + case '10 min': + inSeconds = 600 + break; + case '1 week': + default: + inSeconds = 600 * 6 * 24 * 7 + break; + } + return new Date(cur.getTime() + inSeconds * 1000).toISOString(); + } + handleSubmit(event) { - console.log(`title: ${this.state.title}`) - console.log(`content: ${this.state.content}`) - console.log(`pass: ${this.state.pass}`) - console.log(`expiry: ${this.state.expiry}`) + var bodyFormData = new FormData(); + bodyFormData.set('title', this.state.title); + bodyFormData.set('content', this.state.content); + bodyFormData.set('password', this.state.pass); + bodyFormData.set('expiry', this.parseExpiry(this.state.expiry)); + + axios({ + method: 'post', + url: 'http://localhost:8080/api', + data: bodyFormData, + headers: { 'Content-Type': 'multipart/form-data' }, + }).then(function (response) { + //handle success + console.log(response); + }).catch(function (response) { + //handle error + console.log(response); + }); + event.preventDefault(); } |