+2
-1
cmd/server/main.go
+2
-1
cmd/server/main.go
···-communityEventConsumer := jetstream.NewCommunityEventConsumer(communityRepo, instanceDID, skipDIDWebVerification)communityJetstreamConnector := jetstream.NewCommunityJetstreamConnector(communityEventConsumer, communityJetstreamURL)
···+communityEventConsumer := jetstream.NewCommunityEventConsumer(communityRepo, instanceDID, skipDIDWebVerification, identityResolver)communityJetstreamConnector := jetstream.NewCommunityJetstreamConnector(communityEventConsumer, communityJetstreamURL)
+8
-1
cmd/validate-lexicon/main.go
+8
-1
cmd/validate-lexicon/main.go
···
+65
-1
internal/atproto/jetstream/community_consumer.go
+65
-1
internal/atproto/jetstream/community_consumer.go
······didCache *lru.Cache[string, cachedDIDDoc] // Bounded LRU cache for .well-known verification results···-func NewCommunityEventConsumer(repo communities.Repository, instanceDID string, skipVerification bool) *CommunityEventConsumer {······// This prevents malicious instances from claiming to host communities for domains they don't own······
······+identityResolver interface{ Resolve(context.Context, string) (*identity.Identity, error) } // For resolving handles from DIDsdidCache *lru.Cache[string, cachedDIDDoc] // Bounded LRU cache for .well-known verification results···+func NewCommunityEventConsumer(repo communities.Repository, instanceDID string, skipVerification bool, identityResolver interface{ Resolve(context.Context, string) (*identity.Identity, error) }) *CommunityEventConsumer {······+// atProto Best Practice: Handles are NOT stored in records (they're mutable, resolved from DIDs)+return fmt.Errorf("failed to resolve handle from PLC for %s: %w (no fallback - will retry during backfill)", did, err)// This prevents malicious instances from claiming to host communities for domains they don't own···+// atProto Best Practice: Handles are NOT stored in records (they're mutable, resolved from DIDs)+return fmt.Errorf("failed to resolve handle from PLC for %s: %w (no fallback - will retry during backfill)", did, err)···
-33
internal/atproto/lexicon/social/coves/actor/block.json
-33
internal/atproto/lexicon/social/coves/actor/block.json
···
···
-59
internal/atproto/lexicon/social/coves/actor/blockUser.json
-59
internal/atproto/lexicon/social/coves/actor/blockUser.json
···
···
-85
internal/atproto/lexicon/social/coves/actor/getSaved.json
-85
internal/atproto/lexicon/social/coves/actor/getSaved.json
···
···
-198
internal/atproto/lexicon/social/coves/actor/preferences.json
-198
internal/atproto/lexicon/social/coves/actor/preferences.json
···
···
-63
internal/atproto/lexicon/social/coves/actor/saveItem.json
-63
internal/atproto/lexicon/social/coves/actor/saveItem.json
···
···
-37
internal/atproto/lexicon/social/coves/actor/saved.json
-37
internal/atproto/lexicon/social/coves/actor/saved.json
···
···
-39
internal/atproto/lexicon/social/coves/actor/subscription.json
-39
internal/atproto/lexicon/social/coves/actor/subscription.json
···
···
-37
internal/atproto/lexicon/social/coves/actor/unblockUser.json
-37
internal/atproto/lexicon/social/coves/actor/unblockUser.json
···
···
-37
internal/atproto/lexicon/social/coves/actor/unsaveItem.json
-37
internal/atproto/lexicon/social/coves/actor/unsaveItem.json
···
···
+1
-11
internal/core/communities/service.go
+1
-11
internal/core/communities/service.go
············
············
+6
-1
internal/db/postgres/community_repo.go
+6
-1
internal/db/postgres/community_repo.go
···func (r *postgresCommunityRepo) Create(ctx context.Context, community *communities.Community) (*communities.Community, error) {···
···func (r *postgresCommunityRepo) Create(ctx context.Context, community *communities.Community) (*communities.Community, error) {···
+2
-1
tests/integration/community_blocking_test.go
+2
-1
tests/integration/community_blocking_test.go
···
+271
-24
tests/integration/community_consumer_test.go
+271
-24
tests/integration/community_consumer_test.go
·································
······+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)·········+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)·········+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)···+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)···+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)···+func (m *mockIdentityResolver) Resolve(ctx context.Context, did string) (*identity.Identity, error) {+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)+consumer := jetstream.NewCommunityEventConsumer(repo, "did:web:coves.local", true, mockResolver)
+9
-11
tests/integration/community_e2e_test.go
+9
-11
tests/integration/community_e2e_test.go
·········
···+consumer := jetstream.NewCommunityEventConsumer(communityRepo, "did:web:coves.local", true, identityResolver)···+// Handles are mutable and resolved from DIDs via PLC, so they shouldn't be stored in immutable records···
+10
-5
tests/integration/community_hostedby_security_test.go
+10
-5
tests/integration/community_hostedby_security_test.go
···············
···············
+4
-2
tests/integration/community_v2_validation_test.go
+4
-2
tests/integration/community_v2_validation_test.go
······
······
+6
-3
tests/integration/subscription_indexing_test.go
+6
-3
tests/integration/subscription_indexing_test.go
·········
·········
+12
tests/integration/user_test.go
+12
tests/integration/user_test.go
···+func setupIdentityResolver(db *sql.DB) interface{ Resolve(context.Context, string) (*identity.Identity, error) } {
-5
tests/lexicon-test-data/actor/block-invalid-did.json
-5
tests/lexicon-test-data/actor/block-invalid-did.json
-6
tests/lexicon-test-data/actor/block-valid.json
-6
tests/lexicon-test-data/actor/block-valid.json
-7
tests/lexicon-test-data/actor/preferences-invalid-enum.json
-7
tests/lexicon-test-data/actor/preferences-invalid-enum.json
-40
tests/lexicon-test-data/actor/preferences-valid.json
-40
tests/lexicon-test-data/actor/preferences-valid.json
···
···
-6
tests/lexicon-test-data/actor/profile-invalid-handle-format.json
-6
tests/lexicon-test-data/actor/profile-invalid-handle-format.json
-4
tests/lexicon-test-data/actor/profile-invalid-missing-handle.json
-4
tests/lexicon-test-data/actor/profile-invalid-missing-handle.json
-1
tests/lexicon-test-data/actor/profile-valid.json
-1
tests/lexicon-test-data/actor/profile-valid.json
-6
tests/lexicon-test-data/actor/saved-invalid-type.json
-6
tests/lexicon-test-data/actor/saved-invalid-type.json
-7
tests/lexicon-test-data/actor/saved-valid.json
-7
tests/lexicon-test-data/actor/saved-valid.json
+9
-8
tests/lexicon_validation_test.go
+9
-8
tests/lexicon_validation_test.go
············
············