Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions API_ROUTES_ACCOUNT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# InlineGUI Account API Routes

This document describes the account save/create functionality for InlineGUI.

## Routes

### POST /api/account/register
Creates a new user account.

**Request Body:**
```json
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword123"
}
```

**Response:**
```json
{
"success": true,
"user": {
"name": "John Doe",
"email": "john@example.com"
}
}
```

### POST /api/account/login
Logs in an existing user.

**Request Body:**
```json
{
"email": "john@example.com",
"password": "securepassword123"
}
```

**Response:**
```json
{
"success": true,
"token": "jwt-token-here",
"user": {
"name": "John Doe",
"email": "john@example.com"
}
}
```

### GET /api/account/me
Returns the current logged-in user's information.

**Headers:**
```
Authorization: Bearer <token>
```

## Database Integration

For production use, integrate with MongoDB or LevelUP:

### MongoDB Example
```javascript
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
name: String,
email: { type: String, unique: true },
password: String, // hashed with bcrypt
createdAt: { type: Date, default: Date.now }
});
var User = mongoose.model('User', userSchema);
```

### LevelUP Example
```javascript
var levelup = require('levelup');
var db = levelup('./inlinegui-users');

db.put('user:john@example.com', JSON.stringify({
name: 'John Doe',
email: 'john@example.com',
createdAt: Date.now()
}), function(err) {
if (err) console.error('Error saving user:', err);
});
```

## Security Notes

- Always hash passwords with bcrypt before storing
- Use HTTPS for all authentication routes
- Implement rate limiting on login/register endpoints
- Validate and sanitize all user input
- Set secure HTTP-only cookies for session tokens
106 changes: 106 additions & 0 deletions src/documents/account.html.eco
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: "Account"
layout: "default"
priority: 10
---

<h1>Account</h1>

<section id="login-section">
<h2>Login</h2>
<form id="login-form" action="/api/account/login" method="post">
<div class="field">
<label for="login-email">Email Address</label>
<input type="email" id="login-email" name="email" placeholder="your@email.com" required />
</div>
<div class="field">
<label for="login-password">Password</label>
<input type="password" id="login-password" name="password" placeholder="Enter your password" required />
</div>
<button type="submit" class="ui primary button">Login</button>
</form>
<p>Don't have an account? <a href="/account/register">Register here</a></p>
</section>

<section id="register-section" style="display:none;">
<h2>Create Account</h2>
<form id="register-form" action="/api/account/register" method="post">
<div class="field">
<label for="reg-name">Full Name</label>
<input type="text" id="reg-name" name="name" placeholder="John Doe" required />
</div>
<div class="field">
<label for="reg-email">Email Address</label>
<input type="email" id="reg-email" name="email" placeholder="your@email.com" required />
</div>
<div class="field">
<label for="reg-password">Password</label>
<input type="password" id="reg-password" name="password" placeholder="Min 8 characters" minlength="8" required />
</div>
<div class="field">
<label for="reg-confirm">Confirm Password</label>
<input type="password" id="reg-confirm" name="confirm_password" placeholder="Re-enter password" required />
</div>
<button type="submit" class="ui green button">Create Account</button>
</form>
<p>Already have an account? <a href="/account/login">Login here</a></p>
</section>

<script>
// Toggle between login and register views
document.addEventListener('DOMContentLoaded', function() {
var loginLink = document.querySelector('#login-section a');
var registerLink = document.querySelector('#register-section a');
var loginSection = document.getElementById('login-section');
var registerSection = document.getElementById('register-section');

if (loginLink) {
loginLink.addEventListener('click', function(e) {
e.preventDefault();
loginSection.style.display = 'none';
registerSection.style.display = 'block';
});
}

if (registerLink) {
registerLink.addEventListener('click', function(e) {
e.preventDefault();
registerSection.style.display = 'none';
loginSection.style.display = 'block';
});
}

// Register form validation
var regForm = document.getElementById('register-form');
if (regForm) {
regForm.addEventListener('submit', function(e) {
var password = document.getElementById('reg-password').value;
var confirm = document.getElementById('reg-confirm').value;
if (password !== confirm) {
e.preventDefault();
alert('Passwords do not match!');
return false;
}
});
}

// Check for saved session
var savedUser = localStorage.getItem('inlinegui_user');
if (savedUser) {
try {
var user = JSON.parse(savedUser);
document.getElementById('login-section').innerHTML =
'<h2>Welcome back, ' + user.name + '!</h2>' +
'<p>Email: ' + user.email + '</p>' +
'<button onclick="logout()" class="ui red button">Logout</button>';
} catch(e) {
localStorage.removeItem('inlinegui_user');
}
}
});

function logout() {
localStorage.removeItem('inlinegui_user');
location.reload();
}
</script>