Files
OpenNoodl/dev-docs/tasks/phase-5-multi-target-deployment/01-byob-backend/TASK-006-auth-nodes/README.md
2025-12-31 09:34:27 +01:00

421 lines
11 KiB
Markdown

# TASK-006: Authentication Nodes
**Task ID:** TASK-006
**Phase:** 5 - Multi-Target Deployment (BYOB)
**Priority:** 🔴 Critical
**Difficulty:** 🟡 Medium
**Estimated Time:** 1 week
**Prerequisites:** TASK-001 (Backend Services Panel), TASK-002 (Data Nodes)
**Branch:** `feature/byob-auth-nodes`
## Objective
Create authentication nodes (Sign Up, Log In, Log Out) for BYOB backends, starting with Directus support.
## Background
The BYOB data nodes (TASK-002) enable full CRUD operations, but users cannot build real applications without authentication. This task adds the missing authentication layer, enabling:
- User registration (Sign Up)
- User authentication (Log In)
- Session management (Log Out)
- Secure token storage
Without these nodes, users would need to manually construct auth requests using HTTP nodes, which is error-prone and insecure.
## User Story
> As a Noodl user, I want to authenticate users against my Directus backend, so I can build secure applications with proper user management.
## Current State
- BYOB data nodes work but require manual token management
- No built-in authentication nodes for BYOB backends
- Existing auth nodes only work with Noodl Cloud (deprecated)
## Desired State
- Sign Up node for user registration
- Log In node for authentication
- Log Out node for session cleanup
- Secure token storage mechanism
- Seamless integration with existing BYOB data nodes
## Scope
### In Scope
- **Sign Up Node** - Register new users
- **Log In Node** - Authenticate existing users
- **Log Out Node** - End user session
- **Token Management** - Secure storage and auto-injection into requests
- **Directus Support** - Primary authentication provider
### Out of Scope
- OAuth/Social login (future enhancement)
- Multi-factor authentication (future enhancement)
- Password reset UI (can use existing Directus endpoints)
- Supabase/Appwrite auth adapters (future task)
- Role-based access control UI (use Query Data with directus_roles)
---
## Node Specifications
### 1. Sign Up Node
**Purpose:** Register a new user account
#### Inputs
| Input | Type | Description |
| ---------- | -------- | ---------------------------------- |
| Backend | dropdown | Select backend (or Active Backend) |
| Email | string | User's email address |
| Password | string | User's password |
| First Name | string | Optional first name |
| Last Name | string | Optional last name |
| Role | dropdown | Optional role assignment |
| Sign Up | signal | Trigger registration |
#### Outputs
| Output | Type | Description |
| ------- | ------ | -------------------------- |
| User | object | Created user object |
| User ID | string | ID of created user |
| Success | signal | Fires on successful signup |
| Failed | signal | Fires on error |
| Error | object | Error details |
#### API Call (Directus)
```
POST /users
Body: {
email: "user@example.com",
password: "secure-password",
first_name: "John",
last_name: "Doe",
role: "role-uuid"
}
```
**Note:** User registration in Directus typically requires admin permissions. For public registration, use Directus's public registration endpoint or configure appropriate permissions.
---
### 2. Log In Node
**Purpose:** Authenticate a user and store access tokens
#### Inputs
| Input | Type | Description |
| -------- | -------- | ---------------------------------- |
| Backend | dropdown | Select backend (or Active Backend) |
| Email | string | User's email |
| Password | string | User's password |
| Log In | signal | Trigger authentication |
#### Outputs
| Output | Type | Description |
| ------------- | ------ | ----------------------------------- |
| Access Token | string | JWT access token (handle securely!) |
| Refresh Token | string | Token for refreshing access |
| Expires | number | Token expiration time (ms) |
| User | object | Authenticated user object |
| Success | signal | Fires on successful login |
| Failed | signal | Fires on error |
| Error | object | Error details |
#### API Call (Directus)
```
POST /auth/login
Body: {
email: "user@example.com",
password: "password"
}
Response: {
data: {
access_token: "eyJhbGc...",
refresh_token: "eyJhbGc...",
expires: 900000
}
}
```
#### Token Storage Strategy
**Critical Security Consideration:** Where to store tokens?
**Options:**
1. **Runtime Memory** (Default - Most Secure)
- ✅ Cleared on app refresh
- ✅ Not accessible to XSS attacks
- ❌ Lost on page reload
2. **Session Storage** (Balanced)
- ✅ Cleared on tab close
- ✅ Reasonably secure
- ❌ Lost on tab close
3. **Local Storage** (Least Secure)
- ✅ Persists across sessions
- ❌ Vulnerable to XSS
- ❌ Not recommended for production
4. **Electron Secure Storage** (Best for Desktop)
- ✅ OS-level encryption
- ✅ Persistent and secure
- ✅ Ideal for Noodl desktop apps
- ❌ Not available in web viewer
**Recommended Approach:**
- Desktop apps → Electron `safeStorage` API
- Web apps → Session Storage with "Remember Me" option for Local Storage
- Always clear sensitive data from node outputs after use
---
### 3. Log Out Node
**Purpose:** End user session and clear stored tokens
#### Inputs
| Input | Type | Description |
| ------------- | -------- | ---------------------------------- |
| Backend | dropdown | Select backend (or Active Backend) |
| Refresh Token | string | Token to invalidate (optional) |
| Log Out | signal | Trigger logout |
#### Outputs
| Output | Type | Description |
| ------- | ------ | ---------------- |
| Success | signal | Fires on success |
| Failed | signal | Fires on error |
| Error | object | Error details |
#### API Call (Directus)
```
POST /auth/logout
Body: {
refresh_token: "eyJhbGc..."
}
```
#### Cleanup Actions
1. Clear stored access token
2. Clear stored refresh token
3. Clear user session data
4. Optionally redirect to login page
---
## Token Auto-Injection
### Problem
After logging in, every data node (Query, Create, Update, Delete) needs the access token. Manual token management is tedious.
### Solution
Enhance `byob-utils.js` to check for stored auth token:
```javascript
function resolveBackend(backendId) {
const backendConfig = /* ... resolve from metadata ... */;
// Check for stored auth token
const storedToken = getStoredAuthToken(backendId);
if (storedToken) {
backendConfig.token = storedToken;
}
return backendConfig;
}
function getStoredAuthToken(backendId) {
// Check runtime memory first
if (window.__noodlAuthTokens && window.__noodlAuthTokens[backendId]) {
return window.__noodlAuthTokens[backendId];
}
// Fall back to session storage
const stored = sessionStorage.getItem(`noodl_auth_${backendId}`);
if (stored) {
try {
const { token, expires } = JSON.parse(stored);
if (Date.now() < expires) {
return token;
}
} catch (e) {
// Invalid stored data
}
}
return null;
}
```
This way, once a user logs in, all subsequent data node requests automatically include the auth token.
---
## Implementation Plan
### Phase 1: Core Authentication (Week 1)
1. **Create Auth Utility Module** (`byob-auth-utils.js`)
- Token storage functions
- Token validation
- Auto-injection logic
2. **Implement Log In Node** (`byob-login.js`)
- Most critical - enables testing
- Store tokens securely
- Output user object
3. **Implement Log Out Node** (`byob-logout.js`)
- Clear stored tokens
- Invalidate refresh token
4. **Enhance BYOB Utils**
- Integrate token auto-injection
- Update `resolveBackend()` to check stored tokens
5. **Testing**
- Manual testing with real Directus instance
- Verify token storage and auto-injection
- Test logout cleanup
### Phase 2: User Registration (Week 1)
6. **Implement Sign Up Node** (`byob-signup.js`)
- User creation
- Optional auto-login after signup
### Phase 3: Documentation & Polish (Week 1)
7. **Documentation**
- Update BYOB guide with auth examples
- Security best practices
- Token management guide
8. **Example Project**
- Login/signup form
- Protected routes
- User dashboard
---
## Security Considerations
### ⚠️ Critical Security Rules
1. **Never Log Tokens**
- Don't `console.log()` access tokens
- Don't expose tokens in inspect data
- Clear from outputs after use
2. **Use HTTPS Only**
- Never send tokens over HTTP
- Validate SSL certificates
3. **Token Expiration**
- Respect token expiry times
- Implement token refresh logic (future enhancement)
4. **Input Validation**
- Validate email format
- Enforce password strength (backend responsibility)
- Sanitize all user inputs
5. **Error Messages**
- Don't leak sensitive info in error messages
- Generic errors for auth failures ("Invalid credentials")
---
## Testing Checklist
### Manual Testing
- [ ] Sign up new user
- [ ] Log in with valid credentials
- [ ] Log in with invalid credentials
- [ ] Token auto-injection works in Query Data node
- [ ] Log out clears tokens
- [ ] Token persists across page reload (if configured)
- [ ] Expired tokens are handled gracefully
### Edge Cases
- [ ] Duplicate email during signup
- [ ] Weak password validation
- [ ] Network errors during auth
- [ ] Concurrent login attempts
- [ ] Token storage quota exceeded
---
## Future Enhancements
### Phase 2 Features
- **Token Refresh Node** - Automatically refresh expired tokens
- **Current User Node** - Get currently logged-in user details
- **Password Reset Nodes** - Request and confirm password resets
- **Email Verification** - Send and verify email confirmation
### Phase 3 Features
- **OAuth/Social Login** - Google, GitHub, etc.
- **Multi-Factor Authentication** - TOTP support
- **Session Management** - View/revoke active sessions
- **Backend-Agnostic** - Supabase, Appwrite, custom APIs
---
## Success Criteria
- [ ] Users can sign up for new accounts
- [ ] Users can log in and receive tokens
- [ ] Tokens are stored securely
- [ ] Data nodes automatically use stored tokens
- [ ] Users can log out and clear session
- [ ] No security vulnerabilities
- [ ] Documentation complete
- [ ] Example project demonstrates usage
---
## Related Tasks
- **TASK-001:** Backend Services Panel (provides backend configuration)
- **TASK-002:** Data Nodes (consumes auth tokens)
- **TASK-007:** Token Refresh & Session Management (future)
- **TASK-008:** OAuth/Social Login Support (future)