Home

Awesome

favicon-3 OTS-Share (One-Time Secret Share)

A self-hosting app to share secrets only one-time.

Content

Features

How to run

With the default database

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

Without the default database

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:root@host.docker.internal:3306/ots_share

make start-no-db

OR

Change the modify the DB_URL variable under ots-share-run-no-db service in docker-compose.yml, and then run

make start-no-db

Access UI

After that, the application is accessible via http://localhost:8282

Request and Response

Request

Create record request body

A sample request body is as follows.

{
  "content": "U2FsdGVkX1+XUedzb2748LeKmf9UpN9hVWjBDUwJfXs=",
  "expireIn": {
    "value": 10,
    "unit": "minutes"
  }
}
Propertytypeis requiredpurpose
contentstringyesEncrypted content
expireInobjectyesExpiration configurations
expireIn.valuenumberyesnumerical value of expiration. E,g 1, 2
expireIn.unitenum ('days', 'hours')yesUnit 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'

Response

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"
}
Propertytypeis requiredpurpose
idstringyesPrimary key of the record
slugstringyesFor future use (Primary key of the record)
contentstringyesEncrypted content
expiarystring (Date)yesExpiration date and time
statusenum ('avaiable', 'unavaiable')yesFor future use.
created_atstring (Date)yesRecord created date

How to use

(Please don't lose the generated URL. There is no way to retrieve the content or regenerate the URL !!!)

For text

  1. Visit the landing page and select Text from top menu.
  2. Add your secret content to the Secret content text box.

text-1

  1. Click the Create Button.
  2. Copy the URL in the text box. (Click the Copy Icon). Screenshot (2)
  1. Send the copied URL to the other party via a secure channel.

For files

  1. Visit the landing page and select File from top menu.
  2. Click on the "Drag 'n' drop" area or drag and drop a file.
  1. Upload a file. file-2

  2. Click the Create Button.

  3. Copy the URL in the text box. (Click the Copy Icon). file-3

  1. Send the copied URL to the other party via a secure channel.

View secret content in the shared link.

  1. Visit the shared link using a browser.
  2. You will see the following screen. Screenshot (3)
  3. Click Fetch Content.

For text

  1. You'll see the following screen. Screenshot (4)

  2. Click the "Click there to view the content".

  3. You will see the content as follows. Screenshot (5)

For files

  1. You'll see the following screen. file-4

  2. Click the "Click here to download the file" button to download the file.

Errors.

In case of an error, the following screen will appear.Screenshot (6)

CLI usage

<details> <summary>Sample CLI to use encryption</summary>
#!/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)"
</details> <details> <summary>Output encryption</summary>
!!! Keep these safe !!!
-----------------------------------
Record id: b2nC422huavXfMs2DWZ2Z9
Password: pass-key
-----------------------------------
(This record will expires in: 10 minutes)
</details> <details> <summary>Sample CLI to use Decryption</summary>
#!/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 "-----------------------------------"
</details> <details> <summary>Output decryption</summary>
-----------------------------------
Content: test string to encrypt
-----------------------------------
</details>

Change configurations

All the configurations are mentioned in the docker-compose.yml under or ots-share-run-no-db service.

Change database server.

Change the default server port.

Change the purge process interval.

Tech stack

Using with deploy tools

With https://www.portainer.io/

Format of the generated URL

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.

Road map

Todo