svix 1.60.1 → 1.61.0
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.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/Gemfile.lock +35 -21
- data/README.md +0 -7
- data/lib/svix/api/application.rb +96 -0
- data/lib/svix/api/authentication.rb +65 -0
- data/lib/svix/api/background_task.rb +39 -0
- data/lib/svix/api/endpoint.rb +202 -0
- data/lib/svix/api/environment.rb +39 -0
- data/lib/svix/api/event_type.rb +99 -0
- data/lib/svix/api/health.rb +21 -0
- data/lib/svix/api/integration.rb +91 -0
- data/lib/svix/api/message.rb +112 -0
- data/lib/svix/api/message_attempt.rb +123 -0
- data/lib/svix/api/operational_webhook_endpoint.rb +109 -0
- data/lib/svix/api/statistics.rb +36 -0
- data/lib/svix/api_error.rb +7 -17
- data/lib/svix/errors.rb +9 -9
- data/lib/svix/http_error_out.rb +18 -0
- data/lib/svix/http_validation_error.rb +18 -0
- data/lib/svix/internal.rb +0 -9
- data/lib/svix/models/aggregate_event_types_out.rb +32 -292
- data/lib/svix/models/app_portal_access_in.rb +31 -278
- data/lib/svix/models/app_portal_access_out.rb +27 -243
- data/lib/svix/models/app_usage_stats_in.rb +30 -234
- data/lib/svix/models/app_usage_stats_out.rb +31 -320
- data/lib/svix/models/application_in.rb +31 -298
- data/lib/svix/models/application_out.rb +37 -371
- data/lib/svix/models/application_patch.rb +31 -272
- data/lib/svix/models/application_token_expire_in.rb +28 -219
- data/lib/svix/models/background_task_out.rb +31 -307
- data/lib/svix/models/background_task_status.rb +14 -25
- data/lib/svix/models/background_task_type.rb +23 -26
- data/lib/svix/models/connector_in.rb +58 -385
- data/lib/svix/models/connector_kind.rb +28 -26
- data/lib/svix/models/dashboard_access_out.rb +27 -243
- data/lib/svix/models/endpoint_headers_in.rb +25 -202
- data/lib/svix/models/endpoint_headers_out.rb +30 -230
- data/lib/svix/models/endpoint_headers_patch_in.rb +28 -202
- data/lib/svix/models/endpoint_in.rb +61 -449
- data/lib/svix/models/endpoint_message_out.rb +48 -467
- data/lib/svix/models/endpoint_out.rb +67 -528
- data/lib/svix/models/endpoint_patch.rb +61 -383
- data/lib/svix/models/endpoint_secret_out.rb +25 -222
- data/lib/svix/models/endpoint_secret_rotate_in.rb +28 -212
- data/lib/svix/models/endpoint_stats.rb +31 -245
- data/lib/svix/models/endpoint_transformation_in.rb +30 -226
- data/lib/svix/models/endpoint_transformation_out.rb +30 -228
- data/lib/svix/models/endpoint_update.rb +58 -422
- data/lib/svix/models/environment_in.rb +31 -212
- data/lib/svix/models/environment_out.rb +35 -255
- data/lib/svix/models/event_example_in.rb +27 -261
- data/lib/svix/models/event_type_from_open_api.rb +35 -341
- data/lib/svix/models/event_type_import_open_api_in.rb +37 -228
- data/lib/svix/models/event_type_import_open_api_out.rb +28 -200
- data/lib/svix/models/event_type_import_open_api_out_data.rb +31 -211
- data/lib/svix/models/event_type_in.rb +37 -347
- data/lib/svix/models/event_type_out.rb +58 -389
- data/lib/svix/models/event_type_patch.rb +35 -289
- data/lib/svix/models/event_type_update.rb +35 -301
- data/lib/svix/models/expung_all_contents_out.rb +29 -292
- data/lib/svix/models/integration_in.rb +27 -239
- data/lib/svix/models/integration_key_out.rb +25 -200
- data/lib/svix/models/integration_out.rb +33 -324
- data/lib/svix/models/integration_update.rb +27 -239
- data/lib/svix/models/list_response_application_out.rb +34 -237
- data/lib/svix/models/list_response_background_task_out.rb +34 -237
- data/lib/svix/models/list_response_endpoint_message_out.rb +34 -237
- data/lib/svix/models/list_response_endpoint_out.rb +34 -237
- data/lib/svix/models/list_response_event_type_out.rb +34 -237
- data/lib/svix/models/list_response_integration_out.rb +34 -237
- data/lib/svix/models/list_response_message_attempt_out.rb +34 -237
- data/lib/svix/models/list_response_message_endpoint_out.rb +34 -237
- data/lib/svix/models/list_response_message_out.rb +34 -237
- data/lib/svix/models/list_response_operational_webhook_endpoint_out.rb +34 -237
- data/lib/svix/models/message_attempt_out.rb +64 -521
- data/lib/svix/models/message_attempt_trigger_type.rb +20 -28
- data/lib/svix/models/message_endpoint_out.rb +70 -557
- data/lib/svix/models/message_in.rb +58 -450
- data/lib/svix/models/message_out.rb +37 -414
- data/lib/svix/models/message_status.rb +24 -30
- data/lib/svix/models/operational_webhook_endpoint_headers_in.rb +28 -202
- data/lib/svix/models/operational_webhook_endpoint_headers_out.rb +30 -229
- data/lib/svix/models/operational_webhook_endpoint_in.rb +42 -380
- data/lib/svix/models/operational_webhook_endpoint_out.rb +64 -458
- data/lib/svix/models/operational_webhook_endpoint_secret_in.rb +28 -212
- data/lib/svix/models/operational_webhook_endpoint_secret_out.rb +28 -222
- data/lib/svix/models/operational_webhook_endpoint_update.rb +40 -353
- data/lib/svix/models/ordering.rb +15 -25
- data/lib/svix/models/recover_in.rb +28 -210
- data/lib/svix/models/recover_out.rb +29 -292
- data/lib/svix/models/replay_in.rb +28 -210
- data/lib/svix/models/replay_out.rb +29 -292
- data/lib/svix/models/status_code_class.rb +28 -32
- data/lib/svix/models/template_out.rb +70 -514
- data/lib/svix/svix.rb +50 -50
- data/lib/svix/svix_http_client.rb +110 -0
- data/lib/svix/util.rb +44 -25
- data/lib/svix/validation_error.rb +28 -0
- data/lib/svix/version.rb +1 -1
- data/lib/svix/webhook.rb +69 -65
- data/lib/svix.rb +51 -37
- data/svix.gemspec +1 -10
- metadata +22 -194
- data/lib/svix/api/application_api.rb +0 -772
- data/lib/svix/api/authentication_api.rb +0 -791
- data/lib/svix/api/background_tasks_api.rb +0 -191
- data/lib/svix/api/broadcast_api.rb +0 -93
- data/lib/svix/api/endpoint_api.rb +0 -2752
- data/lib/svix/api/environment_api.rb +0 -153
- data/lib/svix/api/environment_settings_api.rb +0 -79
- data/lib/svix/api/event_type_api.rb +0 -852
- data/lib/svix/api/events_api.rb +0 -102
- data/lib/svix/api/health_api.rb +0 -79
- data/lib/svix/api/inbound_api.rb +0 -209
- data/lib/svix/api/integration_api.rb +0 -707
- data/lib/svix/api/message_api.rb +0 -1192
- data/lib/svix/api/message_attempt_api.rb +0 -1245
- data/lib/svix/api/statistics_api.rb +0 -333
- data/lib/svix/api/stream_api.rb +0 -659
- data/lib/svix/api/stream_event_types_api.rb +0 -486
- data/lib/svix/api/transformation_template_api.rb +0 -967
- data/lib/svix/api/webhook_endpoint_api.rb +0 -748
- data/lib/svix/api_client.rb +0 -423
- data/lib/svix/application_api.rb +0 -35
- data/lib/svix/authentication_api.rb +0 -21
- data/lib/svix/background_tasks_api.rb +0 -17
- data/lib/svix/configuration.rb +0 -312
- data/lib/svix/endpoint_api.rb +0 -80
- data/lib/svix/event_type_api.rb +0 -37
- data/lib/svix/integration_api.rb +0 -38
- data/lib/svix/message_api.rb +0 -54
- data/lib/svix/message_attempt_api.rb +0 -51
- data/lib/svix/models/active_application_out.rb +0 -373
- data/lib/svix/models/active_endpoint_out.rb +0 -355
- data/lib/svix/models/aggregated_event_types.rb +0 -305
- data/lib/svix/models/application_message_failure.rb +0 -277
- data/lib/svix/models/application_message_id_pair.rb +0 -317
- data/lib/svix/models/application_stats.rb +0 -323
- data/lib/svix/models/application_stats_out.rb +0 -324
- data/lib/svix/models/attempt_statistics_data.rb +0 -229
- data/lib/svix/models/attempt_statistics_response.rb +0 -291
- data/lib/svix/models/auth_token_out.rb +0 -325
- data/lib/svix/models/azure_blob_storage_config.rb +0 -253
- data/lib/svix/models/background_task_finished_event.rb +0 -272
- data/lib/svix/models/background_task_finished_event2.rb +0 -331
- data/lib/svix/models/big_query_config.rb +0 -271
- data/lib/svix/models/border_radius_config.rb +0 -254
- data/lib/svix/models/border_radius_enum.rb +0 -43
- data/lib/svix/models/client_secret_jwt_params_in.rb +0 -297
- data/lib/svix/models/completion_choice.rb +0 -253
- data/lib/svix/models/completion_message.rb +0 -237
- data/lib/svix/models/count_out.rb +0 -258
- data/lib/svix/models/create_stream_in.rb +0 -232
- data/lib/svix/models/create_token_in.rb +0 -248
- data/lib/svix/models/custom_color_palette.rb +0 -295
- data/lib/svix/models/custom_strings_override.rb +0 -235
- data/lib/svix/models/custom_theme_override.rb +0 -223
- data/lib/svix/models/data.rb +0 -108
- data/lib/svix/models/data_any_of.rb +0 -240
- data/lib/svix/models/data_any_of1.rb +0 -223
- data/lib/svix/models/data_any_of2.rb +0 -241
- data/lib/svix/models/data_any_of3.rb +0 -223
- data/lib/svix/models/data_any_of4.rb +0 -240
- data/lib/svix/models/duration.rb +0 -275
- data/lib/svix/models/endpoint_created_event.rb +0 -272
- data/lib/svix/models/endpoint_created_event_data.rb +0 -410
- data/lib/svix/models/endpoint_deleted_event.rb +0 -272
- data/lib/svix/models/endpoint_deleted_event_data.rb +0 -410
- data/lib/svix/models/endpoint_disabled_event.rb +0 -272
- data/lib/svix/models/endpoint_disabled_event_data.rb +0 -451
- data/lib/svix/models/endpoint_disabled_trigger.rb +0 -40
- data/lib/svix/models/endpoint_enabled_event.rb +0 -272
- data/lib/svix/models/endpoint_enabled_event_data.rb +0 -410
- data/lib/svix/models/endpoint_mtls_config_in.rb +0 -233
- data/lib/svix/models/endpoint_mtls_config_out.rb +0 -215
- data/lib/svix/models/endpoint_oauth_config_in.rb +0 -350
- data/lib/svix/models/endpoint_oauth_config_out.rb +0 -315
- data/lib/svix/models/endpoint_transformation_simulate_in.rb +0 -330
- data/lib/svix/models/endpoint_transformation_simulate_out.rb +0 -296
- data/lib/svix/models/endpoint_updated_event.rb +0 -272
- data/lib/svix/models/endpoint_updated_event_data.rb +0 -410
- data/lib/svix/models/environment_settings_out.rb +0 -455
- data/lib/svix/models/event_in.rb +0 -258
- data/lib/svix/models/event_out.rb +0 -274
- data/lib/svix/models/event_stream_out.rb +0 -255
- data/lib/svix/models/event_type_example_out.rb +0 -221
- data/lib/svix/models/event_type_schema_in.rb +0 -221
- data/lib/svix/models/export_event_type_out.rb +0 -315
- data/lib/svix/models/font_size_config.rb +0 -230
- data/lib/svix/models/generate_in.rb +0 -221
- data/lib/svix/models/generate_out.rb +0 -287
- data/lib/svix/models/google_cloud_storage_config.rb +0 -239
- data/lib/svix/models/http_error_out.rb +0 -237
- data/lib/svix/models/http_validation_error.rb +0 -223
- data/lib/svix/models/hubspot_oauth_config_in.rb +0 -221
- data/lib/svix/models/inbound_path_params.rb +0 -277
- data/lib/svix/models/incoming_webhook_payload_out.rb +0 -235
- data/lib/svix/models/kafka_security_protocol_type.rb +0 -41
- data/lib/svix/models/list_response_active_application_out.rb +0 -261
- data/lib/svix/models/list_response_application_stats.rb +0 -261
- data/lib/svix/models/list_response_message_attempt_endpoint_out.rb +0 -261
- data/lib/svix/models/list_response_sink_out.rb +0 -261
- data/lib/svix/models/list_response_stream_event_type_out.rb +0 -261
- data/lib/svix/models/list_response_stream_out.rb +0 -261
- data/lib/svix/models/list_response_stream_sink_out.rb +0 -261
- data/lib/svix/models/list_response_template_out.rb +0 -261
- data/lib/svix/models/message_attempt_endpoint_out.rb +0 -545
- data/lib/svix/models/message_attempt_exhausted_event.rb +0 -272
- data/lib/svix/models/message_attempt_exhausted_event_data.rb +0 -482
- data/lib/svix/models/message_attempt_failed_data.rb +0 -293
- data/lib/svix/models/message_attempt_failing_event.rb +0 -272
- data/lib/svix/models/message_attempt_failing_event_data.rb +0 -482
- data/lib/svix/models/message_attempt_headers_out.rb +0 -263
- data/lib/svix/models/message_attempt_recovered_event.rb +0 -272
- data/lib/svix/models/message_attempt_recovered_event_data.rb +0 -482
- data/lib/svix/models/message_broadcast_in.rb +0 -423
- data/lib/svix/models/message_broadcast_out.rb +0 -315
- data/lib/svix/models/message_events_out.rb +0 -255
- data/lib/svix/models/message_precheck_in.rb +0 -288
- data/lib/svix/models/message_precheck_out.rb +0 -221
- data/lib/svix/models/message_raw_payload_out.rb +0 -221
- data/lib/svix/models/message_subscriber_auth_token_out.rb +0 -237
- data/lib/svix/models/o_auth_payload_in.rb +0 -237
- data/lib/svix/models/o_auth_payload_out.rb +0 -235
- data/lib/svix/models/oauth2_auth_method_in_out.rb +0 -41
- data/lib/svix/models/oauth2_grant_type_in_out.rb +0 -40
- data/lib/svix/models/oauth_jws_signing_algorithm.rb +0 -39
- data/lib/svix/models/one_time_token_in.rb +0 -221
- data/lib/svix/models/one_time_token_out.rb +0 -221
- data/lib/svix/models/polling_endpoint_message_out.rb +0 -454
- data/lib/svix/models/polling_endpoint_out.rb +0 -255
- data/lib/svix/models/redshift_config.rb +0 -317
- data/lib/svix/models/retry_schedule_in_out.rb +0 -216
- data/lib/svix/models/rotate_poller_token_in.rb +0 -280
- data/lib/svix/models/rotated_url_out.rb +0 -221
- data/lib/svix/models/s3_config.rb +0 -269
- data/lib/svix/models/sink_http_config.rb +0 -242
- data/lib/svix/models/sink_in.rb +0 -108
- data/lib/svix/models/sink_in_one_of.rb +0 -287
- data/lib/svix/models/sink_in_one_of1.rb +0 -319
- data/lib/svix/models/sink_in_one_of2.rb +0 -325
- data/lib/svix/models/sink_in_one_of3.rb +0 -271
- data/lib/svix/models/sink_in_one_of4.rb +0 -255
- data/lib/svix/models/sink_otel_v1_config.rb +0 -221
- data/lib/svix/models/sink_out.rb +0 -108
- data/lib/svix/models/sink_payload_format.rb +0 -39
- data/lib/svix/models/sink_secret_out.rb +0 -233
- data/lib/svix/models/sink_status.rb +0 -41
- data/lib/svix/models/sink_status_in.rb +0 -40
- data/lib/svix/models/sink_transform_in.rb +0 -248
- data/lib/svix/models/sink_transformation_out.rb +0 -226
- data/lib/svix/models/snowflake_config.rb +0 -287
- data/lib/svix/models/statistics_period.rb +0 -40
- data/lib/svix/models/stream_event_type_in.rb +0 -262
- data/lib/svix/models/stream_event_type_out.rb +0 -294
- data/lib/svix/models/stream_event_type_patch.rb +0 -254
- data/lib/svix/models/stream_in.rb +0 -287
- data/lib/svix/models/stream_out.rb +0 -350
- data/lib/svix/models/stream_patch.rb +0 -261
- data/lib/svix/models/stream_portal_access_in.rb +0 -293
- data/lib/svix/models/stream_sink_in.rb +0 -111
- data/lib/svix/models/stream_sink_in_one_of.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of1.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of2.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of3.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of4.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of5.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of6.rb +0 -271
- data/lib/svix/models/stream_sink_in_one_of7.rb +0 -271
- data/lib/svix/models/stream_sink_out.rb +0 -111
- data/lib/svix/models/stream_sink_patch.rb +0 -111
- data/lib/svix/models/template_patch.rb +0 -382
- data/lib/svix/models/template_update.rb +0 -402
- data/lib/svix/models/transformation_http_method.rb +0 -41
- data/lib/svix/models/transformation_simulate_in.rb +0 -330
- data/lib/svix/models/transformation_simulate_out.rb +0 -296
- data/lib/svix/models/validation_error.rb +0 -259
- data/lib/svix/statistics_api.rb +0 -17
data/lib/svix/svix.rb
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Svix
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class SvixOptions
|
5
|
+
attr_accessor :debug
|
6
|
+
attr_accessor :server_url
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
8
|
+
def initialize(debug = false, server_url = nil)
|
9
|
+
@debug = debug
|
10
|
+
@server_url = server_url
|
12
11
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
12
|
+
end
|
13
|
+
|
14
|
+
class Client
|
15
|
+
attr_accessor :application
|
16
|
+
attr_accessor :authentication
|
17
|
+
attr_accessor :background_task
|
18
|
+
attr_accessor :endpoint
|
19
|
+
attr_accessor :environment
|
20
|
+
attr_accessor :event_type
|
21
|
+
attr_accessor :health
|
22
|
+
attr_accessor :integration
|
23
|
+
attr_accessor :message
|
24
|
+
attr_accessor :message_attempt
|
25
|
+
attr_accessor :operational_webhook_endpoint
|
26
|
+
attr_accessor :statistics
|
27
|
+
|
28
|
+
def initialize(auth_token, options = SvixOptions.new)
|
29
|
+
region = auth_token.split(".").last
|
30
|
+
if region == "us"
|
31
|
+
regional_url = "https://api.us.svix.com"
|
32
|
+
elsif region == "eu"
|
33
|
+
regional_url = "https://api.eu.svix.com"
|
34
|
+
elsif region == "in"
|
35
|
+
regional_url = "https://api.in.svix.com"
|
36
|
+
else
|
37
|
+
regional_url = "https://api.svix.com"
|
38
|
+
end
|
39
|
+
|
40
|
+
uri = URI(options.server_url || regional_url)
|
41
|
+
api_client = SvixHttpClient.new(auth_token, uri)
|
42
|
+
|
43
|
+
@application = Application.new(api_client)
|
44
|
+
@authentication = Authentication.new(api_client)
|
45
|
+
@background_task = BackgroundTask.new(api_client)
|
46
|
+
@endpoint = Endpoint.new(api_client)
|
47
|
+
@environment = Environment.new(api_client)
|
48
|
+
@event_type = EventType.new(api_client)
|
49
|
+
@health = Health.new(api_client)
|
50
|
+
@integration = Integration.new(api_client)
|
51
|
+
@message = Message.new(api_client)
|
52
|
+
@message_attempt = MessageAttempt.new(api_client)
|
53
|
+
@operational_webhook_endpoint = OperationalWebhookEndpoint.new(api_client)
|
54
|
+
@statistics = Statistics.new(api_client)
|
56
55
|
end
|
56
|
+
end
|
57
57
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "uri"
|
3
|
+
require "net/http"
|
4
|
+
|
5
|
+
module Svix
|
6
|
+
class SvixHttpClient
|
7
|
+
def initialize(token, base_url)
|
8
|
+
@token = token
|
9
|
+
@base_url = base_url
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute_request(method, path, **kwargs)
|
13
|
+
query_params = kwargs[:query_params] || {}
|
14
|
+
headers = kwargs[:headers] || {}
|
15
|
+
body = kwargs[:body] || {}
|
16
|
+
|
17
|
+
uri = URI("#{@base_url}#{path}")
|
18
|
+
encoded_query = encode_query_params(query_params)
|
19
|
+
if encoded_query != ""
|
20
|
+
uri.query = encoded_query
|
21
|
+
end
|
22
|
+
|
23
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
24
|
+
http.use_ssl = (uri.scheme == "https")
|
25
|
+
|
26
|
+
# Dynamically select the request class based on method
|
27
|
+
request_class = case method.to_s.upcase
|
28
|
+
when "GET"
|
29
|
+
Net::HTTP::Get
|
30
|
+
when "POST"
|
31
|
+
Net::HTTP::Post
|
32
|
+
when "PUT"
|
33
|
+
Net::HTTP::Put
|
34
|
+
when "DELETE"
|
35
|
+
Net::HTTP::Delete
|
36
|
+
when "PATCH"
|
37
|
+
Net::HTTP::Patch
|
38
|
+
when "HEAD"
|
39
|
+
Net::HTTP::Head
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Unsupported HTTP method: #{method}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Create request object
|
45
|
+
request = request_class.new(uri.request_uri)
|
46
|
+
request["Authorization"] = "Bearer #{@token}"
|
47
|
+
request["User-Agent"] = "svix-libs/#{VERSION}/ruby"
|
48
|
+
request["svix-req-id"] = rand(0...(2 ** 64))
|
49
|
+
|
50
|
+
# Add headers
|
51
|
+
headers.each { |key, value| request[key] = value }
|
52
|
+
|
53
|
+
# Add body for non-GET requests
|
54
|
+
if %w[POST PUT PATCH].include?(method.to_s.upcase) && !body.nil?
|
55
|
+
request.body = body.to_json
|
56
|
+
request["Content-Type"] = "application/json"
|
57
|
+
end
|
58
|
+
|
59
|
+
res = execute_request_with_retries(request, http)
|
60
|
+
|
61
|
+
# Execute request
|
62
|
+
if Integer(res.code) == 204
|
63
|
+
nil
|
64
|
+
elsif Integer(res.code) >= 200 && Integer(res.code) <= 299
|
65
|
+
JSON.parse(res.body)
|
66
|
+
else
|
67
|
+
fail(
|
68
|
+
ApiError.new(
|
69
|
+
:code => Integer(res.code),
|
70
|
+
:response_headers => res.each_header.to_h,
|
71
|
+
:response_body => res.body
|
72
|
+
)
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private def execute_request_with_retries(request, http)
|
78
|
+
res = http.request(request)
|
79
|
+
|
80
|
+
[0.05, 0.1, 0.2].each_with_index do |sleep_duration, index|
|
81
|
+
unless Integer(res.code) >= 500
|
82
|
+
break
|
83
|
+
end
|
84
|
+
|
85
|
+
sleep(sleep_duration)
|
86
|
+
request["svix-retry-count"] = index + 1
|
87
|
+
res = http.request(request)
|
88
|
+
end
|
89
|
+
|
90
|
+
res
|
91
|
+
end
|
92
|
+
|
93
|
+
private def encode_query_params(query_params = {})
|
94
|
+
encoded_query_pairs = []
|
95
|
+
query_params.each do |k, v|
|
96
|
+
unless v.nil?
|
97
|
+
if v.kind_of?(Array)
|
98
|
+
encoded_query_pairs.append("#{k}=" + CGI::escape(v.sort.join(",")))
|
99
|
+
elsif v.kind_of?(Time)
|
100
|
+
encoded_query_pairs.append("#{k}=#{CGI::escape(v.utc.to_datetime.rfc3339)}")
|
101
|
+
else
|
102
|
+
encoded_query_pairs.append("#{k}=#{CGI::escape(v)}")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
encoded_query_pairs.join("&")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/lib/svix/util.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "date"
|
2
3
|
|
3
4
|
# Constant time string comparison, for fixed length strings.
|
4
5
|
# Code borrowed from ActiveSupport
|
@@ -7,31 +8,49 @@
|
|
7
8
|
# The values compared should be of fixed length, such as strings
|
8
9
|
# that have already been processed by HMAC. Raises in case of length mismatch.
|
9
10
|
module Svix
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
else
|
15
|
-
def fixed_length_secure_compare(a, b)
|
16
|
-
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
|
17
|
-
|
18
|
-
l = a.unpack "C#{a.bytesize}"
|
19
|
-
|
20
|
-
res = 0
|
21
|
-
b.each_byte { |byte| res |= byte ^ l.shift }
|
22
|
-
res == 0
|
23
|
-
end
|
11
|
+
if defined?(OpenSSL.fixed_length_secure_compare)
|
12
|
+
def fixed_length_secure_compare(a, b)
|
13
|
+
OpenSSL.fixed_length_secure_compare(a, b)
|
24
14
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
15
|
+
else
|
16
|
+
def fixed_length_secure_compare(a, b)
|
17
|
+
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
|
18
|
+
|
19
|
+
l = a.unpack("C#{a.bytesize}")
|
20
|
+
|
21
|
+
res = 0
|
22
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
23
|
+
res == 0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module_function :fixed_length_secure_compare
|
28
|
+
|
29
|
+
# Secure string comparison for strings of variable length.
|
30
|
+
#
|
31
|
+
# While a timing attack would not be able to discern the content of
|
32
|
+
# a secret compared via secure_compare, it is possible to determine
|
33
|
+
# the secret length. This should be considered when using secure_compare
|
34
|
+
# to compare weak, short secrets to user input.
|
35
|
+
def secure_compare(a, b)
|
36
|
+
a.length == b.length && fixed_length_secure_compare(a, b)
|
37
|
+
end
|
38
|
+
|
39
|
+
module_function :secure_compare
|
40
|
+
|
41
|
+
def serialize_primitive(v)
|
42
|
+
if v.kind_of?(Time)
|
43
|
+
v.utc.to_datetime.rfc3339
|
44
|
+
else
|
45
|
+
v
|
35
46
|
end
|
36
|
-
|
47
|
+
end
|
48
|
+
|
49
|
+
module_function :serialize_primitive
|
50
|
+
|
51
|
+
def deserialize_date(v)
|
52
|
+
DateTime.rfc3339(v)
|
53
|
+
end
|
54
|
+
|
55
|
+
module_function :deserialize_date
|
37
56
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Svix
|
4
|
+
# Validation errors have their own schema to provide context for invalid requests eg. mismatched types and out of bounds values. There may be any number of these per 422 UNPROCESSABLE ENTITY error.
|
5
|
+
class ValidationError
|
6
|
+
# The location as a [`Vec`] of [`String`]s -- often in the form `[\"body\", \"field_name\"]`, `[\"query\", \"field_name\"]`, etc. They may, however, be arbitrarily deep.
|
7
|
+
attr_accessor :loc
|
8
|
+
|
9
|
+
# The message accompanying the validation error item.
|
10
|
+
attr_accessor :msg
|
11
|
+
|
12
|
+
# The type of error, often \"type_error\" or \"value_error\", but sometimes with more context like as \"value_error.number.not_ge\"
|
13
|
+
attr_accessor :type
|
14
|
+
|
15
|
+
def initialize(attributes = {})
|
16
|
+
if (!attributes.is_a?(Hash))
|
17
|
+
fail(
|
18
|
+
ArgumentError,
|
19
|
+
"The input argument (attributes) must be a hash in `Svix::ValidationError` initialize method"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
@loc = attributes[:"loc"]
|
24
|
+
@msg = attributes[:"msg"]
|
25
|
+
@type = attributes[:"type"]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/svix/version.rb
CHANGED
data/lib/svix/webhook.rb
CHANGED
@@ -1,79 +1,83 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Svix
|
4
|
-
|
4
|
+
class Webhook
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def self.new_using_raw_bytes(secret)
|
7
|
+
self.new(secret.pack("C*").force_encoding("UTF-8"))
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def initialize(secret)
|
11
|
+
if secret.start_with?(SECRET_PREFIX)
|
12
|
+
secret = secret[SECRET_PREFIX.length..-1]
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
@secret = Base64.decode64(secret)
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
verify_timestamp(msgTimestamp)
|
32
|
-
|
33
|
-
_, signature = sign(msgId, msgTimestamp, payload).split(",", 2)
|
34
|
-
|
35
|
-
passedSignatures = msgSignature.split(" ")
|
36
|
-
passedSignatures.each do |versionedSignature|
|
37
|
-
version, expectedSignature = versionedSignature.split(",", 2)
|
38
|
-
if version != "v1"
|
39
|
-
next
|
40
|
-
end
|
41
|
-
if ::Svix::secure_compare(signature, expectedSignature)
|
42
|
-
return JSON.parse(payload, symbolize_names: true)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
raise WebhookVerificationError, "No matching signature found"
|
18
|
+
def verify(payload, headers)
|
19
|
+
msgId = headers["svix-id"]
|
20
|
+
msgSignature = headers["svix-signature"]
|
21
|
+
msgTimestamp = headers["svix-timestamp"]
|
22
|
+
if !msgSignature || !msgId || !msgTimestamp
|
23
|
+
msgId = headers["webhook-id"]
|
24
|
+
msgSignature = headers["webhook-signature"]
|
25
|
+
msgTimestamp = headers["webhook-timestamp"]
|
26
|
+
if !msgSignature || !msgId || !msgTimestamp
|
27
|
+
raise WebhookVerificationError, "Missing required headers"
|
46
28
|
end
|
29
|
+
end
|
47
30
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
31
|
+
verify_timestamp(msgTimestamp)
|
32
|
+
|
33
|
+
_, signature = sign(msgId, msgTimestamp, payload).split(",", 2)
|
34
|
+
|
35
|
+
passedSignatures = msgSignature.split(" ")
|
36
|
+
passedSignatures.each do |versionedSignature|
|
37
|
+
version, expectedSignature = versionedSignature.split(",", 2)
|
38
|
+
if version != "v1"
|
39
|
+
next
|
57
40
|
end
|
58
41
|
|
59
|
-
|
60
|
-
|
61
|
-
TOLERANCE = 5 * 60
|
62
|
-
|
63
|
-
def verify_timestamp(timestampHeader)
|
64
|
-
begin
|
65
|
-
now = Integer(Time.now)
|
66
|
-
timestamp = Integer(timestampHeader)
|
67
|
-
rescue
|
68
|
-
raise WebhookVerificationError, "Invalid Signature Headers"
|
69
|
-
end
|
70
|
-
|
71
|
-
if timestamp < (now - TOLERANCE)
|
72
|
-
raise WebhookVerificationError, "Message timestamp too old"
|
73
|
-
end
|
74
|
-
if timestamp > (now + TOLERANCE)
|
75
|
-
raise WebhookVerificationError, "Message timestamp too new"
|
76
|
-
end
|
42
|
+
if ::Svix::secure_compare(signature, expectedSignature)
|
43
|
+
return JSON.parse(payload, symbolize_names: true)
|
77
44
|
end
|
45
|
+
end
|
46
|
+
|
47
|
+
raise WebhookVerificationError, "No matching signature found"
|
48
|
+
end
|
49
|
+
|
50
|
+
def sign(msgId, timestamp, payload)
|
51
|
+
begin
|
52
|
+
now = Integer(timestamp)
|
53
|
+
rescue
|
54
|
+
raise WebhookSigningError, "Invalid timestamp"
|
55
|
+
end
|
56
|
+
|
57
|
+
toSign = "#{msgId}.#{timestamp}.#{payload}"
|
58
|
+
signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new("sha256"), @secret, toSign)).strip
|
59
|
+
return "v1,#{signature}"
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
SECRET_PREFIX = "whsec_"
|
64
|
+
TOLERANCE = 5 * 60
|
65
|
+
|
66
|
+
def verify_timestamp(timestampHeader)
|
67
|
+
begin
|
68
|
+
now = Integer(Time.now)
|
69
|
+
timestamp = Integer(timestampHeader)
|
70
|
+
rescue
|
71
|
+
raise WebhookVerificationError, "Invalid Signature Headers"
|
72
|
+
end
|
73
|
+
|
74
|
+
if timestamp < (now - TOLERANCE)
|
75
|
+
raise WebhookVerificationError, "Message timestamp too old"
|
76
|
+
end
|
77
|
+
|
78
|
+
if timestamp > (now + TOLERANCE)
|
79
|
+
raise WebhookVerificationError, "Message timestamp too new"
|
80
|
+
end
|
78
81
|
end
|
82
|
+
end
|
79
83
|
end
|
data/lib/svix.rb
CHANGED
@@ -1,97 +1,111 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# This file is @generated
|
2
3
|
|
3
4
|
require "json"
|
4
5
|
require "openssl"
|
5
6
|
require "base64"
|
6
7
|
require "uri"
|
8
|
+
require "logger"
|
7
9
|
|
8
10
|
# API
|
9
|
-
require "svix/api/
|
10
|
-
require "svix/api/
|
11
|
-
require "svix/api/
|
12
|
-
require "svix/api/
|
13
|
-
require "svix/api/
|
14
|
-
require "svix/api/
|
15
|
-
require "svix/api/
|
16
|
-
require "svix/api/
|
11
|
+
require "svix/api/application"
|
12
|
+
require "svix/api/authentication"
|
13
|
+
require "svix/api/background_task"
|
14
|
+
require "svix/api/endpoint"
|
15
|
+
require "svix/api/environment"
|
16
|
+
require "svix/api/event_type"
|
17
|
+
require "svix/api/health"
|
18
|
+
require "svix/api/integration"
|
19
|
+
require "svix/api/message"
|
20
|
+
require "svix/api/message_attempt"
|
21
|
+
require "svix/api/operational_webhook_endpoint"
|
22
|
+
require "svix/api/statistics"
|
17
23
|
|
18
24
|
# Models
|
25
|
+
require "svix/models/aggregate_event_types_out"
|
19
26
|
require "svix/models/app_portal_access_in"
|
20
27
|
require "svix/models/app_portal_access_out"
|
28
|
+
require "svix/models/app_usage_stats_in"
|
29
|
+
require "svix/models/app_usage_stats_out"
|
21
30
|
require "svix/models/application_in"
|
22
31
|
require "svix/models/application_out"
|
23
32
|
require "svix/models/application_patch"
|
33
|
+
require "svix/models/application_token_expire_in"
|
34
|
+
require "svix/models/background_task_out"
|
35
|
+
require "svix/models/background_task_status"
|
36
|
+
require "svix/models/background_task_type"
|
37
|
+
require "svix/models/connector_in"
|
38
|
+
require "svix/models/connector_kind"
|
24
39
|
require "svix/models/dashboard_access_out"
|
25
|
-
require "svix/models/endpoint_created_event_data"
|
26
|
-
require "svix/models/endpoint_created_event"
|
27
|
-
require "svix/models/endpoint_deleted_event_data"
|
28
|
-
require "svix/models/endpoint_deleted_event"
|
29
|
-
require "svix/models/endpoint_disabled_event_data"
|
30
|
-
require "svix/models/endpoint_disabled_event"
|
31
40
|
require "svix/models/endpoint_headers_in"
|
32
41
|
require "svix/models/endpoint_headers_out"
|
42
|
+
require "svix/models/endpoint_headers_patch_in"
|
33
43
|
require "svix/models/endpoint_in"
|
34
44
|
require "svix/models/endpoint_message_out"
|
35
45
|
require "svix/models/endpoint_out"
|
46
|
+
require "svix/models/endpoint_patch"
|
36
47
|
require "svix/models/endpoint_secret_out"
|
37
48
|
require "svix/models/endpoint_secret_rotate_in"
|
49
|
+
require "svix/models/endpoint_stats"
|
50
|
+
require "svix/models/endpoint_transformation_in"
|
51
|
+
require "svix/models/endpoint_transformation_out"
|
38
52
|
require "svix/models/endpoint_update"
|
39
|
-
require "svix/models/
|
40
|
-
require "svix/models/
|
41
|
-
require "svix/models/endpoint_patch"
|
53
|
+
require "svix/models/environment_in"
|
54
|
+
require "svix/models/environment_out"
|
42
55
|
require "svix/models/event_example_in"
|
56
|
+
require "svix/models/event_type_from_open_api"
|
43
57
|
require "svix/models/event_type_import_open_api_in"
|
44
58
|
require "svix/models/event_type_import_open_api_out"
|
45
59
|
require "svix/models/event_type_import_open_api_out_data"
|
46
60
|
require "svix/models/event_type_in"
|
47
61
|
require "svix/models/event_type_out"
|
48
|
-
require "svix/models/event_type_update"
|
49
62
|
require "svix/models/event_type_patch"
|
50
|
-
require "svix/models/
|
51
|
-
require "svix/models/
|
63
|
+
require "svix/models/event_type_update"
|
64
|
+
require "svix/models/expung_all_contents_out"
|
52
65
|
require "svix/models/integration_in"
|
53
66
|
require "svix/models/integration_key_out"
|
54
67
|
require "svix/models/integration_out"
|
55
68
|
require "svix/models/integration_update"
|
56
69
|
require "svix/models/list_response_application_out"
|
70
|
+
require "svix/models/list_response_background_task_out"
|
57
71
|
require "svix/models/list_response_endpoint_message_out"
|
58
72
|
require "svix/models/list_response_endpoint_out"
|
59
73
|
require "svix/models/list_response_event_type_out"
|
60
74
|
require "svix/models/list_response_integration_out"
|
61
|
-
require "svix/models/list_response_message_attempt_endpoint_out"
|
62
75
|
require "svix/models/list_response_message_attempt_out"
|
63
76
|
require "svix/models/list_response_message_endpoint_out"
|
64
77
|
require "svix/models/list_response_message_out"
|
65
|
-
require "svix/models/
|
66
|
-
require "svix/models/message_attempt_exhausted_event_data"
|
67
|
-
require "svix/models/message_attempt_exhausted_event"
|
68
|
-
require "svix/models/message_attempt_failing_event_data"
|
69
|
-
require "svix/models/message_attempt_failing_event"
|
70
|
-
require "svix/models/message_attempt_failed_data"
|
78
|
+
require "svix/models/list_response_operational_webhook_endpoint_out"
|
71
79
|
require "svix/models/message_attempt_out"
|
72
80
|
require "svix/models/message_attempt_trigger_type"
|
73
81
|
require "svix/models/message_endpoint_out"
|
74
82
|
require "svix/models/message_in"
|
75
83
|
require "svix/models/message_out"
|
76
84
|
require "svix/models/message_status"
|
85
|
+
require "svix/models/operational_webhook_endpoint_headers_in"
|
86
|
+
require "svix/models/operational_webhook_endpoint_headers_out"
|
87
|
+
require "svix/models/operational_webhook_endpoint_in"
|
88
|
+
require "svix/models/operational_webhook_endpoint_out"
|
89
|
+
require "svix/models/operational_webhook_endpoint_secret_in"
|
90
|
+
require "svix/models/operational_webhook_endpoint_secret_out"
|
91
|
+
require "svix/models/operational_webhook_endpoint_update"
|
92
|
+
require "svix/models/ordering"
|
77
93
|
require "svix/models/recover_in"
|
78
|
-
require "svix/models/
|
94
|
+
require "svix/models/recover_out"
|
95
|
+
require "svix/models/replay_in"
|
96
|
+
require "svix/models/replay_out"
|
79
97
|
require "svix/models/status_code_class"
|
98
|
+
require "svix/models/template_out"
|
80
99
|
|
81
100
|
# Core
|
82
|
-
require "svix/api_client"
|
83
101
|
require "svix/api_error"
|
84
|
-
require "svix/application_api"
|
85
|
-
require "svix/authentication_api"
|
86
|
-
require "svix/configuration"
|
87
|
-
require "svix/endpoint_api"
|
88
102
|
require "svix/errors"
|
89
|
-
require "svix/event_type_api"
|
90
|
-
require "svix/integration_api"
|
91
|
-
require "svix/message_api"
|
92
|
-
require "svix/message_attempt_api"
|
93
103
|
require "svix/svix"
|
94
104
|
require "svix/util"
|
95
105
|
require "svix/version"
|
96
106
|
require "svix/webhook"
|
107
|
+
require "svix/http_error_out"
|
108
|
+
require "svix/http_validation_error"
|
109
|
+
require "svix/validation_error"
|
110
|
+
require "svix/svix_http_client.rb"
|
97
111
|
require "svix/internal"
|
data/svix.gemspec
CHANGED
@@ -19,11 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
Thank you for installing svix!
|
21
21
|
|
22
|
-
If you are using svix to send outgoing webhhooks, you should also install the `typhoeus` gem.
|
23
|
-
If you are only using svix to consume incoming webhooks, you do not need it.
|
24
|
-
|
25
|
-
gem 'typhoeus`
|
26
|
-
|
27
22
|
MESSAGE
|
28
23
|
|
29
24
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
@@ -41,13 +36,9 @@ Gem::Specification.new do |spec|
|
|
41
36
|
|
42
37
|
# Specify which files should be added to the gem when it is released.
|
43
38
|
ignored = Regexp.union(
|
44
|
-
/\A\.openapi-generator/,
|
45
39
|
/\Aspec/,
|
46
40
|
/\Apkg/,
|
47
|
-
/\Atemplates/,
|
48
41
|
/\A.gitignore/,
|
49
|
-
/\A.openapi-generator-ignore/,
|
50
|
-
/\Aopenapi-generator-config.json/,
|
51
42
|
/.gem\z/
|
52
43
|
)
|
53
44
|
spec.files = Dir['**/*'].reject {|f| !File.file?(f) || ignored.match(f) }
|
@@ -58,5 +49,5 @@ Gem::Specification.new do |spec|
|
|
58
49
|
|
59
50
|
spec.add_development_dependency "rake", "~> 13.0"
|
60
51
|
spec.add_development_dependency "rspec", "~> 3.2"
|
61
|
-
spec.add_development_dependency '
|
52
|
+
spec.add_development_dependency 'webmock', '~> 3.25'
|
62
53
|
end
|