* feat: add OIDC/SSO database schema and models (Phase 1) Add database foundation for OpenID Connect authentication: Database Migrations: - Create oidc_identities table (links users to OIDC accounts) - Create oidc_state_nonces table (OAuth state/nonce for CSRF protection) - Create auth_audit_log table (security event logging) - Make password_digest nullable in users table (allow OIDC-only users) Models: - OIDCIdentity: Links users to external OIDC providers - OIDCStateNonce: Temporary OAuth state management - AuthAuditLog: Authentication event audit trail Changes: - Updated User model to allow null password_digest - Added model associations in models/index.js - All migrations tested and verified Related to #977 * feat: add OIDC core services (Phase 2) - Install openid-client@^6.2.0 for OIDC protocol support - Implement providerConfig.js for loading providers from .env - Support single provider or numbered providers (OIDC_PROVIDER_1_*, etc.) - Auto-provision and admin email domain configuration - Provider caching for performance - Implement stateManager.js for OAuth state/nonce management - CSRF protection with 10-minute TTL - One-time use state consumption - Automatic cleanup of expired states - Implement auditService.js for authentication event logging - Track login success/failure, logout, OIDC linking/unlinking - Store IP address, user agent, and metadata - Support for event queries and retention cleanup - Add comprehensive unit tests (60 tests, all passing) - providerConfig: 36 tests for env parsing and validation - stateManager: 12 tests for state lifecycle and security - auditService: 12 tests for event logging and queries Phase 2 completes the backend core services needed for OIDC authentication. * feat: implement OIDC authentication flow (Phase 3) Core OIDC Flow (service.js): - Provider discovery with issuer caching - Authorization URL generation with state/nonce - OAuth callback handling and token exchange - ID token validation using openid-client - Token refresh functionality JIT User Provisioning (provisioningService.js): - Auto-create users from OIDC claims - Link existing email accounts to OIDC identities - Admin role assignment based on email domain rules - Automatic username generation from email - Transaction-safe identity creation Identity Management (oidcIdentityService.js): - List user's linked OIDC identities - Link additional providers to existing accounts - Unlink identities with safety checks - Prevent unlinking last auth method - Update identity claims on login HTTP Layer (controller.js + routes.js): - GET /api/oidc/providers - List configured providers - GET /api/oidc/auth/:slug - Initiate OIDC flow - GET /api/oidc/callback/:slug - Handle OAuth callback - POST /api/oidc/link/:slug - Link provider to current user - DELETE /api/oidc/unlink/:id - Unlink identity - GET /api/oidc/identities - Get user's identities Integration: - Register OIDC routes in Express app (public + authenticated) - Update auth service to reject password login for OIDC-only users - Audit logging for all OIDC operations - Session creation on successful authentication Security: - State/nonce CSRF protection - One-time use state consumption - Transaction-safe user provisioning - Foreign key constraints enforced * feat: implement OIDC frontend login flow (Phase 4) - Created OIDCProviderButtons component for SSO login options - Created OIDCCallback component for OAuth callback handling - Updated Login page to fetch and display OIDC providers - Added /auth/callback/:provider route to App.tsx - Added i18n translations for OIDC UI elements - Downgraded openid-client to v5.7.0 (CommonJS compatibility) - Fixed linting issues in backend OIDC modules Phase 4 completes the frontend login flow for OIDC/SSO authentication. Users can now see configured SSO providers on the login page. * feat: implement OIDC account linking UI (Phase 5) Add Connected Accounts section to Profile Security tab allowing users to: - View linked OIDC provider accounts - Link new SSO providers to their account - Unlink OIDC identities with validation - Prevent unlinking last authentication method Backend changes: - Add has_password virtual field to User model - Include has_password in profile API response - Track whether user has password set for validation Frontend changes: - Create oidcService for OIDC API operations - Create ConnectedAccounts component with link/unlink flows - Add confirmation dialog before unlinking accounts - Validate that users cannot unlink their last auth method - Show warning if user has no password set - Integrate Connected Accounts into SecurityTab User experience: - View all linked SSO provider accounts with email and link date - Link additional providers via "Link Provider" buttons - Unlink with two-step confirmation to prevent accidents - Clear error messages when unlinking would leave no auth method - Warning message suggesting password setup for OIDC-only users Fixes #977 * feat: complete OIDC documentation and UI improvements (Phase 6) This commit completes Phase 6 of the OIDC/SSO implementation with comprehensive documentation, bug fixes, and UI reorganization. Documentation: - Add comprehensive user guide at docs/10-oidc-sso.md with: - Setup guides for 6 major providers (Google, Okta, Keycloak, Authentik, PocketID, Azure AD) - Configuration examples for single and multiple providers - User features documentation (login, account linking, management) - Advanced topics (auto-provisioning, admin role assignment, hybrid auth) - Comprehensive troubleshooting section - Security considerations and best practices - Update README.md with OIDC/SSO section and quick setup examples Internationalization: - Add i18n support to OIDCProviderButtons component - Add translation keys for all OIDC UI text - Update English translations with "sign_in_with" key Bug Fixes: - Fix oidcService.ts to correctly unwrap API responses - Backend returns {providers: [...]} and {identities: [...]} - Frontend was expecting plain arrays, causing "map is not a function" error - Fix initiateOIDCLink to properly handle POST response UI Improvements: - Move OIDC/SSO to dedicated tab in profile settings - Create new OIDCTab component with green LinkIcon - Remove ConnectedAccounts from SecurityTab - Add OIDC tab between Security and API Keys tabs - Update ProfileSettings with new tab configuration - Security tab now focuses solely on password management Testing: - All linting passes - All tests pass (82 suites, 1223 tests) Related to #977 * feat: add OIDC/SSO translations for all 24 languages Add i18n support for OIDC/SSO features across all supported languages: - "Sign in with {{provider}}" button text - "OIDC/SSO" tab label in profile settings - OIDC authentication flow messages Translations added for: Arabic, Bulgarian, Danish, German, Greek, Spanish, Finnish, French, Indonesian, Italian, Japanese, Korean, Dutch, Norwegian, Polish, Portuguese, Romanian, Russian, Slovenian, Swedish, Turkish, Ukrainian, Vietnamese, and Chinese. * fix: resolve 13 CodeQL security alerts This commit addresses critical security vulnerabilities identified by CodeQL scanning: **Security Configuration (2 fixes)** - Fix insecure Helmet configuration - enable CSP and HSTS in production - Fix clear text cookie transmission - enable secure cookies in production **Path Injection (3 fixes)** - Add path validation in users/controller.js to prevent arbitrary file deletion - Add path validation in users/service.js for avatar operations - Add path sanitization in attachment-utils.js deleteFileFromDisk function **Cross-Site Scripting (1 fix)** - Fix XSS vulnerability in GeneralTab.tsx avatar URL handling - Add URL sanitization to prevent javascript: protocol attacks **URL Security (2 fixes)** - Fix double escaping in url/service.js HTML entity decoding - Fix incomplete URL sanitization for YouTube domain validation **Denial of Service (1 fix)** - Add loop bound protection in inboxProcessingService.js (10k char limit) **Rate Limiting (3 fixes)** - Add rate limiting to auth routes (register, verify-email) - Add rate limiting to task attachment upload/delete endpoints - Add rate limiting to user avatar upload/delete endpoints **GitHub Actions Security (1 fix)** - Add explicit read-only permissions to CI workflow Note: CSRF middleware (#10) requires frontend changes and is tracked separately. Relates to PR #1008 * fix: allow test files in path validation for tests * fix: format long condition in attachment-utils for Prettier compliance Break the path validation condition across multiple lines to meet Prettier formatting requirements and fix CI linting failure. * fix: resolve CodeQL security alerts - Add rate limiting to OIDC authentication routes using authLimiter and authenticatedApiLimiter - Implement CSRF protection middleware using csrf-sync (skips for API tokens and test environment) - Add CSRF token endpoint at /api/csrf-token - Fix incomplete URL scheme validation in GeneralTab to block all dangerous schemes (javascript:, data:, vbscript:, file:) This addresses 5 high-severity CodeQL security vulnerabilities: - Missing rate limiting on OIDC auth routes - Missing CSRF middleware protection - Incomplete URL sanitization in avatar handling All 1223 tests passing. * fix: implement CSRF protection with lusca for CodeQL compliance Add CSRF protection using lusca.csrf (CodeQL's recommended library) to protect session-based authentication while supporting hybrid auth patterns. Implementation: - Pre-check middleware marks exempt requests (test env, Bearer tokens) - Lusca CSRF middleware applied with exemption flag check - Session-based requests require valid x-csrf-token header - Bearer token requests exempt (don't use cookies) - Test environment exempt for test execution This addresses CodeQL security alert js/missing-token-validation while maintaining support for both cookie-based and token-based authentication. Related: #977 (OIDC/SSO authentication feature)
286 lines
12 KiB
Markdown
286 lines
12 KiB
Markdown
<p align="center">
|
||
<picture>
|
||
<source media="(prefers-color-scheme: dark)" srcset="public/wide-logo-light.png">
|
||
<source media="(prefers-color-scheme: light)" srcset="public/wide-logo-dark.png">
|
||
<img src="public/wide-logo-light.png" alt="tududi" width="400">
|
||
</picture>
|
||
</p>
|
||
|
||
<p align="center">
|
||
<h2 align="center">Productivity made simple</p></h2>
|
||
<p align="center">Organize your life and projects with a clear, hierarchical structure,<br>
|
||
smart recurring tasks, and seamless Telegram integration.<br>
|
||
Get focused, stay productive, and keep your data private.
|
||
</p>
|
||
</p>
|
||
|
||

|
||
|
||
More screenshots are [available here](#screenshots).
|
||
|
||
## 🚀 How It Works
|
||
|
||
This app allows users to manage their tasks, projects, areas, notes, and tags in an organized way. Users can create tasks, projects, areas (to group projects), notes, and tags. Each task can be associated with a project, and both tasks and notes can be tagged for better organization. Projects can belong to areas and can also have multiple notes and tags. This structure helps users categorize and track their work efficiently, whether they’re managing individual tasks, larger projects, or keeping detailed notes.
|
||
|
||
## 🧠 Philosophy
|
||
|
||
For the thinking behind tududi, read:
|
||
|
||
- [Designing a Life Management System That Doesn't Fight Back](https://medium.com/@chrisveleris/designing-a-life-management-system-that-doesnt-fight-back-2fd58773e857)
|
||
- [From Task to Table: How I Finally Got to the Korean Burger](https://medium.com/@chrisveleris/from-task-to-table-how-i-finally-got-to-the-korean-burger-01245a14d491)
|
||
|
||
## ✨ Features
|
||
|
||
- **Task Management**: Create, update, and delete tasks. Mark tasks as completed and view them by different filters (Today, Upcoming, Someday). Order them by Name, Due Date, Date Created, or Priority.
|
||
- **Subtasks**: Break down complex tasks into smaller, manageable subtasks with progress tracking and seamless navigation.
|
||
- **Recurring Tasks**: Comprehensive recurring task system with intelligent parent-child relationships:
|
||
- **Multiple Recurrence Patterns**: Daily, weekly, monthly, monthly on specific weekdays, and monthly last day
|
||
- **Completion-Based Recurrence**: Option to repeat based on completion date rather than due date
|
||
- **Smart Parent-Child Linking**: Generated task instances maintain connection to their original recurring pattern
|
||
- **Direct Parent Editing**: Edit recurrence settings directly from any generated task instance
|
||
- **Flexible Scheduling**: Set custom intervals (every 2 weeks, every 3 months, etc.)
|
||
- **End Date Control**: Optional end dates for recurring series
|
||
- **Project Sharing & Collaboration**: Share projects with team members and collaborate effectively
|
||
- **Quick Notes**: Create, update, delete, or assign text notes to projects.
|
||
- **Tags**: Create tags for tasks and notes to enhance organization.
|
||
- **Project Tracking**: Organize tasks into projects. Each project can contain multiple tasks and/or multiple notes.
|
||
- **Area Categorization**: Group projects into areas for better organization and focus.
|
||
- **Due Date Tracking**: Set due dates for tasks and view them based on due date categories.
|
||
- **Responsive Design**: Accessible from various devices, ensuring a consistent experience across desktops, tablets, and mobile phones.
|
||
- **Multi-Language Support**: Available in 24 languages with full localization support for a truly global productivity experience.
|
||
- **Telegram Integration**:
|
||
- Create tasks directly through Telegram messages
|
||
- Receive daily digests of your tasks
|
||
- Quick capture of ideas and todos on the go
|
||
- **Open API & Access Tokens**: Versioned Swagger docs exposed at `/api/v1` plus personal API keys for integrating tududi with your own tooling or automations.
|
||
- **OIDC/SSO Authentication**: Enterprise-ready Single Sign-On support with:
|
||
- Multiple OIDC providers (Google, Okta, Keycloak, Authentik, PocketID, Azure AD, and more)
|
||
- Just-In-Time (JIT) user provisioning
|
||
- Account linking for hybrid authentication
|
||
- Simple .env-based configuration perfect for self-hosters
|
||
- Automatic admin role assignment based on email domains
|
||
|
||
## 🗺️ Roadmap
|
||
|
||
Check out our [GitHub Project](https://github.com/users/chrisvel/projects/2) for planned features and progress.
|
||
|
||
## 🛠️ Getting Started
|
||
|
||
Get up and running quickly with our comprehensive documentation:
|
||
|
||
### Quick Start
|
||
|
||
```bash
|
||
docker pull chrisvel/tududi:latest
|
||
|
||
docker run \
|
||
-e TUDUDI_USER_EMAIL=admin@example.com \
|
||
-e TUDUDI_USER_PASSWORD=your-secure-password \
|
||
-e TUDUDI_SESSION_SECRET=$(openssl rand -hex 64) \
|
||
-v ~/tududi_db:/app/backend/db \
|
||
-v ~/tududi_uploads:/app/backend/uploads \
|
||
-p 3002:3002 \
|
||
-d chrisvel/tududi:latest
|
||
```
|
||
|
||
Navigate to [http://localhost:3002](http://localhost:3002) and login with your credentials.
|
||
|
||
### Reverse Proxy Setup
|
||
|
||
When running behind a reverse proxy (Caddy, Nginx, Traefik, etc.), set `TUDUDI_TRUST_PROXY` so that Express correctly reads client IPs from `X-Forwarded-For` headers. Without this, `express-rate-limit` will log a validation error.
|
||
|
||
```bash
|
||
docker run \
|
||
-e TUDUDI_TRUST_PROXY=true \
|
||
-e TUDUDI_ALLOWED_ORIGINS=https://your-domain.com \
|
||
...
|
||
```
|
||
|
||
| Value | Meaning |
|
||
|-------|---------|
|
||
| `true` | Trust all proxies (simplest option for single-proxy setups) |
|
||
| `1` | Trust the first hop only |
|
||
| `loopback` | Trust loopback addresses (127.0.0.1/::1) |
|
||
| `172.16.0.0/12` | Trust a specific subnet |
|
||
|
||
### OIDC/SSO Authentication
|
||
|
||
Tududi supports Single Sign-On via OpenID Connect (OIDC), allowing users to authenticate with external identity providers.
|
||
|
||
**Quick Setup (Single Provider):**
|
||
|
||
```bash
|
||
docker run \
|
||
-e OIDC_ENABLED=true \
|
||
-e OIDC_PROVIDER_NAME=Google \
|
||
-e OIDC_PROVIDER_SLUG=google \
|
||
-e OIDC_ISSUER_URL=https://accounts.google.com \
|
||
-e OIDC_CLIENT_ID=your-client-id.apps.googleusercontent.com \
|
||
-e OIDC_CLIENT_SECRET=your-client-secret \
|
||
-e OIDC_SCOPE="openid profile email" \
|
||
-e OIDC_AUTO_PROVISION=true \
|
||
-e TUDUDI_BASE_URL=https://your-domain.com \
|
||
...
|
||
```
|
||
|
||
**Multiple Providers:**
|
||
|
||
```bash
|
||
# Provider 1: Google
|
||
-e OIDC_PROVIDER_1_NAME=Google \
|
||
-e OIDC_PROVIDER_1_SLUG=google \
|
||
-e OIDC_PROVIDER_1_ISSUER=https://accounts.google.com \
|
||
-e OIDC_PROVIDER_1_CLIENT_ID=xxx \
|
||
-e OIDC_PROVIDER_1_CLIENT_SECRET=xxx \
|
||
|
||
# Provider 2: Company SSO
|
||
-e OIDC_PROVIDER_2_NAME="Company SSO" \
|
||
-e OIDC_PROVIDER_2_SLUG=okta \
|
||
-e OIDC_PROVIDER_2_ISSUER=https://company.okta.com \
|
||
-e OIDC_PROVIDER_2_CLIENT_ID=yyy \
|
||
-e OIDC_PROVIDER_2_CLIENT_SECRET=yyy \
|
||
-e OIDC_PROVIDER_2_ADMIN_EMAIL_DOMAINS=company.com \
|
||
```
|
||
|
||
**Supported Providers:** Google, Okta, Keycloak, Authentik, PocketID, Azure AD, and any OIDC-compliant provider
|
||
|
||
**Key Features:**
|
||
- Automatic user provisioning on first login
|
||
- Account linking for existing users
|
||
- Admin role assignment based on email domains
|
||
- Hybrid authentication (email/password + SSO)
|
||
|
||
**Documentation:** See [docs/10-oidc-sso.md](docs/10-oidc-sso.md) for detailed setup guides and provider-specific configuration.
|
||
|
||
### 📚 Documentation
|
||
|
||
For detailed setup instructions, configuration options, and getting started guides, visit:
|
||
|
||
**[docs.tududi.com](https://docs.tududi.com)**
|
||
|
||
- **[Installation Guide](https://docs.tududi.com/getting-started/installation)** - Docker, development setup, and deployment
|
||
- **[Configuration](https://docs.tududi.com/getting-started/configuration)** - Environment variables and advanced settings
|
||
- **[First Steps](https://docs.tududi.com/getting-started/first-steps)** - Learn the basics and get productive
|
||
- **[Project Sharing](https://docs.tududi.com/features/project-sharing)** - Collaborate with your team
|
||
|
||
## 🚧 Development
|
||
|
||
Want to contribute or run Tududi from source? Check out our comprehensive development guide:
|
||
|
||
**[Development Setup Guide](https://docs.tududi.com/#-development-setup)**
|
||
|
||
Quick overview:
|
||
|
||
```bash
|
||
# Clone and install
|
||
git clone https://github.com/chrisvel/tududi.git
|
||
cd tududi
|
||
npm install
|
||
|
||
# Start development servers
|
||
npm run backend:dev # Terminal 1 - Backend on :3001
|
||
npm run frontend:dev # Terminal 2 - Frontend on :8080
|
||
```
|
||
|
||
For database management, testing, and detailed development instructions, see [docs.tududi.com](https://docs.tududi.com)
|
||
|
||
## 🔌 API
|
||
|
||
Tududi provides a comprehensive REST API for integration with external tools and automation workflows.
|
||
|
||
**Base URL:** `http://localhost:8080/api/v1`
|
||
|
||
**Key Features:**
|
||
- Complete CRUD operations for tasks, projects, notes, and areas
|
||
- Personal API keys for secure access
|
||
- Swagger documentation available at `/api-docs` (requires authentication)
|
||
- Support for recurring tasks, subtasks, and tag management
|
||
- Real-time task metrics and productivity insights
|
||
|
||
**Authentication:** Uses session cookies or Bearer token authentication. Generate personal API keys through the web interface for programmatic access.
|
||
|
||
**Quick Example:**
|
||
```bash
|
||
# Get all tasks
|
||
curl -H "Authorization: Bearer YOUR_API_KEY" \
|
||
http://localhost:3002/api/v1/tasks
|
||
|
||
# Create a new task
|
||
curl -X POST \
|
||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"name":"Complete API documentation","priority":"medium"}' \
|
||
http://localhost:3002/api/v1/task
|
||
```
|
||
|
||
For full API documentation, visit `/api-docs` after authentication or check the Swagger schema definitions in [`backend/config/swagger.js`](backend/config/swagger.js).
|
||
|
||
## 🤝 Contributing
|
||
|
||
Contributions to tududi are welcome! Whether it's bug fixes, new features, documentation improvements, or translations, we appreciate your help.
|
||
|
||
**Before you start:**
|
||
|
||
- Check [existing issues](https://github.com/chrisvel/tududi/issues) and [discussions](https://github.com/chrisvel/tududi/discussions) to avoid duplicate work
|
||
- For bugs, [open an issue](https://github.com/chrisvel/tududi/issues/new/choose) with the bug report template
|
||
- For feature requests, start a [discussion](https://github.com/chrisvel/tududi/discussions/categories/feature-requests)
|
||
|
||
**Quick contribution workflow:**
|
||
|
||
1. Fork the repository
|
||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||
3. Make your changes following our [code standards](.github/CONTRIBUTING.md#code-standards)
|
||
4. Run linting and tests: `npm run pre-push`
|
||
5. Commit your changes with a clear message
|
||
6. Push to your fork and open a Pull Request
|
||
|
||
**Read our [Contributing Guide](.github/CONTRIBUTING.md) for:**
|
||
|
||
- Development setup and workflow
|
||
- Code standards and best practices
|
||
- Testing requirements
|
||
- Database migrations
|
||
- Translation guidelines
|
||
- Pull request checklist
|
||
|
||
## 💖 Support the Project
|
||
|
||
If you find tududi useful, consider supporting its development:
|
||
|
||
<p align="center">
|
||
<a href="https://github.com/sponsors/chrisvel"><img src="https://img.shields.io/badge/GitHub_Sponsors-Support-ea4aaa?logo=githubsponsors&logoColor=white&style=for-the-badge" alt="GitHub Sponsors"></a>
|
||
<a href="https://www.patreon.com/ChrisVeleris"><img src="https://img.shields.io/badge/Patreon-Support-F96854?logo=patreon&logoColor=white&style=for-the-badge" alt="Patreon"></a>
|
||
<a href="https://coff.ee/chrisveleris"><img src="https://img.shields.io/badge/Buy_Me_a_Coffee-Support-FFDD00?logo=buymeacoffee&logoColor=black&style=for-the-badge" alt="Buy Me a Coffee"></a>
|
||
<a href="https://www.paypal.com/donate/?hosted_button_id=QEQCKLXPB6XAE"><img src="https://img.shields.io/badge/PayPal-Donate-0070BA?logo=paypal&logoColor=white&style=for-the-badge" alt="PayPal"></a>
|
||
</p>
|
||
|
||
Your support helps keep tududi free, open-source, and actively maintained. Every contribution — big or small — makes a difference!
|
||
|
||
## 📜 License
|
||
|
||
This project is licensed under the [MIT License](LICENSE).
|
||
|
||
## 📬 Contact
|
||
|
||
For questions or comments, please [open an issue](https://github.com/chrisvel/tududi/issues) or contact the developer directly.
|
||
|
||
Join the tududi community:
|
||
|
||
[](https://discord.gg/fkbeJ9CmcH)
|
||
[](https://www.reddit.com/r/tududi/)
|
||
|
||
## 🌟 Please check my other projects!
|
||
|
||
- **[Reconya](https://reconya.com)** - Network reconnaissance and asset discovery tool
|
||
- **[BreachHarbor](https://breachharbor.com)** - Cybersecurity suite for digital asset protection
|
||
- **[Hevetra](https://hevetra.com)** - Digital tracking for child health milestones
|
||
|
||
# Screenshots
|
||
|
||

|
||
|
||

|
||
|
||
---
|
||
|
||
README created by [Chris Veleris](https://github.com/chrisvel) for `tududi`.
|