├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
└── workflows
│ └── update-changelog.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
├── icon-512x512.png
└── screenshot.png
├── cocopasty-backend
├── Dockerfile
├── README.md
├── database.go
├── go.mod
├── go.sum
├── main.go
├── middleware.go
└── utils.go
├── cocopasty-frontend
├── .dockerignore
├── Dockerfile
├── README.md
├── babel.config.js
├── entrypoint.sh
├── jsconfig.json
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── horizon-dark.min.css
│ └── index.html
├── src
│ ├── App.vue
│ ├── main.js
│ └── utils
│ │ └── env.js
└── vue.config.js
├── docker-compose-deploy.yml
└── docker-compose.yml
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: MasterEvarior
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: MasterEvarior
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "gomod"
4 | directory: "/cocopasty-backend/"
5 | schedule:
6 | interval: "weekly"
7 | day: "friday"
8 | - package-ecosystem: "npm"
9 | directory: "/cocopasty-frontend/"
10 | schedule:
11 | interval: "daily"
12 | day: "friday"
13 | open-pull-requests-limit: 10
14 | - package-ecosystem: "docker"
15 | directory: "/cocopasty-backend"
16 | schedule:
17 | interval: "weekly"
18 | day: "friday"
19 | - package-ecosystem: "docker"
20 | directory: "/cocopasty-frontend"
21 | schedule:
22 | interval: "weekly"
23 | day: "friday"
24 |
--------------------------------------------------------------------------------
/.github/workflows/update-changelog.yml:
--------------------------------------------------------------------------------
1 | name: 'Update dependencies section in changelog'
2 | on:
3 | pull_request:
4 | types:
5 | - closed
6 |
7 | jobs:
8 | changelog:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | with:
13 | token: ${{ secrets.GITHUB_TOKEN }}
14 | - uses: dangoslen/dependabot-changelog-helper@v1
15 | with:
16 | version: 'Unreleased'
17 | newVersionLineNumber: 3
18 | activationLabel: 'dependencies'
19 | changelogPath: './CHANGELOG.md'
20 | - uses: stefanzweifel/git-auto-commit-action@v4.14.1
21 | with:
22 | commit_message: "Update changelog"
23 | branch: main
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6 |
7 | ## [Unreleased]
8 | ### Dependencies
9 | - Bumps `eslint` from 8.18.0 to 8.27.0
10 | - Bumps `core-js` from 3.23.2 to 3.25.3
11 | - Bumps `async` from 2.6.3 to 2.6.4
12 | - Bumps `node` from 14-alpine to 19-alpine
13 | - Bumps `stylus-loader` from 3.0.2 to 7.0.0
14 | - Bumps `stylus` from 0.57.0 to 0.59.0
15 | - Bumps `vue` from 3.2.31 to 3.5.13
16 | - Bumps `highlight.js` from 11.5.0 to 11.5.1
17 | - Bumps `@babel/core` from 7.17.8 to 7.20.12
18 | - Bumps `sass-loader` from 12.6.0 to 13.2.0
19 | - Bumps `@babel/eslint-parser` from 7.17.0 to 7.21.3
20 | - Bumps `eslint-plugin-vue` from 8.5.0 to 9.8.0
21 | - Bumps `@vue/cli-service` from 5.0.4 to 5.0.8
22 | - Bumps `@vue/cli-plugin-babel` from 5.0.4 to 5.0.8
23 | - Bumps `@vue/cli-plugin-eslint` from 5.0.4 to 5.0.8
24 | - Bumps `terser` from 5.12.1 to 5.14.2
25 | - Bumps `node-sass` from 7.0.1 to 8.0.0
26 | - Bumps `loader-utils` from 1.4.0 to 1.4.2
27 | - Bumps `decode-uri-component` from 0.2.0 to 0.2.2
28 |
29 | ### Changed
30 | - Stylesheet for highlight.js is now loaded locally instead from Cloudflare
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 MasterEvarior
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
40 |
41 |
42 |
43 |
44 | # Table of Contents
45 |
46 | - [About the Project](#about-the-project)
47 | * [Screenshots](#screenshots)
48 | * [Tech Stack](#tech-stack)
49 | * [Features](#features)
50 | - [Getting Started](#getting-started)
51 | * [Configuration](#configuration)
52 | * [Prerequisites](#prerequisites)
53 | * [Run Locally](#run-locally)
54 | * [Deployment](#deployment)
55 | - [Roadmap](#roadmap)
56 | - [Contributing](#contributing)
57 | - [FAQ](#faq)
58 | - [License](#license)
59 | - [Contact](#contact)
60 | - [Acknowledgements](#acknowledgements)
61 |
62 |
63 |
64 | ## About the Project
65 | Cocopasty is a small and simply copy-and-paste solution for your code. Paste your code in your browser and copy it on another device!
66 |
67 |
68 | ### Screenshots
69 |
70 |
71 |

72 |
73 |
74 |
75 |
76 | ### Tech Stack
77 |
78 |
79 | Client
80 |
83 |
84 |
85 |
86 | Server
87 |
90 |
91 |
92 |
93 | Database
94 |
97 |
98 |
99 |
100 | DevOps
101 |
104 |
105 |
106 |
107 | ### Features
108 |
109 | - So simple, your pet rock could use it
110 | - 150+ available languages
111 | - Autodetect languages with [highlight.js](https://highlightjs.org)
112 | - Completely dockerized
113 |
114 | ## Getting Started
115 |
116 |
117 | ### Prerequisites
118 | You need to have Go, Docker, Docker Compose and NPM installed to run/develop this project.
119 |
120 | ### Configuration
121 | Explanations for the different environment variables. Examples can be found in the docker-compose.yml files.
122 |
123 | #### Frontend
124 | - `VUE_APP_BACKEND_PORT` is the port your cocopasty-backend container runs.
125 | - `VUE_APP_BACKEND_HOST` is the host of your cocopasty-backend container.
126 |
127 | #### Backend
128 | - `LOG_LEVEL` the log level you wish to use. Default is "info". All log levels can be found [here](https://github.com/Sirupsen/logrus#level-logging).
129 | - `REDIS_HOST` is the host + port of your Redis DB.
130 | - `REDIS_PASSWORD` if your Redis instance uses password authentication, set here your password. If left empty, authentication without password will be tried.
131 |
132 |
133 | ### Run Locally
134 |
135 | Clone the project
136 |
137 | ```bash
138 | git clone https://https://github.com/MasterEvarior/cocopasty.git
139 | ```
140 |
141 | Go to the project directory
142 |
143 | ```bash
144 | cd cocopasty
145 | ```
146 |
147 | Run with Docker Compose
148 |
149 | ```bash
150 | docker-compose up
151 | ```
152 |
153 |
154 | ### Deployment
155 |
156 | #### Docker Compose
157 | To deploy this project copy the contents of the [docker-compose-deploy.yml](https://github.com/MasterEvarior/cocopasty/blob/main/docker-compose-deploy.yml) file and paste it into a new file.
158 |
159 | ```bash
160 | wget https://raw.githubusercontent.com/MasterEvarior/cocopasty/main/docker-compose-deploy.yml
161 | ```
162 | Change the ports, volumes, etc. to your liking.
163 | ```bash
164 | vi docker-compose-deploy.yml
165 | ```
166 |
167 | Rename the file and run it with Docker Compose.
168 | ```bash
169 | mv docker-compose-deploy.yml docker-compose.yml
170 | docker-compose up
171 | ```
172 |
173 | ## Roadmap
174 | Feel free to suggest features through a GitHub issue, in addition to the ones listed below:
175 | - [ ] Backend tests
176 | - [ ] Frontend tests
177 | - [ ] Installation instructions for Unraid
178 | - [ ] CI/CD with GitHub-Actions
179 | - [X] Automatically update Changelog for dependency updates
180 | - [ ] Automatic releases
181 | - [ ] Run tests
182 |
183 |
184 | ## Contributing
185 | Contributions are always welcome!
186 |
187 |
188 | ## FAQ
189 |
190 | - Is there an official method to install WITHOUT Docker?
191 |
192 | + No
193 |
194 | - Is there any sort of build in authentication?
195 |
196 | + No, though you could use something like [Authelia](https://www.authelia.com/docs/)
197 |
198 | - Can I use this to copy my API-Keys etc. from one device to another?
199 |
200 | + You can but I'd strongly advise against it
201 |
202 | - Which languages are available for auto-highligting?
203 |
204 | + A complete list can be found [here](https://highlightjs.readthedocs.io/en/latest/supported-languages.html)
205 |
206 | - Can I use this with my already existing Redis instance?
207 |
208 | + Sure, you just have to adjust the compose file to your liking
209 |
210 | - Does the default compose file configure Redis to be persistent?
211 |
212 | + No
213 |
214 |
215 | ## License
216 |
217 | Distributed under the MIT License. See the LICENSE file for more information.
218 |
219 |
220 | ## Contact
221 |
222 | Email: contact@giannin.dev
223 |
224 | Project Link: [https://github.com/MasterEvarior/cocopasty](https://github.com/MasterEvarior/cocopasty)
225 |
226 |
227 |
228 | ## Acknowledgements
229 |
230 | Cool projects which make Cocopasty possible
231 |
232 | - [Shields.io](https://shields.io/)
233 | - [Awesome Readme Template](https://github.com/Louis3797/awesome-readme-template)
234 | - [highlight.js](https://highlightjs.org)
235 | - [Vue Prism Editor](https://github.com/koca/vue-prism-editor)
236 | - [Guide to Vue.js + Docker env variables](https://medium.com/js-dojo/vue-js-runtime-environment-variables-807fa8f68665)
237 | - [CSS Button Generator](https://www.bestcssbuttongenerator.com)
238 |
--------------------------------------------------------------------------------
/assets/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MasterEvarior/cocopasty/554a44b16abc74b3cba13fb4d38a751795f5f33c/assets/icon-512x512.png
--------------------------------------------------------------------------------
/assets/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MasterEvarior/cocopasty/554a44b16abc74b3cba13fb4d38a751795f5f33c/assets/screenshot.png
--------------------------------------------------------------------------------
/cocopasty-backend/Dockerfile:
--------------------------------------------------------------------------------
1 | # develop stage
2 | FROM golang:alpine as develop-stage
3 | RUN apk add --no-cache git
4 | RUN mkdir /app
5 | ADD . /app
6 | WORKDIR /app
7 |
8 | # build stage
9 | FROM develop-stage as build-stage
10 | RUN go build -o cocopasty-backend .
11 |
12 | # production stage
13 | FROM golang:alpine as production-stage
14 | COPY --from=build-stage /app/cocopasty-backend /app/cocopasty-backend
15 | CMD ["/app/cocopasty-backend"]
--------------------------------------------------------------------------------
/cocopasty-backend/README.md:
--------------------------------------------------------------------------------
1 | # Cocopasty Backend
2 |
3 | ## Project setup
4 | ```
5 | go run main.go
6 | ```
7 |
8 | ### Compiles and minifies for production
9 | ```
10 | go build -o cocopasty-backend .
11 | ```
12 |
13 | ## Docker
14 | Build container locally
15 | ```
16 | docker build -t cocopasty-backend .
17 | ```
--------------------------------------------------------------------------------
/cocopasty-backend/database.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "os"
6 |
7 | "github.com/go-redis/redis/v8"
8 | log "github.com/sirupsen/logrus"
9 | )
10 |
11 | type database struct {
12 | connection *redis.Client
13 | }
14 |
15 | const keyName = "cocopasty-code-snippet"
16 |
17 | func CreateDatabaseClient() (*database, error) {
18 | setLogLevel()
19 | log.Debug("Creating connection to Redis...")
20 |
21 | redisConnection := redis.NewClient(&redis.Options{
22 | Network: "tcp",
23 | Addr: getAddress(),
24 | Password: getPassword(),
25 | DB: 0,
26 | })
27 |
28 | return &database{
29 | connection: redisConnection,
30 | }, redisConnection.Ping(context.Background()).Err()
31 | }
32 |
33 | func (d *database) CreateEntry(ctx context.Context, code string) error {
34 | log.Debug("Setting value in Redis")
35 | status := d.connection.Set(ctx, keyName, code, 0)
36 |
37 | return status.Err()
38 | }
39 |
40 | func (d *database) ReadEntry(ctx context.Context) (string, error) {
41 | log.Debug("Getting value from Redis")
42 |
43 | return d.connection.Get(ctx, keyName).Result()
44 | }
45 |
46 | func getAddress() string {
47 | input := os.Getenv("REDIS_HOST")
48 | log.Info("REDIS_HOST: ", input)
49 |
50 | return input
51 | }
52 |
53 | func getPassword() string {
54 | input := os.Getenv("REDIS_PASSWORD")
55 | if input == "" {
56 | log.Info("No Redis password was set")
57 | } else {
58 | log.Info("A Redis password was set")
59 | }
60 |
61 | return input
62 | }
63 |
--------------------------------------------------------------------------------
/cocopasty-backend/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/MasterEvariour/cocopasty/cocopasty-backend
2 |
3 | go 1.18
4 |
5 | require (
6 | github.com/gorilla/mux v1.8.0
7 | github.com/rs/cors v1.8.3
8 | )
9 |
10 | require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
11 |
12 | require (
13 | github.com/cespare/xxhash/v2 v2.1.2 // indirect
14 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
15 | github.com/go-redis/redis/v8 v8.11.5
16 | github.com/sirupsen/logrus v1.9.0
17 | )
18 |
--------------------------------------------------------------------------------
/cocopasty-backend/go.sum:
--------------------------------------------------------------------------------
1 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
2 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
7 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
8 | github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
9 | github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
10 | github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
11 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
12 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
13 | github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
14 | github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
15 | github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
16 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
17 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
18 | github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo=
19 | github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
20 | github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
21 | github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
22 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
23 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
24 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
25 | golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
26 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
27 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
28 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
29 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
30 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
31 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
32 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
33 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
34 |
--------------------------------------------------------------------------------
/cocopasty-backend/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "net/http"
6 |
7 | "github.com/gorilla/mux"
8 | "github.com/rs/cors"
9 | log "github.com/sirupsen/logrus"
10 | )
11 |
12 | type CodeSnippet struct {
13 | Code string `json:"Code"`
14 | }
15 |
16 | var databaseClient *database
17 |
18 | func main() {
19 | setLogLevel()
20 | //Initialize router
21 | log.Info("Starting Cocopasty...")
22 | router := mux.NewRouter()
23 |
24 | router.Use(LoggingMiddleware)
25 |
26 | router.HandleFunc("/", handleGets).Methods("GET")
27 | router.HandleFunc("/", handlePosts).Methods("POST")
28 |
29 | corsHandler := cors.Default().Handler(router)
30 |
31 | //Create database connection
32 | var err error
33 | databaseClient, err = CreateDatabaseClient()
34 |
35 | if err != nil {
36 | log.Panic("Could not connect to database, shutting down application...")
37 | panic(err)
38 | }
39 |
40 | log.Info("Connection to Redis was successfull")
41 |
42 | //Start server
43 | log.Info("Starting web server...")
44 | err = http.ListenAndServe(":8080", corsHandler)
45 | if err != nil {
46 | log.Fatal(err)
47 | }
48 | log.Info("Cocopasty is started and ready!")
49 | }
50 |
51 | func handlePosts(w http.ResponseWriter, r *http.Request) {
52 | ctx := r.Context()
53 |
54 | contentType := r.Header.Get("Content-Type")
55 | if contentType != "application/json" {
56 | log.Debug("Invalid content type, returning 400")
57 | w.WriteHeader(http.StatusBadRequest)
58 | return
59 | }
60 |
61 | var newSnippet CodeSnippet
62 |
63 | err := json.NewDecoder(r.Body).Decode(&newSnippet)
64 | if err != nil {
65 | log.Errorf("Could not decode JSON: ", err)
66 | w.WriteHeader(http.StatusBadRequest)
67 | return
68 | }
69 |
70 | err = databaseClient.CreateEntry(ctx, newSnippet.Code)
71 | if err != nil {
72 | log.Errorf("Failed to save snippet in Redis: ", err)
73 | w.WriteHeader(http.StatusInternalServerError)
74 | return
75 | }
76 | }
77 |
78 | func handleGets(w http.ResponseWriter, r *http.Request) {
79 | ctx := r.Context()
80 |
81 | w.Header().Set("Content-Type", "application/json")
82 | w.WriteHeader(http.StatusOK)
83 |
84 | value, err := databaseClient.ReadEntry(ctx)
85 |
86 | if err != nil {
87 | log.Error("Could not retrieve snippet from Redis: ", err)
88 | w.WriteHeader(http.StatusInternalServerError)
89 | return
90 | }
91 |
92 | log.Debug("GET-Request successfull, returning 200")
93 | json.NewEncoder(w).Encode(CodeSnippet{value})
94 | }
95 |
--------------------------------------------------------------------------------
/cocopasty-backend/middleware.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "net/http"
5 |
6 | log "github.com/sirupsen/logrus"
7 | )
8 |
9 | func LoggingMiddleware(next http.Handler) http.Handler {
10 | return http.HandlerFunc(
11 | func(w http.ResponseWriter, r *http.Request) {
12 | log.Debugf("Incoming request: \n Method: '%s' \n URI: '%s'", r.Method, r.RequestURI)
13 | next.ServeHTTP(w, r)
14 | },
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/cocopasty-backend/utils.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 |
6 | log "github.com/sirupsen/logrus"
7 | )
8 |
9 | func setLogLevel() {
10 | defer log.Info("Log level to ", log.GetLevel())
11 | input := os.Getenv("LOG_LEVEL")
12 |
13 | parsedLevel, err := log.ParseLevel(input)
14 |
15 | if err != nil {
16 | log.Error(err)
17 | return
18 | }
19 |
20 | log.SetLevel(parsedLevel)
21 | }
22 |
--------------------------------------------------------------------------------
/cocopasty-frontend/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .DS_Store
3 | node_modules
4 | dist
--------------------------------------------------------------------------------
/cocopasty-frontend/Dockerfile:
--------------------------------------------------------------------------------
1 | # develop stage
2 | FROM node:19-alpine as develop-stage
3 | WORKDIR /app
4 | COPY package*.json ./
5 | RUN npm install
6 | COPY . .
7 |
8 | # build stage
9 | FROM develop-stage as build-stage
10 | RUN npm run build
11 |
12 | # production stage
13 | FROM nginx:alpine as production-stage
14 | COPY --from=build-stage /app/dist /usr/share/nginx/html
15 | COPY entrypoint.sh /usr/share/nginx/
16 | ENTRYPOINT ["/usr/share/nginx/entrypoint.sh"]
17 | EXPOSE 90
18 | CMD ["nginx", "-g", "daemon off;"]
--------------------------------------------------------------------------------
/cocopasty-frontend/README.md:
--------------------------------------------------------------------------------
1 | # Cocopasty Frontend
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
26 | ## Docker
27 | Build container locally
28 | ```
29 | docker build -t cocopasty-frontend .
30 | ```
31 |
--------------------------------------------------------------------------------
/cocopasty-frontend/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/cocopasty-frontend/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | JSON_STRING='window.configs = { \
3 | "VUE_APP_BACKEND_PORT":"'"${VUE_APP_BACKEND_PORT}"'", \
4 | "VUE_APP_BACKEND_HOST":"'"${VUE_APP_BACKEND_HOST}"'" \
5 | }'
6 | sed -i "s@// CONFIGURATION_PLACEHOLDER@${JSON_STRING}@" /usr/share/nginx/html/index.html
7 | exec "$@"
--------------------------------------------------------------------------------
/cocopasty-frontend/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "baseUrl": "./",
6 | "moduleResolution": "node",
7 | "paths": {
8 | "@/*": [
9 | "src/*"
10 | ]
11 | },
12 | "lib": [
13 | "esnext",
14 | "dom",
15 | "dom.iterable",
16 | "scripthost"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/cocopasty-frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cocopasty-frontend",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "@beyonk/google-fonts-webpack-plugin": "^1.7.0",
12 | "@meforma/vue-toaster": "^1.3.0",
13 | "core-js": "^3.27.1",
14 | "highlight.js": "^11.7.0",
15 | "stylus": "^0.59.0",
16 | "stylus-loader": "^7.1.0",
17 | "vue": "^3.2.45",
18 | "vue-prism-editor": "^2.0.0-alpha.2"
19 | },
20 | "devDependencies": {
21 | "@babel/core": "^7.20.2",
22 | "@babel/eslint-parser": "^7.19.1",
23 | "@vue/cli-plugin-babel": "~5.0.8",
24 | "@vue/cli-plugin-eslint": "~5.0.8",
25 | "@vue/cli-service": "~5.0.8",
26 | "eslint": "^8.31.0",
27 | "eslint-plugin-vue": "^9.8.0",
28 | "node-sass": "^8.0.0",
29 | "sass-loader": "^13.2.0"
30 | },
31 | "eslintConfig": {
32 | "root": true,
33 | "env": {
34 | "node": true
35 | },
36 | "extends": [
37 | "plugin:vue/vue3-essential",
38 | "eslint:recommended"
39 | ],
40 | "parserOptions": {
41 | "parser": "@babel/eslint-parser"
42 | },
43 | "rules": {}
44 | },
45 | "browserslist": [
46 | "> 1%",
47 | "last 2 versions",
48 | "not dead",
49 | "not ie 11"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/cocopasty-frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MasterEvarior/cocopasty/554a44b16abc74b3cba13fb4d38a751795f5f33c/cocopasty-frontend/public/favicon.ico
--------------------------------------------------------------------------------
/cocopasty-frontend/public/horizon-dark.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | Theme: Horizon Dark
3 | Author: Michaël Ball (http://github.com/michael-ball/)
4 | License: ~ MIT (or more permissive) [via base16-schemes-source]
5 | Maintainer: @highlightjs/core-team
6 | Version: 2021.09.0
7 | */pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#cbced0;background:#1c1e26}.hljs ::selection,.hljs::selection{background-color:#2e303e;color:#cbced0}.hljs-comment{color:#6f6f70}.hljs-tag{color:#9da0a2}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#cbced0}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#e93c58}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#e58d7d}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#efb993}.hljs-strong{font-weight:700;color:#efb993}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#efaf8e}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#24a8b4}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#df5273}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#b072d1}.hljs-emphasis{color:#b072d1;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#e4a382}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}
--------------------------------------------------------------------------------
/cocopasty-frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 | Cocopasty
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/cocopasty-frontend/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Cocopasty
4 |
5 |
6 |
7 | Copy-and-paste your code, open this site on another device and then copy-and-paste again :)
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
104 |
105 |
--------------------------------------------------------------------------------
/cocopasty-frontend/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import Toaster from '@meforma/vue-toaster';
3 | import App from './App.vue'
4 |
5 | let app = createApp(App)
6 |
7 | app
8 | .use(Toaster)
9 | .mount('#app')
10 |
--------------------------------------------------------------------------------
/cocopasty-frontend/src/utils/env.js:
--------------------------------------------------------------------------------
1 | export default function getEnv(name) {
2 | return window?.configs?.[name] || process.env[name]
3 | }
--------------------------------------------------------------------------------
/cocopasty-frontend/vue.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('@vue/cli-service')
2 | const GoogleFontsPlugin = require("@beyonk/google-fonts-webpack-plugin")
3 |
4 | // vue.config.js
5 | module.exports = {
6 | }
7 | module.exports = defineConfig({
8 | transpileDependencies: true,
9 | configureWebpack: {
10 | plugins: [
11 | new GoogleFontsPlugin({
12 | fonts: [
13 | { family: "Roboto Mono", variants: [ "500", "700" ] }
14 | ]
15 | })
16 | ]}
17 | })
18 |
--------------------------------------------------------------------------------
/docker-compose-deploy.yml:
--------------------------------------------------------------------------------
1 | services:
2 | frontend:
3 | image: masterevarior/cocopasty-frontend:1.0.0
4 | ports:
5 | - "8080:80"
6 | environment:
7 | VUE_APP_BACKEND_PORT: 8081
8 | VUE_APP_BACKEND_HOST: "http://localhost"
9 | depends_on:
10 | - backend
11 | backend:
12 | image: masterevarior/cocopasty-backend:1.2.1
13 | ports:
14 | - "8081:8080"
15 | environment:
16 | LOG_LEVEL: "info"
17 | REDIS_HOST: "redis:6379"
18 | # REDIS_PASSWORD: "your_password"
19 | depends_on:
20 | - redis
21 | redis:
22 | image: "redis:alpine"
23 | ports:
24 | - "6379:6379"
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | frontend:
3 | build: ./cocopasty-frontend
4 | ports:
5 | - "8080:80"
6 | environment:
7 | VUE_APP_BACKEND_PORT: 8081
8 | VUE_APP_BACKEND_HOST: "http://localhost"
9 | depends_on:
10 | - backend
11 | backend:
12 | build: ./cocopasty-backend
13 | ports:
14 | - "8081:8080"
15 | environment:
16 | LOG_LEVEL: "debug"
17 | REDIS_HOST: "redis:6379"
18 | # REDIS_PASSWORD: "123" currently not used
19 | depends_on:
20 | - redis
21 | redis:
22 | image: "redis:alpine"
23 | ports:
24 | - "6379:6379"
--------------------------------------------------------------------------------