async-matrix 2.1.0-aarch64-linux → 3.0.1-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -58
  3. data/lib/async/matrix/3.3/async_matrix_e2ee.so +0 -0
  4. data/lib/async/matrix/3.4/async_matrix_e2ee.so +0 -0
  5. data/lib/async/matrix/4.0/async_matrix_e2ee.so +0 -0
  6. data/lib/async/matrix/api/chain.rb +120 -94
  7. data/lib/async/matrix/api/concat.rb +28 -22
  8. data/lib/async/matrix/api/path_tree.rb +71 -44
  9. data/lib/async/matrix/api.rb +6 -1
  10. data/lib/async/matrix/app_service_client.rb +213 -0
  11. data/lib/async/matrix/auth_error.rb +20 -0
  12. data/lib/async/matrix/bad_json_error.rb +20 -0
  13. data/lib/async/matrix/client/encryption.rb +413 -0
  14. data/lib/async/matrix/client/rooms.rb +478 -0
  15. data/lib/async/matrix/client/sync.rb +508 -0
  16. data/lib/async/matrix/client.rb +217 -113
  17. data/lib/async/matrix/config/vivify.rb +107 -0
  18. data/lib/async/matrix/config.rb +184 -0
  19. data/lib/async/matrix/device_store.rb +1621 -0
  20. data/lib/async/matrix/double_puppet_client.rb +1 -1
  21. data/lib/async/matrix/e2ee/pickle_key.rb +182 -0
  22. data/lib/async/matrix/error.rb +9 -36
  23. data/lib/async/matrix/{application_service/error_response.rb → error_response.rb} +10 -10
  24. data/lib/async/matrix/homeserver_error.rb +20 -0
  25. data/lib/async/matrix/invalid_endpoint_error.rb +20 -0
  26. data/lib/async/matrix/media_client.rb +46 -35
  27. data/lib/async/matrix/not_found_error.rb +20 -0
  28. data/lib/async/matrix/notifier.rb +7 -3
  29. data/lib/async/matrix/response_too_large_error.rb +20 -0
  30. data/lib/async/matrix/version.rb +1 -1
  31. data/lib/async/matrix.rb +16 -7
  32. data/lib/protocol/matrix/canonical_json.rb +200 -0
  33. data/lib/protocol/matrix/content.rb +106 -0
  34. data/lib/protocol/matrix/encrypted_message.rb +1018 -0
  35. data/lib/protocol/matrix/error.rb +49 -0
  36. data/lib/protocol/matrix/event.rb +208 -0
  37. data/lib/protocol/matrix/key_backup.rb +347 -0
  38. data/lib/protocol/matrix/keys.rb +381 -0
  39. data/lib/protocol/matrix/message_batch.rb +482 -0
  40. data/lib/protocol/matrix/schema/registry.rb +381 -0
  41. data/lib/protocol/matrix/schema/validation_error.rb +234 -0
  42. data/lib/protocol/matrix/schema.rb +170 -0
  43. data/lib/protocol/matrix/secret_storage.rb +535 -0
  44. data/lib/protocol/matrix/signing.rb +278 -0
  45. data/lib/protocol/matrix.rb +25 -0
  46. metadata +43 -136
  47. data/lib/async/discord/api/path_tree.rb +0 -127
  48. data/lib/async/discord/api.rb +0 -151
  49. data/lib/async/discord/client.rb +0 -283
  50. data/lib/async/discord/error.rb +0 -84
  51. data/lib/async/discord/gateway.rb +0 -359
  52. data/lib/async/discord.rb +0 -15
  53. data/lib/async/matrix/application_service/bot.rb +0 -232
  54. data/lib/async/matrix/application_service/config/schema/analytics.json +0 -21
  55. data/lib/async/matrix/application_service/config/schema/appservice.json +0 -82
  56. data/lib/async/matrix/application_service/config/schema/backfill.json +0 -91
  57. data/lib/async/matrix/application_service/config/schema/bridge.json +0 -209
  58. data/lib/async/matrix/application_service/config/schema/config.json +0 -61
  59. data/lib/async/matrix/application_service/config/schema/database.json +0 -38
  60. data/lib/async/matrix/application_service/config/schema/direct_media.json +0 -35
  61. data/lib/async/matrix/application_service/config/schema/double_puppet.json +0 -24
  62. data/lib/async/matrix/application_service/config/schema/encryption.json +0 -164
  63. data/lib/async/matrix/application_service/config/schema/homeserver.json +0 -58
  64. data/lib/async/matrix/application_service/config/schema/logging.json +0 -50
  65. data/lib/async/matrix/application_service/config/schema/management_room_texts.json +0 -25
  66. data/lib/async/matrix/application_service/config/schema/matrix.json +0 -45
  67. data/lib/async/matrix/application_service/config/schema/permissions.json +0 -54
  68. data/lib/async/matrix/application_service/config/schema/provisioning.json +0 -23
  69. data/lib/async/matrix/application_service/config/schema/public_media.json +0 -39
  70. data/lib/async/matrix/application_service/config/schema/relay.json +0 -43
  71. data/lib/async/matrix/application_service/config/vivify.rb +0 -109
  72. data/lib/async/matrix/application_service/config.rb +0 -225
  73. data/lib/async/matrix/application_service/dispatcher.rb +0 -185
  74. data/lib/async/matrix/application_service/event.rb +0 -285
  75. data/lib/async/matrix/application_service/server.rb +0 -430
  76. data/lib/async/matrix/application_service/transaction.rb +0 -66
  77. data/lib/async/matrix/application_service/transaction_handler.rb +0 -185
  78. data/lib/async/matrix/application_service/transaction_store.rb +0 -80
  79. data/lib/async/matrix/bridge/discord/db/connection.rb +0 -141
  80. data/lib/async/matrix/bridge/discord/db/file.rb +0 -118
  81. data/lib/async/matrix/bridge/discord/db/guild.rb +0 -120
  82. data/lib/async/matrix/bridge/discord/db/message.rb +0 -160
  83. data/lib/async/matrix/bridge/discord/db/migrations/001_create_users.rb +0 -14
  84. data/lib/async/matrix/bridge/discord/db/migrations/002_create_guilds.rb +0 -14
  85. data/lib/async/matrix/bridge/discord/db/migrations/003_create_portals.rb +0 -23
  86. data/lib/async/matrix/bridge/discord/db/migrations/004_create_puppets.rb +0 -19
  87. data/lib/async/matrix/bridge/discord/db/migrations/005_create_messages.rb +0 -20
  88. data/lib/async/matrix/bridge/discord/db/migrations/006_create_reactions.rb +0 -19
  89. data/lib/async/matrix/bridge/discord/db/migrations/007_create_files.rb +0 -18
  90. data/lib/async/matrix/bridge/discord/db/portal.rb +0 -150
  91. data/lib/async/matrix/bridge/discord/db/puppet.rb +0 -128
  92. data/lib/async/matrix/bridge/discord/db/reaction.rb +0 -165
  93. data/lib/async/matrix/bridge/discord/db/schema.rb +0 -18
  94. data/lib/async/matrix/bridge/discord/db/user.rb +0 -112
  95. data/lib/async/matrix/bridge/discord/db.rb +0 -138
  96. data/lib/async/matrix/schema/registry.rb +0 -354
  97. data/lib/async/matrix/schema/validation_error.rb +0 -225
  98. data/lib/async/matrix/schema.rb +0 -170
@@ -1,225 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Released under the Apache License, Version 2.0.
4
- # Copyright, 2026, by General Intelligence Systems.
5
-
6
- require_relative "../error"
7
-
8
- module Async
9
- module Matrix
10
- module Schema
11
- # Raised by Event#valid! when data fails schema validation.
12
- #
13
- # Produces detailed, human-readable error messages that identify the exact
14
- # key path and offending value.
15
- #
16
- # Schema validation failed for m.room.member event $abc123:
17
- # - content.membership = "invalid" -- must be one of: ["invite", "join", "knock", "leave", "ban"]
18
- # - sender is required but missing
19
- #
20
- class ValidationError < Async::Matrix::Error
21
- attr_reader :errors, :event_type, :event_id
22
-
23
- # @param errors [Array<Hash>] raw JSONSchemer error hashes
24
- # @param event_type [String, nil] Matrix event type (e.g. "m.room.member")
25
- # @param event_id [String, nil] Matrix event ID (e.g. "$abc123")
26
- def initialize(errors, event_type: nil, event_id: nil)
27
- @errors = errors
28
- @event_type = event_type
29
- @event_id = event_id
30
- super("M_BAD_JSON", build_message)
31
- end
32
-
33
- private
34
-
35
- def build_message
36
- lines = [header_line]
37
- @errors.each { |e| lines.concat(Array(format_error(e))) }
38
- lines.join("\n")
39
- end
40
-
41
- def header_line
42
- header = "Schema validation failed"
43
- header += " for #{@event_type}" if @event_type
44
- header += " event #{@event_id}" if @event_id
45
- header + ":"
46
- end
47
-
48
- def format_error(error)
49
- path = pointer_to_dot(error["data_pointer"])
50
- type = error["type"]
51
- data = error["data"]
52
-
53
- case type
54
- when "required"
55
- format_required(error, path)
56
- when "string", "integer", "number", "boolean", "array", "object", "null"
57
- " - #{path} = #{truncate(data.inspect)} -- expected #{type}, got #{data.class}"
58
- when "minimum"
59
- " - #{path} = #{truncate(data.inspect)} -- must be >= #{error.dig("schema", "minimum")}"
60
- when "maximum"
61
- " - #{path} = #{truncate(data.inspect)} -- must be <= #{error.dig("schema", "maximum")}"
62
- when "enum"
63
- allowed = error.dig("schema", "enum")
64
- " - #{path} = #{truncate(data.inspect)} -- must be one of: #{truncate(allowed.inspect)}"
65
- when "pattern"
66
- pattern = error.dig("schema", "pattern")
67
- " - #{path} = #{truncate(data.inspect)} -- does not match pattern: #{pattern}"
68
- when "format"
69
- fmt = error.dig("schema", "format")
70
- " - #{path} = #{truncate(data.inspect)} -- invalid #{fmt} format"
71
- when "minLength"
72
- " - #{path} = #{truncate(data.inspect)} -- length must be >= #{error.dig("schema", "minLength")}"
73
- when "maxLength"
74
- " - #{path} = #{truncate(data.inspect)} -- length must be <= #{error.dig("schema", "maxLength")}"
75
- when "minItems"
76
- " - #{path} -- array must have >= #{error.dig("schema", "minItems")} items"
77
- when "maxItems"
78
- " - #{path} -- array must have <= #{error.dig("schema", "maxItems")} items"
79
- when "uniqueItems"
80
- " - #{path} -- array items must be unique"
81
- when "const"
82
- expected = error.dig("schema", "const")
83
- " - #{path} = #{truncate(data.inspect)} -- must be #{truncate(expected.inspect)}"
84
- when "additionalProperties"
85
- " - #{path}: #{error["error"] || "has additional properties that are not allowed"}"
86
- else
87
- msg = error["error"] || type
88
- " - #{path}: #{msg}"
89
- end
90
- end
91
-
92
- def format_required(error, path)
93
- missing = error.dig("details", "missing_keys") || []
94
- if missing.empty?
95
- " - #{path}: #{error["error"] || "required"}"
96
- else
97
- missing.map { |key| " - #{join_path(path, key)} is required but missing" }
98
- end
99
- end
100
-
101
- def pointer_to_dot(pointer)
102
- return "root" if pointer.nil? || pointer.empty?
103
- pointer.delete_prefix("/").gsub("/", ".")
104
- end
105
-
106
- def join_path(base, key)
107
- base == "root" ? key.to_s : "#{base}.#{key}"
108
- end
109
-
110
- def truncate(str, max: 60)
111
- str.length > max ? "#{str[0...max]}..." : str
112
- end
113
- end
114
- end
115
- end
116
- end
117
-
118
- __END__
119
- describe "Async::Matrix::Schema::ValidationError" do
120
- def error_hash(overrides = {})
121
- {
122
- "data" => nil,
123
- "data_pointer" => "",
124
- "schema" => {},
125
- "schema_pointer" => "",
126
- "root_schema" => {},
127
- "type" => "unknown",
128
- "error" => "something went wrong"
129
- }.merge(overrides)
130
- end
131
-
132
- it "includes event type in header" do
133
- err = Async::Matrix::Schema::ValidationError.new(
134
- [error_hash],
135
- event_type: "m.room.message"
136
- )
137
- err.message.should.include "Schema validation failed for m.room.message"
138
- end
139
-
140
- it "includes event ID in header" do
141
- err = Async::Matrix::Schema::ValidationError.new(
142
- [error_hash],
143
- event_type: "m.room.member",
144
- event_id: "$abc123"
145
- )
146
- err.message.should.include "m.room.member event $abc123"
147
- end
148
-
149
- it "formats type mismatch errors" do
150
- err = Async::Matrix::Schema::ValidationError.new([
151
- error_hash(
152
- "data_pointer" => "/content/body",
153
- "type" => "string",
154
- "data" => 42
155
- )
156
- ])
157
- err.message.should.include "content.body = 42 -- expected string, got Integer"
158
- end
159
-
160
- it "formats required errors with missing keys" do
161
- err = Async::Matrix::Schema::ValidationError.new([
162
- error_hash(
163
- "data_pointer" => "/content",
164
- "type" => "required",
165
- "details" => {"missing_keys" => ["msgtype", "body"]}
166
- )
167
- ])
168
- err.message.should.include "content.msgtype is required but missing"
169
- err.message.should.include "content.body is required but missing"
170
- end
171
-
172
- it "formats enum errors" do
173
- err = Async::Matrix::Schema::ValidationError.new([
174
- error_hash(
175
- "data_pointer" => "/content/membership",
176
- "type" => "enum",
177
- "data" => "invalid",
178
- "schema" => {"enum" => %w[invite join knock leave ban]}
179
- )
180
- ])
181
- err.message.should.include 'content.membership = "invalid" -- must be one of:'
182
- err.message.should.include "invite"
183
- end
184
-
185
- it "formats pattern errors" do
186
- err = Async::Matrix::Schema::ValidationError.new([
187
- error_hash(
188
- "data_pointer" => "/state_key",
189
- "type" => "pattern",
190
- "data" => "bad",
191
- "schema" => {"pattern" => "^@"}
192
- )
193
- ])
194
- err.message.should.include 'state_key = "bad" -- does not match pattern: ^@'
195
- end
196
-
197
- it "formats format errors" do
198
- err = Async::Matrix::Schema::ValidationError.new([
199
- error_hash(
200
- "data_pointer" => "/content/avatar_url",
201
- "type" => "format",
202
- "data" => "not-a-uri",
203
- "schema" => {"format" => "uri"}
204
- )
205
- ])
206
- err.message.should.include "invalid uri format"
207
- end
208
-
209
- it "truncates long values" do
210
- err = Async::Matrix::Schema::ValidationError.new([
211
- error_hash(
212
- "data_pointer" => "/content/body",
213
- "type" => "integer",
214
- "data" => "a" * 200
215
- )
216
- ])
217
- err.message.should.include "..."
218
- end
219
-
220
- it "exposes the raw errors array" do
221
- raw = [error_hash]
222
- err = Async::Matrix::Schema::ValidationError.new(raw)
223
- err.errors.should.equal raw
224
- end
225
- end
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Released under the Apache License, Version 2.0.
4
- # Copyright, 2026, by General Intelligence Systems.
5
-
6
- module Async
7
- module Matrix
8
- # Schema-driven validation for Matrix events using the official matrix-org/matrix-spec
9
- # YAML schemas and the json_schemer gem.
10
- #
11
- # Schemas are loaded lazily from data/matrix-spec/event-schemas/schema/ and cached
12
- # for the process lifetime. This ensures validation is always up-to-date with the
13
- # spec -- just re-run `bin/fetch-matrix-schemas` to pull the latest.
14
- #
15
- # # Look up a schema by event type
16
- # Async::Matrix::Schema["m.room.message"] # => JSONSchemer::Schema
17
- #
18
- # # Validate an event hash
19
- # Async::Matrix::Schema.valid?(event_hash) # => true/false
20
- # Async::Matrix::Schema.validate(event_hash) # => [errors]
21
- #
22
- # # List all known event types
23
- # Async::Matrix::Schema.event_types # => ["m.accepted_terms", "m.call.answer", ...]
24
- #
25
- module Schema
26
- class << self
27
- # Look up a schema by Matrix event type.
28
- # @param event_type [String] e.g. "m.room.message"
29
- # @return [JSONSchemer::Schema, nil]
30
- def [](event_type)
31
- Registry.instance[event_type]
32
- end
33
-
34
- # Look up a variant schema.
35
- # @param event_type [String] e.g. "m.room.message"
36
- # @param subtype [String] e.g. "m.text"
37
- # @return [JSONSchemer::Schema, nil]
38
- def variant(event_type, subtype)
39
- Registry.instance.variant(event_type, subtype)
40
- end
41
-
42
- # Validate an event hash against its schema.
43
- # @param event_hash [Hash] the raw event data (string keys)
44
- # @return [Array<Hash>] array of error hashes (empty if valid)
45
- def validate(event_hash)
46
- Registry.instance.validate(event_hash)
47
- end
48
-
49
- # Boolean validation.
50
- # @param event_hash [Hash] the raw event data (string keys)
51
- # @return [Boolean]
52
- def valid?(event_hash)
53
- Registry.instance.valid?(event_hash)
54
- end
55
-
56
- # All known base event types.
57
- # @return [Array<String>] sorted
58
- def event_types
59
- Registry.instance.event_types
60
- end
61
-
62
- # All known variant types as [event_type, subtype] pairs.
63
- # @return [Array<Array(String, String)>]
64
- def variant_types
65
- Registry.instance.variant_types
66
- end
67
-
68
- # Content properties defined by the schema for a given event type.
69
- # @return [Array<String>]
70
- def content_properties(event_type)
71
- Registry.instance.content_properties(event_type)
72
- end
73
-
74
- # Parse a raw event hash into a schema-aware Event.
75
- # @param event_hash [Hash] the raw event data (string keys)
76
- # @return [ApplicationService::Event]
77
- def parse(event_hash)
78
- ApplicationService::Event.new(event_hash)
79
- end
80
-
81
- # Total schemas loaded (base + variants).
82
- # @return [Integer]
83
- def size
84
- Registry.instance.size
85
- end
86
- end
87
- end
88
- end
89
- end
90
-
91
- __END__
92
- describe "Async::Matrix::Schema" do
93
- it "looks up schemas by event type" do
94
- schema = Async::Matrix::Schema["m.room.message"]
95
- schema.should.not.be.nil
96
- schema.should.be.kind_of JSONSchemer::Schema
97
- end
98
-
99
- it "returns nil for unknown event types" do
100
- Async::Matrix::Schema["m.fake.event"].should.be.nil
101
- end
102
-
103
- it "validates event hashes" do
104
- valid_event = {
105
- "type" => "m.room.message",
106
- "content" => {"msgtype" => "m.text", "body" => "hello"},
107
- "event_id" => "$abc123",
108
- "sender" => "@alice:example.org",
109
- "origin_server_ts" => 1234567890,
110
- "room_id" => "!room:example.org"
111
- }
112
- Async::Matrix::Schema.valid?(valid_event).should == true
113
- end
114
-
115
- it "returns errors for invalid events" do
116
- invalid_event = {
117
- "type" => "m.room.message",
118
- "content" => {"msgtype" => "m.text"},
119
- "event_id" => "$abc123",
120
- "sender" => "@alice:example.org",
121
- "origin_server_ts" => 1234567890,
122
- "room_id" => "!room:example.org"
123
- }
124
- errors = Async::Matrix::Schema.validate(invalid_event)
125
- errors.should.not.be.empty
126
- end
127
-
128
- it "lists event types" do
129
- types = Async::Matrix::Schema.event_types
130
- types.should.be.kind_of Array
131
- types.should.include "m.room.message"
132
- types.should.include "m.room.member"
133
- end
134
-
135
- it "lists variant types" do
136
- variants = Async::Matrix::Schema.variant_types
137
- variants.should.not.be.empty
138
- end
139
-
140
- it "looks up variant schemas" do
141
- schema = Async::Matrix::Schema.variant("m.room.message", "m.text")
142
- schema.should.not.be.nil
143
- end
144
-
145
- it "returns content properties" do
146
- props = Async::Matrix::Schema.content_properties("m.room.message")
147
- props.should.include "msgtype"
148
- props.should.include "body"
149
- end
150
-
151
- it "reports total schema count" do
152
- Async::Matrix::Schema.size.should.be > 50
153
- end
154
-
155
- it "parses a raw hash into a schema-aware Event" do
156
- event = Async::Matrix::Schema.parse({
157
- "type" => "m.room.message",
158
- "content" => {"msgtype" => "m.text", "body" => "hello"},
159
- "event_id" => "$abc123",
160
- "sender" => "@alice:example.org",
161
- "origin_server_ts" => 1234567890,
162
- "room_id" => "!room:example.org"
163
- })
164
- event.should.be.kind_of Async::Matrix::ApplicationService::Event
165
- event.type.should == "m.room.message"
166
- event.content.body.should == "hello"
167
- event.valid?.should == true
168
- event.schema.should.not.be.nil
169
- end
170
- end