This project implements a secure and robust authentication system with support for password-based login, two-factor authentication (2FA) using TOTP (Time-based One-Time Password), and backup mechanisms like security questions and backup keys.
- Secure password storage with Argon2.
- Unique username hashing for privacy.
- Encrypted communication for sensitive data.
- Validation with deterministic username hashing.
- Support for multiple active sessions.
- Encrypted responses for added security.
- Verify user and send them server public key
- Store user questions and answers
| Field | Description |
|---|---|
{hashedUsername} |
Key for username hash (string) |
uuid |
User's unique identifier (string) |
Example Data:
{
"hashedUsername": "hashed_value_of_username",
"uuid": "1"
}| Field | Description |
|---|---|
u_hash |
Username hash (string) |
p_hash |
Password hash (string) |
b_code |
Backup code hash (string) |
created |
Account creation timestamp (ISO) |
last_login |
Last login timestamp (ISO) |
bio |
Default bio |
name |
Default name |
p_pic |
Default profile picture |
status |
Account status (active, banned) |
Example Data:
{
"u_hash": "hashed_value_of_username",
"p_hash": "argon2_hash_of_password",
"b_code": "deterministic_backup_code_hash",
"created": "2024-01-01T10:00:00.000+05:30",
"last_login": "2024-01-15T10:30:00.000+05:30",
"bio": "This is a default bio.",
"name": "Default Name",
"p_pic": "https://example.com/default.jpg",
"status": "active"
}| Field | Description |
|---|---|
{uuid} |
Document ID mapped to user sessions |
sessionId |
Unique session ID |
expires_at |
Expiry timestamp |
Example Data:
{
"sessionId": {
"token": "jwt_token",
"expires_at": "2024-01-15T11:30:00.000+05:30"
}
}| Collection | Description |
|---|---|
register |
Logs for registration operations |
login |
Logs for login operations |
ForgotPassword |
Logs for forgot password APIs |
protected |
Logs for protected operations |
Example Data:
{
"timestamp": "2024-01-15T10:00:00+05:30",
"message": "User registered successfully.",
"data": {
"uuid": "1",
"username": "hashed_value"
}
}- Endpoint:
POST /api/register - Purpose: Registers a new user.
- Request:
{
"encryptedData": "BASE64_ENCRYPTED_PAYLOAD"
}- Decrypted Payload:
{
"username": "plain_text_username",
"password": "plain_text_password",
"clientPublicKey": "HEX_PUBLIC_KEY"
}- Response:
{
"encryptedData": "BASE64_ENCRYPTED_RESPONSE"
}- Decrypted Response:
{
"message": "User registered successfully.",
"backupKey": "BACKUP_KEY",
"uuid": "USER_UUID"
}- Database Changes:
reg_userCollection:{ "usernameHash": "HASHED_USERNAME", "uuid": "USER_UUID" }usersCollection:{ "uuid": "USER_UUID", "p_hash": "HASHED_PASSWORD", "b_code": "HASHED_BACKUP_KEY", "bio": "Default bio", "name": "Default name", "p_pic": "Default profile picture URL", "status": "active", "created_at": "TIMESTAMP", "last_login": null }
- Endpoint:
POST /api/login - Purpose: Authenticates an existing user.
- Request:
{
"encryptedData": "BASE64_ENCRYPTED_PAYLOAD"
}- Decrypted Payload:
{
"username": "plain_text_username",
"password": "plain_text_password",
"clientPublicKey": "HEX_PUBLIC_KEY"
}- Response:
{
"encryptedData": "BASE64_ENCRYPTED_RESPONSE"
}- Decrypted Response:
{
"message": "Login successful.",
"token": "SESSION_TOKEN",
"expires_at": "SESSION_EXPIRY_TIME",
"uuid": "USER_UUID"
}- Database Changes:
- Updates
last_loginin theuserscollection. - Adds a new session in the
sessionscollection.
- Updates
- Endpoint:
POST /api/store-user-questions - Purpose: Stores the user's selected security questions and hashed answers.
- Request:
{
"encryptedData": "BASE64_ENCRYPTED_PAYLOAD"
}- Decrypted Payload:
{
"uuid": "USER_UUID",
"selectedQuestions": [0, 4, 7, 11, 20],
"answers": ["plain_text_answer1", "plain_text_answer2", "plain_text_answer3"]
}- Response:
{
"message": "Security questions stored successfully."
}- Database Changes:
user_questionsCollection:{ "uuid": "USER_UUID", "questions": [ { "questionId": 0, "answerHash": "HASHED_ANSWER" }, { "questionId": 4, "answerHash": "HASHED_ANSWER" }, ... ] }
- Endpoint:
POST /api/getapi - Purpose: Verifies app signature and device unique ID.
- Request:
{
"signature": "PLAIN_TEXT_SIGNATURE",
"deviceId": "DEVICE_UNIQUE_ID"
}- Response:
- If signature is valid:
{ "encryptedData": "BASE64_ENCRYPTED_RESPONSE" }- Decrypted Response:
{ "message": "App verified.", "serverPublicKey": "SERVER_PUBLIC_KEY" }
- Decrypted Response:
- If signature is invalid:
{ "error": "Unauthorized app. Please use the official app." }
- If signature is valid:
- Database Changes:
- Warnings are stored in the
bancollection for unauthorized devices.{ "device": { "DEVICE_UNIQUE_ID": WARNING_COUNT } }
- Warnings are stored in the
- Provides strong resistance against brute-force attacks.
- Ensures unique identifiers without storing plain text.
- Adds a second layer of security.
- All sensitive data is encrypted using libsodium.
- Removes expired sessions to maintain session hygiene.