{"id":30943349,"url":"https://github.com/thassiov/sump","last_synced_at":"2026-05-07T13:05:24.098Z","repository":{"id":312300159,"uuid":"862611230","full_name":"thassiov/sump","owner":"thassiov","description":"simple user management platform","archived":false,"fork":false,"pushed_at":"2025-10-01T00:53:05.000Z","size":2443,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-01T02:43:45.824Z","etag":null,"topics":["docker","identity-management","nodejs","oidc","self-hosted","user-management"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thassiov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-24T22:26:36.000Z","updated_at":"2025-10-01T00:53:09.000Z","dependencies_parsed_at":"2025-09-18T20:08:07.314Z","dependency_job_id":"b1228aba-fa2d-4aab-bd96-0c3da8e079cc","html_url":"https://github.com/thassiov/sump","commit_stats":null,"previous_names":["thassiov/sump"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thassiov/sump","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thassiov%2Fsump","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thassiov%2Fsump/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thassiov%2Fsump/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thassiov%2Fsump/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thassiov","download_url":"https://codeload.github.com/thassiov/sump/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thassiov%2Fsump/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278846350,"owners_count":26056090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","identity-management","nodejs","oidc","self-hosted","user-management"],"created_at":"2025-09-10T22:17:10.578Z","updated_at":"2026-05-07T13:05:24.091Z","avatar_url":"https://github.com/thassiov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sump - simple user management platform\n\n[![CI](https://github.com/thassiov/sump/actions/workflows/ci.yml/badge.svg)](https://github.com/thassiov/sump/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n\u003e [!CAUTION]\n\u003e This is still *very* WIP\n\nA definition from [dictionary.com](https://www.dictionary.com/browse/sump):\n\u003e _\"sump: a pit, well, or the like in which water or other liquid is collected.\"_\n\nBut this collects *user accounts* to recirculate (auth).\n\n## Overview\n\nSump is a multi-tenant user management platform that provides:\n\n- **Multi-tenancy**: Create isolated tenants with their own accounts and environments\n- **Environments**: Separate user pools within a tenant (e.g., dev, staging, production)\n- **Authentication**: Built-in auth with password hashing (bcrypt), session management (signed cookies), and password reset flows\n- **Authorization**: Role-based access control (owner, admin, user)\n- **Custom Properties**: Flexible key-value metadata on tenants, environments, and accounts\n\n## Entity Model\n\n![Sump Entity Model](./docs/img/sump-entities.svg)\n\n- **Tenant**: The main container (like an organization). Has a name and custom properties.\n- **Tenant Account**: Administrative accounts for managing the tenant (owner, admin roles).\n- **Environment**: Sub-containers within a tenant (e.g., dev, staging, prod).\n- **Environment Account**: Your application's end users, living within an environment.\n\n## Dependencies\n\n- Node.js (\u003e= v20)\n- PostgreSQL (\u003e= v13)\n- Docker (\u003e= 28.x) [optional, for containerized deployment]\n\n## Installation\n\n```sh\n# Clone the repo and install dependencies\ngit clone https://github.com/thassiov/sump.git\ncd sump\nnpm install\n```\n\n## Running the server\n\n```sh\n# Set required environment variables\nexport AUTH_SECRET=\"your-32-character-secret-key-here\"\nexport DB_HOST=\"localhost\"\nexport DB_PORT=\"5432\"\nexport DB_USER=\"postgres\"\nexport DB_PASSWORD=\"your-password\"\nexport DB_NAME=\"sump\"\n\n# Run database migrations\nnpm run db:migration:up\n\n# Start the development server\nnpm run dev:start\n```\n\n### Using Docker Compose\n\n```sh\n# Start with docker compose (includes PostgreSQL)\nnpm run dev:container:start\n\n# Or with hot-reload\nnpm run dev:container:watch\n```\n\n## Quick Start\n\n### 1. Create a tenant\n\nFirst, create a tenant with an owner account. This will also create a default environment.\n\n```sh\ncurl --location 'http://localhost:8080/api/v1/tenants' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"tenant\": {\n        \"name\": \"my first tenant\",\n        \"customProperties\": {\n            \"app\": \"my-app\"\n        }\n    },\n    \"account\": {\n        \"name\": \"My Name\",\n        \"email\": \"my-email@example.com\",\n        \"phone\": \"+0000000000000\",\n        \"username\": \"myusername\",\n        \"password\": \"SecureP@ssw0rd!\"\n    },\n    \"environment\": {\n        \"name\": \"dev\"\n    }\n}'\n```\n\nResponse (HTTP 201):\n```json\n{\n   \"tenantId\": \"UUID\",\n   \"accountId\": \"UUID\",\n   \"environmentId\": \"UUID\",\n   \"session\": {\n       \"id\": \"UUID\",\n       \"accountType\": \"tenant_account\",\n       \"accountId\": \"UUID\",\n       \"contextType\": \"tenant\",\n       \"contextId\": \"UUID\",\n       \"expiresAt\": \"2025-01-27T12:00:00.000Z\"\n   }\n}\n```\n\n### 2. Sign up users to an environment\n\nUsers can self-register to an environment:\n\n```sh\ncurl --location 'http://localhost:8080/api/v1/auth/environments/\u003cenvironmentId\u003e/signup' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"name\": \"John Doe\",\n    \"email\": \"john@example.com\",\n    \"username\": \"johndoe\",\n    \"password\": \"SecureP@ssw0rd!\"\n}'\n```\n\n### 3. Authenticate users\n\n```sh\ncurl --location 'http://localhost:8080/api/v1/auth/environments/\u003cenvironmentId\u003e/login' \\\n--header 'Content-Type: application/json' \\\n--data '{\n    \"email\": \"john@example.com\",\n    \"password\": \"SecureP@ssw0rd!\"\n}'\n```\n\n## API Endpoints\n\n### Authentication\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| POST | `/api/v1/auth/tenants/:tenantId/login` | Tenant account login |\n| POST | `/api/v1/auth/tenants/:tenantId/logout` | Tenant account logout |\n| GET | `/api/v1/auth/tenants/:tenantId/session` | Get current session |\n| GET | `/api/v1/auth/tenants/:tenantId/sessions` | List all sessions |\n| POST | `/api/v1/auth/tenants/:tenantId/logout-all` | Revoke all sessions |\n| POST | `/api/v1/auth/tenants/:tenantId/forgot-password` | Request password reset |\n| POST | `/api/v1/auth/tenants/:tenantId/reset-password` | Reset password with token |\n| POST | `/api/v1/auth/environments/:envId/signup` | Environment account signup |\n| POST | `/api/v1/auth/environments/:envId/login` | Environment account login |\n| POST | `/api/v1/auth/environments/:envId/logout` | Environment account logout |\n| GET | `/api/v1/auth/environments/:envId/session` | Get current session |\n| GET | `/api/v1/auth/environments/:envId/sessions` | List all sessions |\n| POST | `/api/v1/auth/environments/:envId/logout-all` | Revoke all sessions |\n| POST | `/api/v1/auth/environments/:envId/forgot-password` | Request password reset |\n| POST | `/api/v1/auth/environments/:envId/reset-password` | Reset password with token |\n\n### Tenants\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| POST | `/api/v1/tenants` | Create tenant with owner account |\n| GET | `/api/v1/tenants/:tenantId` | Get tenant by ID |\n| PATCH | `/api/v1/tenants/:tenantId` | Update tenant |\n| DELETE | `/api/v1/tenants/:tenantId` | Delete tenant |\n| PATCH | `/api/v1/tenants/:tenantId/custom-property` | Set custom property |\n| DELETE | `/api/v1/tenants/:tenantId/custom-property` | Delete custom property |\n\n### Tenant Accounts\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `/api/v1/tenants/:tenantId/accounts` | List all accounts |\n| POST | `/api/v1/tenants/:tenantId/accounts` | Create account |\n| GET | `/api/v1/tenants/:tenantId/accounts/:accountId` | Get account by ID |\n| PATCH | `/api/v1/tenants/:tenantId/accounts/:accountId` | Update account |\n| DELETE | `/api/v1/tenants/:tenantId/accounts/:accountId` | Delete account |\n| PATCH | `/api/v1/tenants/:tenantId/accounts/:accountId/email` | Update email |\n| PATCH | `/api/v1/tenants/:tenantId/accounts/:accountId/phone` | Update phone |\n| PATCH | `/api/v1/tenants/:tenantId/accounts/:accountId/username` | Update username |\n| PATCH | `/api/v1/tenants/:tenantId/accounts/:accountId/disable` | Disable account |\n| PATCH | `/api/v1/tenants/:tenantId/accounts/:accountId/enable` | Enable account |\n\n### Environments\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| POST | `/api/v1/tenants/:tenantId/environments` | Create environment |\n| GET | `/api/v1/tenants/:tenantId/environments/:envId` | Get environment |\n| PATCH | `/api/v1/tenants/:tenantId/environments/:envId` | Update environment |\n| DELETE | `/api/v1/tenants/:tenantId/environments/:envId` | Delete environment |\n| PATCH | `/api/v1/tenants/:tenantId/environments/:envId/custom-property` | Set custom property |\n| DELETE | `/api/v1/tenants/:tenantId/environments/:envId/custom-property` | Delete custom property |\n\n### Environment Accounts\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| POST | `/api/v1/environments/:envId/accounts` | Create account |\n| GET | `/api/v1/environments/:envId/accounts/:accountId` | Get account |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId` | Update account |\n| DELETE | `/api/v1/environments/:envId/accounts/:accountId` | Delete account |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId/email` | Update email |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId/phone` | Update phone |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId/username` | Update username |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId/custom-property` | Set custom property |\n| DELETE | `/api/v1/environments/:envId/accounts/:accountId/custom-property` | Delete custom property |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId/disable` | Disable account |\n| PATCH | `/api/v1/environments/:envId/accounts/:accountId/enable` | Enable account |\n\n### Health\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `/api/v1/health` | Health check |\n\n## Testing\n\n```sh\n# Run unit tests\nnpm run test:unit\n\n# Run integration tests (requires Docker)\nnpm run test:integration\n\n# Run linting\nnpm run lint\n```\n\n## Related Projects\n\n- [sump-ui](https://github.com/thassiov/sump-ui) - Admin dashboard for managing tenants and environments\n\n## Reference\n\n- [OpenAPI Specification](./openapi.yaml)\n- [Architecture details](./docs/img/readme.md)\n\n## License\n\n[MIT](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthassiov%2Fsump","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthassiov%2Fsump","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthassiov%2Fsump/lists"}