Help us shape the future of Go! Take the 2026 Go Developer Survey

capserver

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 25, 2025 License: Apache-2.0 Imports: 10 Imported by: 0

README

Cap Go Server

A Go implementation of Cap - a lightweight, modern open-source CAPTCHA alternative using SHA-256 proof-of-work.

Overview

Cap Challenge Example

Cap Go Server is a Go port of the original JavaScript Cap server library. It provides server-side challenge generation and verification for Cap, a proof-of-work based CAPTCHA alternative that eliminates the need for tracking, fingerprinting, or data collection.

Features

  • Proof-of-Work Based: Uses SHA-256 proof-of-work instead of complex puzzles
  • Privacy-Focused: No tracking, fingerprinting, or data collection required
  • Lightweight: Minimal dependencies and efficient implementation
  • Configurable: Customizable challenge difficulty, expiration times, and storage options
  • Token Management: Secure token generation, validation, and cleanup
  • File-based Persistence: Optional file-based token storage with automatic cleanup

Installation

go get github.com/samwafgo/cap_go_server

Quick Start

Basic Usage
package main

import (
    "fmt"
    "github.com/samwafgo/cap_go_server"
)

func main() {
    // Initialize Cap server with default configuration
    config := &capserver.CapConfig{
        TokensStorePath: "./tokens.json",
        NoFSState:       false,
    }
    cap := capserver.New(config)

    // Create a challenge
    challengeConfig := &capserver.ChallengeConfig{
        ChallengeCount:      50,
        ChallengeSize:       32,
        ChallengeDifficulty: 4,
        ExpiresMs:           300000, // 5 minutes
        Store:               true,
    }
    
    challenge, err := cap.CreateChallenge(challengeConfig)
    if err != nil {
        fmt.Printf("Error creating challenge: %v\n", err)
        return
    }
    
    fmt.Printf("Challenge created with token: %s\n", challenge.Token)
}
HTTP Server Example
  1. Start the server:

    cd example/http_server
    go run main.go
    
  2. Open your browser: Navigate to http://localhost:8080

API Endpoints
  1. POST /challenge - Create a new challenge

    • Returns: Challenge object with token and challenge array
    • Response: {"token": "...", "challenges": [...], "expires": 1234567890}
  2. POST /redeem - Submit challenge solution

    • Body: {"token": "challenge_token", "solutions": [["salt", "target", solution_value], ...]}
    • Returns: {"success": true, "token": "verification_token", "expires": 1234567890}
  3. POST /validate - Validate verification token

    • Body: {"token": "verification_token"}
    • Returns: {"success": true, "message": "Token validation completed"}
Running the Server
go run main.go

The server will start on http://localhost:8080 and provide the three endpoints for challenge creation, solution verification, and token validation.

API Reference

Types
ChallengeTuple

Represents a single challenge consisting of a salt and target.

ChallengeData

Contains the complete challenge information including challenges array, expiration time, and token.

ChallengeConfig

Configuration options for challenge generation:

  • ChallengeCount: Number of challenges to generate (default: 50)
  • ChallengeSize: Size of each challenge in bytes (default: 32)
  • ChallengeDifficulty: Difficulty level (default: 4)
  • ExpiresMs: Expiration time in milliseconds (default: 600000)
  • Store: Whether to store the challenge in memory (default: true)
Solution

Represents a solution to a challenge:

  • Token: The challenge token
  • Solutions: Array of [salt, target, solution] tuples
CapConfig

Main configuration for the Cap instance:

  • TokensStorePath: Path to store tokens file (default: ".data/tokensList.json")
  • NoFSState: Whether to disable file-based state storage (default: false)
Methods
New(config *CapConfig) *Cap

Creates a new Cap instance with the given configuration.

CreateChallenge(config *ChallengeConfig) (*ChallengeResponse, error)

Generates a new challenge with the specified configuration.

RedeemChallenge(solution *Solution) (*RedeemResponse, error)

Validates a challenge solution and returns a verification token.

ValidateToken(token string, config *TokenConfig) (*ValidationResponse, error)

Validates a verification token.

Cleanup() error

Cleans up expired tokens and syncs state to disk.

Configuration

Challenge Configuration
config := &capserver.ChallengeConfig{
    ChallengeCount:      100,    // Generate 100 challenges
    ChallengeSize:       64,     // 64-byte challenges
    ChallengeDifficulty: 6,      // Higher difficulty
    ExpiresMs:          300000,  // 5-minute expiration
    Store:              true,    // Store in memory
}

challenge, err := cap.CreateChallenge(config)
Cap Configuration
config := &capserver.CapConfig{
    TokensStorePath: "./tokens/tokens.json",
    NoFSState:       false, // Enable file-based storage
}

cap := capserver.New(config)

Security Considerations

  • Challenges expire automatically to prevent replay attacks
  • Tokens are cryptographically secure and include random components
  • SHA-256 hashing ensures computational difficulty for bots
  • File-based storage includes proper error handling and recovery

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgments

Documentation

Index

Constants

View Source
const (
	DefaultTokensStore         = ".data/tokensList.json"
	DefaultChallengeCount      = 50
	DefaultChallengeSize       = 32
	DefaultChallengeDifficulty = 4
	DefaultExpiresMs           = 600000  // 10 minutes
	DefaultTokenExpiresMs      = 1200000 // 20 minutes
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Cap

type Cap struct {
	// contains filtered or unexported fields
}

Cap represents the main Cap instance

func New

func New(configObj *CapConfig) *Cap

New creates a new Cap instance with the given configuration

func (*Cap) Cleanup

func (c *Cap) Cleanup() error

Cleanup cleans up expired tokens and syncs state to disk

func (*Cap) CreateChallenge

func (c *Cap) CreateChallenge(conf *ChallengeConfig) (*ChallengeResponse, error)

CreateChallenge generates a new challenge with the specified configuration

func (*Cap) RedeemChallenge

func (c *Cap) RedeemChallenge(solution *Solution) (*RedeemResponse, error)

RedeemChallenge validates a challenge solution and returns a verification token

func (*Cap) ValidateToken

func (c *Cap) ValidateToken(token string, conf *TokenConfig) (*ValidationResponse, error)

ValidateToken validates a verification token

type CapConfig

type CapConfig struct {
	TokensStorePath string          `json:"tokensStorePath,omitempty"` // Path to store tokens file
	State           *ChallengeState `json:"state,omitempty"`           // State configuration
	NoFSState       bool            `json:"noFSState,omitempty"`       // Whether to disable file-based state storage
}

CapConfig contains the main configuration for the Cap instance

type ChallengeConfig

type ChallengeConfig struct {
	ChallengeCount      int  `json:"challengeCount,omitempty"`      // Number of challenges to generate (default: 50)
	ChallengeSize       int  `json:"challengeSize,omitempty"`       // Size of each challenge in bytes (default: 32)
	ChallengeDifficulty int  `json:"challengeDifficulty,omitempty"` // Difficulty level (default: 4)
	ExpiresMs           int  `json:"expiresMs,omitempty"`           // Expiration time in milliseconds (default: 600000)
	Store               bool `json:"store,omitempty"`               // Whether to store the challenge in memory (default: true)
}

ChallengeConfig contains configuration options for challenge generation

type ChallengeData

type ChallengeData struct {
	Challenge []ChallengeTuple `json:"challenge"`
	Expires   int64            `json:"expires"`
	Token     string           `json:"token"`
}

ChallengeData contains the complete challenge information

type ChallengeResponse

type ChallengeResponse struct {
	Challenge []ChallengeTuple `json:"challenge"`
	Token     string           `json:"token,omitempty"`
	Expires   int64            `json:"expires"`
}

ChallengeResponse represents the response from CreateChallenge

type ChallengeState

type ChallengeState struct {
	ChallengesList map[string]*ChallengeData `json:"challengesList"`
	TokensList     map[string]int64          `json:"tokensList"`
}

ChallengeState represents the internal state of challenges and tokens

type ChallengeTuple

type ChallengeTuple [2]string

ChallengeTuple represents a single challenge consisting of salt and target

type RedeemResponse

type RedeemResponse struct {
	Success bool   `json:"success"`
	Message string `json:"message,omitempty"`
	Token   string `json:"token,omitempty"`
	Expires int64  `json:"expires,omitempty"`
}

RedeemResponse represents the response from RedeemChallenge

type Solution

type Solution struct {
	Token     string          `json:"token"`
	Solutions [][]interface{} `json:"solutions"` // Array of [salt, target, solution] tuples
}

Solution represents a solution to a challenge

type TokenConfig

type TokenConfig struct {
	KeepToken bool `json:"keepToken,omitempty"` // Whether to keep the token after validation
}

TokenConfig contains configuration options for token validation

type ValidationResponse

type ValidationResponse struct {
	Success bool `json:"success"`
}

ValidationResponse represents the response from ValidateToken

Directories

Path Synopsis
example
http_server command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL