mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2025-09-04 00:20:39 +00:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
c2b557246b | |||
df9cd08473 | |||
|
0b8e1d1b2e | ||
70481341b9 | |||
6271ec1ee9 | |||
c7ec587a2d | |||
3e8e82f51c | |||
|
c314d4b485 | ||
|
57ea5f0b28 | ||
|
fca8761515 | ||
a47b8a482c | |||
847fc9677d | |||
6979be0c4a | |||
f61d3ece8b | |||
14d3e9eb03 |
10
README.md
10
README.md
@@ -12,6 +12,7 @@
|
||||
<br/><br/>
|
||||
<a href="https://www.producthunt.com/posts/cryptgeon?utm_source=badge-featured&utm_medium=badge&utm_souce=badge-cryptgeon" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=295189&theme=light" alt="Cryptgeon - Securely share self-destructing notes | Product Hunt" height="50" /></a>
|
||||
<a href=""><img src="./.github/lokalise.png" height="50">
|
||||
<a title="Install cryptgeon Raycast Extension" href="https://www.raycast.com/cupcakearmy/cryptgeon"><img src="https://www.raycast.com/cupcakearmy/cryptgeon/install_button@2x.png?v=1.1" height="64" alt="" style="height: 64px;"></a>
|
||||
<br/><br/>
|
||||
|
||||
EN | [简体中文](README_zh-CN.md) | [ES](README_ES.md)
|
||||
@@ -39,6 +40,12 @@ npx cryptgeon send text "This is a secret note"
|
||||
|
||||
For more documentation about the CLI see the [readme](./packages/cli/README.md).
|
||||
|
||||
### Raycast Extension
|
||||
|
||||
There is an [official Raycast extension](https://www.raycast.com/cupcakearmy/cryptgeon).
|
||||
|
||||
<a title="Install cryptgeon Raycast Extension" href="https://www.raycast.com/cupcakearmy/cryptgeon"><img src="https://www.raycast.com/cupcakearmy/cryptgeon/install_button@2x.png?v=1.1" height="64" alt="" style="height: 64px;"></a>
|
||||
|
||||
## Features
|
||||
|
||||
- send text or files
|
||||
@@ -77,7 +84,8 @@ of the notes even if it tried to.
|
||||
| `THEME_PAGE_TITLE` | `""` | Custom text the page title |
|
||||
| `THEME_FAVICON` | `""` | Custom url for the favicon. Must be publicly reachable |
|
||||
| `THEME_NEW_NOTE_NOTICE` | `true` | Show the message about how notes are stored in the memory and may be evicted after creating a new note. Defaults to `true`. |
|
||||
|
||||
| `IMPRINT_URL` | `""` | Custom url for an Imprint hosted somewhere else. Must be publicly reachable. Takes precedence above `IMPRINT_HTML`. |
|
||||
| `IMPRINT_HTML` | `""` | Alternative to `IMPRINT_URL`, this can be used to specify the HTML code to show on `/imprint`. Only `IMPRINT_HTML` or `IMPRINT_URL` should be specified, not both.|
|
||||
## Deployment
|
||||
|
||||
> ℹ️ `https` is required otherwise browsers will not support the cryptographic functions.
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
Assumptions:
|
||||
|
||||
- Traefik 2 installed.
|
||||
- Traefik 2/3 installed.
|
||||
- External proxy docker network `proxy`.
|
||||
- A certificate resolver `le`.
|
||||
- A https entrypoint `secure`.
|
||||
@@ -34,3 +34,43 @@ services:
|
||||
- traefik.http.routers.cryptgeon.entrypoints=secure
|
||||
- traefik.http.routers.cryptgeon.tls.certresolver=le
|
||||
```
|
||||
|
||||
## With basic auth
|
||||
|
||||
Some times it's useful to hide the service behind auth. This is easily achieved with traefik middleware. Many reverse proxies support similar features, so while traefik is used in this example, other reverse proxies can do the same.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.0
|
||||
command:
|
||||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
|
||||
cryptgeon:
|
||||
image: cupcakearmy/cryptgeon
|
||||
depends_on:
|
||||
- redis
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.cryptgeon.rule=Host(`cryptgeon.localhost`)"
|
||||
- "traefik.http.routers.cryptgeon.entrypoints=web"
|
||||
- "traefik.http.routers.cryptgeon.middlewares=cryptgeon-auth"
|
||||
- "traefik.http.middlewares.cryptgeon-auth.basicauth.users=user:$$2y$$05$$juUw0zgc5ebvJ00MFPVVLujF6P.rcEMbGZ99Jfq6ZWEa1dgetacEq"
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
1. Open http://cryptgeon.localhost
|
||||
2. Log in with `user` and `secret`
|
||||
|
@@ -17,5 +17,5 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"shelljs": "^0.8.5"
|
||||
},
|
||||
"packageManager": "pnpm@9.9.0"
|
||||
"packageManager": "pnpm@9.11.0"
|
||||
}
|
||||
|
2
packages/backend/Cargo.lock
generated
2
packages/backend/Cargo.lock
generated
@@ -261,7 +261,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cryptgeon"
|
||||
version = "2.8.1"
|
||||
version = "2.8.4"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"bs62",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cryptgeon"
|
||||
version = "2.8.1"
|
||||
version = "2.8.4"
|
||||
authors = ["cupcakearmy <hi@nicco.io>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.80"
|
||||
|
@@ -38,6 +38,14 @@ pub static ref ALLOW_FILES: bool = std::env::var("ALLOW_FILES")
|
||||
.unwrap_or("true".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
pub static ref IMPRINT_URL: String = std::env::var("IMPRINT_URL")
|
||||
.unwrap_or("".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
pub static ref IMPRINT_HTML: String = std::env::var("IMPRINT_HTML")
|
||||
.unwrap_or("".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// THEME
|
||||
|
@@ -12,6 +12,8 @@ pub struct Status {
|
||||
pub max_expiration: u32,
|
||||
pub allow_advanced: bool,
|
||||
pub allow_files: bool,
|
||||
pub imprint_url: String,
|
||||
pub imprint_html: String,
|
||||
// Theme
|
||||
pub theme_image: String,
|
||||
pub theme_text: String,
|
||||
@@ -28,6 +30,8 @@ pub async fn get_status() -> (StatusCode, Json<Status>) {
|
||||
max_expiration: *config::MAX_EXPIRATION,
|
||||
allow_advanced: *config::ALLOW_ADVANCED,
|
||||
allow_files: *config::ALLOW_FILES,
|
||||
imprint_url: config::IMPRINT_URL.to_string(),
|
||||
imprint_html: config::IMPRINT_HTML.to_string(),
|
||||
theme_new_note_notice: *config::THEME_NEW_NOTE_NOTICE,
|
||||
theme_image: config::THEME_IMAGE.to_string(),
|
||||
theme_text: config::THEME_TEXT.to_string(),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cryptgeon",
|
||||
"version": "2.8.1",
|
||||
"version": "2.8.4",
|
||||
"homepage": "https://github.com/cupcakearmy/cryptgeon",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -113,6 +113,8 @@ export type Status = {
|
||||
max_expiration: number
|
||||
allow_advanced: boolean
|
||||
allow_files: boolean
|
||||
imprint_url: string
|
||||
imprint_html: string
|
||||
theme_image: string
|
||||
theme_text: string
|
||||
theme_favicon: string
|
||||
|
58
packages/frontend/locales/zh-TW.json
Normal file
58
packages/frontend/locales/zh-TW.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"common": {
|
||||
"note": "筆記",
|
||||
"file": "檔案",
|
||||
"advanced": "進階",
|
||||
"create": "創建",
|
||||
"loading": "載入中",
|
||||
"mode": "模式",
|
||||
"views": "{n, plural, =0 {瀏覽次數} =1 {1 次瀏覽} other {# 次瀏覽}}",
|
||||
"minutes": "{n, plural, =0 {分鐘} =1 {1 分鐘} other {# 分鐘}}",
|
||||
"max": "最大",
|
||||
"share_link": "分享連結",
|
||||
"copy_clipboard": "複製到剪貼板",
|
||||
"copied_to_clipboard": "已複製到剪貼板",
|
||||
"encrypting": "加密中",
|
||||
"decrypting": "解密中",
|
||||
"uploading": "上傳中",
|
||||
"downloading": "下載中",
|
||||
"qr_code": "QR 碼",
|
||||
"password": "密碼"
|
||||
},
|
||||
"home": {
|
||||
"intro": "輕鬆地以一鍵傳送<i>完全加密</i>的安全筆記或檔案。只需創建筆記並分享連結。",
|
||||
"explanation": "筆記將在 {type} 後過期並被銷毀。",
|
||||
"new_note": "新筆記",
|
||||
"new_note_notice": "<b>可用性:</b><br />筆記不保證被儲存,因為所有內容都保留在 RAM 中,如果 RAM 填滿,最舊的筆記將被移除。<br />(您可能會沒事,只是提醒一下。)",
|
||||
"errors": {
|
||||
"note_to_big": "無法創建筆記。筆記過大",
|
||||
"note_error": "無法創建筆記。請再試一次。",
|
||||
"max": "最大值:{n}",
|
||||
"empty_content": "筆記內容為空。"
|
||||
},
|
||||
"messages": {
|
||||
"note_created": "筆記已創建。"
|
||||
},
|
||||
"advanced": {
|
||||
"explanation": "預設情況下,每個筆記都會使用安全生成的密碼。您也可以選擇自己的密碼,該密碼不會包含在連結中。",
|
||||
"custom_password": "自定義密碼"
|
||||
}
|
||||
},
|
||||
"show": {
|
||||
"errors": {
|
||||
"not_found": "筆記未找到或已被刪除。",
|
||||
"decryption_failed": "密碼錯誤。無法解密。可能是連結已損壞。筆記已被銷毀。",
|
||||
"unsupported_type": "不支持的筆記類型。"
|
||||
},
|
||||
"explanation": "如果計數器達到限制,請點擊下方以顯示並刪除筆記",
|
||||
"show_note": "顯示筆記",
|
||||
"warning_will_not_see_again": "您將<b>無法</b>再次查看筆記。",
|
||||
"download_all": "全部下載",
|
||||
"links_found": "在筆記中找到的連結:"
|
||||
},
|
||||
"file_upload": {
|
||||
"selected_files": "已選擇的檔案",
|
||||
"no_files_selected": "未選擇檔案",
|
||||
"clear": "重置"
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
export let icon: keyof typeof map
|
||||
</script>
|
||||
|
||||
<button on:click {...$$restProps}>
|
||||
<button type="button" on:click {...$$restProps}>
|
||||
{#if map[icon]}
|
||||
<svelte:component this={map[icon]} />
|
||||
{/if}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import ThemeToggle from '$lib/ui/ThemeToggle.svelte'
|
||||
import { status } from '$lib/stores/status'
|
||||
</script>
|
||||
|
||||
<footer>
|
||||
@@ -7,6 +8,11 @@
|
||||
<nav>
|
||||
<a href="/">/home</a>
|
||||
<a href="/about">/about</a>
|
||||
{#if $status?.imprint_url}
|
||||
<a href={$status.imprint_url} target="_blank" rel="noopener noreferrer">/imprint</a>
|
||||
{:else if $status?.imprint_html}
|
||||
<a href="/imprint">/imprint</a>
|
||||
{/if}
|
||||
<a href="https://github.com/cupcakearmy/cryptgeon" target="_blank" rel="noopener noreferrer">
|
||||
code
|
||||
</a>
|
||||
|
35
packages/frontend/src/routes/imprint/+page.svelte
Normal file
35
packages/frontend/src/routes/imprint/+page.svelte
Normal file
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { get } from 'svelte/store';
|
||||
import { goto } from '$app/navigation';
|
||||
import { status } from '$lib/stores/status'
|
||||
|
||||
status.subscribe((config) => {
|
||||
if (config != null) {
|
||||
if (config.imprint_url) {
|
||||
window.location = config.imprint_url;
|
||||
}
|
||||
else if (config.imprint_html == "") {
|
||||
goto("/about");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Imprint</title>
|
||||
</svelte:head>
|
||||
|
||||
<section class="content">
|
||||
{#if $status?.imprint_html}
|
||||
{@html $status.imprint_html}
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user