Repository navigation
Releases
3.17.0 - Email Handling, Audit Log, Better Selfhosting Stack, Token Limits
⚠️ Breaking changes
Retired v1 account auth endpoints (#322): these predate Cloudflare Turnstile and had captcha-less request bodies. They now return 410 Gone with a problem response pointing at the replacement, and are hidden from the OpenAPI document:
| Retired | Replacement |
|---|---|
POST /1/account/login |
POST /2/account/login |
POST /1/account/signup |
POST /2/account/signup |
POST /1/account/reset |
POST /2/account/password-reset |
POST /2/account/reset-password |
POST /2/account/password-reset |
GET / HEAD /1/account/recover/{id}/{secret} |
canonical password-reset routes |
LCG Redis index re-keyed: LcgNode is now keyed by a composite host[:port][/path] id; index lcg-online-v4 → lcg-online-v5. Fqdn was renamed to Host, with new Port and PathPrefix fields. Default port / root-path deployments stay byte-identical to the old bare-host key.
6 new database migrations: AddUserSecurityStamp, MakeApiTokenLastUsedNullable, AddApiTokenShockerControl, AddEmailOutbox, RefactorPgEnums, AddUserAuditLog. RefactorPgEnums and AddEmailOutbox introduce new Postgres enum types, so non-migrating services (gateways) need a restart after the migration to refresh their type catalog.
✨ What's new
Audit log (#314)
A new per-user audit trail covering logins/logouts, email/username/password changes, OAuth connection changes, token create/delete, and admin actions (deactivate / reactivate / delete / patch user). Exposed via GET /1/account/audit-log for users, plus an admin-scoped endpoint for operators.
Durable email outbox (#327)
Transactional email moved from inline sends to a database-backed outbox, so mail is never lost on provider failure.
- Push-triggered worker via Redis pub/sub with a 15s poll fallback; claims rows with
FOR UPDATE SKIP LOCKED, so it's safe across every replica. - Exponential backoff + jitter; retries on 5xx / 429 / transport errors.
- Tokens are minted lazily at send time (and re-minted on resend), so the queue never stores a usable link.
IEmailServicenow returnsEmailSendResult(Sent / Transient / Permanent) instead of throwing.
v2 token endpoints (#312)
Reworked API token surface with per-token control limits (intensity/duration caps, allowed control types) and pausing.
Single-host reverse proxying
Self-hosters can run the whole stack on one host under path prefixes (example.org/api, example.org/gateway) instead of a subdomain per service.
- API/LCG mount under an optional path base (
OpenShock:Api:PathBase,OPENSHOCK__LCG__PUBLICPATH); generated URLs (OAuthredirect_uri, Scalar) keep the prefix. - LCG advertises a configurable public port/path (
LcgOptions.PublicPort/PublicPath). assignLCGv2 returns the real host/port/path, plus a new v2{deviceId}/lcgreturning gateway host/port/base-path so the browser builds the live-control URL itself. v1 endpoints stay bare-host:443 legacy.
Email change flow & password reset hardening (#301)
Full email-change flow with confirmation, plus an EmailChangeNotice mail to the old address. Password reset paths hardened across initiate / check / complete.
Admin mail queue management (#335)
New admin endpoints for the outbox: list, stats, requeue, cancel, delete, bulk operations, and test-send.
Other additions
- Disable signups (#318): new
OpenShock:Account:RegistrationEnabledoption (defaulttrue), enforced on v1/v2 signup and OAuth signup finalize. - Mail-disabled mode: new
OpenShock:Mail:Typeoption withNone; accounts are activated immediately when no activation link can be delivered. - Generated email templates (#305): templates now built from a pnpm workspace and exported at build time.
- Shocker log pagination: the all-shocker logs endpoint is now paginated via a new shared
PaginationQuery/PagedResulthelper. HasPasswordadded to theUserSelfresponse.- Reworked docker-compose: restructured compose files and
.env, plus a configurable image tag variable.
🔒 Security
- CVE-2026-40372 patched via dependency updates.
- Defense-in-depth admin re-verification: every admin action independently re-checks
CurrentUser.RolesforAdminat the top of the handler, so a loosened or removed[Authorize]attribute can't leak an admin operation. - Expired or duplicate Turnstile tokens now return 403 instead of a misleading status.
- Used email addresses are properly rejected on OAuth register.
🐛 Notable fixes
- Fixed an exception caused by firmware sending bad timestamps.
- Email outbox listing no longer 500s on the jsonb payload.
- Cron host gates startup on schema readiness before opening the pooled context (#329).
- Enum types are reloaded when migrations need to apply.
- Improved Cloudflare IP list fetching (#293).
- Fixed the compose port mapping.
New Contributors
Full Changelog: 3.16.0...3.17.0
3.16.0 - Wellturn T330 Shocker Support!
OpenShock Backend 3.16.0
This release includes new device support, new API capabilities, share handling fixes, and reliability improvements across the LiveControlGateway and backend services.
Added
- Added /shockers/logs endpoint for retrieving shocker log history
- Added support for the Wellturn T330 shocker model
- Added bulk removal support for user shares
- Added connected hub metrics and improved gateway metric tagging
- Share invite responses now include names
Improved
- Reworked LCG assignment logic and added integration test coverage for it
- Improved gateway keep-alive handling
- Improved hub self-online resilience
- Improved SHA-256 hashing helper
- Cleaned up deprecated device pair exposure in OpenAPI
- Normalized response model naming for device-related API responses
Fixed
- Fixed public share handling
- Public share listings now return only non-expired shares
- Prevented users from claiming their own share
- Fixed incorrect offline status handling
- Updated seed/test SQL and expanded test coverage around LCG behavior
Platform / Maintenance
- Upgraded the backend/tooling to .NET 10
- Multiple dependency updates across NuGet packages and GitHub Actions
- Dependabot configuration cleanup and grouped update improvements
- General code cleanup, test cleanup, and test parallelization improvements
Contributors
Thanks to everyone who contributed to this release:
Full Changelog: 3.15.1...3.16.0
3.15.1
What's Changed
- Reduce IOptions usage by @hhvrc in #237
- Password timing attack mitigation by @hhvrc in #238
- feat: Add oauth support by @hhvrc in #235
- fixed: docker image tags being published correctly by @LucHeart
- Bump the nuget-dependencies group with 1 update by @dependabot[bot] in #239
- Bump the nuget-dependencies group with 1 update by @dependabot[bot] in #241
- Bump the nuget-dependencies group with 4 updates by @dependabot[bot] in #242
- Bump the nuget-dependencies group with 6 updates by @dependabot[bot] in #243
Full Changelog: 3.15.0...3.15.1
3.15.0
What's Changed
- Update MailKit and 5 other dependencies by @dependabot[bot] in #191
- feat: Automatically update cloudflare proxy ip lists by @hhvrc in #192
- Update TUnit to 0.19.143; Z.EntityFramework.Plus.EFCore to 9.103.8.1 by @dependabot[bot] in #193
- Shares rework by @hhvrc and @LucHeart in #194
- AssignLCG v2 endpoint by @hhvrc in #195
- Rework account activation and deactivation by @hhvrc in #196
- Feature/ci tests by @LucHeart in #202
- Add webhook support by @hhvrc in #201
- Add token reporting endpoint by @LucHeart in #151
- Bump Scalar.AspNetCore and TUnit by @dependabot[bot] in #204
- Bump the nuget-dependencies group with 6 updates by @dependabot[bot] in #206
- Introduce max devices and shockers per user limit by @hhvrc in #207
- Add CRON job to delete deactivated accounts by @hhvrc in #208
- Create seeder for e2e testing by @hhvrc in #205
- Improve null checking project-wide by @hhvrc in #210
- Bump the nuget-dependencies group with 2 updates by @dependabot[bot] in #212
- Fix password reset lifetime check by @hhvrc in #217
- Verify user exists after signup by @hhvrc in #221
- Fix typos in README by @hhvrc in #218
- Redishub cache subscriptions dict by @hhvrc in #225
- Add AGENTS instructions by @hhvrc in #220
- Make user deactivation prevent login by @hhvrc in #222
- Add device estop and reboot support by @hhvrc in #224
- Create dirty word/email domain list by @hhvrc in #223
- chore: Clean up token and hash columns by @hhvrc in #230
- Add ratelimiting middleware by @hhvrc in #226
- Email verification/Account activation by @hhvrc in #229
- Add configuration service by @hhvrc in #209
- Bump actions/checkout from 4 to 5 by @dependabot[bot] in #232
- Implement binary serialization for backchannel comms by @hhvrc in #231
- Bump actions/setup-dotnet from 4 to 5 by @dependabot[bot] in #236
Full Changelog: 3.13.0...3.15.0
3.13.0
What's Changed
- build(deps): Bump the nuget-dependencies group with 2 updates by @dependabot in #188
- Feature/rework websocketbase by @LucHeart in #190
-
- OpenAPI / scalar adjustments and improvements
Full Changelog: 3.12.0...3.13.0
3.11.0
What's Changed
- build(deps): Bump the nuget-dependencies group with 8 updates by @dependabot in #162
- Allow tokens to delete themselves by @LucHeart in #165
- build(deps): Bump the nuget-dependencies group with 20 updates by @dependabot in #166
- Decrease IEnumerable usage by @hhvrc in #161
- Create API integration tests by @hhvrc in #158
- feat: Take Options pattern into use by @hhvrc in #168
- bugfix: Fix integration tests by @hhvrc in #170
- build(deps): Bump the nuget-dependencies group across 1 directory with 10 updates by @dependabot in #171
- chore: NuGet packages cleanup by @hhvrc in #172
- Move endpoint configuration to appsettings.json files by @hhvrc in #173
- build(deps): Bump the nuget-dependencies group with 2 updates by @dependabot in #174
- build(deps): Bump the nuget-dependencies group with 2 updates by @dependabot in #176
- build(deps): Bump the nuget-dependencies group with 3 updates by @dependabot in #178
- Feature/improve livecontrol handling by @LucHeart in #179
- Fix firmware update reporting being able to cause issues
Full Changelog: 3.10.5...3.11.0
3.10.5
- Made changes to the new Shocker Control Log Cleanup Job
Full Changelog: 3.10.4...3.10.5
3.10.4
What's Changed
- Cleanup project files by @hhvrc in #156
- build(deps): Bump the nuget-dependencies group with 2 updates by @dependabot in #159
- Query ExpressionBuilder BugFixing by @hhvrc in #160
- Add ShockerControlLogs Cron clear job by @hhvrc in #157
- Fix ota history endpoint
Full Changelog: 3.10.3...3.10.4