Noas is a username-password authentication server for Nostr that manages encrypted keys, making Nostr accessible to normal users.
Find a file
2026-03-16 10:44:02 +01:00
src feat(private-key): add hex to bytes conversion for private key validation 2026-03-16 12:29:24 +03:00
.dockerignore feat: add Docker support with Dockerfile and docker-compose configuration 2026-02-20 09:48:41 +00:00
.env.example chore: add gitignore and environment template 2026-02-13 09:18:46 +03:00
.gitignore chore: add gitignore and environment template 2026-02-13 09:18:46 +03:00
docker-compose.yml chore(docker): fix docker compose file 2026-03-16 10:44:02 +01:00
Dockerfile feat: add Docker support with Dockerfile and docker-compose configuration 2026-02-20 09:48:41 +00:00
justfile test(just): enhance NIP-46 testing suite with stable, unit, and integration tests 2026-03-03 16:55:08 +03:00
package-lock.json feat(dependencies): update package.json to include nostr-tools and ws, enhance test scripts 2026-03-03 16:52:07 +03:00
package.json feat(dependencies): update package.json to include nostr-tools and ws, enhance test scripts 2026-03-03 16:52:07 +03:00
README.md docs(readme): add task runner section with common development commands 2026-03-16 12:39:27 +03:00
setup.sh chore: add quick start setup script 2026-02-13 09:25:01 +03:00
test-api.sh test(integration): update test scripts and add integration test script for API 2026-02-16 16:10:32 +03:00
test-nip46.sh test(NIP-46): add comprehensive NIP-46 service and integration tests for API endpoints 2026-03-03 16:54:27 +03:00

Noas - Nostr Authentication Server

Simple username-password authentication server for Nostr with NIP-05 verification.

Features

  • Username/password registration
  • Secure password hashing (bcrypt)
  • NIP-49 encrypted private key storage
  • NIP-05 verification endpoint
  • Update password and relays
  • Test coverage

Setup

Task runner (justfile)

This project includes a justfile with common development commands for setup, database lifecycle, testing, demos, and health checks.

If you have just installed, you can list all available recipes with:

just --list

Common examples:

# One-time local setup (install deps + start DB + apply schema)
just setup

# Run API in dev mode
just dev

# Unit tests
just test

# Integration tests (server must already be running)
just test-integration

1. Install dependencies

npm install

2. Configure database

Create a .env file:

cp .env.example .env

Edit .env with your PostgreSQL connection string:

DATABASE_URL=postgresql://user:password@localhost:5432/noas
DOMAIN=yourdomain.com
PORT=3000

3. Set up database

npm run db:setup

4. Run tests

# Unit tests (auth, validation, database)
npm run test:unit

# Or all tests
npm test

# Watch mode
npm run test:watch

5. Start server

# Development (auto-reload)
npm run dev

# Production
npm start

API Endpoints

POST /register

Register a new user.

Request:

{
  "username": "alice",
  "password": "securepassword123",
  "publicKey": "a0b1c2d3...",
  "encryptedPrivateKey": "ncryptsec1...",
  "relays": ["wss://relay.example.com"]
}

Response:

{
  "success": true,
  "user": {
    "username": "alice",
    "publicKey": "a0b1c2d3..."
  }
}

POST /signin

Sign in and retrieve encrypted private key.

Request:

{
  "username": "alice",
  "password": "securepassword123"
}

Response:

{
  "success": true,
  "encryptedPrivateKey": "ncryptsec1...",
  "publicKey": "a0b1c2d3...",
  "relays": ["wss://relay.example.com"]
}

POST /update

Update password or relays (requires authentication).

Request:

{
  "username": "alice",
  "password": "currentpassword",
  "updates": {
    "newPassword": "newpassword123",
    "encryptedPrivateKey": "ncryptsec1...",
    "relays": ["wss://new-relay.com"]
  }
}

GET /.well-known/nostr.json?name=alice

NIP-05 verification endpoint.

Response:

{
  "names": {
    "alice": "a0b1c2d3..."
  }
}

Security Notes

  • Passwords are hashed with bcrypt (never stored plain)
  • Private keys are stored encrypted (NIP-49 format)
  • Client encrypts private key with user's password before sending
  • Uses HTTPS in production
  • Username validation: 3-32 chars, lowercase alphanumeric + underscore

Development

Testing

The project has comprehensive test coverage:

# Unit tests (auth, validation, database)
npm run test:unit

# Integration tests (API endpoints - requires server running)
npm run test:integration

# All tests
npm test

# Watch mode for TDD
npm run test:watch

Unit tests cover:

  • Password hashing and verification (bcrypt)
  • Input validation (usernames, keys, passwords)
  • Database operations (CRUD)
  • NIP-49 encrypted key validation

Integration tests cover:

  • Complete registration flow
  • Authentication and sign-in
  • Invalid password rejection
  • NIP-05 verification
  • Duplicate username prevention
  • Input validation

Integration tests use real HTTP requests to test the full API.