The separate J3vb/OwnCord-releases repo existed only because this repo was private: it carried the AGPL source snapshot and provided a publicly-readable update feed. Once this repo is public both roles collapse into its own Releases page, so the mirror is pure redundancy. - Server/config/config.go: github.repo default OwnCord-releases -> OwnCord. This one default drives both the server self-update and the client auto-update chain (tauri.conf.json updater.endpoints is empty, so the client resolves through the server). No test pinned the old value. - release.yml: drop the mirror step and its RELEASES_REPO_TOKEN guard, whose AGPL/private-repo premise no longer holds. The existing Create GitHub Release step is now the sole publish target. All 31 SHA pins verified intact. - Repoint the README badge/download link, both SECURITY.md links, the server-configuration table and sample, the system-overview diagram node and the CHANGELOG note. SECURITY.md's advisory link is the load-bearing one: left alone it would 404 once the mirror repo is deleted. - README: Go 1.25+ -> 1.26+ (badge and prerequisite) to match the toolchain actually required. Deleting the mirror repo loses nothing: both repos' v1.1.0-alpha.2 carry byte-identical asset sets, signatures and update manifest included. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.6 KiB
Changelog
All notable changes to OwnCord are listed here. The repository's release
tooling (npm run changelog) auto-generates entries from commit messages
on each release; this file is the curated counterpart that calls out
behavioural changes operators must know about.
Unreleased — v1.1.0-alpha series (Phase B + C)
Project reset note: OwnCord has re-entered alpha. The
v1.0.0release is superseded; versioning continues forward asv1.1.0-alpha.Nso deployed servers and clients keep receiving updates. Releases are published to this repository's Releases page, including a full source snapshot with every release.
Phase B — Acceleration
- Event persistence layer (Step 7). A new
eventstable backs the WebSocket reconnect path. When a client'slast_seqis too old for the in-memory ring buffer (~1000 events), the server now falls back to a SQLite query before forcing a full re-sync. The hub seeds its monotonic sequence counter fromMAX(events.seq)at startup so row seqs and wrapped-payload seqs stay aligned across restarts. Configurable via the newevent_persistenceblock; enabled by default (see "Behavioural changes" below). - Tiered reconnect telemetry.
auth_oknow includes areplay_sourcefield ("none" | "buffer" | "db") so clients can attribute reconnection behaviour. The same tier label is exported as thews_reconnect_tier_total{tier}counter. - OpenTelemetry skeleton (Step 8). Public API + no-op default
provider in
Server/telemetry/. Chi router middleware mounted unconditionally. Service-layer spans onMessageService.SendMessage,PermissionService.HasChannelPerm,ChannelService.ListVisibleChannels,DMService.CreateDM,VoiceService.JoinChannel,InviteService.CreateInvite,ModerationService.BanUser,BlockService.BlockUser,UserService.UpdateProfile. The real OTel SDK is gated behind-tags oteland is currently a placeholder; completing it is deferred until after the beta reset. - Solid.js proof of concept (Step 6). Two leaf components migrated
(
Badge,ChannelListItem), Vite + JSX configured, store→signal adapter landed. The remaining vanilla components remain in place; migration is mechanical and tracked in the local TODO.
Phase C — Differentiation
- Plugin runtime skeleton (Step 9). New
Server/plugin/package with manifest parser, on-disk loader, registry, and host capability surfaces (commands,events,storage,http,ui). Manifest format is JSON (plugin.json); the design's TOML format is gated behind the-tags wazerobuild and tracked locally. - Plugin admin REST surface. Lifecycle endpoints under
/api/v1/admin/plugins: list, enable, disable, uninstall, and the new install path that accepts a multipart zip upload, validates it zip-slip safe with size + symlink rejection, and atomically installs it. Mounted under bothAdminIPRestrictand theadmin.RequireAdminAuthsession/permission middleware. - Plugin admin client bridge.
pluginBridge.tsmounts plugin UI tabs in sandboxed iframes with origin-validated postMessage routing.
Security
- SSRF defense for
httpcapability. Plugin outbound HTTP requests are now validated throughnet/url.Parse, suffix-matched with a dot boundary (soevil-api.example.comdoes not matchapi.example.com), and rejected for empty allowlist entries. A customTransport.DialContextre-resolves DNS on every dial and refuses any resolved address in loopback / RFC1918 / RFC4193 / RFC6598 (CGN) / link-local / multicast / unspecified ranges. Closes the DNS-rebinding TOCTOU window. Response body is capped at 5 MiB. - Plugin manifest hardening.
Manifest.Namemust match^[a-z0-9][a-z0-9_-]{0,63}$. Entrypoint and UI tab asset paths are rejected if absolute, non-canonical, contain.., or contain NUL bytes / backslashes. - Plugin asset handler. Defends against symlink escapes (rejected
at install time via
filepath.Walk+Lstat) and prefix-without- separator path traversal (viafilepath.Relcheck after join). - Plugin postMessage routing. The host bridge looks up the trusted
pluginId via
e.source -> contentWindowinstead of trusting thepluginIdfield in the message body. Spoofed messages from any non-iframe source are dropped.
Behavioural changes operators must know about
event_persistence.enableddefaults totrue. Every broadcast WebSocket event is written to theeventstable, retained for 24 hours by default, and pruned by a background goroutine every hour. This is a new on-disk write path that did not exist before. Disable it by adding toconfig.yaml:event_persistence: enabled: false- DM events are persisted under the same retention. Operators with
GDPR or compliance requirements should review the retention window
and consider setting
event_persistence.enabled: falseuntil a per-channel-type opt-out lands. - Plugin admin endpoints require admin session auth in addition to the existing IP restriction. A previous prerelease shipped with only the IP gate; that has been corrected.
Deferred work
The project is under a feature freeze until the beta reset completes.
Explicitly deferred (not abandoned unless noted): real OpenTelemetry SDK
wiring, the Postgres backend (scaffolding removed pending real demand),
the slash-command dispatcher (docs/plans/slash-commands.md), and the
Solid.js migration (abandoned — the experiment is being removed in favor
of the established vanilla component pattern).