mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2025-09-06 01:10:40 +00:00
Compare commits
27 Commits
fdc2722fb9
...
v2.3.1
Author | SHA1 | Date | |
---|---|---|---|
c46f80aaa0 | |||
e2711cc887 | |||
e02224216a | |||
1b0d5449a0 | |||
9695d3a63f | |||
22d4efb03e | |||
97741ed73f | |||
c9e5de0f37 | |||
dc1c03d912 | |||
2a75acae3f | |||
815ac4e8ba | |||
7c85c1e621 | |||
a323d48c41 | |||
2bff6a37db | |||
f8223dfc62 | |||
063d073c27 | |||
ac32b97383 | |||
9c9c23d958 | |||
92893a5b2d | |||
ac68f4a540 | |||
83b2fa5372 | |||
3c86f3f3be | |||
80e64ad207 | |||
a5809c216c | |||
fb95a68b0d | |||
b43b802221 | |||
2e89007c83 |
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@@ -12,15 +12,22 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
cache: 'pnpm'
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
- uses: pnpm/action-setup@v2
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
pnpm install --frozen-lockfile
|
pnpm install --frozen-lockfile
|
||||||
pnpm run build
|
pnpm run build
|
||||||
|
|
||||||
|
- run: npm publish
|
||||||
|
working-directory: ./packages/cli
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
3
.github/workflows/test.yaml
vendored
3
.github/workflows/test.yaml
vendored
@@ -13,10 +13,11 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
# Node
|
# Node
|
||||||
|
- uses: pnpm/action-setup@v2
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
cache: 'pnpm'
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
- uses: pnpm/action-setup@v2
|
|
||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
- uses: docker/setup-qemu-action@v2
|
- uses: docker/setup-qemu-action@v2
|
||||||
|
17
CHANGELOG.md
17
CHANGELOG.md
@@ -5,18 +5,23 @@ 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).
|
||||||
|
|
||||||
## [2.3.0] - 2023-05-XX
|
## [2.3.1] - 2023-06-23
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- New CLI 🎉
|
- #92: Endpoint (`/api/live/`) for checking health status.
|
||||||
- Russian language
|
|
||||||
|
## [2.3.0] - 2023-05-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New CLI 🎉.
|
||||||
|
- Russian language.
|
||||||
|
- Option for reducing note id size (`ID_LENGTH`).
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Moved to monorepo
|
- Moved to monorepo.
|
||||||
|
|
||||||
## [2.2.0] - 2023-01-14
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"info": {
|
"info": {
|
||||||
"_postman_id": "52d9e661-2d99-47f8-b09a-40b6a1c0b364",
|
"_postman_id": "3aaeac19-4eac-4911-b3c8-912b17a48634",
|
||||||
"name": "Cryptgeon",
|
"name": "Cryptgeon",
|
||||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
},
|
},
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"cookie": [],
|
"cookie": [],
|
||||||
"body": null
|
"body": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -479,7 +479,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"cookie": [],
|
"cookie": [],
|
||||||
"body": null
|
"body": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -489,7 +489,7 @@
|
|||||||
"name": "Status",
|
"name": "Status",
|
||||||
"item": [
|
"item": [
|
||||||
{
|
{
|
||||||
"name": "Get",
|
"name": "Get server status",
|
||||||
"request": {
|
"request": {
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"header": [],
|
"header": [],
|
||||||
@@ -554,6 +554,106 @@
|
|||||||
"body": "{\n \"version\": \"2.3.0-beta.4\",\n \"max_size\": 10485760,\n \"max_views\": 100,\n \"max_expiration\": 360,\n \"allow_advanced\": true,\n \"theme_image\": \"\",\n \"theme_text\": \"\",\n \"theme_page_title\": \"\",\n \"theme_favicon\": \"\"\n}"
|
"body": "{\n \"version\": \"2.3.0-beta.4\",\n \"max_size\": 10485760,\n \"max_views\": 100,\n \"max_expiration\": 360,\n \"allow_advanced\": true,\n \"theme_image\": \"\",\n \"theme_text\": \"\",\n \"theme_page_title\": \"\",\n \"theme_favicon\": \"\"\n}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Health Check",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{BASE}}/live/",
|
||||||
|
"host": [
|
||||||
|
"{{BASE}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"live",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Return `200` for healthy service. `503` if service is unavailable."
|
||||||
|
},
|
||||||
|
"response": [
|
||||||
|
{
|
||||||
|
"name": "Healthy",
|
||||||
|
"originalRequest": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{BASE}}/live/",
|
||||||
|
"host": [
|
||||||
|
"{{BASE}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"live",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status": "OK",
|
||||||
|
"code": 200,
|
||||||
|
"_postman_previewlanguage": "plain",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "transfer-encoding",
|
||||||
|
"value": "chunked"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "vary",
|
||||||
|
"value": "accept-encoding"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "content-encoding",
|
||||||
|
"value": "gzip"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "date",
|
||||||
|
"value": "Thu, 22 Jun 2023 20:17:58 GMT"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cookie": [],
|
||||||
|
"body": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Service Unavilable",
|
||||||
|
"originalRequest": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{BASE}}/live/",
|
||||||
|
"host": [
|
||||||
|
"{{BASE}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"live",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status": "Service Unavailable",
|
||||||
|
"code": 503,
|
||||||
|
"_postman_previewlanguage": "plain",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "transfer-encoding",
|
||||||
|
"value": "chunked"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "content-encoding",
|
||||||
|
"value": "gzip"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "vary",
|
||||||
|
"value": "accept-encoding"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "date",
|
||||||
|
"value": "Thu, 22 Jun 2023 20:18:55 GMT"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cookie": [],
|
||||||
|
"body": null
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@ FROM rust:1.69-alpine as backend
|
|||||||
WORKDIR /tmp
|
WORKDIR /tmp
|
||||||
RUN apk add libc-dev openssl-dev alpine-sdk
|
RUN apk add libc-dev openssl-dev alpine-sdk
|
||||||
COPY ./packages/backend/Cargo.* ./
|
COPY ./packages/backend/Cargo.* ./
|
||||||
|
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
|
||||||
RUN cargo fetch
|
RUN cargo fetch
|
||||||
COPY ./packages/backend ./
|
COPY ./packages/backend ./
|
||||||
RUN cargo build --release
|
RUN cargo build --release
|
||||||
@@ -20,6 +21,7 @@ RUN cargo build --release
|
|||||||
# RUNNER
|
# RUNNER
|
||||||
FROM alpine
|
FROM alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
RUN apk add --no-cache curl
|
||||||
COPY --from=backend /tmp/target/release/cryptgeon .
|
COPY --from=backend /tmp/target/release/cryptgeon .
|
||||||
COPY --from=client /tmp/packages/frontend/build ./frontend
|
COPY --from=client /tmp/packages/frontend/build ./frontend
|
||||||
ENV FRONTEND_PATH="./frontend"
|
ENV FRONTEND_PATH="./frontend"
|
||||||
|
44
README.md
44
README.md
@@ -18,7 +18,8 @@ EN | [简体中文](README_zh-CN.md)
|
|||||||
|
|
||||||
## About?
|
## About?
|
||||||
|
|
||||||
_cryptgeon_ is a secure, open source sharing note or file service inspired by [_PrivNote_](https://privnote.com)
|
_cryptgeon_ is a secure, open source sharing note or file service inspired by [_PrivNote_](https://privnote.com).
|
||||||
|
It includes a server, a web page and a CLI client.
|
||||||
|
|
||||||
> 🌍 If you want to translate the project feel free to reach out to me.
|
> 🌍 If you want to translate the project feel free to reach out to me.
|
||||||
>
|
>
|
||||||
@@ -26,10 +27,21 @@ _cryptgeon_ is a secure, open source sharing note or file service inspired by [_
|
|||||||
|
|
||||||
## Live Service / Demo
|
## Live Service / Demo
|
||||||
|
|
||||||
|
### Web
|
||||||
|
|
||||||
Check out the live service / demo and see for yourself [cryptgeon.org](https://cryptgeon.org)
|
Check out the live service / demo and see for yourself [cryptgeon.org](https://cryptgeon.org)
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```
|
||||||
|
npx cryptgeon send text "This is a secret note"
|
||||||
|
```
|
||||||
|
|
||||||
|
For more documentation about the CLI see the [readme](./packages/cli/README.md).
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
- send text or files
|
||||||
- server cannot decrypt contents due to client side encryption
|
- server cannot decrypt contents due to client side encryption
|
||||||
- view or time constraints
|
- view or time constraints
|
||||||
- in memory, no persistence
|
- in memory, no persistence
|
||||||
@@ -57,6 +69,7 @@ of the notes even if it tried to.
|
|||||||
| `MAX_VIEWS` | `100` | Maximal number of views. |
|
| `MAX_VIEWS` | `100` | Maximal number of views. |
|
||||||
| `MAX_EXPIRATION` | `360` | Maximal expiration in minutes. |
|
| `MAX_EXPIRATION` | `360` | Maximal expiration in minutes. |
|
||||||
| `ALLOW_ADVANCED` | `true` | Allow custom configuration. If set to `false` all notes will be one view only. |
|
| `ALLOW_ADVANCED` | `true` | Allow custom configuration. If set to `false` all notes will be one view only. |
|
||||||
|
| `ID_LENGTH` | `32` | Set the size of the note `id` in bytes. By default this is `32` bytes. This is useful for reducing link size. _This setting does not affect encryption strength_. |
|
||||||
| `VERBOSITY` | `warn` | Verbosity level for the backend. [Possible values](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) are: `error`, `warn`, `info`, `debug`, `trace` |
|
| `VERBOSITY` | `warn` | Verbosity level for the backend. [Possible values](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) are: `error`, `warn`, `info`, `debug`, `trace` |
|
||||||
| `THEME_IMAGE` | `""` | Custom image for replacing the logo. Must be publicly reachable |
|
| `THEME_IMAGE` | `""` | Custom image for replacing the logo. Must be publicly reachable |
|
||||||
| `THEME_TEXT` | `""` | Custom text for replacing the description below the logo |
|
| `THEME_TEXT` | `""` | Custom text for replacing the description below the logo |
|
||||||
@@ -65,7 +78,9 @@ of the notes even if it tried to.
|
|||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
ℹ️ `https` is required otherwise browsers will not support the cryptographic functions.
|
> ℹ️ `https` is required otherwise browsers will not support the cryptographic functions.
|
||||||
|
|
||||||
|
> ℹ️ There is a health endpoint available at `/api/health/`. It returns either 200 or 503.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
@@ -81,7 +96,7 @@ services:
|
|||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
# Set a size limit. See link below on how to customise.
|
# Set a size limit. See link below on how to customise.
|
||||||
# https://redis.io/docs/manual/eviction/
|
# https://redis.io/docs/manual/eviction/
|
||||||
command: redis-server --maxmemory 1gb --maxmemory-policy allkeys-lru
|
# command: redis-server --maxmemory 1gb --maxmemory-policy allkeys-lru
|
||||||
|
|
||||||
app:
|
app:
|
||||||
image: cupcakearmy/cryptgeon:latest
|
image: cupcakearmy/cryptgeon:latest
|
||||||
@@ -92,6 +107,14 @@ services:
|
|||||||
SIZE_LIMIT: 4 MiB
|
SIZE_LIMIT: 4 MiB
|
||||||
ports:
|
ports:
|
||||||
- 80:8000
|
- 80:8000
|
||||||
|
|
||||||
|
# Optional health checks
|
||||||
|
# healthcheck:
|
||||||
|
# test: ["CMD", "curl", "--fail", "http://127.0.0.1:8000/api/live/"]
|
||||||
|
# interval: 1m
|
||||||
|
# timeout: 3s
|
||||||
|
# retries: 2
|
||||||
|
# start_period: 5s
|
||||||
```
|
```
|
||||||
|
|
||||||
### NGINX Proxy
|
### NGINX Proxy
|
||||||
@@ -121,14 +144,13 @@ There is a [guide](https://mariushosting.com/how-to-install-cryptgeon-on-your-sy
|
|||||||
**Requirements**
|
**Requirements**
|
||||||
|
|
||||||
- `pnpm`: `>=6`
|
- `pnpm`: `>=6`
|
||||||
- `node`: `>=16`
|
- `node`: `>=18`
|
||||||
- `rust`: edition `2021`
|
- `rust`: edition `2021`
|
||||||
|
|
||||||
**Install**
|
**Install**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm --prefix frontend install
|
|
||||||
|
|
||||||
# Also you need cargo watch if you don't already have it installed.
|
# Also you need cargo watch if you don't already have it installed.
|
||||||
# https://lib.rs/crates/cargo-watch
|
# https://lib.rs/crates/cargo-watch
|
||||||
@@ -148,19 +170,19 @@ Running `pnpm run dev` in the root folder will start the following things:
|
|||||||
- redis docker container
|
- redis docker container
|
||||||
- rust backend
|
- rust backend
|
||||||
- client
|
- client
|
||||||
|
- cli
|
||||||
|
|
||||||
You can see the app under [localhost:1234](http://localhost:1234).
|
You can see the app under [localhost:1234](http://localhost:1234).
|
||||||
|
|
||||||
## Tests
|
> There is a Postman collection with some example requests [available in the repo](./Cryptgeon.postman_collection.json)
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
Tests are end to end tests written with Playwright.
|
Tests are end to end tests written with Playwright.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pnpm run test:prepare
|
pnpm run test:prepare
|
||||||
docker compose up redis -d
|
|
||||||
pnpm run test:server
|
|
||||||
|
|
||||||
# In another terminal.
|
|
||||||
# Use the test or test:local script. The local version only runs in one browser for quicker development.
|
# Use the test or test:local script. The local version only runs in one browser for quicker development.
|
||||||
pnpm run test:local
|
pnpm run test:local
|
||||||
```
|
```
|
||||||
@@ -169,7 +191,9 @@ pnpm run test:local
|
|||||||
|
|
||||||
Please refer to the security section [here](./SECURITY.md).
|
Please refer to the security section [here](./SECURITY.md).
|
||||||
|
|
||||||
###### Attributions
|
---
|
||||||
|
|
||||||
|
_Attributions_
|
||||||
|
|
||||||
- Test data:
|
- Test data:
|
||||||
- Text for tests [Nietzsche Ipsum](https://nietzsche-ipsum.com/)
|
- Text for tests [Nietzsche Ipsum](https://nietzsche-ipsum.com/)
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
"i18n-ally.localesPaths": ["packages/frontend/locales"],
|
"i18n-ally.localesPaths": ["locales"],
|
||||||
"cSpell.words": ["cryptgeon"]
|
"cSpell.words": ["cryptgeon"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,3 +16,10 @@ services:
|
|||||||
- redis
|
- redis
|
||||||
ports:
|
ports:
|
||||||
- 1234:8000
|
- 1234:8000
|
||||||
|
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "--fail", "http://127.0.0.1:8000/api/live/"]
|
||||||
|
interval: 1m
|
||||||
|
timeout: 3s
|
||||||
|
retries: 2
|
||||||
|
start_period: 5s
|
||||||
|
@@ -16,3 +16,11 @@ services:
|
|||||||
SIZE_LIMIT: 4 MiB
|
SIZE_LIMIT: 4 MiB
|
||||||
ports:
|
ports:
|
||||||
- 80:8000
|
- 80:8000
|
||||||
|
|
||||||
|
# Optional health checks
|
||||||
|
# healthcheck:
|
||||||
|
# test: ["CMD", "curl", "--fail", "http://127.0.0.1:8000/api/live/"]
|
||||||
|
# interval: 1m
|
||||||
|
# timeout: 3s
|
||||||
|
# retries: 2
|
||||||
|
# start_period: 5s
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"packageManager": "pnpm@8.4.0",
|
"packageManager": "pnpm@8.6.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:docker": "docker-compose -f docker-compose.dev.yaml up redis",
|
"dev:docker": "docker-compose -f docker-compose.dev.yaml up redis",
|
||||||
"dev:packages": "pnpm --parallel run dev",
|
"dev:packages": "pnpm --parallel run dev",
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"docker:up": "docker compose -f docker-compose.dev.yaml up",
|
"docker:up": "docker compose -f docker-compose.dev.yaml up",
|
||||||
"docker:build": "docker compose -f docker-compose.dev.yaml build",
|
"docker:build": "docker compose -f docker-compose.dev.yaml build",
|
||||||
"test": "playwright test --project chrome firefox safari",
|
"test": "playwright test --project chrome firefox safari",
|
||||||
"test:local": "playwright test --project local",
|
"test:local": "playwright test --project chrome",
|
||||||
"test:server": "run-s docker:up",
|
"test:server": "run-s docker:up",
|
||||||
"test:prepare": "run-p build docker:build",
|
"test:prepare": "run-p build docker:build",
|
||||||
"build": "pnpm run --recursive --filter=!@cryptgeon/backend build"
|
"build": "pnpm run --recursive --filter=!@cryptgeon/backend build"
|
||||||
|
269
packages/backend/Cargo.lock
generated
269
packages/backend/Cargo.lock
generated
@@ -73,7 +73,7 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rand",
|
"rand",
|
||||||
"sha1 0.10.5",
|
"sha1",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
@@ -237,9 +237,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
|
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@@ -265,17 +265,6 @@ version = "0.10.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-trait"
|
|
||||||
version = "0.1.68"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.15",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@@ -295,9 +284,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.0"
|
version = "0.21.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
@@ -348,9 +337,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.12.2"
|
version = "3.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b"
|
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byte-unit"
|
name = "byte-unit"
|
||||||
@@ -421,9 +410,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.7"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
|
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -439,7 +428,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cryptgeon"
|
name = "cryptgeon"
|
||||||
version = "2.3.0-beta.4"
|
version = "2.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-files",
|
"actix-files",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
@@ -448,6 +437,7 @@ dependencies = [
|
|||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
"redis",
|
"redis",
|
||||||
"ring",
|
"ring",
|
||||||
@@ -480,9 +470,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.6"
|
version = "0.10.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
@@ -534,9 +524,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
@@ -583,9 +573,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.9"
|
version = "0.2.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
|
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -672,9 +662,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-bidi",
|
"unicode-bidi",
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
@@ -707,9 +697,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.62"
|
version = "0.3.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5"
|
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
@@ -728,9 +718,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.144"
|
version = "0.2.146"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "local-channel"
|
name = "local-channel"
|
||||||
@@ -752,9 +742,9 @@ checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.9"
|
version = "0.4.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
@@ -762,12 +752,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.17"
|
version = "0.4.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
@@ -802,14 +789,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.8.6"
|
version = "0.8.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys 0.45.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -854,9 +841,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.17.1"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
@@ -870,15 +857,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.9.7"
|
version = "0.9.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-sys 0.45.0",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -889,9 +876,9 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.2.0"
|
version = "2.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
@@ -919,18 +906,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.56"
|
version = "1.0.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.27"
|
version = "1.0.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
|
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -967,33 +954,32 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redis"
|
name = "redis"
|
||||||
version = "0.21.7"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "152f3863635cbb76b73bc247845781098302c6c9ad2060e1a9a7de56840346b6"
|
checksum = "3ea8c51b5dc1d8e5fd3350ec8167f464ec0995e79f2e90a075b63371500d557f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
|
||||||
"combine",
|
"combine",
|
||||||
"itoa",
|
"itoa",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"ryu",
|
"ryu",
|
||||||
"sha1 0.6.1",
|
"sha1_smol",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.16"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.8.1"
|
version = "1.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -1002,9 +988,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
@@ -1050,29 +1036,29 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.163"
|
version = "1.0.164"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
|
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.163"
|
version = "1.0.164"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
|
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.15",
|
"syn 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.96"
|
version = "1.0.97"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
@@ -1091,15 +1077,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sha1"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
|
|
||||||
dependencies = [
|
|
||||||
"sha1_smol",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
@@ -1170,9 +1147,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.15"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
|
checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1190,9 +1167,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.21"
|
version = "0.3.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
|
checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1232,9 +1209,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.28.1"
|
version = "1.28.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105"
|
checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -1244,7 +1221,7 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1305,9 +1282,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.8"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
@@ -1326,9 +1303,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.3.1"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
@@ -1355,9 +1332,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.85"
|
version = "0.2.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4"
|
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
@@ -1365,24 +1342,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.85"
|
version = "0.2.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822"
|
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.15",
|
"syn 2.0.18",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.85"
|
version = "0.2.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434"
|
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@@ -1390,28 +1367,28 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.85"
|
version = "0.2.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869"
|
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.15",
|
"syn 2.0.18",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.85"
|
version = "0.2.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb"
|
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.62"
|
version = "0.3.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721"
|
checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -1448,37 +1425,13 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.45.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.42.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.48.0",
|
"windows-targets",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.42.2",
|
|
||||||
"windows_aarch64_msvc 0.42.2",
|
|
||||||
"windows_i686_gnu 0.42.2",
|
|
||||||
"windows_i686_msvc 0.42.2",
|
|
||||||
"windows_x86_64_gnu 0.42.2",
|
|
||||||
"windows_x86_64_gnullvm 0.42.2",
|
|
||||||
"windows_x86_64_msvc 0.42.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1487,93 +1440,51 @@ version = "0.48.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm 0.48.0",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc 0.48.0",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu 0.48.0",
|
"windows_i686_gnu",
|
||||||
"windows_i686_msvc 0.48.0",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu 0.48.0",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_gnullvm 0.48.0",
|
"windows_x86_64_gnullvm",
|
||||||
"windows_x86_64_msvc 0.48.0",
|
"windows_x86_64_msvc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.42.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cryptgeon"
|
name = "cryptgeon"
|
||||||
version = "2.3.0-beta.4"
|
version = "2.3.1"
|
||||||
authors = ["cupcakearmy <hi@nicco.io>"]
|
authors = ["cupcakearmy <hi@nicco.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
@@ -8,11 +8,6 @@ edition = "2021"
|
|||||||
name = "cryptgeon"
|
name = "cryptgeon"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[registries.crates-io]
|
|
||||||
protocol = "sparse"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "4"
|
actix-web = "4"
|
||||||
actix-files = "0.6"
|
actix-files = "0.6"
|
||||||
@@ -25,4 +20,5 @@ byte-unit = "4"
|
|||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
env_logger = "0.9"
|
env_logger = "0.9"
|
||||||
redis = "0.21.5"
|
log = "0.4"
|
||||||
|
redis = "0.23"
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
|
|
||||||
|
use crate::health;
|
||||||
use crate::note;
|
use crate::note;
|
||||||
use crate::status;
|
use crate::status;
|
||||||
|
|
||||||
@@ -7,6 +8,7 @@ pub fn init(cfg: &mut web::ServiceConfig) {
|
|||||||
cfg.service(
|
cfg.service(
|
||||||
web::scope("/api")
|
web::scope("/api")
|
||||||
.service(note::init())
|
.service(note::init())
|
||||||
.service(status::init()),
|
.service(status::init())
|
||||||
|
.service(health::init()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,10 @@ lazy_static! {
|
|||||||
.unwrap_or("true".to_string())
|
.unwrap_or("true".to_string())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
pub static ref ID_LENGTH: u32 = std::env::var("ID_LENGTH")
|
||||||
|
.unwrap_or("32".to_string())
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// THEME
|
// THEME
|
||||||
|
3
packages/backend/src/health/mod.rs
Normal file
3
packages/backend/src/health/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod routes;
|
||||||
|
|
||||||
|
pub use routes::*;
|
16
packages/backend/src/health/routes.rs
Normal file
16
packages/backend/src/health/routes.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
use actix_web::{get, web, HttpResponse, Responder, Scope};
|
||||||
|
|
||||||
|
use crate::store;
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
async fn get_live() -> impl Responder {
|
||||||
|
if store::can_reach_redis() {
|
||||||
|
return HttpResponse::Ok();
|
||||||
|
} else {
|
||||||
|
return HttpResponse::ServiceUnavailable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() -> Scope {
|
||||||
|
web::scope("/live").service(get_live)
|
||||||
|
}
|
@@ -1,8 +1,10 @@
|
|||||||
use actix_web::{
|
use actix_web::{
|
||||||
middleware::{self, Logger},
|
middleware::{self, Logger},
|
||||||
web, App, HttpServer,
|
web::{self},
|
||||||
|
App, HttpServer,
|
||||||
};
|
};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
use log::error;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
@@ -10,6 +12,7 @@ extern crate lazy_static;
|
|||||||
mod api;
|
mod api;
|
||||||
mod client;
|
mod client;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod health;
|
||||||
mod note;
|
mod note;
|
||||||
mod size;
|
mod size;
|
||||||
mod status;
|
mod status;
|
||||||
@@ -20,6 +23,11 @@ async fn main() -> std::io::Result<()> {
|
|||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or(config::VERBOSITY.as_str()));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or(config::VERBOSITY.as_str()));
|
||||||
|
|
||||||
|
if !store::can_reach_redis() {
|
||||||
|
error!("cannot reach redis");
|
||||||
|
panic!("canont reach redis");
|
||||||
|
}
|
||||||
|
|
||||||
return HttpServer::new(|| {
|
return HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(Logger::new("\"%r\" %s %b %T"))
|
.wrap(Logger::new("\"%r\" %s %b %T"))
|
||||||
|
@@ -2,6 +2,8 @@ use bs62;
|
|||||||
use ring::rand::SecureRandom;
|
use ring::rand::SecureRandom;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
pub meta: String,
|
pub meta: String,
|
||||||
@@ -22,8 +24,13 @@ pub struct NotePublic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_id() -> String {
|
pub fn generate_id() -> String {
|
||||||
let mut id: [u8; 32] = [0; 32];
|
let mut result = "".to_owned();
|
||||||
|
let mut id: [u8; 1] = [0; 1];
|
||||||
let sr = ring::rand::SystemRandom::new();
|
let sr = ring::rand::SystemRandom::new();
|
||||||
let _ = sr.fill(&mut id);
|
|
||||||
return bs62::encode_data(&id);
|
for _ in 0..*config::ID_LENGTH {
|
||||||
|
let _ = sr.fill(&mut id);
|
||||||
|
result.push_str(&bs62::encode_data(&id));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,14 @@ fn get_connection() -> Result<redis::Connection, &'static str> {
|
|||||||
.map_err(|_| "Unable to connect to redis")
|
.map_err(|_| "Unable to connect to redis")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_reach_redis() -> bool {
|
||||||
|
let conn = get_connection();
|
||||||
|
return match conn {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(_) => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(id: &String, note: &Note) -> Result<(), &'static str> {
|
pub fn set(id: &String, note: &Note) -> Result<(), &'static str> {
|
||||||
let serialized = serde_json::to_string(¬e.clone()).unwrap();
|
let serialized = serde_json::to_string(¬e.clone()).unwrap();
|
||||||
let mut conn = get_connection()?;
|
let mut conn = get_connection()?;
|
||||||
|
54
packages/cli/README.md
Normal file
54
packages/cli/README.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Cryptgeon CLI
|
||||||
|
|
||||||
|
The CLI is a functionally identical way to interact with cryptgeon notes.
|
||||||
|
It supports text, files, expiration, password, etc.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx cryptgeon
|
||||||
|
|
||||||
|
# Or install globally
|
||||||
|
npm -g install cryptgeon
|
||||||
|
cryptgeon
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create simple note
|
||||||
|
cryptgeon send text "Foo bar"
|
||||||
|
|
||||||
|
# Send two files
|
||||||
|
cryptgeon send file my.pdf picture.png
|
||||||
|
|
||||||
|
# 3 views
|
||||||
|
cryptgeon send text "My message" --views 3
|
||||||
|
|
||||||
|
# 10 minutes
|
||||||
|
cryptgeon send text "My message" --minutes 10
|
||||||
|
|
||||||
|
# Custom password
|
||||||
|
cryptgeon send text "My message" --password "1337"
|
||||||
|
|
||||||
|
# Password from stdin
|
||||||
|
echo "1337" | cryptgeon send text "My message"
|
||||||
|
|
||||||
|
# Open a link
|
||||||
|
cryptgeon open https://cryptgeon.org/note/16gOIkxWjCxYNuXM8tCqMUzl...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
### Custom server
|
||||||
|
|
||||||
|
The default server is `cryptgeon.org`, however you can use any cryptgeon server by passing the `-s` or `--server` option, or by setting the `CRYPTGEON_SERVER` environment variable.
|
||||||
|
|
||||||
|
### Password
|
||||||
|
|
||||||
|
Optionally, just like in the web ui, you can choose to use a manual password. You can do that by passing the `-p` or `--password` options, or by piping it into stdin.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "my pw" | cryptgeon send text "my text"
|
||||||
|
cat pass.txt | cryptgeon send text "my text"
|
||||||
|
```
|
@@ -1,6 +1,12 @@
|
|||||||
{
|
{
|
||||||
"version": "2.3.0-beta.4",
|
"version": "2.3.1",
|
||||||
"name": "cryptgeon",
|
"name": "cryptgeon",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cupcakearmy/cryptgeon.git",
|
||||||
|
"directory": "packages/cli"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/cupcakearmy/cryptgeon",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
@@ -7,7 +7,7 @@ import pretty from 'pretty-bytes'
|
|||||||
|
|
||||||
import { exit } from './utils'
|
import { exit } from './utils'
|
||||||
|
|
||||||
export async function download(url: URL) {
|
export async function download(url: URL, all: boolean, suggestedPassword?: string) {
|
||||||
setBase(url.origin)
|
setBase(url.origin)
|
||||||
const id = url.pathname.split('/')[2]
|
const id = url.pathname.split('/')[2]
|
||||||
const preview = await info(id).catch(() => exit('Note does not exist or is expired'))
|
const preview = await info(id).catch(() => exit('Note does not exist or is expired'))
|
||||||
@@ -16,14 +16,18 @@ export async function download(url: URL) {
|
|||||||
let password: string
|
let password: string
|
||||||
const derivation = preview?.meta.derivation
|
const derivation = preview?.meta.derivation
|
||||||
if (derivation) {
|
if (derivation) {
|
||||||
const response = await inquirer.prompt([
|
if (suggestedPassword) {
|
||||||
{
|
password = suggestedPassword
|
||||||
type: 'password',
|
} else {
|
||||||
message: 'Note password',
|
const response = await inquirer.prompt([
|
||||||
name: 'password',
|
{
|
||||||
},
|
type: 'password',
|
||||||
])
|
message: 'Note password',
|
||||||
password = response.password
|
name: 'password',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
password = response.password
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
password = url.hash.slice(1)
|
password = url.hash.slice(1)
|
||||||
}
|
}
|
||||||
@@ -39,25 +43,29 @@ export async function download(url: URL) {
|
|||||||
exit('No files found in note')
|
exit('No files found in note')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { names } = await inquirer.prompt([
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
message: 'What files should be saved?',
|
|
||||||
name: 'names',
|
|
||||||
choices: files.map((file) => ({
|
|
||||||
value: file.name,
|
|
||||||
name: `${file.name} - ${file.type} - ${pretty(file.size, { binary: true })}`,
|
|
||||||
checked: true,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const selected = files.filter((file) => names.includes(file.name))
|
let selected: typeof files
|
||||||
|
if (all) {
|
||||||
|
selected = files
|
||||||
|
} else {
|
||||||
|
const { names } = await inquirer.prompt([
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
message: 'What files should be saved?',
|
||||||
|
name: 'names',
|
||||||
|
choices: files.map((file) => ({
|
||||||
|
value: file.name,
|
||||||
|
name: `${file.name} - ${file.type} - ${pretty(file.size, { binary: true })}`,
|
||||||
|
checked: true,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
selected = files.filter((file) => names.includes(file.name))
|
||||||
|
}
|
||||||
|
|
||||||
if (!selected.length) exit('No files selected')
|
if (!selected.length) exit('No files selected')
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (file) => {
|
selected.map(async (file) => {
|
||||||
let filename = resolve(file.name)
|
let filename = resolve(file.name)
|
||||||
try {
|
try {
|
||||||
// If exists -> prepend timestamp to not overwrite the current file
|
// If exists -> prepend timestamp to not overwrite the current file
|
||||||
@@ -68,6 +76,7 @@ export async function download(url: URL) {
|
|||||||
console.log(`Saved: ${basename(filename)}`)
|
console.log(`Saved: ${basename(filename)}`)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
break
|
break
|
||||||
case 'text':
|
case 'text':
|
||||||
const plaintext = await Adapters.Text.decrypt(note.contents, key).catch(couldNotDecrypt)
|
const plaintext = await Adapters.Text.decrypt(note.contents, key).catch(couldNotDecrypt)
|
||||||
|
@@ -15,6 +15,7 @@ const server = new Option('-s --server <url>', 'the cryptgeon server to use').de
|
|||||||
const files = new Argument('<file...>', 'Files to be sent').argParser(parseFile)
|
const files = new Argument('<file...>', 'Files to be sent').argParser(parseFile)
|
||||||
const text = new Argument('<text>', 'Text content of the note')
|
const text = new Argument('<text>', 'Text content of the note')
|
||||||
const password = new Option('-p --password <string>', 'manually set a password')
|
const password = new Option('-p --password <string>', 'manually set a password')
|
||||||
|
const all = new Option('-a --all', 'Save all files without prompt').default(false)
|
||||||
const url = new Argument('<url>', 'The url to open')
|
const url = new Argument('<url>', 'The url to open')
|
||||||
const views = new Option('-v --views <number>', 'Amount of views before getting destroyed').argParser(parseNumber)
|
const views = new Option('-v --views <number>', 'Amount of views before getting destroyed').argParser(parseNumber)
|
||||||
const minutes = new Option('-m --minutes <number>', 'Minutes before the note expires').argParser(parseNumber)
|
const minutes = new Option('-m --minutes <number>', 'Minutes before the note expires').argParser(parseNumber)
|
||||||
@@ -41,6 +42,7 @@ program.name('cryptgeon').version(version).configureHelp({ showGlobalOptions: tr
|
|||||||
|
|
||||||
program
|
program
|
||||||
.command('info')
|
.command('info')
|
||||||
|
.description('show information about the server')
|
||||||
.addOption(server)
|
.addOption(server)
|
||||||
.action(async (options) => {
|
.action(async (options) => {
|
||||||
setBase(options.server)
|
setBase(options.server)
|
||||||
@@ -55,7 +57,7 @@ program
|
|||||||
console.table(formatted)
|
console.table(formatted)
|
||||||
})
|
})
|
||||||
|
|
||||||
const send = program.command('send')
|
const send = program.command('send').description('send a note')
|
||||||
send
|
send
|
||||||
.command('file')
|
.command('file')
|
||||||
.addArgument(files)
|
.addArgument(files)
|
||||||
@@ -85,11 +87,15 @@ send
|
|||||||
|
|
||||||
program
|
program
|
||||||
.command('open')
|
.command('open')
|
||||||
|
.description('open a link with text or files inside')
|
||||||
.addArgument(url)
|
.addArgument(url)
|
||||||
|
.addOption(password)
|
||||||
|
.addOption(all)
|
||||||
.action(async (note, options) => {
|
.action(async (note, options) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(note)
|
const url = new URL(note)
|
||||||
await download(url)
|
options.password ||= await getStdin()
|
||||||
|
await download(url, options.all, options.password)
|
||||||
} catch {
|
} catch {
|
||||||
exit('Invalid URL')
|
exit('Invalid URL')
|
||||||
}
|
}
|
||||||
|
@@ -2,19 +2,23 @@ export function getStdin(timeout: number = 10): Promise<string> {
|
|||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
// Store the data from stdin in a buffer
|
// Store the data from stdin in a buffer
|
||||||
let buffer = ''
|
let buffer = ''
|
||||||
process.stdin.on('data', (d) => (buffer += d.toString()))
|
let t: NodeJS.Timeout
|
||||||
|
|
||||||
|
const dataHandler = (d: Buffer) => (buffer += d.toString())
|
||||||
|
const endHandler = () => {
|
||||||
|
clearTimeout(t)
|
||||||
|
resolve(buffer.trim())
|
||||||
|
}
|
||||||
|
|
||||||
// Stop listening for data after the timeout, otherwise hangs indefinitely
|
// Stop listening for data after the timeout, otherwise hangs indefinitely
|
||||||
const t = setTimeout(() => {
|
t = setTimeout(() => {
|
||||||
process.stdin.destroy()
|
process.stdin.removeListener('data', dataHandler)
|
||||||
|
process.stdin.removeListener('end', endHandler)
|
||||||
|
process.stdin.pause()
|
||||||
resolve('')
|
resolve('')
|
||||||
}, timeout)
|
}, timeout)
|
||||||
|
|
||||||
// Listen for end and error events
|
process.stdin.on('data', dataHandler)
|
||||||
process.stdin.on('end', () => {
|
process.stdin.on('end', endHandler)
|
||||||
clearTimeout(t)
|
|
||||||
resolve(buffer.trim())
|
|
||||||
})
|
|
||||||
process.stdin.on('error', reject)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -8,10 +8,11 @@
|
|||||||
|
|
||||||
export let note: Note
|
export let note: Note
|
||||||
export let timeExpiration = false
|
export let timeExpiration = false
|
||||||
|
export let customPassword: string | null = null
|
||||||
|
|
||||||
let customPassword = false
|
let hasCustomPassword = false
|
||||||
|
|
||||||
$: if (!customPassword) note.password = undefined
|
$: if (!hasCustomPassword) customPassword = null
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex col">
|
<div class="flex col">
|
||||||
@@ -47,12 +48,17 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<Switch bind:value={customPassword} label={$t('home.advanced.custom_password')} />
|
<Switch
|
||||||
|
data-testid="custom-password"
|
||||||
|
bind:value={hasCustomPassword}
|
||||||
|
label={$t('home.advanced.custom_password')}
|
||||||
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
|
data-testid="password"
|
||||||
type="password"
|
type="password"
|
||||||
bind:value={note.password}
|
bind:value={customPassword}
|
||||||
label={$t('common.password')}
|
label={$t('common.password')}
|
||||||
disabled={!customPassword}
|
disabled={!hasCustomPassword}
|
||||||
random
|
random
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
let advanced = false
|
let advanced = false
|
||||||
let isFile = false
|
let isFile = false
|
||||||
let timeExpiration = false
|
let timeExpiration = false
|
||||||
|
let customPassword: string | null = null
|
||||||
let description = ''
|
let description = ''
|
||||||
let loading: string | null = null
|
let loading: string | null = null
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
try {
|
try {
|
||||||
loading = $t('common.encrypting')
|
loading = $t('common.encrypting')
|
||||||
|
|
||||||
const derived = note.password && (await AES.derive(note.password))
|
const derived = customPassword && (await AES.derive(customPassword))
|
||||||
const key = derived ? derived[0] : await AES.generateKey()
|
const key = derived ? derived[0] : await AES.generateKey()
|
||||||
|
|
||||||
const data: Note = {
|
const data: Note = {
|
||||||
@@ -79,7 +80,7 @@
|
|||||||
const response = await create(data)
|
const response = await create(data)
|
||||||
result = {
|
result = {
|
||||||
id: response.id,
|
id: response.id,
|
||||||
password: note.password ? undefined : Hex.encode(key),
|
password: customPassword ? undefined : Hex.encode(key),
|
||||||
}
|
}
|
||||||
notify.success($t('home.messages.note_created'))
|
notify.success($t('home.messages.note_created'))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -150,7 +151,7 @@
|
|||||||
{#if advanced}
|
{#if advanced}
|
||||||
<div transition:blur={{ duration: 250 }}>
|
<div transition:blur={{ duration: 250 }}>
|
||||||
<hr />
|
<hr />
|
||||||
<AdvancedParameters bind:note bind:timeExpiration />
|
<AdvancedParameters bind:note bind:timeExpiration bind:customPassword />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@@ -75,6 +75,9 @@
|
|||||||
<style>
|
<style>
|
||||||
section {
|
section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
33
test/cli/file/simple.spec.ts
Normal file
33
test/cli/file/simple.spec.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { test } from '@playwright/test'
|
||||||
|
import { basename } from 'node:path'
|
||||||
|
import { Files, getFileChecksum, rm, tmpFile } from '../../files'
|
||||||
|
import { CLI, getLinkFromCLI } from '../../utils'
|
||||||
|
|
||||||
|
test.describe('file @cli', () => {
|
||||||
|
test('simple', async ({ page }) => {
|
||||||
|
const file = await tmpFile(Files.Image)
|
||||||
|
const checksum = await getFileChecksum(file)
|
||||||
|
const note = await CLI('send', 'file', file)
|
||||||
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
await rm(file)
|
||||||
|
|
||||||
|
await CLI('open', link, '--all')
|
||||||
|
const c = await getFileChecksum(basename(file))
|
||||||
|
await rm(basename(file))
|
||||||
|
test.expect(checksum).toBe(c)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('simple with password', async ({ page }) => {
|
||||||
|
const file = await tmpFile(Files.Image)
|
||||||
|
const password = 'password'
|
||||||
|
const checksum = await getFileChecksum(file)
|
||||||
|
const note = await CLI('send', 'file', file, '--password', password)
|
||||||
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
await rm(file)
|
||||||
|
|
||||||
|
await CLI('open', link, '--all', '--password', password)
|
||||||
|
const c = await getFileChecksum(basename(file))
|
||||||
|
await rm(basename(file))
|
||||||
|
test.expect(checksum).toBe(c)
|
||||||
|
})
|
||||||
|
})
|
@@ -1,13 +1,23 @@
|
|||||||
import { test } from '@playwright/test'
|
import { test } from '@playwright/test'
|
||||||
import { CLI } from '../../utils'
|
import { CLI, getLinkFromCLI } from '../../utils'
|
||||||
|
|
||||||
test.describe('text @cli', () => {
|
test.describe('text @cli', () => {
|
||||||
test('simple', async ({ page }) => {
|
test('simple', async ({ page }) => {
|
||||||
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
||||||
const note = await CLI('send', 'text', text)
|
const note = await CLI('send', 'text', text)
|
||||||
const link = note.stdout.trim().replace(/(.|\s)*http/g, 'http')
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
|
||||||
const retrieved = await CLI('open', link)
|
const retrieved = await CLI('open', link)
|
||||||
test.expect(retrieved.stdout.trim()).toBe(text)
|
test.expect(retrieved.stdout.trim()).toBe(text)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('simple with password', async ({ page }) => {
|
||||||
|
const text = `Endless prejudice endless play derive joy eternal-return selfish burying.`
|
||||||
|
const password = 'password'
|
||||||
|
const note = await CLI('send', 'text', text, '--password', password)
|
||||||
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
|
||||||
|
const retrieved = await CLI('open', link, '--password', password)
|
||||||
|
test.expect(retrieved.stdout.trim()).toBe(text)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
53
test/cross/file/simple.spec.ts
Normal file
53
test/cross/file/simple.spec.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { test } from '@playwright/test'
|
||||||
|
import { CLI, checkLinkForDownload, checkLinkForText, createNote, getLinkFromCLI } from '../../utils'
|
||||||
|
import { Files, getFileChecksum, rm, tmpFile } from '../../files'
|
||||||
|
import { basename } from 'path'
|
||||||
|
|
||||||
|
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
||||||
|
const password = 'password'
|
||||||
|
|
||||||
|
test.describe('text @cross', () => {
|
||||||
|
test('cli to web', async ({ page }) => {
|
||||||
|
const file = await tmpFile(Files.Image)
|
||||||
|
const checksum = await getFileChecksum(file)
|
||||||
|
const note = await CLI('send', 'file', file)
|
||||||
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
await rm(file)
|
||||||
|
|
||||||
|
await checkLinkForDownload(page, { link, text: basename(file), checksum })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('cli to web with password', async ({ page }) => {
|
||||||
|
const file = await tmpFile(Files.Image)
|
||||||
|
const checksum = await getFileChecksum(file)
|
||||||
|
const note = await CLI('send', 'file', file, '--password', password)
|
||||||
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
await rm(file)
|
||||||
|
|
||||||
|
await checkLinkForDownload(page, { link, text: basename(file), checksum, password })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('web to cli', async ({ page }) => {
|
||||||
|
const files = [Files.Image]
|
||||||
|
const checksum = await getFileChecksum(files[0])
|
||||||
|
const link = await createNote(page, { files })
|
||||||
|
|
||||||
|
const filename = basename(files[0])
|
||||||
|
await CLI('open', link, '--all')
|
||||||
|
const c = await getFileChecksum(filename)
|
||||||
|
await rm(basename(filename))
|
||||||
|
test.expect(checksum).toBe(c)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('web to cli with password', async ({ page }) => {
|
||||||
|
const files = [Files.Image]
|
||||||
|
const checksum = await getFileChecksum(files[0])
|
||||||
|
const link = await createNote(page, { files, password })
|
||||||
|
|
||||||
|
const filename = basename(files[0])
|
||||||
|
await CLI('open', link, '--all', '--password', password)
|
||||||
|
const c = await getFileChecksum(filename)
|
||||||
|
await rm(basename(filename))
|
||||||
|
test.expect(checksum).toBe(c)
|
||||||
|
})
|
||||||
|
})
|
@@ -1,14 +1,15 @@
|
|||||||
import { test } from '@playwright/test'
|
import { test } from '@playwright/test'
|
||||||
import { CLI, checkLinkForText, createNote } from '../../utils'
|
import { CLI, checkLinkForText, createNote, getLinkFromCLI } from '../../utils'
|
||||||
|
|
||||||
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
||||||
|
const password = 'password'
|
||||||
|
|
||||||
test.describe('text @cross', () => {
|
test.describe('text @cross', () => {
|
||||||
test('cli to web', async ({ page }) => {
|
test('cli to web', async ({ page }) => {
|
||||||
const note = await CLI('send', 'text', text)
|
const note = await CLI('send', 'text', text)
|
||||||
const link = note.stdout.trim().replace(/(.|\s)*http/g, 'http')
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
|
||||||
await checkLinkForText(page, link, text)
|
await checkLinkForText(page, { link, text })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('web to cli', async ({ page }) => {
|
test('web to cli', async ({ page }) => {
|
||||||
@@ -16,4 +17,16 @@ test.describe('text @cross', () => {
|
|||||||
const retrieved = await CLI('open', link)
|
const retrieved = await CLI('open', link)
|
||||||
test.expect(retrieved.stdout.trim()).toBe(text)
|
test.expect(retrieved.stdout.trim()).toBe(text)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('cli to web with password', async ({ page }) => {
|
||||||
|
const note = await CLI('send', 'text', text, '--password', password)
|
||||||
|
const link = getLinkFromCLI(note.stdout)
|
||||||
|
await checkLinkForText(page, { link, text, password })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('web to cli with password', async ({ page }) => {
|
||||||
|
const link = await createNote(page, { text, password })
|
||||||
|
const retrieved = await CLI('open', link, '--password', password)
|
||||||
|
test.expect(retrieved.stdout.trim()).toBe(text)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
25
test/files.ts
Normal file
25
test/files.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { createHash } from 'crypto'
|
||||||
|
import { cp as cpFN, rm as rmFN } from 'fs'
|
||||||
|
import { readFile } from 'fs/promises'
|
||||||
|
import { promisify } from 'util'
|
||||||
|
|
||||||
|
export const cp = promisify(cpFN)
|
||||||
|
export const rm = promisify(rmFN)
|
||||||
|
|
||||||
|
export const Files = {
|
||||||
|
PDF: 'test/assets/AES.pdf',
|
||||||
|
Image: 'test/assets/image.jpg',
|
||||||
|
Zip: 'test/assets/Pigeons.zip',
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getFileChecksum(file: string) {
|
||||||
|
const buffer = await readFile(file)
|
||||||
|
const hash = createHash('sha3-256').update(buffer).digest('hex')
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function tmpFile(file: string) {
|
||||||
|
const name = `./tmp/${Math.random().toString(36).substring(7)}`
|
||||||
|
await cp(file, name)
|
||||||
|
return name
|
||||||
|
}
|
@@ -1,19 +1,25 @@
|
|||||||
import { expect, type Page } from '@playwright/test'
|
import { expect, type Page } from '@playwright/test'
|
||||||
import { createHash } from 'crypto'
|
|
||||||
import { readFile } from 'fs/promises'
|
|
||||||
import { execFile } from 'node:child_process'
|
import { execFile } from 'node:child_process'
|
||||||
import { promisify } from 'node:util'
|
import { promisify } from 'node:util'
|
||||||
|
import { getFileChecksum } from './files'
|
||||||
|
|
||||||
const exec = promisify(execFile)
|
const exec = promisify(execFile)
|
||||||
|
|
||||||
type CreatePage = { text?: string; files?: string[]; views?: number; expiration?: number; error?: string }
|
type CreatePage = {
|
||||||
|
text?: string
|
||||||
|
files?: string[]
|
||||||
|
views?: number
|
||||||
|
expiration?: number
|
||||||
|
error?: string
|
||||||
|
password?: string
|
||||||
|
}
|
||||||
export async function createNote(page: Page, options: CreatePage): Promise<string> {
|
export async function createNote(page: Page, options: CreatePage): Promise<string> {
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
|
|
||||||
if (options.text) {
|
if (options.text) {
|
||||||
await page.locator('[data-testid="text-field"]').fill(options.text)
|
await page.getByTestId('text-field').fill(options.text)
|
||||||
} else if (options.files) {
|
} else if (options.files) {
|
||||||
await page.locator('[data-testid="switch-file"]').click()
|
await page.getByTestId('switch-file').click()
|
||||||
|
|
||||||
const [fileChooser] = await Promise.all([
|
const [fileChooser] = await Promise.all([
|
||||||
page.waitForEvent('filechooser'),
|
page.waitForEvent('filechooser'),
|
||||||
@@ -22,13 +28,16 @@ export async function createNote(page: Page, options: CreatePage): Promise<strin
|
|||||||
await fileChooser.setFiles(options.files)
|
await fileChooser.setFiles(options.files)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.views || options.expiration || options.password) await page.getByTestId('switch-advanced').click()
|
||||||
if (options.views) {
|
if (options.views) {
|
||||||
await page.locator('[data-testid="switch-advanced"]').click()
|
await page.getByTestId('field-views').fill(options.views.toString())
|
||||||
await page.locator('[data-testid="field-views"]').fill(options.views.toString())
|
|
||||||
} else if (options.expiration) {
|
} else if (options.expiration) {
|
||||||
await page.locator('[data-testid="switch-advanced"]').click()
|
await page.getByTestId('switch-advanced-toggle').click()
|
||||||
await page.locator('[data-testid="switch-advanced-toggle"]').click()
|
await page.getByTestId('field-expiration').fill(options.expiration.toString())
|
||||||
await page.locator('[data-testid="field-expiration"]').fill(options.expiration.toString())
|
}
|
||||||
|
if (options.password) {
|
||||||
|
await page.getByTestId('custom-password').click()
|
||||||
|
await page.getByTestId('password').fill(options.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.locator('button:has-text("create")').click()
|
await page.locator('button:has-text("create")').click()
|
||||||
@@ -37,29 +46,39 @@ export async function createNote(page: Page, options: CreatePage): Promise<strin
|
|||||||
await expect(page.locator('.error-text')).toContainText(options.error, { timeout: 60_000 })
|
await expect(page.locator('.error-text')).toContainText(options.error, { timeout: 60_000 })
|
||||||
}
|
}
|
||||||
|
|
||||||
const shareLink = await page.locator('[data-testid="share-link"]').inputValue()
|
// Return share link
|
||||||
return shareLink
|
return await page.getByTestId('share-link').inputValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkLinkForDownload(page: Page, link: string, text: string, checksum: string) {
|
type CheckLinkBase = {
|
||||||
|
link: string
|
||||||
|
text: string
|
||||||
|
password?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkLinkForDownload(page: Page, options: CheckLinkBase & { checksum: string }) {
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
await page.goto(link)
|
await page.goto(options.link)
|
||||||
await page.locator('[data-testid="show-note-button"]').click()
|
if (options.password) await page.getByTestId('show-note-password').fill(options.password)
|
||||||
|
await page.getByTestId('show-note-button').click()
|
||||||
|
|
||||||
const [download] = await Promise.all([
|
const [download] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.locator(`[data-testid="result"] >> text=${text}`).click(),
|
page.getByTestId(`result`).locator(`text=${options.text}`).click(),
|
||||||
])
|
])
|
||||||
const path = await download.path()
|
const path = await download.path()
|
||||||
if (!path) throw new Error('Download failed')
|
if (!path) throw new Error('Download failed')
|
||||||
const cs = await getFileChecksum(path)
|
const cs = await getFileChecksum(path)
|
||||||
await expect(cs).toBe(checksum)
|
await expect(cs).toBe(options.checksum)
|
||||||
}
|
}
|
||||||
export async function checkLinkForText(page: Page, link: string, text: string) {
|
|
||||||
|
export async function checkLinkForText(page: Page, options: CheckLinkBase) {
|
||||||
await page.goto('/')
|
await page.goto('/')
|
||||||
await page.goto(link)
|
await page.goto(options.link)
|
||||||
await page.locator('[data-testid="show-note-button"]').click()
|
if (options.password) await page.getByTestId('show-note-password').fill(options.password)
|
||||||
await expect(await page.locator('[data-testid="result"] >> .note').innerText()).toContain(text)
|
await page.getByTestId('show-note-button').click()
|
||||||
|
const text = await page.getByTestId('result').locator('.note').innerText()
|
||||||
|
await expect(text).toContain(options.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkLinkDoesNotExist(page: Page, link: string) {
|
export async function checkLinkDoesNotExist(page: Page, link: string) {
|
||||||
@@ -68,12 +87,6 @@ export async function checkLinkDoesNotExist(page: Page, link: string) {
|
|||||||
await expect(page.locator('main')).toContainText('note was not found or was already deleted')
|
await expect(page.locator('main')).toContainText('note was not found or was already deleted')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getFileChecksum(file: string) {
|
|
||||||
const buffer = await readFile(file)
|
|
||||||
const hash = createHash('sha3-256').update(buffer).digest('hex')
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function CLI(...args: string[]) {
|
export async function CLI(...args: string[]) {
|
||||||
return await exec('./packages/cli/dist/index.cjs', args, {
|
return await exec('./packages/cli/dist/index.cjs', args, {
|
||||||
env: {
|
env: {
|
||||||
@@ -82,3 +95,9 @@ export async function CLI(...args: string[]) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLinkFromCLI(output: string): string {
|
||||||
|
const match = output.match(/(https?:\/\/[^\s]+)/)
|
||||||
|
if (!match) throw new Error('No link found in CLI output')
|
||||||
|
return match[0]
|
||||||
|
}
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
export default {
|
|
||||||
PDF: 'test/assets/AES.pdf',
|
|
||||||
Image: 'test/assets/image.jpg',
|
|
||||||
Zip: 'test/assets/Pigeons.zip',
|
|
||||||
}
|
|
@@ -1,13 +1,13 @@
|
|||||||
import { test } from '@playwright/test'
|
import { test } from '@playwright/test'
|
||||||
import { checkLinkForDownload, createNote, getFileChecksum } from '../../utils'
|
import { Files, getFileChecksum } from '../../files'
|
||||||
import Files from './files'
|
import { checkLinkForDownload, createNote } from '../../utils'
|
||||||
|
|
||||||
test.describe('@web', () => {
|
test.describe('@web', () => {
|
||||||
test('multiple', async ({ page }) => {
|
test('multiple', async ({ page }) => {
|
||||||
const files = [Files.PDF, Files.Image]
|
const files = [Files.PDF, Files.Image]
|
||||||
const checksums = await Promise.all(files.map(getFileChecksum))
|
const checksums = await Promise.all(files.map(getFileChecksum))
|
||||||
const link = await createNote(page, { files, views: 2 })
|
const link = await createNote(page, { files, views: 2 })
|
||||||
await checkLinkForDownload(page, link, 'image.jpg', checksums[1])
|
await checkLinkForDownload(page, { link, text: 'image.jpg', checksum: checksums[1] })
|
||||||
await checkLinkForDownload(page, link, 'AES.pdf', checksums[0])
|
await checkLinkForDownload(page, { link, text: 'AES.pdf', checksum: checksums[0] })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
import { test } from '@playwright/test'
|
import { test } from '@playwright/test'
|
||||||
import { checkLinkDoesNotExist, checkLinkForDownload, checkLinkForText, createNote, getFileChecksum } from '../../utils'
|
import { Files, getFileChecksum } from '../../files'
|
||||||
import Files from './files'
|
import { checkLinkDoesNotExist, checkLinkForDownload, checkLinkForText, createNote } from '../../utils'
|
||||||
|
|
||||||
test.describe('@web', () => {
|
test.describe('@web', () => {
|
||||||
test('simple pdf', async ({ page }) => {
|
test('simple pdf', async ({ page }) => {
|
||||||
const files = [Files.PDF]
|
const files = [Files.PDF]
|
||||||
const link = await createNote(page, { files })
|
const link = await createNote(page, { files })
|
||||||
await checkLinkForText(page, link, 'AES.pdf')
|
await checkLinkForText(page, { link, text: 'AES.pdf' })
|
||||||
await checkLinkDoesNotExist(page, link)
|
await checkLinkDoesNotExist(page, link)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -14,13 +14,21 @@ test.describe('@web', () => {
|
|||||||
const files = [Files.PDF]
|
const files = [Files.PDF]
|
||||||
const checksum = await getFileChecksum(files[0])
|
const checksum = await getFileChecksum(files[0])
|
||||||
const link = await createNote(page, { files })
|
const link = await createNote(page, { files })
|
||||||
await checkLinkForDownload(page, link, 'AES.pdf', checksum)
|
await checkLinkForDownload(page, { link, text: 'AES.pdf', checksum })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('image content', async ({ page }) => {
|
test('image content', async ({ page }) => {
|
||||||
const files = [Files.Image]
|
const files = [Files.Image]
|
||||||
const checksum = await getFileChecksum(files[0])
|
const checksum = await getFileChecksum(files[0])
|
||||||
const link = await createNote(page, { files })
|
const link = await createNote(page, { files })
|
||||||
await checkLinkForDownload(page, link, 'image.jpg', checksum)
|
await checkLinkForDownload(page, { link, text: 'image.jpg', checksum })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('simple pdf with password', async ({ page }) => {
|
||||||
|
const files = [Files.PDF]
|
||||||
|
const password = 'password'
|
||||||
|
const link = await createNote(page, { files, password })
|
||||||
|
await checkLinkForText(page, { link, text: 'AES.pdf', password })
|
||||||
|
await checkLinkDoesNotExist(page, link)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { test } from '@playwright/test'
|
import { test } from '@playwright/test'
|
||||||
import { createNote } from '../../utils'
|
import { createNote } from '../../utils'
|
||||||
import Files from './files'
|
import { Files } from '../../files'
|
||||||
|
|
||||||
test.describe('@web', () => {
|
test.describe('@web', () => {
|
||||||
test.skip('to big zip', async ({ page }) => {
|
test.skip('to big zip', async ({ page }) => {
|
||||||
|
@@ -7,10 +7,10 @@ test.describe('@web', () => {
|
|||||||
const minutes = 1
|
const minutes = 1
|
||||||
const timeout = minutes * 60_000
|
const timeout = minutes * 60_000
|
||||||
test.setTimeout(timeout * 2)
|
test.setTimeout(timeout * 2)
|
||||||
const shareLink = await createNote(page, { text, expiration: minutes })
|
const link = await createNote(page, { text, expiration: minutes })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
await page.waitForTimeout(timeout)
|
await page.waitForTimeout(timeout)
|
||||||
await checkLinkDoesNotExist(page, shareLink)
|
await checkLinkDoesNotExist(page, link)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@@ -3,8 +3,15 @@ import { checkLinkForText, createNote } from '../../utils'
|
|||||||
|
|
||||||
test.describe('@web', () => {
|
test.describe('@web', () => {
|
||||||
test('simple', async ({ page }) => {
|
test('simple', async ({ page }) => {
|
||||||
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of decieve play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
const text = `Endless prejudice endless play derive joy eternal-return selfish burying. Of deceive play pinnacle faith disgust. Spirit reason salvation burying strong of joy ascetic selfish against merciful sea truth. Ubermensch moral prejudice derive chaos mountains ubermensch justice philosophy justice ultimate joy ultimate transvaluation. Virtues convictions war ascetic eternal-return spirit. Ubermensch transvaluation noble revaluation sexuality intentions salvation endless decrepit hope noble fearful. Justice ideal ultimate snare god joy evil sexuality insofar gains oneself ideal.`
|
||||||
const shareLink = await createNote(page, { text })
|
const link = await createNote(page, { text })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('simple with password', async ({ page }) => {
|
||||||
|
const text = 'Foo bar'
|
||||||
|
const password = '123'
|
||||||
|
const shareLink = await createNote(page, { text, password })
|
||||||
|
await checkLinkForText(page, { link: shareLink, text, password })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@@ -4,17 +4,17 @@ import { checkLinkDoesNotExist, checkLinkForText, createNote } from '../../utils
|
|||||||
test.describe('@web', () => {
|
test.describe('@web', () => {
|
||||||
test('only shown once', async ({ page }) => {
|
test('only shown once', async ({ page }) => {
|
||||||
const text = `Christian victorious reason suicide dead. Right ultimate gains god hope truth burying selfish society joy. Ultimate.`
|
const text = `Christian victorious reason suicide dead. Right ultimate gains god hope truth burying selfish society joy. Ultimate.`
|
||||||
const shareLink = await createNote(page, { text })
|
const link = await createNote(page, { text })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
await checkLinkDoesNotExist(page, shareLink)
|
await checkLinkDoesNotExist(page, link)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('view 3 times', async ({ page }) => {
|
test('view 3 times', async ({ page }) => {
|
||||||
const text = `Justice holiest overcome fearful strong ultimate holiest christianity.`
|
const text = `Justice holiest overcome fearful strong ultimate holiest christianity.`
|
||||||
const shareLink = await createNote(page, { text, views: 3 })
|
const link = await createNote(page, { text, views: 3 })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
await checkLinkForText(page, shareLink, text)
|
await checkLinkForText(page, { link, text })
|
||||||
await checkLinkDoesNotExist(page, shareLink)
|
await checkLinkDoesNotExist(page, link)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user