.github/workflows | ||
.mvn/wrapper | ||
src | ||
.gitignore | ||
docker-compose.yml | ||
Dockerfile | ||
LICENSE | ||
mvnw | ||
mvnw.cmd | ||
pom.xml | ||
README.md |
Bit ![](https://github.com/ceticamarco/bit/actions/workflows/bit.yml/badge.svg)
Bit is a simple, web-based, self-hostable text sharing platform written in Java and Spring. You can access it from here.
The frontend is also open-source and it's available on this page.
General
Bit can be used both from the frontend and through the REST API. Before using it, read the following technical notices:
-
By default, each new "text"(from now on: post) added to the platform is anonymous and does not expire. In order to associate a new post to an identity, you first need to register a new user account. The registration process requires a unique username, a unique email address and a password. User accounts can NOT be modified or recovered; therefore if you lose your password, you will need to create a new account using a new email address.
-
Each user account is associated with a user role that determines the granular access to the special endpoints. The user role is set by default to unprivileged at registration time and can be altered only by manually modifying the database.
-
Special endpoints are only accessible to the privileged user class.
-
Posts published with a valid user identity can be altered or deleted. In order to do that, you need to authenticate yourself with your credentials within the update/delete request. Anonymous posts, on the other hand, can NOT be altered or removed; if you think that a certain content goes against the terms of service, you can email the owner of the bit instance.
-
The expiration date controls whether the post can be showed or not, once the current date is greater or equal than the expiration date, the post is classified as expired and thus shall not be showed. Expired posts are NOT deleted but may be manually removed by the instance owner.
-
The bit platform is stateless, hence there is no such thing as user session. Every time you need to use your user account for a certain operation(e.g., create a new post with an identity or delete an existing, non-anonymous post) you will need to provide your user credentials.
-
Deleting an existing user, will result in a cascade delete of any existing post associated with that user.
Database
New posts are stored on a relational database(PostgreSQL) using the Spring ORM system(Hibernate). The architecture of the bit platform consists of two tables: bt_users and bt_posts. The former stores the user accounts, and it's defined as follows:
Column | Data Type | Nullable |
---|---|---|
user ID | String |
false |
created at | YYYY-MM-DD Date |
false |
String |
false |
|
password | BCrypt |
false |
role | UserRole |
false |
username | String |
false |
The latter, instead, stores the posts, and it's defined as follows:
Column | Data Type | Nullable |
---|---|---|
post ID | String |
false |
content | String |
false |
created at | YYYY-MM-DD date |
false |
expiration date | YYYY-MM-DD date |
true |
title | String |
false |
user ID | Foreign key constrain |
true |
The user password is stored using a BCrypt
based hash. Each post can be associated with one
user(eventually zero) while each user can be associate with multiple posts(eventually zero).
The relationship is of the type "one to many" from the user's perspective.
Deploy
In order to deploy the bit platform, you will need to install Docker/Podman and docker-compose. Once done that, you can easily launch the backend using the following command:
$> docker-compose up -d
By default, the following parameters are used:
SERVER_PORT
: "3000";POSTGRES_USER
: "bituser";POSTGRES_PASSWORD
: "qwerty1234";POSTGRES_DB
: "bit";SPRING_SECURITY_USER_NAME
: "admin";SPRING_SECURITY_USER_PASSWORD
: "admin".
Be sure to update these values by editing thedocker-compose.yml
file. Once the containers
are deployed, you can expose the application through a reverse proxy:
location /api {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Endpoints
The backend exposes the following REST APIs:
POST
New User(/api/users/new
):
Description: Add new user.
Parameters: username(string
), email(string
) password(string
).
DELETE
Delete User(/api/users/delete
):
Description: Delete an existing user.
Parameters: email(string
) password(string
).
GET
User List(/api/users
):
(special endpoint)
Description: Retrieve all users.
Parameters: email(string
), password(string
).
GET
Post List(/api/posts
):
(special endpoint)
Description: Retrieve all posts.
Parameters: email(string
), password(string
).
GET
Post By ID(/api/posts/{postID}
):
Description: Search a post by its ID.
Parameters: none.
GET
Post By Title(/api/posts/bytitle
):
(special endpoint)
Description: Search a post by its title.
Parameters: title(string
), user(User
).
POST
New Post(/api/posts/new
):
Description: Add a new post.
Parameters: title(string
), content(string
), expirationDate(YYYY-MM-DD
),
user(User
).
PUT
Edit Post(/api/posts/{postID}
):
Description: Update an existing, non-anonymous post.
Parameters: title(string
), content(string
), user(User
).
DELETE
Delete Post(/api/posts/{postID}
):
Description: Delete an existing, non-anonymous post.
Parameters: user(User
).
Examples
Below there are some practical examples on how to use the REST API:
- Add a non-anonymous, perpetual post(note: the user must exist)
POST
request to /api/posts/new
with the following body:
{
"title": "Hello World",
"content": "This is a example text snippet",
"expirationDate": null,
"user": {
"email": "john@example.com",
"password": "very_bad_pw"
}
}
- Add an anonymous post with expiration date set to January 25, 2024
POST
request to /api/posts/new
with the following body:
{
"title": "Hello World",
"content": "This is a example text snippet",
"expirationDate": "2024-01-25"
}
- Delete post "
afj45c
"
DELETE
request to /api/posts/afj45c
with the following body:
{
"email": "john@example.com",
"password": "very_bad_pw"
}
- Get list of all post whose title is "
foo
"
GET
request to /api/posts/bytitle
with the following body:
{
"title": "foo",
"user": {
"email": "john@example.com",
"password": "very_bad_pw"
}
}
In this case user john@example.com
is an user of the class PRIVILEGED
.
Unit tests
The bit platform provides some unit tests for the post and the user controllers. You can
find them in src/test
. The unit tests are automatically executed during the container bootstrap
process, to manually run them issue the following command:
$> ./mvnw test
License
This software is released under the GPLv3 license. You can find a copy of the license with this repository or by visiting the following page.