A self-hosting app to share secrets only one-time.
- Features
- How to run
- Request and response
- How to use
- CLI usage
- Change configurations
- Tech stack
- Using with deploy tools
- Format of the generated URL
- Road map
- Todo
- Support both texts and small files (maximum
1MB). - Creates shareable links which valid for a maximum of 24 hours.
- The contents are encrypted with
AESinCBCmode, with a256-bitkey. (Using Crypto-js) - Passwords are NOT sent to the backend server.
- The app periodically deletes encrypted content after it expires, and the encrypted content gets deleted once the web UI fetches it.
- CLI support.
- Multiple database connectivity support.
MongoPostgresMySQL
This application is entirely run in Docker and comes with Mongo 4.2 image. (view the docker-compose.yml for further reference.)
To execute this app, simply run following command.
make start
This application can connect to a external database.
(Currently support Postgres and Mysql).
To execute this app, simply run following command.
# Set the connection string to your database.
export DB_URL=mysql://root:[email protected]:3306/ots_share
make start-no-dbOR
Change the modify the DB_URL variable under ots-share-run-no-db service in docker-compose.yml,
and then run
make start-no-dbAfter that, the application is accessible via http://localhost:8282
A sample request body is as follows.
{
"content": "U2FsdGVkX1+XUedzb2748LeKmf9UpN9hVWjBDUwJfXs=",
"expireIn": {
"value": 10,
"unit": "minutes"
}
}| Property | type | is required | purpose |
|---|---|---|---|
content |
string |
yes | Encrypted content |
expireIn |
object |
yes | Expiration configurations |
expireIn.value |
number |
yes | numerical value of expiration. E,g 1, 2 |
expireIn.unit |
enum ('days', 'hours') |
yes | Unit of expiration. |
curl 'http://localhost:8282/api/record' -H 'Content-Type: application/json' \
--data-raw \
'{
"content" : "U2FsdGVkX1+bozD8VjexiUeHJ3BfdxrXCmRyai8V0hY=",
"expireIn": {
"value": 1,
"unit": "minutes"
}
}'
--compressed
curl 'http://localhost:8282/api/record/b2nC422huavXfMs2DWZ2Z9' -H 'Content-Type: application/json'A sample record body is as follows.
{
"id": "iN2jS3y1pstio7JVXs1zLF",
"slug": "iN2jS3y1pstio7JVXs1zLF",
"content": "U2FsdGVkX1+XUedzb2748LeKmf9UpN9hVWjBDUwJfXs=",
"expiary": "2023-02-12T14:55:41.510Z",
"status": "avaiable",
"created_at": "2023-02-12T14:45:41.521Z"
}| Property | type | is required | purpose |
|---|---|---|---|
id |
string |
yes | Primary key of the record |
slug |
string |
yes | For future use (Primary key of the record) |
content |
string |
yes | Encrypted content |
expiary |
string (Date) |
yes | Expiration date and time |
status |
enum ('avaiable', 'unavaiable') |
yes | For future use. |
created_at |
string (Date) |
yes | Record created date |
(Please don't lose the generated URL. There is no way to retrieve the content or regenerate the URL !!!)
- Visit the landing page and select
Textfrom top menu. - Add your secret content to the
Secret contenttext box.
- (Please don't lose the generated URL. There is no way to retrieve the content or regenerate the URL !!!)
- Send the copied URL to the other party via a secure channel.
- Visit the landing page and select
Filefrom top menu. - Click on the
"Drag 'n' drop"area or drag and drop a file.
- (Please don't lose the generated URL. There is no way to retrieve the content or regenerate the URL !!!)
- Send the copied URL to the other party via a secure channel.
-
Click the
"Click there to view the content".
-
Click the
"Click here to download the file"button to download the file.
In case of an error, the following screen will appear.
-
Support only for
texts. -
You can use the
CLIto utilizeAPIs. -
Encryption using CLI
Sample CLI to use encryption
#!/bin/bash
# Configs
PASSWORD="pass-key"
OTS_SHARE_DOMIN="http://host.docker.internal:8282"
OTS_SHARE_API="$OTS_SHARE_DOMIN/api/record"
OPENSSL_PARAMETERS_PASSWORD="-pass pass:$PASSWORD"
OPENSSL_PARAMETERS_ALGORITHM="-base64 -aes-256-cbc -pbkdf2"
text_to_encrypt="test string to encrypt"
################
## Encryption ##
################
# Record expiration value. A numerical value
RECORD_EXPIRATION_VALUE=10
# Record expiration unit. It can be "minutes" or "hours"
RECORD_EXPIRATION_UNIT="minutes"
# 1. Generate encrypted string
encrypted_content=$(echo $text_to_encrypt | openssl enc -e $OPENSSL_PARAMETERS_ALGORITHM $OPENSSL_PARAMETERS_PASSWORD)
# 2. Make API call OTS-Share and retrieve the Id
# We need this id for encryption
record_id=$(\
curl -s "$OTS_SHARE_API" \
-H 'Content-Type: application/json' \
--data-raw \
'{ "content" : "'$encrypted_content'", "expireIn": { "value": '$RECORD_EXPIRATION_VALUE', "unit": "'$RECORD_EXPIRATION_UNIT'" }}' \
--compressed \
| jq '.id' \
| tr -d '"' \
)
#### Encryption results
echo "!!! Keep these safe !!!"
echo "-----------------------------------"
echo "Record id: $record_id"
echo "Password: $PASSWORD"
echo "-----------------------------------"
echo "(This record will expires in: $RECORD_EXPIRATION_VALUE $RECORD_EXPIRATION_UNIT)"Output encryption
!!! Keep these safe !!!
-----------------------------------
Record id: b2nC422huavXfMs2DWZ2Z9
Password: pass-key
-----------------------------------
(This record will expires in: 10 minutes)- Decryption using CLI
Sample CLI to use Decryption
#!/bin/bash
# Configs
PASSWORD="pass-key"
OTS_SHARE_DOMIN="http://host.docker.internal:8282"
OTS_SHARE_API="$OTS_SHARE_DOMIN/api/record"
OPENSSL_PARAMETERS_PASSWORD="-pass pass:$PASSWORD"
OPENSSL_PARAMETERS_ALGORITHM="-base64 -aes-256-cbc -pbkdf2"
$record_id="b2nC422huavXfMs2DWZ2Z9" # ID from previous encryption operation
################
## DECRYPTION ##
################
# 1. Fetch content
content=$(\
curl "$OTS_SHARE_API/$record_id" \
-s -H 'Content-Type: application/json' \
--compressed \
| jq '.content' \
| tr -d '"' \
)
# 2. Decrypt
decrypted_content=$(echo $content | openssl enc -d $OPENSSL_PARAMETERS_ALGORITHM $OPENSSL_PARAMETERS_PASSWORD)
echo "-----------------------------------"
echo "Content: $decrypted_content"
echo "-----------------------------------"Output decryption
-----------------------------------
Content: test string to encrypt
-----------------------------------All the configurations are mentioned in the docker-compose.yml under or ots-share-run-no-db service.
- Change default port to access the application are available in
docker-compose.ymlunderots-share-runorots-share-run-no-dbservice. - You can modify the
mongo-localservice indocker-compose.ymlto keep the data persistent.
-
Please change the
DEV_PORTvariable thedocker-compose.ymlunderots-share-runorots-share-run-no-dbservice. -
Please change the
DEV_PORTvariable thedocker-compose.ymlunderots-share-run-no-dbservice to connect to external database. -
DB_URLmust be a connection string.- The app parse the
DB_URLas anURLand use theprotocolto identify thedatabasedriver. - sample connection strings:
mongodb://mongo-local/ots-share- forMongopostgres://db:[email protected]:5432/ots_share- forPostgresmysql://root:[email protected]:3306/ots_share- forMySQL
- The app parse the
- Please change
SERVER_PORTvariable in the indocker-compose.ymlunderots-share-runorots-share-run-no-dbservice.
- Default value is 1 minute.
- Please set
PURGE_TRIGGER_INTERVALvariable in the indocker-compose.ymlunderots-share-runorots-share-run-no-dbservice. - The
PURGE_TRIGGER_INTERVALvalue must be inmilliseconds.
-
UI:
- React
- Material UI
-
Server:
- Typescript
- Node
- Express
-
DB support:
MongoDB- (default DB)PostgresMySQL
The URL format, which required sending to the other party, is as follows. The id received from the backend API gets concatenated with the password. After that, the contaminated string gets encoded into Base 58.
The format is as follows.
<hosted-domain>/r/Base58Encoded(id-from-api : password : type : file-name)- Possible values for
typeis'text'or'file'. typeandfile-nameis optional.typeis default totextif not mentioned.file-nameis available for file.- It supports
Base 64encoding.
- A Chrome extension
- A Slack app
- Add
Contributioninstructions. - Learn more ReactJs. π
- Fix any bugs. π