{"id":47356672,"url":"https://github.com/etiennecollin/unifi-voucher-manager","last_synced_at":"2026-05-15T05:01:49.695Z","repository":{"id":308609651,"uuid":"1032554027","full_name":"etiennecollin/unifi-voucher-manager","owner":"etiennecollin","description":" A touch-friendly and secure interface for streamlined creation and management of guest Wi-Fi vouchers on UniFi controllers.","archived":false,"fork":false,"pushed_at":"2026-05-15T02:56:43.000Z","size":5463,"stargazers_count":69,"open_issues_count":1,"forks_count":9,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-15T04:33:13.071Z","etag":null,"topics":["axum","nextjs","rust","tailwindcss","ubiquiti","ubiquiti-router","ubiquiti-unifi-controller","ubiquiti-unifi-network","unifi","unifi-api","unifi-controller","unifi-network","unifi-network-application","unifi-voucher"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/etiennecollin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-05T13:28:15.000Z","updated_at":"2026-05-15T02:55:33.000Z","dependencies_parsed_at":"2025-08-06T22:14:21.451Z","dependency_job_id":"e93cac37-223a-4e4b-8da4-c936aad841de","html_url":"https://github.com/etiennecollin/unifi-voucher-manager","commit_stats":null,"previous_names":["etiennecollin/unifi-voucher-manager"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/etiennecollin/unifi-voucher-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etiennecollin%2Funifi-voucher-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etiennecollin%2Funifi-voucher-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etiennecollin%2Funifi-voucher-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etiennecollin%2Funifi-voucher-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/etiennecollin","download_url":"https://codeload.github.com/etiennecollin/unifi-voucher-manager/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etiennecollin%2Funifi-voucher-manager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33054454,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-15T02:00:06.351Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axum","nextjs","rust","tailwindcss","ubiquiti","ubiquiti-router","ubiquiti-unifi-controller","ubiquiti-unifi-network","unifi","unifi-api","unifi-controller","unifi-network","unifi-network-application","unifi-voucher"],"created_at":"2026-03-18T03:00:18.694Z","updated_at":"2026-05-15T05:01:49.676Z","avatar_url":"https://github.com/etiennecollin.png","language":"TypeScript","funding_links":[],"categories":["Guest Portal \u0026 Vouchers"],"sub_categories":["Other Platforms"],"readme":"# UniFi Voucher Manager\n\n[![Docker Image Version (latest by date)](https://img.shields.io/docker/v/etiennecollin/unifi-voucher-manager?sort=semver\u0026label=Version\u0026logo=docker\u0026color=blue) ![Docker Pulls](https://img.shields.io/docker/pulls/etiennecollin/unifi-voucher-manager?label=Pulls\u0026logo=docker\u0026color=blue)](https://hub.docker.com/r/etiennecollin/unifi-voucher-manager)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/etiennecollin/unifi-voucher-manager/release_docker.yaml?label=Docker%20Build\u0026logo=github) ![GitHub License](https://img.shields.io/github/license/etiennecollin/unifi-voucher-manager?label=License\u0026logo=github\u0026color=red)](https://github.com/etiennecollin/unifi-voucher-manager)\n\nUVM is a modern, touch-friendly web application for managing WiFi vouchers on UniFi controllers.\nPerfect for businesses, cafes, hotels, and home networks that need to provide guest WiFi access.\n\n![WiFi Voucher Manager](./assets/view.png)\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n- [✨ Features](#-features)\n  - [🎫 Voucher Management \u0026 WiFi QR Code](#-voucher-management--wifi-qr-code)\n  - [Kiosk Display](#kiosk-display)\n  - [🎨 Modern Interface](#-modern-interface)\n  - [🔧 Technical Features](#-technical-features)\n- [🚀 Quick Start](#-quick-start)\n  - [Using Docker Compose (Recommended)](#using-docker-compose-recommended)\n  - [Without Docker](#without-docker)\n- [⚙️ Configuration](#-configuration)\n  - [Getting UniFi API Credentials](#getting-unifi-api-credentials)\n  - [Rolling Vouchers and Kiosk Page](#rolling-vouchers-and-kiosk-page)\n    - [How Rolling Vouchers Work](#how-rolling-vouchers-work)\n  - [Environment Variables](#environment-variables)\n- [🐛 Troubleshooting](#-troubleshooting)\n  - [Common Issues](#common-issues)\n  - [Getting Help](#getting-help)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## ✨ Features\n\n### 🎫 Voucher Management \u0026 WiFi QR Code\n\n- **Quick Create** - Generate guest vouchers with preset durations (1 hour to 1 week)\n- **Custom Create** - Full control over voucher parameters:\n  - Custom name\n  - Duration (minutes to days)\n  - Guest count limits\n  - Data usage limits\n  - Upload/download speed limits\n- **Browse Vouchers** - Browse and search existing vouchers by name\n- **Bulk Operations** - Select and delete multiple vouchers at once\n- **Print Vouchers** - Print vouchers in either list or grid format; thermal printers friendly\n- **Auto-cleanup** - Remove expired vouchers with a single click\n- **QR Code** - Easily connect guests to your network\n- **Rolling Vouchers** - Automatically generate a voucher for the next guest when the current one gets used\n\n### Kiosk Display\n\nThe kiosk page (`/kiosk`) provides a guest-friendly interface displaying:\n\n- **QR Code**: For easy network connection (if configured in [Environment Variables](#environment-variables))\n- **Current Voucher**: The active rolling voucher code\n- **Real-time Updates**: Automatically refreshes when the rolling voucher changes\n\n### 🎨 Modern Interface\n\n- **Touch-Friendly** – Optimized for tablet, mobile, and desktop\n- **Dark/Light Mode** – Follows system preference, with manual override\n- **Responsive Design** - Works seamlessly across all screen sizes\n- **Smooth Animations** – Semantic transitions for polished UX\n- **Real-time Notifications** - Instant feedback for all operations\n\n### 🔧 Technical Features\n\n- **Docker Ready** - Easy deployment with Docker Compose and included healthcheck\n- **UniFi Integration** - Direct API connection to UniFi controllers\n- **Secure Architecture** - Next.js (TypeScript + Tailwind CSS) frontend with an Axum-based Rust backend that handles all UniFi Controller communication, keeping credentials isolated from the user-facing UI\n\n## 🚀 Quick Start\n\n### Using Docker Compose (Recommended)\n\n1. **Create the configuration files**\n   ```bash\n   # Download the compose file\n   curl -o compose.yaml https://raw.githubusercontent.com/etiennecollin/unifi-voucher-manager/main/compose.yaml\n   ```\n2. **Configure your environment**\n   - Set the required environment variables (see [Environment Variables](#environment-variables)) in the `compose.yaml` file.\n3. **Start the application**\n   ```bash\n   docker compose up -d --force-recreate\n   ```\n4. **Access the interface**\n   - Open your browser to `http://localhost:3000`.\n\n### Without Docker\n\n1. **Install the dependencies**\n   - `rust \u003e= 1.88.0`\n   - `nodejs \u003e= 24.3.0`\n   - `npm \u003e= 11.4.2`\n2. **Clone the repository**\n   ```bash\n   git clone https://github.com/etiennecollin/unifi-voucher-manager\n   ```\n3. **Configure your environment**\n   - In your shell, set the required environment variables (see [Environment Variables](#environment-variables))\n     or set them in a `.env` file at the root of the repository and use the `dotenv` feature of the rust backend.\n4. **Start the frontend and backend**\n\n   ```bash\n   # Backend (without using a .env file)\n   cd backend \u0026\u0026 cargo run --release\n\n   # Backend (using a .env file)\n   cd backend \u0026\u0026 cargo run --release --features dotenv\n\n   # Frontend (development)\n   cd frontend \u0026\u0026 npm install \u0026\u0026 npm run dev\n\n   # Frontend (release)\n   cd frontend \u0026\u0026 npm ci \u0026\u0026 npm run build \u0026\u0026 npm run start\n   ```\n\n5. **Access the interface**\n   - Open your browser to `http://localhost:3000`.\n\n## ⚙️ Configuration\n\n### Getting UniFi API Credentials\n\n1. **Access your UniFi Controller**\n2. **Navigate to Settings -\u003e Control Plane -\u003e Integration**\n3. **Create a new API key** by giving it a name and an expiration.\n4. **Find your Site ID** in the controller URL or on [unifi.ui.com](https://unifi.ui.com)\n\n### Rolling Vouchers and Kiosk Page\n\nRolling vouchers provide a seamless way to automatically generate guest network access codes. When one voucher is used, a new one is automatically created for the next guest.\n\n\u003e [!IMPORTANT]\n\u003e **Setup Required**\n\u003e\n\u003e For rolling vouchers to work properly, you **must** configure your UniFi Hotspot:\n\u003e\n\u003e 1. Go to your UniFi Controller -\u003e Insights -\u003e Hotspot\n\u003e 2. Set the **Success Landing Page** to: `https://your-uvm-domain.com/welcome`, the `/welcome` page of UVM\n\u003e\n\u003e Without this configuration, vouchers **will not** automatically roll when guests connect.\n\n\u003e [!CAUTION]\n\u003e To restrict UVM access to the guest subnetwork users while still allowing access to `/welcome` page, set the `GUEST_SUBNETWORK` environment variable. This makes sure guests do not have access to other UVM pages, such as the voucher management interface (the root `/` page).\n\u003e\n\u003e Without this configuration, guests **will be able** to access the voucher management interface of UVM. This means they will be able to both create and delete vouchers by themselves.\n\n#### How Rolling Vouchers Work\n\n1. **Initial Setup**: Rolling vouchers are generated automatically when needed\n2. **Guest Connection**: When a guest connects to your network, they're redirected to the `/welcome` page\n3. **Automatic Rolling**: The welcome page triggers the creation of a new voucher for the next guest\n   - Rolling vouchers are created with special naming conventions to distinguish them from manually created vouchers, making them easy to identify in your voucher management interface\n4. **IP-Based Uniqueness**: Each IP address can only generate one voucher per session (prevents abuse from page reloads)\n5. **Daily Maintenance**: To prevent clutter, expired rolling vouchers are automatically deleted at midnight (based on your configured `TIMEZONE` in [Environment Variables](#environment-variables))\n\n### Environment Variables\n\nMake sure to configure the required variables. The optional variables generally have default values that you should not have to change.\n\n\u003e [!TIP]\n\u003e\n\u003e - To configure the WiFi QR code, you are required to configure the `WIFI_SSID` and `WIFI_PASSWORD` variables.\n\u003e - For proper timezone, make sure to set the `TIMEZONE` variable.\n\n\u003e [!IMPORTANT]\n\u003e Make sure to expand this section and read what the environment variables are doing. Some variables are **required**, they are placed at the top of the list.\n\n- **`UNIFI_CONTROLLER_URL`: `string`** (_Required_)\n  - **Description**: URL to your UniFi controller with protocol (`http://` or `https://`).\n  - **Example**: `https://unifi.example.com` or `https://192.168.8.1:443`\n- **`UNIFI_API_KEY`: `string`** (_Required_)\n  - **Description**: API Key for your UniFi controller.\n  - **Example**: `abc123...`\n\n\u003e [!WARNING]\n\u003e Improperly setting the `UNIFI_HAS_VALID_CERT` variable **will** prevent UVM from communicating with the UniFi controller.\n\n- **`UNIFI_HAS_VALID_CERT`: `bool`** (_Optional_)\n  - **Description**: Whether your UniFi controller uses a valid SSL certificate. This should normally be set to `true`, especially if you access the controller through a reverse proxy or another setup that provides trusted certificates (e.g., Let's Encrypt). **If you connect directly to the controller’s IP address (which usually serves a self-signed certificate), you may need to set this to `false`.**\n  - **Example**: `true` (default)\n- **`UNIFI_SITE_ID`: `string`** (_Optional_)\n  - **Description**: Site ID of your UniFi controller. Using the value `default`, the backend will try to fetch the ID of the default site.\n  - **Example**: `default` (default)\n\n\u003e [!CAUTION]\n\u003e To restrict UVM access to the guest subnetwork users while still allowing access to `/welcome` page, set the `GUEST_SUBNETWORK` variable. This makes sure guests do not have access to other UVM pages, such as the voucher management interface (the root `/` page).\n\u003e\n\u003e Without this configuration, guests **will be able** to access the voucher management interface of UVM. This means they will be able to both create and delete vouchers by themselves.\n\n- **`GUEST_SUBNETWORK`: `IPv4 CIDR`** (_Optional_)\n  - **Description**: Restrict guest subnetwork access to UVM while still permitting access to the `/welcome` page, which users are redirected to from the UniFi captive portal. For more details, see [Rolling Vouchers and Kiosk Page](#rolling-vouchers-and-kiosk-page).\n  - **Example**: `10.0.5.0/24`\n- **`FRONTEND_BIND_HOST`: `IPv4`** (_Optional_)\n  - **Description**: Address on which the frontend server binds.\n  - **Example**: `0.0.0.0` (default)\n- **`FRONTEND_BIND_PORT`: `u16`** (_Optional_)\n  - **Description**: Port on which the frontend server binds.\n  - **Example**: `3000` (default)\n- **`FRONTEND_TO_BACKEND_URL`: `URL`** (_Optional_)\n  - **Description**: URL where the frontend will make its API requests to the backend.\n  - **Example**: `http://127.0.0.1` (default)\n- **`BACKEND_BIND_HOST`: `IPv4`** (_Optional_)\n  - **Description**: Address on which the server binds.\n  - **Example**: `127.0.0.1` (default)\n- **`BACKEND_BIND_PORT`: `u16`** (_Optional_)\n  - **Description**: Port on which the backend server binds.\n  - **Example**: `8080` (default)\n- **`BACKEND_LOG_LEVEL`: `trace|debug|info|warn|error`** (_Optional_)\n  - **Description**: Log level of the Rust backend.\n  - **Example**: `info`(default)\n- **`TIMEZONE`: [`timezone identifier`](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List)** (_Optional_)\n  - **Description**: [Timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) used to format dates and time.\n  - **Example**: `UTC` (default)\n- **`ROLLING_VOUCHER_DURATION_MINUTES`: `minutes`** (_Optional_)\n  - **Description**: Number of minutes a rolling voucher will be valid for once activated.\n  - **Example**: `480` (default)\n- **`WIFI_SSID`: `string`** (_Optional_)\n  - **Description**: WiFi SSID used for the QR code. (required for QR code to be generated)\n  - **Example**: `My WiFi SSID`\n- **`WIFI_PASSWORD`: `string`** (_Optional_)\n  - **Description**: WiFi password used for the QR code. If the WiFi network does not have a password, set to an empty string `\"\"`. (required for QR code to be generated)\n  - **Example**: `My WiFi Password`\n- **`WIFI_TYPE`: `WPA|WEP|nopass`** (_Optional_)\n  - **Description**: WiFi security type used. Defaults to `WPA` if a password is provided and `nopass` otherwise.\n  - **Example**: `WPA`\n- **`WIFI_HIDDEN`: `bool`** (_Optional_)\n  - **Description**: Whether the WiFi SSID is hidden or broadcasted.\n  - **Example**: `false` (default)\n\n## 🐛 Troubleshooting\n\n### Common Issues\n\n- **Vouchers not appearing or connection issue to UniFi controller**\n  - Verify `UNIFI_CONTROLLER_URL` is correct and accessible\n  - Verify `UNIFI_SITE_ID` matches your controller's site\n  - Verify `UNIFI_HAS_VALID_CERT` is correct (depending on whether your `UNIFI_CONTROLLER_URL` has a valid SSL certificate or not)\n  - Check if the UniFi controller is running and reachable (DNS issues?)\n  - Ensure API key is valid\n  - Ensure the site has the hotspot/guest portal enabled\n- **Application won't start**\n  - Check all environment variables are set\n  - Verify Docker container has network access to UniFi controller\n  - Check logs: `docker logs unifi-voucher-manager`\n- **The WiFi QR code button is disabled**\n  - Check the [Environment Variables](#environment-variables) section and make sure you configured the variables required for the WiFi QR code\n  - Check the browser console for variable configuration errors (generally by hitting `F12` and going to the 'console' tab)\n\n### Getting Help\n\n- Check the [Issues](https://github.com/etiennecollin/unifi-voucher-manager/issues) page\n- Create a new issue with detailed information about your problem\n- Include relevant logs and environment details (redact sensitive information)\n  - Run the container/backend with `BACKEND_LOG_LEVEL=\"debug\"`\n  - Include Docker logs: `docker logs unifi-voucher-manager`\n  - Include browser logs: generally by hitting `F12` and going to the 'console' tab of your browser\n\n---\n\n**⭐ If this project helped you, please consider giving it a star!**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetiennecollin%2Funifi-voucher-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fetiennecollin%2Funifi-voucher-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetiennecollin%2Funifi-voucher-manager/lists"}