5139fbb79a
Prepares the docs for the public release announcement: removes obsolete/dead material, fixes drift between the API reference and the actual routes, and standardizes on the default GitHub Pages URL. - Remove Vagrant entirely: delete Vagrantfile, docs/dev_setup.md, and stale vagrant references in .gitignore/.dockerignore; rewrite openresty/README.md to describe the actual (currently unused) directory and point to ops/nginx_conf/ for the real OpenResty config. - Delete docs/Update 4.11.md (personal scratch changelog) and drop both its and dev_setup.md's references from docs/README.md's Legacy Documentation section. - Remove checkmark emoji from docs/contributing.md's PR Requirements list. - Bring the auth model docs up to date with the code: document GET /api/auth/oidc/start + /callback, the /api/permission and /api/group RBAC routers, the /api/dns/dynamic/* sub-API, and /api/api-token (self -service PATs) in both nodejs/api.md and docs/api.md; add the missing "Clear Host Cache" section; drop the invite-token/SSH-key endpoints that no longer exist in nodejs/routes/user.js; note admin-only routes. Mention OIDC/LDAP/RBAC as core features in README.md. - Keep nodejs/api.md and docs/api.md fully in sync (same body, differing only in Jekyll front matter / relative links) instead of letting them drift. - Fix Node.js version references (20.x -> 22.x) in README.md and docs/installation.md to match ops/install.sh and the Dockerfile. - Note that the manual nginx-conf/systemd install steps in README.md and docs/installation.md won't auto-track repo changes the way install.sh's symlink approach does, and recommend install.sh. - Update the stale test/unit file lists in docs/contributing.md and nodejs/test/README.md to match the actual directory contents. - Add npm run test:integration to README.md's Running Tests section. - Add nodejs/conf/, nodejs/controller/, and nodejs/migrations/ to the project structure diagrams in README.md, docs/architecture.md, and docs/contributing.md. - Standardize "CloudFlare" -> "Cloudflare" everywhere to match the actual API value in nodejs/models/dns_provider.js. - Add the missing app_auth__adminGroups row to DEPLOYMENT.md's app_* table. - Delete docs/CNAME (custom domain) so GitHub Pages serves from the default https://theta42.github.io/proxy/, matching docs/README.md. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
344 lines
8.2 KiB
Markdown
344 lines
8.2 KiB
Markdown
---
|
|
layout: default
|
|
title: Contributing
|
|
---
|
|
|
|
# Contributing Guide
|
|
|
|
[← Back to Home](index.html)
|
|
|
|
Thank you for considering contributing to the Proxy project! This guide will help you get started.
|
|
|
|
## Development Setup
|
|
|
|
### Prerequisites
|
|
|
|
- Node.js 18+ (18.x, 20.x, or 22.x recommended)
|
|
- Redis server
|
|
- Git
|
|
|
|
### Local Development
|
|
|
|
1. **Clone the repository**
|
|
```bash
|
|
git clone https://github.com/theta42/proxy.git
|
|
cd proxy/nodejs
|
|
```
|
|
|
|
2. **Install dependencies**
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
3. **Start Redis** (if not already running)
|
|
```bash
|
|
redis-server
|
|
```
|
|
|
|
4. **Run in development mode**
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
This starts the Node.js API with nodemon for auto-reload on file changes.
|
|
|
|
5. **Access the API**
|
|
- API: `http://localhost:3000/api`
|
|
- Web UI: `http://localhost:3000`
|
|
|
|
## Testing
|
|
|
|
The project uses Node.js built-in test runner (requires Node 18+).
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
# Run all tests
|
|
npm test
|
|
|
|
# Run only unit tests
|
|
npm run test:unit
|
|
|
|
# Run only integration tests
|
|
npm run test:integration
|
|
|
|
# Watch mode for development
|
|
npm run test:watch
|
|
```
|
|
|
|
### Test Structure
|
|
|
|
```
|
|
test/
|
|
├── unit/ # Unit tests for isolated components
|
|
│ ├── basicauth.test.js
|
|
│ ├── callback_queue.test.js
|
|
│ ├── dynamic_record.test.js
|
|
│ ├── host_features.test.js
|
|
│ ├── host_lookup.test.js
|
|
│ ├── hostname_validate.test.js
|
|
│ ├── host_sso.test.js
|
|
│ ├── oidc.test.js
|
|
│ ├── password_policy.test.js
|
|
│ ├── roles.test.js
|
|
│ ├── safe_redirect.test.js
|
|
│ ├── unix_socket.test.js
|
|
│ └── wildcard_matchany.test.js
|
|
├── integration/ # Integration tests
|
|
│ └── dns_provider.test.js
|
|
└── helpers/ # Test utilities
|
|
└── dns_provider_contract.js
|
|
```
|
|
|
|
### Writing Tests
|
|
|
|
We test **custom logic**, not third-party libraries:
|
|
|
|
**DO test:**
|
|
- Host lookup algorithm
|
|
- Socket buffering logic
|
|
- DNS provider contracts
|
|
- Custom utility functions
|
|
|
|
**DON'T test:**
|
|
- Express.js routing
|
|
- Redis ORM
|
|
- External DNS APIs (use mocks instead)
|
|
|
|
### Adding DNS Provider Tests
|
|
|
|
When adding a new DNS provider, you **must** add contract tests:
|
|
|
|
```javascript
|
|
describe('NewProvider Provider', () => {
|
|
const NewProvider = require('../../models/dns_provider/newprovider');
|
|
|
|
test('should meet DNS provider contract', () => {
|
|
const mockCredentials = {api_key: 'mock-key'};
|
|
const instance = validateDnsProviderContract(NewProvider, mockCredentials);
|
|
assert.ok(instance);
|
|
});
|
|
|
|
test('should have valid method signatures', () => {
|
|
const instance = new NewProvider({api_key: 'mock'});
|
|
validateMethodSignatures(instance);
|
|
});
|
|
|
|
test('should validate key mapping', () => {
|
|
const instance = new NewProvider({api_key: 'mock'});
|
|
validateKeyMapping(instance);
|
|
});
|
|
|
|
test('should validate type checking', () => {
|
|
const instance = new NewProvider({api_key: 'mock'});
|
|
validateTypeChecking(instance);
|
|
});
|
|
});
|
|
```
|
|
|
|
See `test/integration/dns_provider.test.js` for examples.
|
|
|
|
## Code Style
|
|
|
|
### General Guidelines
|
|
|
|
- Use strict mode: `'use strict';`
|
|
- Use tabs for indentation
|
|
- Clear, descriptive variable names
|
|
- Comment complex logic
|
|
- No trailing whitespace
|
|
|
|
### File Organization
|
|
|
|
```javascript
|
|
'use strict';
|
|
|
|
// 1. Node.js built-ins
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// 2. Third-party modules
|
|
const express = require('express');
|
|
const redis = require('redis');
|
|
|
|
// 3. Local modules
|
|
const {Host} = require('./models');
|
|
const middleware = require('./middleware/auth');
|
|
|
|
// 4. Code...
|
|
```
|
|
|
|
### Naming Conventions
|
|
|
|
- Classes: `PascalCase`
|
|
- Functions: `camelCase`
|
|
- Constants: `UPPER_SNAKE_CASE`
|
|
- Private methods: `__privateMethod` (double underscore prefix)
|
|
|
|
## Project Structure
|
|
|
|
Understanding the codebase:
|
|
|
|
```
|
|
nodejs/
|
|
├── conf/ # Configuration (base.js, environment overlays, secrets.js)
|
|
├── controller/ # App-level wiring (pubsub, startup)
|
|
├── migrations/ # One-off Redis data migration scripts
|
|
├── models/ # Data models (Host, User, DNS providers)
|
|
├── routes/ # API route handlers
|
|
├── services/ # Background services (lookup, scheduler)
|
|
├── middleware/ # Express middleware
|
|
├── utils/ # Utility functions
|
|
├── public/ # Static web assets
|
|
├── views/ # EJS templates
|
|
└── test/ # Test suite
|
|
```
|
|
|
|
## Pull Request Process
|
|
|
|
### Before Submitting
|
|
|
|
1. **Run tests** - Ensure all tests pass
|
|
```bash
|
|
npm test
|
|
```
|
|
|
|
2. **Test locally** - Verify your changes work
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
3. **Update documentation** - Keep docs in sync with code changes
|
|
|
|
4. **Commit messages** - Use clear, descriptive messages
|
|
```
|
|
Add DNS provider for Route53
|
|
|
|
- Implement Route53 DNS API client
|
|
- Add contract tests for Route53
|
|
- Update documentation with Route53 setup
|
|
```
|
|
|
|
### Submitting a PR
|
|
|
|
1. **Fork the repository**
|
|
|
|
2. **Create a feature branch**
|
|
```bash
|
|
git checkout -b feature/my-new-feature
|
|
```
|
|
|
|
3. **Make your changes**
|
|
|
|
4. **Commit your changes**
|
|
```bash
|
|
git add .
|
|
git commit -m "Description of changes"
|
|
```
|
|
|
|
5. **Push to your fork**
|
|
```bash
|
|
git push origin feature/my-new-feature
|
|
```
|
|
|
|
6. **Open a Pull Request** on GitHub
|
|
|
|
### PR Requirements
|
|
|
|
- All tests must pass (CI/CD runs automatically)
|
|
- Tests run on Node.js 18.x, 20.x, and 22.x
|
|
- No merge conflicts with `master`
|
|
- Code follows project conventions
|
|
- New features include tests
|
|
- Documentation updated if needed
|
|
|
|
### CI/CD Process
|
|
|
|
When you open a PR:
|
|
1. GitHub Actions automatically runs tests
|
|
2. Tests execute on multiple Node.js versions
|
|
3. PR cannot be merged until all checks pass
|
|
4. Review from maintainers
|
|
5. Merge to master
|
|
|
|
## Data Models
|
|
|
|
The project uses [model-redis](https://www.npmjs.com/package/model-redis) as the ORM for Redis data storage. All models extend the `Table` class and use a declarative schema via `_keyMap`.
|
|
|
|
**Example Model:**
|
|
```javascript
|
|
const Table = require('../utils/redis_model');
|
|
|
|
class Host extends Table {
|
|
static _key = 'host'; // Primary key field
|
|
static _keyMap = {
|
|
'host': {isRequired: true, type: 'string', min: 3, max: 500},
|
|
'ip': {isRequired: true, type: 'string', min: 3, max: 500},
|
|
'targetPort': {isRequired: true, type: 'number', min: 0, max: 65535},
|
|
'forcessl': {default: true, type: 'boolean'},
|
|
'created_on': {default: () => Date.now(), type: 'number'}
|
|
};
|
|
}
|
|
```
|
|
|
|
**Learn more:** [model-redis documentation](https://www.npmjs.com/package/model-redis)
|
|
|
|
## Adding Features
|
|
|
|
### Adding a DNS Provider
|
|
|
|
1. **Create provider file** in `models/dns_provider/yourprovider.js`
|
|
|
|
2. **Extend DnsApi base class**
|
|
```javascript
|
|
const {DnsApi} = require('./common');
|
|
|
|
class YourProvider extends DnsApi {
|
|
static _keyMap = {
|
|
api_key: {isRequired: true, type: 'string', isPrivate: true}
|
|
};
|
|
|
|
// Implement required methods
|
|
async listDomains() { }
|
|
async getRecords(domain, options) { }
|
|
async createRecord(domain, options) { }
|
|
async deleteRecords(domain, options) { }
|
|
}
|
|
```
|
|
|
|
3. **Add to provider list** in `models/dns_provider.js`
|
|
|
|
4. **Add contract tests** in `test/integration/dns_provider.test.js`
|
|
|
|
5. **Test your provider**
|
|
```bash
|
|
npm run test:integration
|
|
```
|
|
|
|
### Adding API Endpoints
|
|
|
|
1. **Add route** in appropriate file (`routes/`)
|
|
2. **Update API documentation** (`nodejs/api.md` and `docs/api.md` — keep them in sync)
|
|
3. **Test the endpoint** manually and add integration tests if needed
|
|
|
|
## Getting Help
|
|
|
|
- **Questions?** Open a [GitHub Discussion](https://github.com/theta42/proxy/discussions)
|
|
- **Bug reports** Use [GitHub Issues](https://github.com/theta42/proxy/issues)
|
|
- **Security issues** Email maintainers directly (see package.json)
|
|
|
|
## Code of Conduct
|
|
|
|
- Be respectful and inclusive
|
|
- Focus on constructive feedback
|
|
- Help others learn and grow
|
|
- Follow the project's technical direction
|
|
|
|
## License
|
|
|
|
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
|
|
---
|
|
|
|
[← Back to Home](index.html) | [View on GitHub](https://github.com/theta42/proxy)
|