mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2025-09-05 17:00:39 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
53c7c9d9e2 | |||
df9c60c29e | |||
f29b6b23f0 | |||
cc88fa6763 | |||
19022e7cb5 | |||
44f43dbc2c | |||
45f6f3af32 | |||
9bd544f0d5 | |||
a315e58284 | |||
d576b71bc5 |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -5,7 +5,25 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [1.4.0] - 2022-01-16
|
## [1.5.1] - 2022-05-15
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Remove double note content
|
||||||
|
|
||||||
|
## [1.5.0] - 2022-05-14
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Links in notes are not highlighted and can be directly clicked #30.
|
||||||
|
|
||||||
|
## [1.4.1] - 2022-03-05
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Router in prod build.
|
||||||
|
|
||||||
|
## [1.4.0] - 2022-03-02
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
37
README.md
37
README.md
@@ -49,9 +49,12 @@ of the notes even if it tried to.
|
|||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
| Variable | Default | Description |
|
| Variable | Default | Description |
|
||||||
| ------------ | ----------------- | --------------------------------------------------------------------------------------- |
|
| ---------------- | ----------------- | --------------------------------------------------------------------------------------- |
|
||||||
| `MEMCACHE` | `memcached:11211` | Memcached URL to connect to. |
|
| `MEMCACHE` | `memcached:11211` | Memcached URL to connect to. |
|
||||||
| `SIZE_LIMIT` | `1 KiB` | Max size for body. Accepted values according to [byte-unit](https://docs.rs/byte-unit/) |
|
| `SIZE_LIMIT` | `1 KiB` | Max size for body. Accepted values according to [byte-unit](https://docs.rs/byte-unit/) |
|
||||||
|
| `MAX_VIEWS` | `100` | Maximal number of views. |
|
||||||
|
| `MAX_EXPIRATION` | `360` | Maximal expiration in minutes. |
|
||||||
|
| `ALLOW_ADVANCED` | `true` | Allow custom configuration. If set to `false` all notes will be one view only. |
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
@@ -124,11 +127,35 @@ services:
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
1. Clone
|
**Requirements**
|
||||||
2. run `pnpm i` in the root and and client `client/` folders.
|
|
||||||
3. Run `pnpm run dev` to start development.
|
|
||||||
|
|
||||||
Running `npm run dev` in the root folder will start the following things
|
- `pnpm`: `>=6`
|
||||||
|
- `node`: `>=14`
|
||||||
|
- `rust`: edition `2021`
|
||||||
|
|
||||||
|
**Install**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
pnpm --prefix frontend install
|
||||||
|
|
||||||
|
# Also you need cargo watch if you don't already have it installed.
|
||||||
|
# https://lib.rs/crates/cargo-watch
|
||||||
|
cargo install cargo-watch
|
||||||
|
```
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
Make sure you have docker running.
|
||||||
|
|
||||||
|
> If you are on `macOS` you might need to disable AirPlay Receiver as it uses port 5000 (So stupid...)
|
||||||
|
> https://developer.apple.com/forums/thread/682332
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Running `pnpm run dev` in the root folder will start the following things:
|
||||||
|
|
||||||
- a memcache docker container
|
- a memcache docker container
|
||||||
- rust backend with hot reload
|
- rust backend with hot reload
|
||||||
|
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
@@ -398,7 +398,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cryptgeon"
|
name = "cryptgeon"
|
||||||
version = "1.4.0"
|
version = "1.5.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-files",
|
"actix-files",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cryptgeon"
|
name = "cryptgeon"
|
||||||
version = "1.4.0"
|
version = "1.5.1"
|
||||||
authors = ["cupcakearmy <hi@nicco.io>"]
|
authors = ["cupcakearmy <hi@nicco.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
use actix_files::Files;
|
use actix_files::{Files, NamedFile};
|
||||||
use actix_web::web;
|
use actix_web::{web, Result};
|
||||||
|
|
||||||
pub fn init(cfg: &mut web::ServiceConfig) {
|
pub fn init(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(
|
cfg.service(
|
||||||
@@ -8,3 +8,7 @@ pub fn init(cfg: &mut web::ServiceConfig) {
|
|||||||
.use_etag(true),
|
.use_etag(true),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn index() -> Result<NamedFile> {
|
||||||
|
Ok(NamedFile::open("./frontend/build/index.html")?)
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use actix_web::{middleware, App, HttpServer};
|
use actix_web::{middleware, web, App, HttpServer};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -22,6 +22,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.configure(size::init)
|
.configure(size::init)
|
||||||
.configure(api::init)
|
.configure(api::init)
|
||||||
.configure(client::init)
|
.configure(client::init)
|
||||||
|
.default_service(web::to(client::index))
|
||||||
})
|
})
|
||||||
.bind("0.0.0.0:5000")?
|
.bind("0.0.0.0:5000")?
|
||||||
.run()
|
.run()
|
||||||
|
161
examples/scratch/README.md
Normal file
161
examples/scratch/README.md
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
# Install from scratch.
|
||||||
|
|
||||||
|
This is a tiny guide to install cryptgeon on (probably) any unix system (and maybe windows?) from scratch using traefik as the proxy, which will manage certificates and handle https for us.
|
||||||
|
|
||||||
|
1. Install Docker & Docker Compose.
|
||||||
|
2. Install Traefik.
|
||||||
|
3. Run the cryptgeon.
|
||||||
|
4. [Optional] install watchtower to keep up to date.
|
||||||
|
|
||||||
|
## Install Docker & DOcker Compose
|
||||||
|
|
||||||
|
- [Docker](https://docs.docker.com/engine/install/)
|
||||||
|
- [Compose](https://docs.docker.com/compose/install/)
|
||||||
|
|
||||||
|
## Install Traefik 2.0
|
||||||
|
|
||||||
|
[Traefik](https://doc.traefik.io/traefik/) is a router & proxy that makes deployment of containers incredibly easy. It will manage all the https certificates, routing, etc.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
/foo/bar/traefik/
|
||||||
|
├── docker-compose.yaml
|
||||||
|
└── traefik.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker-compose.yaml
|
||||||
|
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:2.6
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- '80:80'
|
||||||
|
- '443:443'
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./traefik.yaml:/etc/traefik/traefik.yaml:ro
|
||||||
|
- ./data:/data
|
||||||
|
labels:
|
||||||
|
- 'traefik.enable=true'
|
||||||
|
|
||||||
|
# HTTP to HTTPS redirection
|
||||||
|
- 'traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)'
|
||||||
|
- 'traefik.http.routers.http_catchall.entrypoints=insecure'
|
||||||
|
- 'traefik.http.routers.http_catchall.middlewares=https_redirect'
|
||||||
|
- 'traefik.http.middlewares.https_redirect.redirectscheme.scheme=https'
|
||||||
|
- 'traefik.http.middlewares.https_redirect.redirectscheme.permanent=true'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
external: true
|
||||||
|
name: proxy
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# traefik.yaml
|
||||||
|
|
||||||
|
api:
|
||||||
|
dashboard: true
|
||||||
|
|
||||||
|
# Define HTTP and HTTPS entrypoint
|
||||||
|
entryPoints:
|
||||||
|
insecure:
|
||||||
|
address: ':80'
|
||||||
|
secure:
|
||||||
|
address: ':443'
|
||||||
|
|
||||||
|
# Dynamic configuration will come from docker labels
|
||||||
|
providers:
|
||||||
|
docker:
|
||||||
|
endpoint: 'unix:///var/run/docker.sock'
|
||||||
|
network: 'proxy'
|
||||||
|
exposedByDefault: false
|
||||||
|
|
||||||
|
# Enable acme with http file challenge
|
||||||
|
certificatesResolvers:
|
||||||
|
le:
|
||||||
|
acme:
|
||||||
|
email: me@example.org
|
||||||
|
storage: /data/acme.json
|
||||||
|
httpChallenge:
|
||||||
|
entryPoint: insecure
|
||||||
|
```
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker network create proxy
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cryptgeon
|
||||||
|
|
||||||
|
Create another docker-compose.yaml file in another folder. We will assume that the domain is `cryptgeon.example.org`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
/foo/bar/cryptgeon/
|
||||||
|
└── docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
memcached:
|
||||||
|
image: memcached:1-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
entrypoint: memcached -m 256M -I 4M # Limit to 128 MB Ram, customize at free will.
|
||||||
|
|
||||||
|
app:
|
||||||
|
image: cupcakearmy/cryptgeon:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- memcached
|
||||||
|
environment:
|
||||||
|
SIZE_LIMIT: 4 MiB
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.cryptgeon.rule=Host(`cryptgeon.example.org`)
|
||||||
|
- traefik.http.routers.cryptgeon.entrypoints=secure
|
||||||
|
- traefik.http.routers.cryptgeon.tls.certresolver=le
|
||||||
|
```
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Watchtower
|
||||||
|
|
||||||
|
> A container-based solution for automating Docker container base image updates.
|
||||||
|
|
||||||
|
[Watchtower](https://containrrr.dev/watchtower/) will keep our containers up to date. The interval is set to once a day and also configured to delete old images to prevent cluttering.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
/foo/bar/watchtower/
|
||||||
|
└── docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker-compose.yaml
|
||||||
|
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
watchtower:
|
||||||
|
image: containrrr/watchtower
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
command: --cleanup --interval 86400
|
||||||
|
```
|
@@ -11,23 +11,25 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lokalise/node-api": "^7.1.1",
|
"@lokalise/node-api": "^7.1.1",
|
||||||
"@sveltejs/adapter-static": "^1.0.0-next.26",
|
"@sveltejs/adapter-static": "^1.0.0-next.28",
|
||||||
"@sveltejs/kit": "^1.0.0-next.231",
|
"@sveltejs/kit": "1.0.0-next.288",
|
||||||
"@types/file-saver": "^2.0.5",
|
"@types/file-saver": "^2.0.5",
|
||||||
|
"@types/sanitize-html": "^2.6.2",
|
||||||
"adm-zip": "^0.5.9",
|
"adm-zip": "^0.5.9",
|
||||||
"dotenv": "^16.0.0",
|
"dotenv": "^16.0.0",
|
||||||
"svelte": "^3.46.2",
|
"svelte": "^3.46.4",
|
||||||
"svelte-check": "^2.4.5",
|
"svelte-check": "^2.4.5",
|
||||||
"svelte-intl-precompile": "^0.8.0",
|
"svelte-intl-precompile": "^0.8.1",
|
||||||
"svelte-preprocess": "^4.10.1",
|
"svelte-preprocess": "^4.10.4",
|
||||||
"tslib": "^2.3.1",
|
"tslib": "^2.3.1",
|
||||||
"typescript": "^4.5.4",
|
"typescript": "^4.6.2",
|
||||||
"vite": "^2.7.12"
|
"vite": "^2.8.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/fira-mono": "^4.5.0",
|
"@fontsource/fira-mono": "^4.5.3",
|
||||||
"copy-to-clipboard": "^3.3.1",
|
"copy-to-clipboard": "^3.3.1",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"pretty-bytes": "^5.6.0"
|
"pretty-bytes": "^5.6.0",
|
||||||
|
"sanitize-html": "^2.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
579
frontend/pnpm-lock.yaml
generated
579
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -4,11 +4,13 @@
|
|||||||
import copy from 'copy-to-clipboard'
|
import copy from 'copy-to-clipboard'
|
||||||
import { saveAs } from 'file-saver'
|
import { saveAs } from 'file-saver'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import prettyBytes from 'pretty-bytes'
|
||||||
|
import sanitize from 'sanitize-html'
|
||||||
import { t } from 'svelte-intl-precompile'
|
import { t } from 'svelte-intl-precompile'
|
||||||
import Button from './Button.svelte'
|
import Button from './Button.svelte'
|
||||||
|
|
||||||
export let note: NotePublic
|
export let note: NotePublic
|
||||||
|
|
||||||
|
const RE_URL = /[A-Za-z]+:\/\/([A-Z a-z0-9\-._~:\/?#\[\]@!$&'()*+,;%=])+/g
|
||||||
let files: FileDTO[] = []
|
let files: FileDTO[] = []
|
||||||
|
|
||||||
$: if (note.meta.type === 'file') {
|
$: if (note.meta.type === 'file') {
|
||||||
@@ -27,12 +29,20 @@
|
|||||||
})
|
})
|
||||||
saveAs(f)
|
saveAs(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function contentWithLinks(content: string): string {
|
||||||
|
const replaced = note.contents.replace(
|
||||||
|
RE_URL,
|
||||||
|
(url) => `<a href="${url}" rel="noreferrer">${url}</a>`
|
||||||
|
)
|
||||||
|
return sanitize(replaced, { allowedTags: ['a'], allowedAttributes: { a: ['href', 'rel'] } })
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p class="error-text">{@html $t('show.warning_will_not_see_again')}</p>
|
<p class="error-text">{@html $t('show.warning_will_not_see_again')}</p>
|
||||||
{#if note.meta.type === 'text'}
|
{#if note.meta.type === 'text'}
|
||||||
<div class="note">
|
<div class="note">
|
||||||
{note.contents}
|
{@html contentWithLinks(note.contents)}
|
||||||
</div>
|
</div>
|
||||||
<Button on:click={() => copy(note.contents)}>{$t('common.copy_clipboard')}</Button>
|
<Button on:click={() => copy(note.contents)}>{$t('common.copy_clipboard')}</Button>
|
||||||
{:else}
|
{:else}
|
||||||
|
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
export const hydrate = dev
|
export const hydrate = dev
|
||||||
export const router = browser
|
export const router = browser
|
||||||
export const prerender = true
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@@ -1,7 +1,3 @@
|
|||||||
<script context="module" lang="ts">
|
|
||||||
export const prerender = true
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Create from '$lib/views/Create.svelte'
|
import Create from '$lib/views/Create.svelte'
|
||||||
</script>
|
</script>
|
||||||
|
@@ -9,7 +9,6 @@ export default {
|
|||||||
adapter: adapter({
|
adapter: adapter({
|
||||||
fallback: 'index.html',
|
fallback: 'index.html',
|
||||||
}),
|
}),
|
||||||
target: '#svelte',
|
|
||||||
vite: {
|
vite: {
|
||||||
plugins: [
|
plugins: [
|
||||||
precompileIntl('locales'), // if your translations are defined in /locales/[lang].json
|
precompileIntl('locales'), // if your translations are defined in /locales/[lang].json
|
||||||
|
Reference in New Issue
Block a user