Repository navigation
v4.9.0
Upgrading from 4.8 takes three steps. The API contract stays at 7 and the module contract at 1, so barakoBrew 1.8.0, barakoPress 0.12.0 and every module built for 4.x keep working.
- Stop the API. Two migrations ship under
migrations/4.9.0/, both core's and both new tables, empty on arrival:gapless-numbering.sql(the number counters and the external number ledger) andstations.sql(station keys). - Run
db-migrate, thendb-assert.scripts/upgrade-check.sh --listprints both files and their rollbacks. Rolling backgapless-numbering.sqlloses where each series stands, so take a backup first. - Start 4.9.0. Nothing new has to be configured. A role with
RequireMfaset sends its users without MFA to MFA setup from their next sign in or token refresh (within 15 minutes), so tell them before you turn it on.
Added
- Gapless numbering.
INumberAllocatorhands out gapless numbers per tenant and series, with yearly, monthly or daily reset at local midnight in a chosen time zone. The counter row stays locked until the caller's session commits, and a rolled back session gives its number to the next caller. - External number ledger.
IExternalNumberLedgerrecords numbers issued outside barakoCMS, andGET /api/numbering/external/{series}/gaps(capabilityview_number_gaps, granted to Admin) lists the ones in a range that were never recorded. - Change feed.
GET /api/changes?after=&topics=&limit=returns the events after a sequence for the topics the caller holds, in the caller's tenant. It never reads past the store's high-water mark, so an event that commits after a higher one is still delivered. - Module topics. Modules declare topics with
IBarakoModule.ConfigureTopics, each a group of the module's own event types and the capability needed to read them. Topic capabilities appear inGET /api/capabilitiesand can be granted through roles. - Caller capability check.
ICallerCapabilitiesanswers whether the signed-in caller holds a capability, for code outside an endpoint. - Roles can require MFA.
Role.RequireMfa. A user holding such a role who has not turned on MFA gets a token markedmfa_enroll=required(andMfaEnrollmentRequiredin the login response) that reaches only/api/auth/mfa/setup,/enable,/status, refresh and logout. Other endpoints answer 403 withX-Mfa-Enrollment-Required: true.PUT /api/roles/{id}withoutRequireMfakeeps the stored value. - Step-up codes.
POST /api/auth/mfa/step-uptakes a TOTP or recovery code and returns a token good forAuth:StepUp:Seconds(default 300). Endpoints markedDefinition.RequireStepUp()need it inX-Step-Up, and answer 403 withX-Step-Up-Required: truewithout it. Wrong codes count toward account lockout. - Modules can register their own events and projections.
IModuleSchema.AddEventType<T>()andIModuleSchema.AddProjection<T>(lifecycle)follow the same ownership rule asFor<T>(), and events are stored under{module}.{event}. - Realtime hub. SignalR hub at
/hubs/realtime. A signed-in caller subscribes to module topics it holds the capability for, and hearschangednotices (topic,sequence,streamId,type, never event data) after each commit, for its own tenant only. The hub is closed to API keys: a connection that signs in with one is aborted andSubscriberefuses it. The bearer token may come in theaccess_tokenquery string on hub paths only. - Test host handler.
BarakoTestHost.CreateHandler()for clients that need the in-memory server's handler, such as a SignalRHubConnection. - Notice then feed. A notice can arrive before the feed reaches its
sequence.docs/realtime.mdsays to read again after a short delay, backing off, untilnextreaches it. - Station keys.
POST /api/stations,GET /api/stationsandPOST /api/stations/{id}/revoke, gated by the newmanage_stationscapability. A station is a machine with no signed-in person, such as a kiosk or display board, holding a fixed list of capabilities in one tenant. The key (bsta_prefix) is returned once and only its hash is stored. A caller can only grant capabilities they hold, and*andmanage_stationsare refused. - Stations sign in with the key.
Authorization: Bearer bsta_...works on the change feed (GET /api/changes) and the realtime hub, which also accepts it asaccess_tokenin the query string. Prefer the header: a station key never expires, and the query form puts it in access logs. The station's tenant comes from the key, not fromX-Tenant. A revoke is refused on the station's next request. - Stations are closed by default. A station can call only endpoints that opt in with
Definition.AllowStations(). Every other endpoint answers 403. Module endpoints use the same call to let stations in. - Revoked stations lose the hub. A station's sign-in lasts 15 minutes, so an open hub connection closes and the reconnect is refused, and
Subscriberefuses a revoked station at once.
Changed
- The stale pull request refresher needed a token made by hand. It now updates a branch with
GITHUB_TOKENand then startsci.ymlon it throughworkflow_dispatch, since a push made with
that token starts no workflow. The checks report on the updated head under their usual names.
REFRESH_PR_TOKENis no longer read and can be deleted. A branch whose update would bring in a
change under.github/workflows/is reported as needing a hand, becauseGITHUB_TOKENmay not
write there.