chore: sync upstream SiaFoundation/indexd - #19
Conversation
update openapi spec track sharing key stats track sharing key stats review fixes - sync openapi to the SealedObject list response and key stat fields - fix migration trigger to maintain sharing_keys.size like init.sql - drop redundant test comments
Support adding and removing sharing keys and shared objects
The UPDATE paths already truncate to whole seconds; inserts took the column default and kept microseconds. A client cursor carries milliseconds, so a row with a sub-millisecond remainder stays strictly greater than the cursor built from it and is redelivered on every poll, leaving that client's cursor stuck until something else updates the object. Changes the default rather than the column type, so no table rewrite. Rows already written are not corrected here.
chore: prepare release 0.4.2
Bumps the dependencies group with 1 update: [go.sia.tech/coreutils](https://github.com/SiaFoundation/coreutils). Updates `go.sia.tech/coreutils` from 0.23.6-0.20260717131215-dfd89d065259 to 0.24.0 - [Release notes](https://github.com/SiaFoundation/coreutils/releases) - [Changelog](https://github.com/SiaFoundation/coreutils/blob/master/CHANGELOG.md) - [Commits](https://github.com/SiaFoundation/coreutils/commits/v0.24.0) --- updated-dependencies: - dependency-name: go.sia.tech/coreutils dependency-version: 0.24.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps the dependencies group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto). Updates `golang.org/x/crypto` from 0.54.0 to 0.55.0 - [Commits](golang/crypto@v0.54.0...v0.55.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.55.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps the dependencies group with 1 update: [github.com/klauspost/reedsolomon](https://github.com/klauspost/reedsolomon). Updates `github.com/klauspost/reedsolomon` from 1.14.1 to 1.14.2 - [Release notes](https://github.com/klauspost/reedsolomon/releases) - [Commits](klauspost/reedsolomon@v1.14.1...v1.14.2) --- updated-dependencies: - dependency-name: github.com/klauspost/reedsolomon dependency-version: 1.14.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] <support@github.com>
# Conflicts: # .github/workflows/publish.yml
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
| // register one account. | ||
| var status int | ||
| var err error | ||
| a.mu.Lock() |
There was a problem hiding this comment.
The one-time connection request is removed from a.authRequests at line 904 under the lock before RegisterAppKey succeeds at line 914, consuming the approval even on failure. ErrKeyExhausted (403), ErrKeyNotFound (401), or transient/internal errors permanently discard the user's request with no retry possible; delete the request only after successful registration, or move the delete into the success branch of the switch (lines 921-937).
Prompt for LLM
File api/app/app.go:
Line 892:
The one-time connection request is removed from a.authRequests at line 904 under the lock before RegisterAppKey succeeds at line 914, consuming the approval even on failure. ErrKeyExhausted (403), ErrKeyNotFound (401), or transient/internal errors permanently discard the user's request with no retry possible; delete the request only after successful registration, or move the delete into the success branch of the switch (lines 921-937).
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| } | ||
|
|
||
| err := a.accounts.RegisterAppKey(authReq.ConnectKey, registerReq.AppKey, accounts.AppMeta{ | ||
| // validate the request and consume it, so that one approval can only ever |
There was a problem hiding this comment.
The auth request is deleted from a.authRequests (line 904) under the lock before RegisterAppKey (line 914) succeeds, permanently consuming the one-time approval on transient failures like DB errors, ErrKeyExhausted, or ErrKeyNotFound. Move the deletion into the success path after line 936 to preserve the consume-once anti-replay guarantee while retaining the request on failure.
default:
// deferred: only consume on successful registration below
}
a.mu.Unlock()
if err != nil {
jc.Error(err, status)
return
} else if authReq.UserSecret == (types.Hash256{}) {
panic("user secret is empty for approved request")
}
err = a.accounts.RegisterAppKey(authReq.ConnectKey, registerReq.AppKey, accounts.AppMeta{
ID: authReq.Request.AppID,
Name: authReq.Request.Name,
Description: authReq.Request.Description,
LogoURL: authReq.Request.LogoURL,
ServiceURL: authReq.Request.ServiceURL,
})
// on success (no error), consume the request under the lock
if err == nil {
a.mu.Lock()
delete(a.authRequests, requestID)
a.mu.Unlock()
}Prompt for LLM
File api/app/app.go:
Line 888:
The auth request is deleted from a.authRequests (line 904) under the lock before RegisterAppKey (line 914) succeeds, permanently consuming the one-time approval on transient failures like DB errors, ErrKeyExhausted, or ErrKeyNotFound. Move the deletion into the success path after line 936 to preserve the consume-once anti-replay guarantee while retaining the request on failure.
Suggested Code:
default:
// deferred: only consume on successful registration below
}
a.mu.Unlock()
if err != nil {
jc.Error(err, status)
return
} else if authReq.UserSecret == (types.Hash256{}) {
panic("user secret is empty for approved request")
}
err = a.accounts.RegisterAppKey(authReq.ConnectKey, registerReq.AppKey, accounts.AppMeta{
ID: authReq.Request.AppID,
Name: authReq.Request.Name,
Description: authReq.Request.Description,
LogoURL: authReq.Request.LogoURL,
ServiceURL: authReq.Request.ServiceURL,
})
// on success (no error), consume the request under the lock
if err == nil {
a.mu.Lock()
delete(a.authRequests, requestID)
a.mu.Unlock()
}
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| // key must resolve to an existing, unexpired sharing key. On success it returns | ||
| // that sharing key. | ||
| func validateSharedURLAuth(jc jape.Context, hostname string, store Sharing) (sharing.Key, bool) { | ||
| pk, ok := ValidateURLSignature(jc.Request, jc.ResponseWriter, hostname) |
There was a problem hiding this comment.
No hard-coded secrets are introduced in this diff; only the provided public key and environment-derived values are used. No issue found.
Kody rule violation: Ban hard-coded secrets in Go source
Prompt for LLM
File api/app/auth.go:
Line 131:
No hard-coded secrets are introduced in this diff; only the provided public key and environment-derived values are used. No issue found.
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
| return fmt.Errorf("failed to get object: %w", err) | ||
| } | ||
|
|
||
| // capture the object's sizes at attach time so the trigger can |
There was a problem hiding this comment.
AddSharedObject persists a one-time snapshot of size/pinned_data/pinned_size into shared_objects without updating it when the underlying object's slab footprint changes, leaving both the shared_objects row and the key's aggregate totals permanently stale. Recompute and refresh the shared_objects size columns on object update, or recalculate the key totals on read rather than relying on the maintain-totals trigger alone.
Prompt for LLM
File persist/postgres/sharing.go:
Line 189:
AddSharedObject persists a one-time snapshot of size/pinned_data/pinned_size into shared_objects without updating it when the underlying object's slab footprint changes, leaving both the shared_objects row and the key's aggregate totals permanently stale. Recompute and refresh the shared_objects size columns on object update, or recalculate the key totals on read rather than relying on the maintain-totals trigger alone.
Talk to Kody by mentioning @kody
Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.
Merges
SiaFoundation/indexd:masterintoLumeWeb/indexd:master(52 upstream commits through54410b0f).Summary
This pull request synchronizes the repository with upstream changes from the
SiaFoundation/indexdrepository, bringing a substantial set of new features, performance improvements, and bug fixes. The primary additions are a new object blocklist for content moderation and a new sharing key system for granting scoped, read-only access to objects without requiring viewer accounts. The update also includes host management improvements, administrative API enhancements, and various performance optimizations.Object Blocklist (Content Moderation)
GET /objects/blocklist,GET/PUT/DELETE /objects/blocklist/{objectkey}for managing a list of blocked objects.GET /objects, sharing key listings) and cannot be fetched, pinned, or shared. Fetching returns HTTP status451 Unavailable For Legal Reasons.Sharing Keys
POST/GET/DELETE /sharing,GET/DELETE /sharing/{key},POST/GET/DELETE /sharing/{key}/objectsto manage sharing keys and attach/detach objects.GET /shared,GET /shared/objects,GET /shared/objects/{id},GET /shared/hostsprovide read-only access to objects via a sharing key./shared/hostsendpoint includes tokens for paying for downloads from hosts.Host Management
POST /hostsendpoint to manually add a host and its network addresses to the indexer for scanning. Validates addresses and formats.POST /hosts/scan?force=trueendpoint to force scanning every host, regardless of schedule.host:portchecking and port range validation.Performance Improvements
Bug Fixes
Version Updates
Changelog