From 509a1c03068ac1463ca5dde9c4508ebfa6084980 Mon Sep 17 00:00:00 2001 From: Evan Jarrett Date: Sat, 20 Dec 2025 10:46:40 -0600 Subject: [PATCH] some lexicon json cleanup. code formatting --- go.mod | 10 ++--- go.sum | 16 ++++---- lexicons/io/atcr/hold.json | 37 ----------------- lexicons/io/atcr/hold/captain.json | 47 +++++++++++++++++++++ lexicons/io/atcr/hold/crew.json | 35 +++++++--------- lexicons/io/atcr/hold/layer.json | 48 ++++++++++++++++++++++ lexicons/io/atcr/manifest.json | 9 +++- pkg/appview/middleware/registry.go | 6 +-- pkg/appview/ogcard/card.go | 2 +- pkg/appview/routes/routes.go | 2 +- pkg/appview/storage/manifest_store_test.go | 12 +++--- pkg/atproto/lexicon.go | 2 +- pkg/auth/token/handler.go | 8 ++-- 13 files changed, 145 insertions(+), 89 deletions(-) delete mode 100644 lexicons/io/atcr/hold.json create mode 100644 lexicons/io/atcr/hold/captain.json create mode 100644 lexicons/io/atcr/hold/layer.json diff --git a/go.mod b/go.mod index a65e07d..4b24f26 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module atcr.io -go 1.24.7 +go 1.25.5 require ( github.com/aws/aws-sdk-go v1.55.5 - github.com/bluesky-social/indigo v0.0.0-20251031012455-0b4bd2478a61 + github.com/bluesky-social/indigo v0.0.0-20251218205144-034a2c019e64 github.com/distribution/distribution/v3 v3.0.0 github.com/distribution/reference v0.6.0 github.com/earthboundkid/versioninfo/v2 v2.24.1 @@ -32,7 +32,7 @@ require ( github.com/yuin/goldmark v1.7.13 go.opentelemetry.io/otel v1.32.0 go.yaml.in/yaml/v4 v4.0.0-rc.2 - golang.org/x/crypto v0.39.0 + golang.org/x/crypto v0.44.0 golang.org/x/image v0.34.0 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 gorm.io/gorm v1.25.9 @@ -143,9 +143,9 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/net v0.37.0 // indirect + golang.org/x/net v0.47.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.33.0 // indirect + golang.org/x/sys v0.38.0 // indirect golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect diff --git a/go.sum b/go.sum index b5fad16..5347770 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bluesky-social/indigo v0.0.0-20251031012455-0b4bd2478a61 h1:lU2NnyuvevVWtE35sb4xWBp1AQxa1Sv4XhexiWlrWng= -github.com/bluesky-social/indigo v0.0.0-20251031012455-0b4bd2478a61/go.mod h1:GuGAU33qKulpZCZNPcUeIQ4RW6KzNvOy7s8MSUXbAng= +github.com/bluesky-social/indigo v0.0.0-20251218205144-034a2c019e64 h1:84EWie083DZT0eMo76kcZ0mBDcLUmWQu5UFE8/3ZW4k= +github.com/bluesky-social/indigo v0.0.0-20251218205144-034a2c019e64/go.mod h1:KIy0FgNQacp4uv2Z7xhNkV3qZiUSGuRky97s7Pa4v+o= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= @@ -466,8 +466,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8= @@ -487,8 +487,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -510,8 +510,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/lexicons/io/atcr/hold.json b/lexicons/io/atcr/hold.json deleted file mode 100644 index c4e7e93..0000000 --- a/lexicons/io/atcr/hold.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "lexicon": 1, - "id": "io.atcr.hold", - "defs": { - "main": { - "type": "record", - "description": "Storage hold definition for Bring Your Own Storage (BYOS). Defines where blobs are stored.", - "key": "any", - "record": { - "type": "object", - "required": ["endpoint", "owner", "createdAt"], - "properties": { - "endpoint": { - "type": "string", - "format": "uri", - "description": "URL of the hold service (e.g., 'https://hold1.example.com')" - }, - "owner": { - "type": "string", - "format": "did", - "description": "DID of the hold owner" - }, - "public": { - "type": "boolean", - "description": "Whether this hold allows public blob reads (pulls) without authentication. Writes always require crew membership.", - "default": false - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Hold creation timestamp" - } - } - } - } - } -} diff --git a/lexicons/io/atcr/hold/captain.json b/lexicons/io/atcr/hold/captain.json new file mode 100644 index 0000000..7a7664f --- /dev/null +++ b/lexicons/io/atcr/hold/captain.json @@ -0,0 +1,47 @@ +{ + "lexicon": 1, + "id": "io.atcr.hold.captain", + "defs": { + "main": { + "type": "record", + "description": "Represents the hold's ownership and metadata. Stored as a singleton record at rkey 'self' in the hold's embedded PDS.", + "key": "literal:self", + "record": { + "type": "object", + "required": ["owner", "public", "allowAllCrew", "enableBlueskyPosts", "deployedAt"], + "properties": { + "owner": { + "type": "string", + "format": "did", + "description": "DID of the hold owner" + }, + "public": { + "type": "boolean", + "description": "Whether this hold allows public blob reads (pulls) without authentication" + }, + "allowAllCrew": { + "type": "boolean", + "description": "Allow any authenticated user to register as crew" + }, + "enableBlueskyPosts": { + "type": "boolean", + "description": "Enable Bluesky posts when manifests are pushed" + }, + "deployedAt": { + "type": "string", + "format": "datetime", + "description": "RFC3339 timestamp of when the hold was deployed" + }, + "region": { + "type": "string", + "description": "S3 region where blobs are stored" + }, + "provider": { + "type": "string", + "description": "Deployment provider (e.g., fly.io, aws, etc.)" + } + } + } + } + } +} diff --git a/lexicons/io/atcr/hold/crew.json b/lexicons/io/atcr/hold/crew.json index 6887cc7..1f62fc1 100644 --- a/lexicons/io/atcr/hold/crew.json +++ b/lexicons/io/atcr/hold/crew.json @@ -4,40 +4,33 @@ "defs": { "main": { "type": "record", - "description": "Crew membership for a storage hold. Stored in the hold owner's PDS to maintain control over write access. Supports explicit DIDs (with backlinks), wildcard access, and handle patterns. Crew members can push blobs to the hold. Read access is controlled by the hold's public flag, not crew membership.", + "description": "Crew member in a hold's embedded PDS. Grants access permissions to push blobs to the hold. Stored in the hold's embedded PDS (one record per member).", "key": "any", "record": { "type": "object", - "required": ["hold", "role", "createdAt"], + "required": ["member", "role", "permissions", "addedAt"], "properties": { - "hold": { - "type": "string", - "format": "at-uri", - "description": "AT-URI of the hold record (e.g., 'at://did:plc:owner/io.atcr.hold/hold1')" - }, "member": { "type": "string", "format": "did", - "description": "DID of crew member (for individual access with backlinks). Exactly one of 'member' or 'memberPattern' must be set." - }, - "memberPattern": { - "type": "string", - "description": "Pattern for matching multiple users. Supports wildcards: '*' (all users), '*.domain.com' (handle glob). Exactly one of 'member' or 'memberPattern' must be set." + "description": "DID of the crew member" }, "role": { "type": "string", - "description": "Member's role/permissions for write access. 'owner' = hold owner, 'write' = can push blobs. Read access is controlled by hold's public flag.", - "knownValues": ["owner", "write"] + "description": "Member's role in the hold", + "knownValues": ["owner", "admin", "write", "read"] }, - "expiresAt": { + "permissions": { + "type": "array", + "description": "Specific permissions granted to this member", + "items": { + "type": "string" + } + }, + "addedAt": { "type": "string", "format": "datetime", - "description": "Optional expiration for this membership" - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Membership creation timestamp" + "description": "RFC3339 timestamp of when the member was added" } } } diff --git a/lexicons/io/atcr/hold/layer.json b/lexicons/io/atcr/hold/layer.json new file mode 100644 index 0000000..e735eb3 --- /dev/null +++ b/lexicons/io/atcr/hold/layer.json @@ -0,0 +1,48 @@ +{ + "lexicon": 1, + "id": "io.atcr.hold.layer", + "defs": { + "main": { + "type": "record", + "key": "tid", + "description": "Represents metadata about a container layer stored in the hold. Stored in the hold's embedded PDS for tracking and analytics.", + "record": { + "type": "object", + "required": ["digest", "size", "mediaType", "repository", "userDid", "userHandle", "createdAt"], + "properties": { + "digest": { + "type": "string", + "description": "Layer digest (e.g., sha256:abc123...)" + }, + "size": { + "type": "integer", + "description": "Size in bytes" + }, + "mediaType": { + "type": "string", + "description": "Media type (e.g., application/vnd.oci.image.layer.v1.tar+gzip)" + }, + "repository": { + "type": "string", + "description": "Repository this layer belongs to" + }, + "userDid": { + "type": "string", + "format": "did", + "description": "DID of user who uploaded this layer" + }, + "userHandle": { + "type": "string", + "format": "handle", + "description": "Handle of user (for display purposes)" + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "RFC3339 timestamp of when the layer was uploaded" + } + } + } + } + } +} diff --git a/lexicons/io/atcr/manifest.json b/lexicons/io/atcr/manifest.json index 781df9c..b080c21 100644 --- a/lexicons/io/atcr/manifest.json +++ b/lexicons/io/atcr/manifest.json @@ -8,7 +8,7 @@ "key": "tid", "record": { "type": "object", - "required": ["repository", "digest", "mediaType", "schemaVersion", "holdEndpoint", "createdAt"], + "required": ["repository", "digest", "mediaType", "schemaVersion", "createdAt"], "properties": { "repository": { "type": "string", @@ -19,10 +19,15 @@ "type": "string", "description": "Content digest (e.g., 'sha256:abc123...')" }, + "holdDid": { + "type": "string", + "format": "did", + "description": "DID of the hold service where blobs are stored (e.g., 'did:web:hold01.atcr.io'). Primary reference for hold resolution." + }, "holdEndpoint": { "type": "string", "format": "uri", - "description": "Hold service endpoint where blobs are stored (e.g., 'https://hold1.bob.com'). Historical reference." + "description": "Hold service endpoint URL where blobs are stored. DEPRECATED: Use holdDid instead. Kept for backward compatibility." }, "mediaType": { "type": "string", diff --git a/pkg/appview/middleware/registry.go b/pkg/appview/middleware/registry.go index 1e90d22..48c0e85 100644 --- a/pkg/appview/middleware/registry.go +++ b/pkg/appview/middleware/registry.go @@ -33,9 +33,9 @@ const authMethodKey contextKey = "auth.method" type validationCacheEntry struct { serviceToken string validUntil time.Time - err error // Cached error for fast-fail - mu sync.Mutex // Per-entry lock to serialize cache population - inFlight bool // True if another goroutine is fetching the token + err error // Cached error for fast-fail + mu sync.Mutex // Per-entry lock to serialize cache population + inFlight bool // True if another goroutine is fetching the token done chan struct{} // Closed when fetch completes } diff --git a/pkg/appview/ogcard/card.go b/pkg/appview/ogcard/card.go index b1b55a2..b9020a4 100644 --- a/pkg/appview/ogcard/card.go +++ b/pkg/appview/ogcard/card.go @@ -403,7 +403,7 @@ func createCircleMask(diameter int) *image.Alpha { // Common colors var ( - ColorBackground = color.RGBA{R: 22, G: 27, B: 34, A: 255} // #161b22 - GitHub dark elevated + ColorBackground = color.RGBA{R: 22, G: 27, B: 34, A: 255} // #161b22 - GitHub dark elevated ColorText = color.RGBA{R: 230, G: 237, B: 243, A: 255} // #e6edf3 - Light text ColorMuted = color.RGBA{R: 125, G: 133, B: 144, A: 255} // #7d8590 - Muted text ColorAccent = color.RGBA{R: 47, G: 129, B: 247, A: 255} // #2f81f7 - Blue accent diff --git a/pkg/appview/routes/routes.go b/pkg/appview/routes/routes.go index 709f8a2..985512e 100644 --- a/pkg/appview/routes/routes.go +++ b/pkg/appview/routes/routes.go @@ -12,8 +12,8 @@ import ( "atcr.io/pkg/appview/middleware" "atcr.io/pkg/appview/readme" "atcr.io/pkg/auth/oauth" - "github.com/go-chi/chi/v5" indigooauth "github.com/bluesky-social/indigo/atproto/auth/oauth" + "github.com/go-chi/chi/v5" ) // UIDependencies contains all dependencies needed for UI route registration diff --git a/pkg/appview/storage/manifest_store_test.go b/pkg/appview/storage/manifest_store_test.go index a9f5bc1..b84d932 100644 --- a/pkg/appview/storage/manifest_store_test.go +++ b/pkg/appview/storage/manifest_store_test.go @@ -926,12 +926,12 @@ func TestManifestStore_Put_ManifestListValidation(t *testing.T) { childDigest := digest.FromBytes(childManifest) tests := []struct { - name string - manifestList []byte - childExists bool // Whether the child manifest exists - wantErr bool - wantErrType string // "ErrManifestBlobUnknown" or empty - checkErrDigest string // Expected digest in error + name string + manifestList []byte + childExists bool // Whether the child manifest exists + wantErr bool + wantErrType string // "ErrManifestBlobUnknown" or empty + checkErrDigest string // Expected digest in error }{ { name: "valid manifest list - child exists", diff --git a/pkg/atproto/lexicon.go b/pkg/atproto/lexicon.go index cbb7d32..451ef5f 100644 --- a/pkg/atproto/lexicon.go +++ b/pkg/atproto/lexicon.go @@ -41,7 +41,7 @@ const ( // TangledProfileCollection is the collection name for tangled profiles // Stored in hold's embedded PDS (singleton record at rkey "self") TangledProfileCollection = "sh.tangled.actor.profile" - + // BskyPostCollection is the collection name for Bluesky posts BskyPostCollection = "app.bsky.feed.post" diff --git a/pkg/auth/token/handler.go b/pkg/auth/token/handler.go index f3d1c75..33dbfaf 100644 --- a/pkg/auth/token/handler.go +++ b/pkg/auth/token/handler.go @@ -31,10 +31,10 @@ type OAuthSessionValidator interface { // Handler handles /auth/token requests type Handler struct { - issuer *Issuer - validator *auth.SessionValidator - deviceStore *db.DeviceStore // For validating device secrets - postAuthCallback PostAuthCallback + issuer *Issuer + validator *auth.SessionValidator + deviceStore *db.DeviceStore // For validating device secrets + postAuthCallback PostAuthCallback oauthSessionValidator OAuthSessionValidator }