Skip to content

About

This is the API service for the PixelIt project, this provides the bitmaps for the Pixelit.

Resources

Stars

2 stars

Watchers

2 watching

Forks

Repository files navigation

PixelIt.API

This is the API service for the PixelIt project, this provides the bitmaps for the Pixelit.

CodeQL


Installation

Use Docker Compose. The production image runs on Node.js 24 as the unprivileged node user and installs only production dependencies from package-lock.json.

services:
  pixelit_api:
    restart: unless-stopped
    container_name: pixelit_api
    image: ghcr.io/pixelit-project/pixelit.api:latest
    ports:
      - "8080:8080"
    volumes:
      - /etc/localtime:/etc/localtime:ro
    environment:
      PORT: 8080
      TELEMETRY_USER_CHECK: "true"
      # Set to the actual reverse proxy IP(s) or CIDR(s); empty disables proxy trust.
      # Example for a proxy container with a fixed IP: "172.20.0.10"
      TRUSTED_PROXIES: ""
      MYSQL_HOST: host
      MYSQL_DATABASE: database
      MYSQL_USER: user
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      # Optional admin access (HTTPS origin, no trailing slash):
      # ADMIN_ORIGIN: https://pixelit.bastelbunker.de
      # ADMIN_GITHUB_CLIENT_ID: ${PIXELIT_GITHUB_CLIENT_ID}
      # ADMIN_GITHUB_CLIENT_SECRET: ${PIXELIT_GITHUB_CLIENT_SECRET}
      # ADMIN_GITHUB_OWNER_ID: "123456"
      # Optional Telegram moderation notifications (see docs/telegram.md):
      # TELEGRAM_BOT_TOKEN: ${PIXELIT_TELEGRAM_BOT_TOKEN}
      # TELEGRAM_BOT_USERNAME: YourPixelItBot
      # TELEGRAM_WEBHOOK_SECRET: ${PIXELIT_TELEGRAM_WEBHOOK_SECRET}
      GITHUB_TOKEN: ${GITHUB_TOKEN}
      API_GLOBAL_LIMIT_WINDOW_MS: 300000
      API_GLOBAL_LIMIT_MAX: 100
      API_TELEMETRY_LIMIT_WINDOW_MS: 900000
      API_TELEMETRY_LIMIT_MAX: 10
      API_SAVEBITMAP_LIMIT_WINDOW_MS: 900000
      API_SAVEBITMAP_LIMIT_MAX: 10
      API_GLOBAL_LIMIT_EXCLUDE: "192.168.0.1, 192.168.2.1, 192.168.3.1, ::1"
      API_TELEMETRY_LIMIT_EXCLUDE: "192.168.0.1, 192.168.2.1, 192.168.3.1, ::1"
      API_SAVEBITMAP_LIMIT_EXCLUDE: "192.168.0.1, 192.168.2.1, 192.168.3.1, ::1"
      SEQ_SERVER: http://seqserver:5341
      SEQ_APIKEY: ${SEQ_APIKEY}

Environment variables

Set these values in the Docker Compose environment section or in a .env file when running the API locally. Defaults below apply when a variable is not set; the Compose example explicitly enables TELEMETRY_USER_CHECK.

Variable Default Description
PORT 8080 Port on which the API listens inside the container. If changed, update the container side of the port mapping, e.g. 8080:9090 for PORT: 9090.
TELEMETRY_USER_CHECK false Set to "true" to restrict /api/Statistics, /api/UserMap, and /api/UserMapData to clients whose uuid query parameter matches a telemetry record updated within the last 30 days. Otherwise the response contains error: { telemetryUser: false }. This does not disable telemetry collection. The check is cached for 30 seconds.
TRUSTED_PROXIES Empty (no proxy trust) Comma-separated trusted proxy IPs or CIDRs used to resolve the client IP from X-Forwarded-For. Leave empty for direct access. See the proxy configuration notes below.
MYSQL_HOST Not set by the API MySQL server hostname or IP, reachable from the API container.
MYSQL_DATABASE Not set by the API Name of the existing PixelIt database.
MYSQL_USER Not set by the API MySQL user with access to the PixelIt tables.
MYSQL_PASSWORD Not set by the API Password for the MySQL user.
TELEGRAM_BOT_TOKEN Not set (notifications disabled) Optional bot token for moderation notifications. Requires GitHub admin login and the other Telegram settings; see setup.
TELEGRAM_BOT_USERNAME Not set Bot username without @.
TELEGRAM_WEBHOOK_SECRET Not set Random 32–256 character webhook authentication secret (A-Z, a-z, 0-9, _, -).
GITHUB_TOKEN Not set (unauthenticated requests) Optional token sent with GitHub API requests for PixelIt release information.
API_GLOBAL_LIMIT_WINDOW_MS 300000 (5 minutes) Rate-limit window in milliseconds for all /api/ routes.
API_GLOBAL_LIMIT_MAX 100 Maximum requests per client in the global window.
API_GLOBAL_LIMIT_EXCLUDE Empty Comma-separated exact client IPs exempt from the global limiter only.
API_TELEMETRY_LIMIT_WINDOW_MS 900000 (15 minutes) Additional rate-limit window in milliseconds for POST /api/Telemetry.
API_TELEMETRY_LIMIT_MAX 10 Maximum telemetry requests per client in the telemetry window.
API_TELEMETRY_LIMIT_EXCLUDE Empty Comma-separated exact client IPs exempt from the telemetry limiter only.
API_SAVEBITMAP_LIMIT_WINDOW_MS 900000 (15 minutes) Additional rate-limit window in milliseconds for POST /api/SaveBitmap.
API_SAVEBITMAP_LIMIT_MAX 10 Maximum bitmap uploads per client in the bitmap window.
API_SAVEBITMAP_LIMIT_EXCLUDE Empty Comma-separated exact client IPs exempt from the bitmap limiter only.
SEQ_SERVER Not set (Seq logging disabled) Optional Seq server URL, e.g. http://seqserver:5341. Console logging remains enabled.
SEQ_APIKEY Not set API key for the Seq server, if required by that server.

Use positive integers for rate-limit windows and request counts. A value of 0 falls back to the default; it does not disable the limiter. Exceeding a limit returns HTTP 429. Telemetry and bitmap requests are subject to both the global and their endpoint-specific limiter. Excluding an IP from one limiter does not exempt it from the others. Rate-limit counters are stored in memory per API process and reset on restart.

Proxy configuration and rate limits

By default the API uses the direct peer IP and ignores X-Forwarded-For. When running behind a reverse proxy, set TRUSTED_PROXIES to a comma-separated list of trusted proxy IPs or CIDRs, for example 127.0.0.1,::1 for a local proxy. For a reverse proxy in another Docker container, use its address on the shared Docker network; 127.0.0.1 refers to the API container itself. Keep the value empty when accessing the API directly. Use the actual proxy addresses for your deployment, restrict direct access to the API, and ensure the proxy overwrites incoming forwarding headers. Do not trust all addresses or a shared network containing untrusted clients.

Rate limits group IPv6 clients by /56 subnet. The existing *_LIMIT_EXCLUDE settings match exact resolved client IPs, including normalized IPv4-mapped IPv6.

Develop

Use Node.js 24.15.0 or newer within the Node.js 24 series, or Node.js 26+. Install the locked dependencies with npm ci and run the dev server with npm run dev.

Write requests

SaveBitmap and Telemetry return HTTP 200 only after the database write completes, HTTP 400 for invalid input, and HTTP 500 for persistence failures. The JSON body limit remains 100 KB (HTTP 413 when exceeded).

Bitmap uploads require nonempty name and userName strings (up to 255 characters), integer sizeX/sizeY dimensions from 1 to 256, a boolean animated, and a string rgb565array. Each frame must contain exactly sizeX * sizeY integer RGB565 values from 0 to 65535. Static data uses [0,65535]; animated data uses [0,65535],[65535,0], without an outer array.

Telemetry requires a 40-character hexadecimal uuid, nonempty version and type strings, a matrix object with positive integer type, nonempty name, and integer width/height from 1 to 256, plus a sensors array of at most 32 nonempty strings. Text fields are limited to 255 characters. buildSection is optional and may be empty. GeoIP data is resolved by the server.

Error responses

All asynchronous API routes forward errors to the central error handler. Database failures return HTTP 500 instead of successful empty data. GitHub requests time out after 10 seconds; failures return HTTP 502 and timeouts return HTTP 504. Failed upstream requests are not cached as empty release lists.

An empty database returns valid empty statistics and bitmap lists. LastVersion and Releases accept ?includePrereleases=true to include published prereleases alongside stable releases, retaining their existing bounded response formats and shared cache. Releases returns up to four stable releases plus up to four prereleases when opted in. All other values preserve stable-only behavior. Deploy this API support before enabling beta searches in firmware/WebUI.

LastVersion and LastRelease return {} when no stable release is available. OfficialReleases and Releases exclude prereleases; draft releases are ignored.

Firmware download metadata

/api/Releases and /api/LastRelease expose fwdownloads entries with the existing name (display label) and downloads fields, plus fileName (original asset filename) and downloadURL (GitHub browser download URL). Clients should match the exact hardware filename and exclude .full-upgrade.bin images for OTA uploads. Only show a direct download when a matching asset and its URL are present; older API deployments may omit these fields. Deploy this API update before the WebUI that uses direct firmware downloads. Existing release caching (600 seconds) also covers this metadata; no extra upstream request is made. /api/LastVersion continues to omit fwdownloads, keeping device version checks small.

Tests and Docker build

Run the regression tests with npm test. HTTP and Seq logging tests use temporary loopback servers; database, GitHub, and GeoIP calls are stubbed, so no credentials are needed. Run npm audit --omit=dev to check production dependencies.

Build and smoke-test the production image locally:

docker build --file dockerfile --tag pixelit-api:test .
docker run --rm --network none \
  --mount "type=bind,src=${PWD}/scripts/container-smoke.js,dst=/tmp/container-smoke.js,readonly" \
  pixelit-api:test node /tmp/container-smoke.js

The smoke test checks application startup, unprivileged execution, excluded development files, input validation, and controlled database connection errors. The Docker build context includes only production source, package files, and the license; local .env files, credentials, and node_modules are excluded. CI runs the regression tests and dependency audit before building and smoke-testing Docker.

Icon reports and administration

The API includes a dark-mode admin page at /admin/ for reviewing icon reports, hiding or restoring icons, and viewing aggregate device telemetry statistics.

The API creates the moderation tables automatically before accepting requests. The MySQL account needs CREATE permission in addition to its existing access. Enable GitHub login with ADMIN_ORIGIN (public HTTPS origin, no trailing slash), ADMIN_GITHUB_CLIENT_ID, ADMIN_GITHUB_CLIENT_SECRET and ADMIN_GITHUB_OWNER_ID (your numeric GitHub ID). The owner manages up to 100 moderators by GitHub username in the admin UI. Separate audit views show moderation decisions and owner-only membership changes. Without GitHub configuration, existing ADMIN_PASSWORD login remains supported.

See moderation setup and API reference for setup, deployment requirements and endpoints. Admins and moderators can optionally connect Telegram for bundled notifications about new reports. Webhook registration is automatic at startup; see Telegram setup.

Changelog

2.3.3 (2026-11-04)

  • (o0shojo0o) Refresh bitmap caches after successful uploads so newly saved icons appear immediately.

2.3.2 (2026-11-02)

  • (o0shojo0o) Finish GitHub sign-in through a same-site completion page to avoid returning to the login screen after cross-site redirects with Strict session cookies, including iOS Safari.

2.3.1 (2026-11-02)

  • (o0shojo0o) Use English throughout the admin UI, sign-in flow and Telegram notifications, including accessibility labels and date/number formatting.

2.3.0 (2026-11-02)

  • (o0shojo0o) Add optional prerelease selection to LastVersion and Releases; stable-only remains the default.

2.2.0 (2026-11-02)

  • (o0shojo0o) Refresh the dark admin workspace with consistent navigation icons, clearer cards and account settings, and scrollable mobile navigation.

  • (o0shojo0o) Add separate moderation and owner-only administrative audit views; record moderator membership changes transactionally and allow adding moderators by GitHub username while retaining stable account IDs.

  • (o0shojo0o) Confirm successful Telegram account linking once in the bot's private chat.

2.1.1 (2026-11-02)

  • (o0shojo0o) Register the Telegram webhook automatically at startup while preserving queued updates; retry failed registrations with increasing delays without preventing API startup.

  • (o0shojo0o) Add optional per-account Telegram notifications for new icon reports, with expiring account links, bundled delivery, unsubscribe controls and automatic removal with moderator access.

  • (o0shojo0o) Add GitHub OAuth login with an owner role, UI-managed moderators, membership revocation and individual moderation audit identities; retain password login for installations without GitHub configuration.

  • (o0shojo0o) Show open reports by default in the admin UI.

  • (o0shojo0o) Validate matrix names against supported firmware names in admin and public statistics; group other names as Custom without changing stored telemetry.

2.0.1 (2026-11-01)

  • (o0shojo0o) Serve a minimal login page before authentication; protect dashboard HTML and JavaScript with the admin session.

2.0.0 (2026-11-01)

  • (o0shojo0o) Return to the login page after logout or session expiry and verify dashboard access is revoked in regression tests.
  • (o0shojo0o) Add public icon reports and a dark-mode admin UI for reviewing reports, hiding icons and restoring them with a transactional audit history.
  • (o0shojo0o) Add aggregate telemetry statistics for recent device activity, firmware versions, hardware types and matrix configurations.
  • (o0shojo0o) Configure admin access through ADMIN_PASSWORD and ADMIN_ORIGIN, with internal password hashing, expiring sessions and CSRF protection.
  • (o0shojo0o) Run database migrations automatically before startup and include migration and route files in Docker images.
  • (o0shojo0o) Add configurable reporting, login, admin-read and admin-action rate limits, operational logging and bitmap cache invalidation.
  • (o0shojo0o) Group existing endpoints into route modules while preserving their URLs and responses; document code-style conventions in AGENTS.md.
  • (o0shojo0o) Add regression coverage for admin access, moderation, rate limits, log redaction, telemetry aggregates and migrations.

1.9.1 (2026-11-01)

  • (o0shojo0o) Add original asset filenames and browser download URLs to firmware release metadata while preserving existing labels and download counts. Document client compatibility and add regression coverage.

1.9.0 (2026-10-28)

  • (o0shojo0o) Upgrade to Express 5 and body-parser 2; update dotenv, mysql2, express-rate-limit, and CodeQL.
  • (o0shojo0o) Require successful regression tests, dependency auditing, Docker build, and container smoke tests before eligible Dependabot updates can be automatically merged.
  • (o0shojo0o) Switch Docker to Node.js 24, install locked production dependencies, run as an unprivileged user, and exclude local files from the build context.
  • (o0shojo0o) Update vulnerable dependencies within existing version ranges and declare supported Node.js versions.
  • (o0shojo0o) Fix Seq logging initialization for the ES module used by seq-logging 3.
  • (o0shojo0o) Forward asynchronous route errors and return proper error responses for database and GitHub failures.
  • (o0shojo0o) Add a 10-second GitHub request timeout and handle empty statistics, missing release metadata, and prerelease-only release lists.
  • (o0shojo0o) Preserve full release data when serving LastVersion and exclude prereleases from OfficialReleases.
  • (o0shojo0o) Extend regression tests and CI with dependency auditing and production container smoke tests.
  • (o0shojo0o) Document all environment variables, defaults, telemetry access checks, and rate-limit configuration.
  • (o0shojo0o) Trust forwarded client IPs only from proxies configured via TRUSTED_PROXIES.
  • (o0shojo0o) Normalize client IPs and group IPv6 rate limits by /56 subnet.
  • (o0shojo0o) Validate bitmap and telemetry payloads before writing to the database.
  • (o0shojo0o) Return HTTP 200 only after successful persistence and HTTP 500 on write failures.
  • (o0shojo0o) Add regression tests and a CI workflow for API validation, persistence errors, and rate limits.

1.8.10 (2025-12-28)

  • (o0shojo0o) added new api endpoint getBMPByID_v2 for better handling of animated bitmaps

1.8.7 (2024-10-07)

  • (o0shojo0o) add uuid to each request

1.8.6 (2024-10-06)

  • (o0shojo0o) change node from 20 to 21
  • (o0shojo0o) update dependencies

1.8.5 (2023-11-16)

  • (o0shojo0o) Build statistics revised

1.8.3 (2023-11-15)

  • (o0shojo0o) Version statistics revised

1.8.1 (2023-11-11)

  • (o0shojo0o) small fixes

1.8.0 (2023-11-11)

  • (o0shojo0o) only active telemetry users can see statistics
  • (o0shojo0o) added ENV param TELEMETRY_USER_CHECK

1.7.2 (2023-11-03)

  • (o0shojo0o) small fixes

1.7.1 (2023-11-03)

  • (o0shojo0o) added more statistics to endpoint Statistics

1.7.0 (2023-11-03)

  • (o0shojo0o) added new api endpoint Statistics

1.6.0 (2023-10-27)

  • (o0shojo0o) added buildSection for endpoint Telemetry

1.5.0 (2023-09-26)

  • (o0shojo0o) added ENV param API_SAVEBITMAP_LIMIT_EXCLUDE

1.4.2 (2023-09-05)

  • (o0shojo0o) fix endpoint SaveBitmap

1.4.1 (2023-09-05)

  • (o0shojo0o) small fixes

1.4.0 (2023-09-05)

  • (o0shojo0o) added new api endpoint SaveBitmap

1.3.0 (2023-07-27)

  • (o0shojo0o) added environment variable API_GLOBAL_LIMIT_EXCLUDE
  • (o0shojo0o) added environment variable API_TELEMETRY_LIMIT_EXCLUDE

1.2.1 (2023-07-27)

  • (o0shojo0o) fix rate limit key

1.2.0 (2023-07-27)

  • (o0shojo0o) added environment variable API_GLOBAL_LIMIT_WINDOW_MS
  • (o0shojo0o) added environment variable API_GLOBAL_LIMIT_MAX
  • (o0shojo0o) added environment variable API_TELEMETRY_LIMIT_WINDOW_MS
  • (o0shojo0o) added environment variable API_TELEMETRY_LIMIT_MAX
  • (o0shojo0o) added environment variable API_TELEMETRY_LIMIT_MAX
  • (o0shojo0o) enrich log with rate limit data
  • (o0shojo0o) added .env file support

1.1.1 (2023-02-14)

  • (o0shojo0o) added rate limits

1.1.0 (2022-12-13)

  • (o0shojo0o) no prereleases for releases statistics, information, etc. not considered.

1.0.1 (2022-09-05)

  • (o0shojo0o) fix id check

1.0.0 (2022-09-05)

  • (o0shojo0o) inital commit

About

This is the API service for the PixelIt project, this provides the bitmaps for the Pixelit.

Resources

Stars

2 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages