Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

squidward-chat

A minimal barebones instant chat messenger app built with Solid.JS (frontend) and Erlang (backend).

Features

  • πŸ” In-house authentication system (username/password)
  • πŸ’¬ Real-time messaging via HTTP polling
  • πŸš€ Built for scalability with extensible OAuth 2.0 architecture
  • ⚑ Lightweight and fast - no external dependencies
  • 🎨 Clean, modern UI

Architecture

Backend (Erlang)

  • Built-in TCP/HTTP server using only standard library modules
  • OTP application structure for reliability
  • gen_server based authentication and chat room management
  • Token-based authentication (easily extensible to OAuth 2.0)
  • No external dependencies - uses only Erlang/OTP built-ins

Frontend (Solid.JS)

  • Reactive UI with minimal bundle size
  • HTTP polling for real-time updates (1 second interval)
  • Local storage for session persistence

Prerequisites

Installation

1. Clone the repository

git clone https://github.com/codewriter3000/squidward-chat.git
cd squidward-chat

2. Build the backend

rebar3 compile

3. Build the frontend

cd frontend
npm install
npm run build
cd ..

Quick Start

One-command build and run

# Build frontend
cd frontend && npm install && npm run build && cd ..

# Start the backend (includes compiled frontend)
rebar3 shell

The application will be available at http://localhost:8080

Development mode (optional)

For frontend development with hot reload:

# Terminal 1: Start backend
rebar3 shell

# Terminal 2: Start frontend dev server
cd frontend
npm run dev

Frontend dev server will run on http://localhost:5173 with proxy to backend at http://localhost:8080

Usage

Web Interface

  1. Open your browser to http://localhost:8080
  2. Register a new account with a username and password
  3. Login with your credentials
  4. Start chatting in real-time!

Testing the API

Run the included test script to verify all API endpoints:

./test_api.sh

Or test manually with curl:

# Register
curl -X POST http://localhost:8080/api/register \
  -H "Content-Type: application/json" \
  -d '{"username": "alice", "password": "pass123"}'

# Login
curl -X POST http://localhost:8080/api/login \
  -H "Content-Type: application/json" \
  -d '{"username": "alice", "password": "pass123"}'

# Send message (replace TOKEN with actual token from login)
curl -X POST http://localhost:8080/api/messages/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"message": "Hello, World!"}'

# Get messages
curl -X GET http://localhost:8080/api/messages \
  -H "Authorization: Bearer TOKEN"

API Endpoints

Authentication

  • POST /api/register - Register a new user
    • Body: {"username": "string", "password": "string"}
  • POST /api/login - Login user
    • Body: {"username": "string", "password": "string"}
    • Returns: {"success": true, "token": "string", "username": "string"}

Messaging

  • POST /api/messages/send - Send a chat message (requires Bearer token)
    • Body: {"message": "string"}
  • GET /api/messages - Get recent messages (requires Bearer token)
    • Returns: {"success": true, "messages": [...]}

Extending with OAuth 2.0

The authentication system is designed with extensibility in mind. The current architecture supports easy integration of OAuth 2.0 providers:

Current Architecture

  • squidward_chat_auth module manages all authentication
  • Token-based system with Bearer authentication
  • Stateless JWT-ready token generation
  • Separate authentication from authorization

Adding OAuth 2.0 Support

1. Add OAuth library to rebar.config:

{deps, [
    {oauth2, "..."}  % or other OAuth library
]}.

2. Extend squidward_chat_auth module:

% New function for OAuth login
oauth_login(Provider, Code) ->
    % Exchange authorization code for access token
    AccessToken = exchange_code(Provider, Code),
    % Fetch user info from provider
    {ok, UserInfo} = get_user_info(Provider, AccessToken),
    % Create or retrieve user in local system
    Username = maps:get(<<"email">>, UserInfo),
    % Generate internal token
    Token = generate_token(Username),
    store_oauth_mapping(Username, Provider, AccessToken),
    {ok, Token, Username}.

3. Add OAuth HTTP handlers:

% In squidward_chat_app.erl, add routes:
{"/api/oauth/:provider/callback", oauth_callback_handler, []},
{"/api/oauth/:provider/login", oauth_login_handler, []}

4. Update frontend for OAuth:

// In Auth.jsx component
<button onClick={() => window.location.href = '/api/oauth/google/login'}>
  Login with Google
</button>

The modular design means OAuth can be added without changing core chat functionality.

Project Structure

squidward-chat/
β”œβ”€β”€ src/                          # Erlang backend source
β”‚   β”œβ”€β”€ squidward_chat_app.erl   # Main application
β”‚   β”œβ”€β”€ squidward_chat_sup.erl   # Supervisor
β”‚   β”œβ”€β”€ squidward_chat_auth.erl  # Authentication module
β”‚   β”œβ”€β”€ squidward_chat_room.erl  # Chat room manager
β”‚   β”œβ”€β”€ squidward_chat_ws_handler.erl      # WebSocket handler
β”‚   β”œβ”€β”€ squidward_chat_login_handler.erl   # Login HTTP handler
β”‚   └── squidward_chat_register_handler.erl # Register HTTP handler
β”œβ”€β”€ frontend/                     # Solid.JS frontend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/          # UI components
β”‚   β”‚   β”‚   β”œβ”€β”€ Auth.jsx        # Login/Register component
β”‚   β”‚   β”‚   └── Chat.jsx        # Chat interface component
β”‚   β”‚   β”œβ”€β”€ App.jsx             # Main app component
β”‚   β”‚   β”œβ”€β”€ index.jsx           # Entry point
β”‚   β”‚   └── styles.css          # Styles
β”‚   β”œβ”€β”€ index.html              # HTML template
β”‚   β”œβ”€β”€ package.json            # Node dependencies
β”‚   └── vite.config.js          # Vite configuration
β”œβ”€β”€ rebar.config                # Erlang dependencies
└── README.md                   # This file

Security Notes

⚠️ This is a minimal implementation for demonstration purposes:

  • Passwords are hashed with SHA-256 (use bcrypt in production)
  • Tokens are simple hashes (use proper JWT in production)
  • No HTTPS enforcement (enable in production)
  • No rate limiting (add in production)
  • No input validation (add comprehensive validation in production)

License

Apache 2.0

Contributing

Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages