Skip to content
Merged
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
20 changes: 20 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"root": true,
"env": {
"es2021": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"extends": [
"eslint:recommended"
],
"ignorePatterns": [
"node_modules/",
"dist/",
"coverage/"
]
}

4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [12, 14, 16]
node: [18, 20, 22]
os: [ubuntu-latest, windows-latest]

steps:
Expand All @@ -30,7 +30,7 @@ jobs:
# run: npm run lint

- name: Run tests
run: npm test
run: npm run lint && npm test

# - name: Coveralls
# uses: coverallsapp/github-action@master
Expand Down
48 changes: 48 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# AGENTS.md for node-chess

## Project Overview

This is a Node.js library for calculating chess moves.

## Build and Test Commands

**Installation:**

- Use `npm install` at the project root to install all dependencies.

**Development:**

- Please alphabetize imports and variables.
- Use camelCase for variable and function names.
- Follow the existing code style and conventions.

**Testing:**

- Run the full test suite for all packages: `npm run test`
- All code changes must pass the entire test suite before merging.
- Run the linter: `npm run lint`
- All linting issues must be resolved before merging.

## Coding Conventions and Style

- **Linting:** We use ESLint with the Airbnb style guide for TypeScript. Run `npm run lint` to check for style and coding errors.
- **Naming:**
- Components and files use PascalCase (e.g., `Button.tsx`).
- Functions and variables use camelCase (e.g., `getUsers`).
- Constants use screaming snake case (e.g., `API_ENDPOINT`).
- **TypeScript:** Use strict mode and explicitly type all function arguments and returns. Avoid using `any`.
- **Comments:**
- Use JSDoc style comments for all functions and classes. Include parameter and return types.
- Use inline comments sparingly to explain complex logic. Start inline comments with a lower case letter and do not end with a period.

## Testing Guidelines

## PR Instructions

- **Commit Messages:** Follow the Conventional Commits specification (e.g., `feat:`, `fix:`, `docs:`) to ensure changelogs are generated correctly.
- **Pre-Commit Checks:** Always run `npm run build`, `npm run lint` and `npm run test` before committing your code.

## Security Considerations

- **Secrets:** Never hard-code API keys, credentials, or other sensitive information.
- **Dependencies:** All dependencies must be vetted and installed via `npm`. No manual installations.
26 changes: 26 additions & 0 deletions examples/createMultipleServers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import socks5 from '../src/socks5.js';

// Replace these with the local IPs on your machine
const
hosts = ['10.0.0.1', '10.0.0.2', '10.0.0.3'],
port = 1080;

hosts.forEach((host) => {
const server = socks5.createServer();

server.on('listening', () => {
const addr = server.address();

// addr.address should match the host below, not 0.0.0.0
console.log('listening on %s:%d', addr.address, addr.port);
});

server.on('error', (err) => {
console.error('error on %s:%d -> %s', host, port, err.message);
});

// Use the options form so we can force an exclusive bind
// This ensures nothing is listening on 0.0.0.0 for the same port
server.listen({ exclusive: true, host, port });
});

6 changes: 4 additions & 2 deletions examples/createServer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import socks5 from '../src/socks5.js';

const server = socks5.createServer();
const
port = 1080,
server = socks5.createServer();

// start listening!
server.listen(1080);
server.listen(port);

server.on('handshake', function (socket) {
console.log();
Expand Down
44 changes: 27 additions & 17 deletions examples/createServerConnectionFilter.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
import dns from 'dns';
import socks5 from '../src/socks5.js';

const server = socks5.createServer({
connectionFilter : function (destination, origin, callback) {
console.log('Attempting to connect to...');
console.log(destination);
console.log();
console.log('Inbound origin of request is...');
console.log(origin);
const
port = 1080,
server = socks5.createServer({
connectionFilter (destination, origin, callback) {
console.log('Attempting to connect to...');
console.log(destination);
console.log();
console.log('Inbound origin of request is...');
console.log(origin);

return dns.reverse(destination.address, function (err, hostnames) {
if (!hostnames || !hostnames.length || !/github/.test(hostnames[0])) {
console.log('Not allowing connection to %s:%s', destination.address, destination.port);
return dns.reverse(destination.address, function (err, hostnames) {
if (err) {
console.error('DNS reverse lookup failed for %s', destination.address);
console.error(err);

return callback(new Error('connection to destination address is denied (only github is allowed)'));
}
// if the reverse lookup fails, we just deny the connection
return callback(new Error('connection to destination address is denied (only github is allowed)'));
}

return callback();
});
if (!hostnames || !hostnames.length || !/github/.test(hostnames[0])) {
console.log('Not allowing connection to %s:%s', destination.address, destination.port);

}
});
return callback(new Error('connection to destination address is denied (only github is allowed)'));
}

return callback();
});

}
});

server.on('connectionFilter', function (destination, origin, err) {
console.log('connection to %s:%s has been denied (only requests to github are allowed)', destination.address, destination.port);
console.error(err);
});

// start listening!
server.listen(1080);
server.listen(port);
26 changes: 14 additions & 12 deletions examples/createServerWithAuthentication.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import socks5 from '../src/socks5.js';

const server = socks5.createServer({
authenticate : function (username, password, socket, callback) {
// verify username/password
if (username !== 'foo' || password !== 'bar') {
// respond with auth failure (can be any error)
return setImmediate(callback, new Error('invalid credentials'));
const
port = 1080,
server = socks5.createServer({
authenticate (username, password, socket, callback) {
// verify username/password
if (username !== 'foo' || password !== 'bar') {
// respond with auth failure (can be any error)
return setImmediate(callback, new Error('invalid credentials'));
}

// return successful authentication
return setImmediate(callback);
}

// return successful authentication
return setImmediate(callback);
}
});
});

// start listening!
server.listen(1080);
server.listen(port);

server.on('handshake', function () {
console.log();
Expand Down
50 changes: 50 additions & 0 deletions examples/createServerWithGssapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Demonstrates enabling GSSAPI/Negotiate with a provider backed by `kerberos`.
//
// Prerequisites on the host:
// - A service principal available to the server, e.g., rcmd/<hostname>@REALM
// - Keytab accessible to the process (if required by your Kerberos setup)
// - npm install kerberos

import createKerberosProvider from './gssapiKerberosProvider.js';
import socks5 from '../src/socks5.js';

const port = 1080;

const server = socks5.createServer({
gssapi: {
enabled: true,
provider: createKerberosProvider({
// Adjust service/hostname/principal for your environment.
service: 'rcmd'
// hostname: 'my-host.example.com', // defaults to os.hostname()
// principal: 'rcmd/my-host.example.com@EXAMPLE.COM', // optional explicit SPN
})
}
});

server.on('handshake', () => {
console.log('new socks5 client');
});

server.on('authenticate', (username) => {
console.log('GSSAPI authenticated principal:', username);
});

server.on('authenticateError', (username, err) => {
console.error('authentication failed for principal:', username);
console.error(err);
});

server.on('proxyConnect', (info) => {
console.log('connected to remote server at %s:%d', info.address, info.port);
});

server.on('proxyError', (err) => {
console.error('unable to connect to remote server');
console.error(err);
});

server.listen(port, () => {
console.log('SOCKS5 proxy server with GSSAPI started on 0.0.0.0:%d', port);
});

Loading