Commit graph

16 commits

Author SHA1 Message Date
Claude
a1021a0f84
feat: comprehensive UI/UX and feature improvements
- Dark mode: CSS custom properties (global.css) + toggle button, persisted in localStorage
- i18n: German/English language switcher (lang/de.php, lang/en.php, includes/I18n.php)
- Mobile-responsive admin layout: hamburger menu, sidebar overlay (global.js + global.css)
- Shared admin navigation include (includes/admin_nav.php) used across all admin pages
- Toast notifications system globally available via global.js
- Voucher templates/profiles: CRUD UI at admin/templates.php with voucher_templates DB table
- Bulk voucher creation: create 1-20 vouchers at once with multi-print layout on index.php
- Configurable voucher defaults: expire time, device limit, max limit in admin settings
- Template quick-select on voucher form: auto-fills max_uses and expire_minutes
- Password reset flow: forgot_password.php + reset_password.php with token-based reset
- Audit log UI: admin/audit_log.php with filter, pagination, audit_log DB table
- Audit logging on login, user create/edit/delete, site create/edit/delete
- Admin pages updated: index, vouchers, users, sites all use admin_nav.php + dark mode + i18n
- Voucher admin: live search input added alongside existing status filter + pagination
- Users admin: password-reset-link button per user row (when SMTP enabled)
- Login page: i18n, dark mode, language switcher, forgot password link

https://claude.ai/code/session_01YN6Bcm1VSi8mpDeyKpyrdJ
2026-05-08 17:59:17 +00:00
friloo
bf3e55a967
Merge pull request #5 from friloo/claude/unifi-api-migration-dbNMa
Claude/unifi api migration db n ma
2026-04-22 09:24:08 +02:00
Claude
e0a999b27b
Login only once per UniFiController instance to avoid rate limiting
createVoucher() calls apiRequest() twice (cmd/hotspot + stat/voucher),
which previously triggered two separate login requests in rapid succession.
The UniFi controller was rate-limiting the second attempt with 403.

Fix: $loggedIn flag ensures login() is a no-op after the first successful
authentication, reusing the existing session cookie for all API calls.

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-22 05:52:45 +00:00
Claude
897392041a
Fix session cookie not persisting due to Partitioned attribute
The TOKEN cookie set by UniFi OS includes the 'Partitioned' attribute
(CHIPS), which some libcurl versions do not write to the Netscape cookie
jar file. This caused every API request to go out unauthenticated,
resulting in 401/403 errors even after a successful login.

Fix: extract the TOKEN value directly from the Set-Cookie response
header in login() and pass it via CURLOPT_COOKIE in apiRequest(),
bypassing the broken file-based cookie jar. Cookie file remains as
fallback for environments where extraction fails.

Also update test.php section 8 to validate this fix and show the
extracted cookie value.

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-22 05:41:42 +00:00
Claude
e705458af3
Add UniFi API diagnostic section to test.php
Shows raw login HTTP code, all response headers, X-CSRF-Token extraction
(header + cookie file fallback), login response body, cookie file contents,
and a follow-up stat/voucher GET to verify the full auth+API flow.

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-22 05:35:15 +00:00
Claude
dbce0299d6
Add response body detail to login error messages for debugging
https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-22 05:31:04 +00:00
Claude
78a2b41329
Fix HTTP 403 on login: add Origin and Referer headers
UniFi OS enforces CSRF protection on the login endpoint itself and
returns 403 if Origin/Referer headers are absent, regardless of whether
the credentials are correct. Required headers:
  Origin: https://controller:port
  Referer: https://controller:port/login

Documented in Art-of-WiFi UniFi-API-client reference implementation.

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-22 05:28:17 +00:00
friloo
d3e2e669a7
Merge pull request #4 from friloo/claude/unifi-api-migration-dbNMa
Fix sites modal save: disabled button doesn't submit name attribute
2026-04-22 07:23:59 +02:00
Claude
7fdf156f5f
Fix sites modal save: disabled button doesn't submit name attribute
Move form action identifiers to hidden inputs (add_site, edit_site) so
the server-side isset() check always succeeds regardless of button state.
Pattern matches index.php (create_voucher hidden input).
Update JS loading-state selectors to match new button IDs.

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-22 05:20:53 +00:00
friloo
c418f8c5b5
Merge pull request #3 from friloo/claude/unifi-api-migration-dbNMa
Fix UniFi OS API login validation and HTTP method handling
2026-04-21 20:34:22 +02:00
Claude
2874ca0839
Fix UniFi OS API login validation and HTTP method handling
- Login: replace fragile unique_id/email check with proper HTTP 200 trust +
  explicit meta.rc=error detection (matches Art-of-WiFi reference impl)
- Login: add TOKEN cookie fallback for CSRF token extraction in case
  the X-CSRF-Token response header is absent (some firmware versions)
- getVouchers(): pass explicit 'GET' method instead of relying on cURL default
- apiRequest(): use CURLOPT_HTTPGET for GET requests; send CURLOPT_POSTFIELDS
  as empty object for POST with no data; CSRF header only on non-GET requests
- Remove array_filter() header construction, replace with clean conditional append

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-21 18:29:50 +00:00
friloo
b86746fef3
Merge pull request #2 from friloo/claude/unifi-api-migration-dbNMa
Fix sites freeze bug, add features and shorten README
2026-04-21 20:27:56 +02:00
Claude
73967caefa
Fix sites freeze bug, add features and shorten README
Bug fixes:
- UniFiController: add CURLOPT_TIMEOUT (10s) and CURLOPT_CONNECTTIMEOUT (5s)
  to login() and apiRequest() — prevents page freeze when controller unreachable
- UniFiController: fix login response validation for UniFi OS API which returns
  a user object instead of meta.rc=ok
- admin/sites.php: add JS loading state on form submit to give visual feedback
- login.php: handle new 'rate_limited' return value from Auth::login()

New features:
- Database: in-memory settings cache eliminates redundant DB queries per request
- Auth: login rate limiting (10 attempts per 10 min per IP/email) via login_attempts table
- admin/vouchers.php: CSV export with UTF-8 BOM for Excel compatibility
- admin/vouchers.php: client-side pagination (50 per page)
- index.php: QR code display after voucher creation (qrcodejs CDN)
- Mailer: sendTestEmail() method
- admin/settings.php: SMTP test button with AJAX handler
- database.sql: add login_attempts and audit_log tables

Readme: condensed from ~420 to ~220 lines, removed duplicated sections,
M365 Azure Portal walkthrough, contribution guidelines, update/migration section

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-21 16:08:08 +00:00
friloo
a667b65180
Merge pull request #1 from friloo/claude/unifi-api-migration-dbNMa
Migrate to UniFi OS API (port 11443)
2026-04-21 17:55:33 +02:00
Claude
3fd9b2190a
Migrate to UniFi OS API (port 11443)
- Update login endpoint: /api/login → /api/auth/login
- Add X-CSRF-Token extraction via CURLOPT_HEADERFUNCTION in login()
- Inject X-CSRF-Token header into all POST requests in apiRequest()
- Prefix all API paths with /proxy/network (createVoucher, getVouchers, deleteVoucher)
- Update admin/sites.php placeholder and help text to reflect port 11443
- Update Readme.md: fix GitHub clone URL, update port references, rewrite
  API documentation section for UniFi OS, add UniFi OS troubleshooting entry,
  bump version to 2.1.0

https://claude.ai/code/session_01UsuvFAmmeagtQa14QA4iaq
2026-04-21 15:54:56 +00:00
friloo
dbdc237fa1
Initial Upload 2026-04-21 17:45:58 +02:00