workosv2 2.15.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.
Files changed (242) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +5 -0
  3. data/.github/pull_request_template.md +11 -0
  4. data/.github/renovate.json +5 -0
  5. data/.gitignore +49 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +24 -0
  8. data/.ruby-version +1 -0
  9. data/.semaphore/rubygems.yml +24 -0
  10. data/.semaphore/semaphore.yml +51 -0
  11. data/Gemfile +5 -0
  12. data/Gemfile.lock +126 -0
  13. data/Gemfile.lock.old +127 -0
  14. data/LICENSE +21 -0
  15. data/README.md +53 -0
  16. data/bin/build +3 -0
  17. data/bin/console +3 -0
  18. data/bin/docs +5 -0
  19. data/bin/publish +3 -0
  20. data/bin/tapioca +29 -0
  21. data/codecov.yml +12 -0
  22. data/docs/WorkOS/APIError.html +160 -0
  23. data/docs/WorkOS/AuditLog.html +235 -0
  24. data/docs/WorkOS/AuditTrail.html +235 -0
  25. data/docs/WorkOS/AuthenticationError.html +160 -0
  26. data/docs/WorkOS/Base.html +287 -0
  27. data/docs/WorkOS/Client.html +504 -0
  28. data/docs/WorkOS/InvalidRequestError.html +160 -0
  29. data/docs/WorkOS/Profile.html +788 -0
  30. data/docs/WorkOS/RequestError.html +135 -0
  31. data/docs/WorkOS/SSO.html +691 -0
  32. data/docs/WorkOS/Types/ProfileStruct.html +135 -0
  33. data/docs/WorkOS/Types/Provider.html +135 -0
  34. data/docs/WorkOS/Types.html +128 -0
  35. data/docs/WorkOS/WorkOSError.html +447 -0
  36. data/docs/WorkOS.html +324 -0
  37. data/docs/class_list.html +51 -0
  38. data/docs/css/common.css +1 -0
  39. data/docs/css/full_list.css +58 -0
  40. data/docs/css/style.css +496 -0
  41. data/docs/file.README.html +252 -0
  42. data/docs/file_list.html +56 -0
  43. data/docs/frames.html +17 -0
  44. data/docs/index.html +250 -0
  45. data/docs/js/app.js +314 -0
  46. data/docs/js/full_list.js +216 -0
  47. data/docs/js/jquery.js +4 -0
  48. data/docs/method_list.html +267 -0
  49. data/docs/top-level-namespace.html +110 -0
  50. data/lib/workosv2/audit_log_export.rb +55 -0
  51. data/lib/workosv2/audit_logs.rb +114 -0
  52. data/lib/workosv2/audit_trail.rb +111 -0
  53. data/lib/workosv2/challenge.rb +55 -0
  54. data/lib/workosv2/client.rb +186 -0
  55. data/lib/workosv2/configuration.rb +17 -0
  56. data/lib/workosv2/connection.rb +66 -0
  57. data/lib/workosv2/deprecated_hash_wrapper.rb +76 -0
  58. data/lib/workosv2/directory.rb +65 -0
  59. data/lib/workosv2/directory_group.rb +68 -0
  60. data/lib/workosv2/directory_sync.rb +218 -0
  61. data/lib/workosv2/directory_user.rb +97 -0
  62. data/lib/workosv2/errors.rb +81 -0
  63. data/lib/workosv2/event.rb +51 -0
  64. data/lib/workosv2/events.rb +52 -0
  65. data/lib/workosv2/factor.rb +54 -0
  66. data/lib/workosv2/hash_provider.rb +19 -0
  67. data/lib/workosv2/mfa.rb +178 -0
  68. data/lib/workosv2/organization.rb +57 -0
  69. data/lib/workosv2/organizations.rb +188 -0
  70. data/lib/workosv2/passwordless.rb +85 -0
  71. data/lib/workosv2/portal.rb +66 -0
  72. data/lib/workosv2/profile.rb +76 -0
  73. data/lib/workosv2/profile_and_token.rb +29 -0
  74. data/lib/workosv2/sso.rb +297 -0
  75. data/lib/workosv2/types/audit_log_export_struct.rb +17 -0
  76. data/lib/workosv2/types/challenge_struct.rb +18 -0
  77. data/lib/workosv2/types/connection_struct.rb +20 -0
  78. data/lib/workosv2/types/directory_group_struct.rb +19 -0
  79. data/lib/workosv2/types/directory_struct.rb +19 -0
  80. data/lib/workosv2/types/directory_user_struct.rb +26 -0
  81. data/lib/workosv2/types/event_struct.rb +15 -0
  82. data/lib/workosv2/types/factor_struct.rb +18 -0
  83. data/lib/workosv2/types/intent_enum.rb +17 -0
  84. data/lib/workosv2/types/list_struct.rb +13 -0
  85. data/lib/workosv2/types/organization_struct.rb +17 -0
  86. data/lib/workosv2/types/passwordless_session_struct.rb +17 -0
  87. data/lib/workosv2/types/profile_struct.rb +21 -0
  88. data/lib/workosv2/types/provider_enum.rb +15 -0
  89. data/lib/workosv2/types/verify_challenge_struct.rb +13 -0
  90. data/lib/workosv2/types/webhook_struct.rb +15 -0
  91. data/lib/workosv2/types.rb +25 -0
  92. data/lib/workosv2/verify_challenge.rb +39 -0
  93. data/lib/workosv2/version.rb +6 -0
  94. data/lib/workosv2/webhook.rb +51 -0
  95. data/lib/workosv2/webhooks.rb +217 -0
  96. data/lib/workosv2.rb +79 -0
  97. data/sorbet/config +2 -0
  98. data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
  99. data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
  100. data/sorbet/rbi/gems/codecov@0.2.12.rbi +55 -0
  101. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  102. data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
  103. data/sorbet/rbi/gems/diff-lcs@1.4.4.rbi +185 -0
  104. data/sorbet/rbi/gems/docile@1.3.5.rbi +54 -0
  105. data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
  106. data/sorbet/rbi/gems/json@2.5.1.rbi +109 -0
  107. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  108. data/sorbet/rbi/gems/parallel@1.20.1.rbi +113 -0
  109. data/sorbet/rbi/gems/parser@3.0.1.0.rbi +1187 -0
  110. data/sorbet/rbi/gems/pry@0.14.2.rbi +8 -0
  111. data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +146 -0
  112. data/sorbet/rbi/gems/rainbow@3.0.0.rbi +153 -0
  113. data/sorbet/rbi/gems/rake@13.0.3.rbi +807 -0
  114. data/sorbet/rbi/gems/rbi@0.0.16.rbi +2118 -0
  115. data/sorbet/rbi/gems/regexp_parser@2.1.1.rbi +1117 -0
  116. data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
  117. data/sorbet/rbi/gems/rspec-core@3.9.3.rbi +2467 -0
  118. data/sorbet/rbi/gems/rspec-expectations@3.9.4.rbi +1569 -0
  119. data/sorbet/rbi/gems/rspec-mocks@3.9.1.rbi +1493 -0
  120. data/sorbet/rbi/gems/rspec-support@3.9.4.rbi +511 -0
  121. data/sorbet/rbi/gems/rspec@3.9.0.rbi +38 -0
  122. data/sorbet/rbi/gems/rubocop-ast@1.4.1.rbi +1881 -0
  123. data/sorbet/rbi/gems/rubocop@0.93.1.rbi +11497 -0
  124. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
  125. data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +89 -0
  126. data/sorbet/rbi/gems/simplecov@0.21.2.rbi +577 -0
  127. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.2.rbi +8 -0
  128. data/sorbet/rbi/gems/spoom@1.1.15.rbi +1549 -0
  129. data/sorbet/rbi/gems/tapioca@0.7.3.rbi +1718 -0
  130. data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
  131. data/sorbet/rbi/gems/unicode-display_width@1.7.0.rbi +22 -0
  132. data/sorbet/rbi/gems/unparser@0.6.2.rbi +8 -0
  133. data/sorbet/rbi/gems/vcr@5.0.0.rbi +699 -0
  134. data/sorbet/rbi/gems/webmock@3.12.2.rbi +662 -0
  135. data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +268 -0
  136. data/sorbet/rbi/gems/yard@0.9.26.rbi +4048 -0
  137. data/sorbet/tapioca/config.yml +13 -0
  138. data/sorbet/tapioca/require.rb +4 -0
  139. data/spec/lib/workos/audit_logs_spec.rb +151 -0
  140. data/spec/lib/workos/audit_trail_spec.rb +146 -0
  141. data/spec/lib/workos/configuration_spec.rb +61 -0
  142. data/spec/lib/workos/directory_sync_spec.rb +492 -0
  143. data/spec/lib/workos/directory_user_spec.rb +36 -0
  144. data/spec/lib/workos/event_spec.rb +88 -0
  145. data/spec/lib/workos/mfa_spec.rb +281 -0
  146. data/spec/lib/workos/organizations_spec.rb +257 -0
  147. data/spec/lib/workos/passwordless_spec.rb +77 -0
  148. data/spec/lib/workos/portal_spec.rb +87 -0
  149. data/spec/lib/workos/sso_spec.rb +650 -0
  150. data/spec/lib/workos/webhooks_spec.rb +236 -0
  151. data/spec/spec_helper.rb +56 -0
  152. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event.yml +59 -0
  153. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_custom_idempotency_key.yml +60 -0
  154. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_event_invalid.yml +59 -0
  155. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export.yml +76 -0
  156. data/spec/support/fixtures/vcr_cassettes/audit_logs/create_export_with_filters.yml +77 -0
  157. data/spec/support/fixtures/vcr_cassettes/audit_logs/get_export.yml +73 -0
  158. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event.yml +65 -0
  159. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_custom_idempotency_key.yml +67 -0
  160. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_event_invalid.yml +68 -0
  161. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_and_payload.yml +131 -0
  162. data/spec/support/fixtures/vcr_cassettes/audit_trail/create_events_duplicate_idempotency_key_different_payload.yml +134 -0
  163. data/spec/support/fixtures/vcr_cassettes/audit_trail/get_events.yml +61 -0
  164. data/spec/support/fixtures/vcr_cassettes/base/execute_request_unauthenticated.yml +66 -0
  165. data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
  166. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_invalid_id.yml +83 -0
  167. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_directory_with_valid_id.yml +84 -0
  168. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group.yml +80 -0
  169. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_group_with_invalid_id.yml +62 -0
  170. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +83 -0
  171. data/spec/support/fixtures/vcr_cassettes/directory_sync/get_user_with_invalid_id.yml +62 -0
  172. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_after.yml +87 -0
  173. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_before.yml +89 -0
  174. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_domain.yml +84 -0
  175. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_limit.yml +85 -0
  176. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_no_options.yml +93 -0
  177. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +85 -0
  178. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +90 -0
  179. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +90 -0
  180. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +90 -0
  181. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +84 -0
  182. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_no_options.yml +84 -0
  183. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +82 -0
  184. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +186 -0
  185. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +88 -0
  186. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +194 -0
  187. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +186 -0
  188. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +189 -0
  189. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_no_options.yml +74 -0
  190. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_after.yml +80 -0
  191. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_event.yml +80 -0
  192. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_no_options.yml +80 -0
  193. data/spec/support/fixtures/vcr_cassettes/events/list_events_with_range.yml +80 -0
  194. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_generic_valid.yml +82 -0
  195. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_sms_valid.yml +82 -0
  196. data/spec/support/fixtures/vcr_cassettes/mfa/challenge_factor_totp_valid.yml +82 -0
  197. data/spec/support/fixtures/vcr_cassettes/mfa/delete_factor.yml +80 -0
  198. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_generic_valid.yml +82 -0
  199. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_sms_valid.yml +82 -0
  200. data/spec/support/fixtures/vcr_cassettes/mfa/enroll_factor_totp_valid.yml +82 -0
  201. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_invalid.yml +82 -0
  202. data/spec/support/fixtures/vcr_cassettes/mfa/get_factor_valid.yml +82 -0
  203. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_expired.yml +84 -0
  204. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_invalid.yml +84 -0
  205. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid.yml +82 -0
  206. data/spec/support/fixtures/vcr_cassettes/mfa/verify_challenge_generic_valid_is_false.yml +82 -0
  207. data/spec/support/fixtures/vcr_cassettes/organization/create.yml +84 -0
  208. data/spec/support/fixtures/vcr_cassettes/organization/create_invalid.yml +72 -0
  209. data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_different_payload.yml +155 -0
  210. data/spec/support/fixtures/vcr_cassettes/organization/create_with_duplicate_idempotency_key_and_payload.yml +154 -0
  211. data/spec/support/fixtures/vcr_cassettes/organization/create_with_idempotency_key.yml +79 -0
  212. data/spec/support/fixtures/vcr_cassettes/organization/delete.yml +72 -0
  213. data/spec/support/fixtures/vcr_cassettes/organization/delete_invalid.yml +72 -0
  214. data/spec/support/fixtures/vcr_cassettes/organization/get.yml +84 -0
  215. data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
  216. data/spec/support/fixtures/vcr_cassettes/organization/list.yml +87 -0
  217. data/spec/support/fixtures/vcr_cassettes/organization/update.yml +84 -0
  218. data/spec/support/fixtures/vcr_cassettes/passwordless/create_session.yml +72 -0
  219. data/spec/support/fixtures/vcr_cassettes/passwordless/create_session_invalid.yml +73 -0
  220. data/spec/support/fixtures/vcr_cassettes/passwordless/send_session.yml +72 -0
  221. data/spec/support/fixtures/vcr_cassettes/passwordless/send_session_invalid.yml +73 -0
  222. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_audit_logs.yml +72 -0
  223. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_dsync.yml +72 -0
  224. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_invalid.yml +72 -0
  225. data/spec/support/fixtures/vcr_cassettes/portal/generate_link_sso.yml +72 -0
  226. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_invalid_id.yml +72 -0
  227. data/spec/support/fixtures/vcr_cassettes/sso/delete_connection_with_valid_id.yml +70 -0
  228. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_invalid_id.yml +72 -0
  229. data/spec/support/fixtures/vcr_cassettes/sso/get_connection_with_valid_id.yml +86 -0
  230. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +83 -0
  231. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +86 -0
  232. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +90 -0
  233. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_domain.yml +86 -0
  234. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +83 -0
  235. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +89 -0
  236. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_organization_id.yml +86 -0
  237. data/spec/support/fixtures/vcr_cassettes/sso/profile.yml +74 -0
  238. data/spec/support/profile.txt +1 -0
  239. data/spec/support/shared_examples/client_spec.rb +30 -0
  240. data/spec/support/webhook_payload.txt +1 -0
  241. data/workosv2.gemspec +38 -0
  242. metadata +531 -0
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOSV2
5
+ # The Webhook class provides a lightweight wrapper around
6
+ # a WorkOSV2 Webhook resource. This class is not meant to be instantiated
7
+ # in user space, and is instantiated internally but exposed.
8
+ class Webhook
9
+ include HashProvider
10
+ extend T::Sig
11
+
12
+ attr_accessor :id, :event, :data, :created_at
13
+
14
+ sig { params(json: String).void }
15
+ def initialize(json)
16
+ raw = parse_json(json)
17
+
18
+ @id = T.let(raw.id, String)
19
+ @event = T.let(raw.event, String)
20
+ @data = raw.data
21
+ @created_at = T.let(raw.created_at, String)
22
+ end
23
+
24
+ def to_json(*)
25
+ {
26
+ id: id,
27
+ event: event,
28
+ data: data,
29
+ created_at: created_at,
30
+ }
31
+ end
32
+
33
+ private
34
+
35
+ sig do
36
+ params(
37
+ json_string: String,
38
+ ).returns(WorkOSV2::Types::WebhookStruct)
39
+ end
40
+ def parse_json(json_string)
41
+ hash = JSON.parse(json_string, symbolize_names: true)
42
+
43
+ WorkOSV2::Types::WebhookStruct.new(
44
+ id: hash[:id],
45
+ event: hash[:event],
46
+ data: hash[:data],
47
+ created_at: hash[:created_at],
48
+ )
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'openssl'
5
+
6
+ module WorkOSV2
7
+ # The Webhooks module provides convenience methods for working with the WorkOSV2 webhooks.
8
+ # You'll need to extract the signature header and payload from the webhook request
9
+ # sig_header = request.headers['WorkOSV2-Signature']
10
+ # payload = request.body.read
11
+ #
12
+ # The secret is the Webhook Secret from your WorkOSV2 Dashboard
13
+ # The tolerance is for the timestamp validation
14
+ #
15
+ module Webhooks
16
+ class << self
17
+ extend T::Sig
18
+
19
+ DEFAULT_TOLERANCE = 180
20
+
21
+ # Initializes an Event object from a JSON payload
22
+ # rubocop:disable Layout/LineLength
23
+ #
24
+ # @param [String] payload The payload from the webhook sent by WorkOSV2. This is the RAW_POST_DATA of the request.
25
+ # @param [String] sig_header The signature from the webhook sent by WorkOSV2.
26
+ # @param [String] secret The webhook secret from the WorkOSV2 dashboard.
27
+ # @param [Integer] tolerance The time tolerance in seconds for the webhook.
28
+ #
29
+ # @example
30
+ # WorkOSV2::Webhooks.construct_event(
31
+ # payload: "{"id": "wh_123","data":{"id":"directory_user_01FAEAJCR3ZBZ30D8BD1924TVG","state":"active","emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"idp_id":"00u1e8mutl6wlH3lL4x7","object":"directory_user","username":"blair@foo-corp.com","last_name":"Lunceford","first_name":"Blair","directory_id":"directory_01F9M7F68PZP8QXP8G7X5QRHS7","raw_attributes":{"name":{"givenName":"Blair","familyName":"Lunceford","middleName":"Elizabeth","honorificPrefix":"Ms."},"title":"Developer Success Engineer","active":true,"emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"groups":[],"locale":"en-US","schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],"userName":"blair@foo-corp.com","addresses":[{"region":"CO","primary":true,"locality":"Steamboat Springs","postalCode":"80487"}],"externalId":"00u1e8mutl6wlH3lL4x7","displayName":"Blair Lunceford","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":{"manager":{"value":"2","displayName":"Kathleen Chung"},"division":"Engineering","department":"Customer Success"}}},"event":"dsync.user.created"}",
32
+ # sig_header: 't=1626125972272, v1=80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928',
33
+ # secret: 'LJlTiC19GmCKWs8AE0IaOQcos',
34
+ # )
35
+ #
36
+ # => #<WorkOSV2::Webhook:0x00007fa64b980910 @event="dsync.user.created", @data={:id=>"directory_user_01FAEAJCR3ZBZ30D8BD1924TVG", :state=>"active", :emails=>[{:type=>"work", :value=>"blair@foo-corp.com", :primary=>true}], :idp_id=>"00u1e8mutl6wlH3lL4x7", :object=>"directory_user", :username=>"blair@foo-corp.com", :last_name=>"Lunceford", :first_name=>"Blair", :directory_id=>"directory_01F9M7F68PZP8QXP8G7X5QRHS7", :raw_attributes=>{:name=>{:givenName=>"Blair", :familyName=>"Lunceford", :middleName=>"Elizabeth", :honorificPrefix=>"Ms."}, :title=>"Developer Success Engineer", :active=>true, :emails=>[{:type=>"work", :value=>"blair@foo-corp.com", :primary=>true}], :groups=>[], :locale=>"en-US", :schemas=>["urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"], :userName=>"blair@foo-corp.com", :addresses=>[{:region=>"CO", :primary=>true, :locality=>"Steamboat Springs", :postalCode=>"80487"}], :externalId=>"00u1e8mutl6wlH3lL4x7", :displayName=>"Blair Lunceford", :"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"=>{:manager=>{:value=>"2", :displayName=>"Kathleen Chung"}, :division=>"Engineering", :department=>"Customer Success"}}}>
37
+ #
38
+ # @return [WorkOSV2::Webhook]
39
+ # rubocop:enable Layout/LineLength
40
+ sig do
41
+ params(
42
+ payload: String,
43
+ sig_header: String,
44
+ secret: String,
45
+ tolerance: Integer,
46
+ ).returns(WorkOSV2::Webhook)
47
+ end
48
+ def construct_event(
49
+ payload:,
50
+ sig_header:,
51
+ secret:,
52
+ tolerance: DEFAULT_TOLERANCE
53
+ )
54
+ verify_header(payload: payload, sig_header: sig_header, secret: secret, tolerance: tolerance)
55
+ WorkOSV2::Webhook.new(payload)
56
+ end
57
+
58
+ # Verifies WorkOSV2-Signature header from request
59
+ # rubocop:disable Layout/LineLength
60
+ #
61
+ # @param [String] payload The payload from the webhook sent by WorkOSV2. This is the RAW_POST_DATA of the request.
62
+ # @param [String] sig_header The signature from the webhook sent by WorkOSV2.
63
+ # @param [String] secret The webhook secret from the WorkOSV2 dashboard.
64
+ # @param [Integer] tolerance The time tolerance in seconds for the webhook.
65
+ #
66
+ # @example
67
+ # WorkOSV2::Webhooks.verify_header(
68
+ # payload: "{"id": "wh_123","data":{"id":"directory_user_01FAEAJCR3ZBZ30D8BD1924TVG","state":"active","emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"idp_id":"00u1e8mutl6wlH3lL4x7","object":"directory_user","username":"blair@foo-corp.com","last_name":"Lunchford","first_name":"Blair","directory_id":"directory_01F9M7F68PZP8QXP8G7X5QRHS7","raw_attributes":{"name":{"givenName":"Blair","familyName":"Lunchford","middleName":"Elizabeth","honorificPrefix":"Ms."},"title":"Developer Success Engineer","active":true,"emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"groups":[],"locale":"en-US","schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],"userName":"blair@foo-corp.com","addresses":[{"region":"CA","primary":true,"locality":"San Francisco","postalCode":"94016"}],"externalId":"00u1e8mutl6wlH3lL4x7","displayName":"Blair Lunchford","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":{"manager":{"value":"2","displayName":"Kate Chapman"},"division":"Engineering","department":"Customer Success"}}},"event":"dsync.user.created"}",
69
+ # sig_header: 't=1626125972272, v1=80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928',
70
+ # secret: 'LJlTiC19GmCKWs8AE0IaOQcos',
71
+ # )
72
+ #
73
+ # => true
74
+ #
75
+ # @return Boolean
76
+ # rubocop:enable Layout/LineLength
77
+ sig do
78
+ params(
79
+ payload: String,
80
+ sig_header: String,
81
+ secret: String,
82
+ tolerance: Integer,
83
+ ).returns(T::Boolean)
84
+ end
85
+ # rubocop:disable Metrics/AbcSize
86
+ def verify_header(
87
+ payload:,
88
+ sig_header:,
89
+ secret:,
90
+ tolerance: DEFAULT_TOLERANCE
91
+ )
92
+ begin
93
+ timestamp, signature_hash = get_timestamp_and_signature_hash(sig_header: sig_header)
94
+ rescue StandardError
95
+ raise WorkOSV2::SignatureVerificationError.new(
96
+ message: 'Unable to extract timestamp and signature hash from header',
97
+ )
98
+ end
99
+
100
+ if signature_hash.empty?
101
+ raise WorkOSV2::SignatureVerificationError.new(
102
+ message: 'No signature hash found with expected scheme v1',
103
+ )
104
+ end
105
+
106
+ timestamp_to_time = Time.at(timestamp.to_i / 1000)
107
+
108
+ if timestamp_to_time < Time.now - tolerance
109
+ raise WorkOSV2::SignatureVerificationError.new(
110
+ message: 'Timestamp outside the tolerance zone',
111
+ )
112
+ end
113
+
114
+ expected_sig = compute_signature(timestamp: timestamp, payload: payload, secret: secret)
115
+ unless secure_compare(str_a: expected_sig, str_b: signature_hash)
116
+ raise WorkOSV2::SignatureVerificationError.new(
117
+ message: 'Signature hash does not match the expected signature hash for payload',
118
+ )
119
+ end
120
+
121
+ true
122
+ end
123
+ # rubocop:enable Metrics/AbcSize
124
+
125
+ # Extracts timestamp and signature hash from WorkOSV2-Signature header
126
+ #
127
+ # @param [String] sig_header The signature from the webhook sent by WorkOSV2.
128
+ #
129
+ # @example
130
+ # WorkOSV2::Webhooks.get_timestamp_and_signature_hash(
131
+ # sig_header: 't=1626125972272, v1=80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928',
132
+ # )
133
+ #
134
+ # => ['1626125972272', '80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928']
135
+ #
136
+ # @return Array
137
+ sig do
138
+ params(
139
+ sig_header: String,
140
+ ).returns([String, String])
141
+ end
142
+ def get_timestamp_and_signature_hash(
143
+ sig_header:
144
+ )
145
+ timestamp, signature_hash = sig_header.split(', ')
146
+
147
+ if timestamp.nil? || signature_hash.nil?
148
+ raise WorkOSV2::SignatureVerificationError.new(
149
+ message: 'Unable to extract timestamp and signature hash from header',
150
+ )
151
+ end
152
+
153
+ timestamp = timestamp.sub('t=', '')
154
+ signature_hash = signature_hash.sub('v1=', '')
155
+
156
+ [timestamp, signature_hash]
157
+ end
158
+
159
+ # Computes expected signature
160
+ # rubocop:disable Layout/LineLength
161
+ #
162
+ # @param [String] timestamp The timestamp from the webhook signature.
163
+ # @param [String] payload The payload from the webhook sent by WorkOSV2. This is the RAW_POST_DATA of the request.
164
+ # @param [String] secret The webhook secret from the WorkOSV2 dashboard.
165
+ #
166
+ # @example
167
+ # WorkOSV2::Webhooks.compute_signature(
168
+ # timestamp: '1626125972272',
169
+ # payload: "{"id": "wh_123","data":{"id":"directory_user_01FAEAJCR3ZBZ30D8BD1924TVG","state":"active","emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"idp_id":"00u1e8mutl6wlH3lL4x7","object":"directory_user","username":"blair@foo-corp.com","last_name":"Lunchford","first_name":"Blair","directory_id":"directory_01F9M7F68PZP8QXP8G7X5QRHS7","raw_attributes":{"name":{"givenName":"Blair","familyName":"Lunchford","middleName":"Elizabeth","honorificPrefix":"Ms."},"title":"Developer Success Engineer","active":true,"emails":[{"type":"work","value":"blair@foo-corp.com","primary":true}],"groups":[],"locale":"en-US","schemas":["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],"userName":"blair@foo-corp.com","addresses":[{"region":"CA","primary":true,"locality":"San Francisco","postalCode":"94016"}],"externalId":"00u1e8mutl6wlH3lL4x7","displayName":"Blair Lunchford","urn:ietf:params:scim:schemas:extension:enterprise:2.0:User":{"manager":{"value":"2","displayName":"Kate Chapman"},"division":"Engineering","department":"Customer Success"}}},"event":"dsync.user.created"}",
170
+ # secret: 'LJlTiC19GmCKWs8AE0IaOQcos',
171
+ # )
172
+ #
173
+ # => '80f7ab7efadc306eb5797c588cee9410da9be4416782b497bf1e1bf4175fb928'
174
+ #
175
+ # @return String
176
+ # rubocop:enable Layout/LineLength
177
+ sig do
178
+ params(
179
+ timestamp: String,
180
+ payload: String,
181
+ secret: String,
182
+ ).returns(String)
183
+ end
184
+ def compute_signature(
185
+ timestamp:,
186
+ payload:,
187
+ secret:
188
+ )
189
+ unhashed_string = "#{timestamp}.#{payload}"
190
+ digest = OpenSSL::Digest.new('sha256')
191
+ OpenSSL::HMAC.hexdigest(digest, secret, unhashed_string)
192
+ end
193
+
194
+ # Constant time string comparison to prevent timing attacks
195
+ # Code borrowed from ActiveSupport
196
+ sig do
197
+ params(
198
+ str_a: String,
199
+ str_b: String,
200
+ ).returns(T::Boolean)
201
+ end
202
+ def secure_compare(
203
+ str_a:,
204
+ str_b:
205
+ )
206
+ return false unless str_a.bytesize == str_b.bytesize
207
+
208
+ l = T.unsafe(str_a.unpack("C#{str_a.bytesize}"))
209
+
210
+ res = 0
211
+ str_b.each_byte { |byte| res |= byte ^ l.shift }
212
+
213
+ res.zero?
214
+ end
215
+ end
216
+ end
217
+ end
data/lib/workosv2.rb ADDED
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'workosv2/version'
5
+ require 'sorbet-runtime'
6
+ require 'json'
7
+ require 'workosv2/hash_provider'
8
+ require 'workosv2/configuration'
9
+
10
+ # Use the WorkOSV2 module to authenticate your
11
+ # requests to the WorkOSV2 API. The gem will read
12
+ # your API key automatically from the ENV var `WORKOS_API_KEY`.
13
+ # Alternatively, you can set the key yourself with
14
+ # `WorkOSV2.key = [your api key]` somewhere in the load path of
15
+ # your application, such as an initializer.
16
+ module WorkOSV2
17
+ API_HOSTNAME = ENV['WORKOS_API_HOSTNAME'] || 'api.workos.com'
18
+
19
+ def self.key=(value)
20
+ warn '`WorkOSV2.key=` is deprecated. Use `WorkOSV2.configure` instead.'
21
+
22
+ config.key = value
23
+ end
24
+
25
+ def self.key
26
+ warn '`WorkOSV2.key` is deprecated. Use `WorkOSV2.configure` instead.'
27
+
28
+ config.key
29
+ end
30
+
31
+ def self.config
32
+ @config ||= Configuration.new
33
+ end
34
+
35
+ def self.configure
36
+ yield(config)
37
+ end
38
+
39
+ autoload :Types, 'workosv2/types'
40
+ autoload :Client, 'workosv2/client'
41
+ autoload :Configuration, 'workosv2/configuration'
42
+ autoload :AuditLogExport, 'workosv2/audit_log_export'
43
+ autoload :AuditLogs, 'workosv2/audit_logs'
44
+ autoload :AuditTrail, 'workosv2/audit_trail'
45
+ autoload :Connection, 'workosv2/connection'
46
+ autoload :DirectorySync, 'workosv2/directory_sync'
47
+ autoload :Directory, 'workosv2/directory'
48
+ autoload :DirectoryGroup, 'workosv2/directory_group'
49
+ autoload :Event, 'workosv2/event'
50
+ autoload :Events, 'workosv2/events'
51
+ autoload :Organization, 'workosv2/organization'
52
+ autoload :Organizations, 'workosv2/organizations'
53
+ autoload :Passwordless, 'workosv2/passwordless'
54
+ autoload :Portal, 'workosv2/portal'
55
+ autoload :Profile, 'workosv2/profile'
56
+ autoload :ProfileAndToken, 'workosv2/profile_and_token'
57
+ autoload :SSO, 'workosv2/sso'
58
+ autoload :DirectoryUser, 'workosv2/directory_user'
59
+ autoload :Webhook, 'workosv2/webhook'
60
+ autoload :Webhooks, 'workosv2/webhooks'
61
+ autoload :MFA, 'workosv2/mfa'
62
+ autoload :Factor, 'workosv2/factor'
63
+ autoload :Challenge, 'workosv2/challenge'
64
+ autoload :VerifyChallenge, 'workosv2/verify_challenge'
65
+ autoload :DeprecatedHashWrapper, 'workosv2/deprecated_hash_wrapper'
66
+
67
+
68
+ # Errors
69
+ autoload :APIError, 'workosv2/errors'
70
+ autoload :AuthenticationError, 'workosv2/errors'
71
+ autoload :InvalidRequestError, 'workosv2/errors'
72
+ autoload :SignatureVerificationError, 'workosv2/errors'
73
+ autoload :TimeoutError, 'workosv2/errors'
74
+
75
+ # Remove WORKOS_KEY at some point in the future. Keeping it here now for
76
+ # backwards compatibility.
77
+ key = ENV['WORKOS_API_KEY'] || ENV['WORKOS_KEY']
78
+ config.key = key unless key.nil?
79
+ end
data/sorbet/config ADDED
@@ -0,0 +1,2 @@
1
+ --dir
2
+ .
@@ -0,0 +1,290 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This is an autogenerated file for types exported from the `addressable` gem.
5
+ # Please instead update this file by running `bin/tapioca gem addressable`.
6
+
7
+ module Addressable; end
8
+
9
+ module Addressable::IDNA
10
+ class << self
11
+ def to_ascii(input); end
12
+ def to_unicode(input); end
13
+ def unicode_normalize_kc(input); end
14
+
15
+ private
16
+
17
+ def lookup_unicode_combining_class(codepoint); end
18
+ def lookup_unicode_compatibility(codepoint); end
19
+ def lookup_unicode_composition(unpacked); end
20
+ def lookup_unicode_lowercase(codepoint); end
21
+ def punycode_adapt(delta, numpoints, firsttime); end
22
+ def punycode_basic?(codepoint); end
23
+ def punycode_decode(punycode); end
24
+ def punycode_decode_digit(codepoint); end
25
+ def punycode_delimiter?(codepoint); end
26
+ def punycode_encode(unicode); end
27
+ def punycode_encode_digit(d); end
28
+ def ucs4_to_utf8(char, buffer); end
29
+ def unicode_compose(unpacked); end
30
+ def unicode_compose_pair(ch_one, ch_two); end
31
+ def unicode_decompose(unpacked); end
32
+ def unicode_decompose_hangul(codepoint); end
33
+ def unicode_downcase(input); end
34
+ def unicode_sort_canonical(unpacked); end
35
+ end
36
+ end
37
+
38
+ Addressable::IDNA::ACE_MAX_LENGTH = T.let(T.unsafe(nil), Integer)
39
+ Addressable::IDNA::ACE_PREFIX = T.let(T.unsafe(nil), String)
40
+ Addressable::IDNA::COMPOSITION_TABLE = T.let(T.unsafe(nil), Hash)
41
+ Addressable::IDNA::HANGUL_LBASE = T.let(T.unsafe(nil), Integer)
42
+ Addressable::IDNA::HANGUL_LCOUNT = T.let(T.unsafe(nil), Integer)
43
+ Addressable::IDNA::HANGUL_NCOUNT = T.let(T.unsafe(nil), Integer)
44
+ Addressable::IDNA::HANGUL_SBASE = T.let(T.unsafe(nil), Integer)
45
+ Addressable::IDNA::HANGUL_SCOUNT = T.let(T.unsafe(nil), Integer)
46
+ Addressable::IDNA::HANGUL_TBASE = T.let(T.unsafe(nil), Integer)
47
+ Addressable::IDNA::HANGUL_TCOUNT = T.let(T.unsafe(nil), Integer)
48
+ Addressable::IDNA::HANGUL_VBASE = T.let(T.unsafe(nil), Integer)
49
+ Addressable::IDNA::HANGUL_VCOUNT = T.let(T.unsafe(nil), Integer)
50
+ Addressable::IDNA::PUNYCODE_BASE = T.let(T.unsafe(nil), Integer)
51
+ Addressable::IDNA::PUNYCODE_DAMP = T.let(T.unsafe(nil), Integer)
52
+ Addressable::IDNA::PUNYCODE_DELIMITER = T.let(T.unsafe(nil), Integer)
53
+ Addressable::IDNA::PUNYCODE_INITIAL_BIAS = T.let(T.unsafe(nil), Integer)
54
+ Addressable::IDNA::PUNYCODE_INITIAL_N = T.let(T.unsafe(nil), Integer)
55
+ Addressable::IDNA::PUNYCODE_MAXINT = T.let(T.unsafe(nil), Integer)
56
+ Addressable::IDNA::PUNYCODE_PRINT_ASCII = T.let(T.unsafe(nil), String)
57
+ Addressable::IDNA::PUNYCODE_SKEW = T.let(T.unsafe(nil), Integer)
58
+ Addressable::IDNA::PUNYCODE_TMAX = T.let(T.unsafe(nil), Integer)
59
+ Addressable::IDNA::PUNYCODE_TMIN = T.let(T.unsafe(nil), Integer)
60
+ class Addressable::IDNA::PunycodeBadInput < ::StandardError; end
61
+ class Addressable::IDNA::PunycodeBigOutput < ::StandardError; end
62
+ class Addressable::IDNA::PunycodeOverflow < ::StandardError; end
63
+ Addressable::IDNA::UNICODE_DATA = T.let(T.unsafe(nil), Hash)
64
+ Addressable::IDNA::UNICODE_DATA_CANONICAL = T.let(T.unsafe(nil), Integer)
65
+ Addressable::IDNA::UNICODE_DATA_COMBINING_CLASS = T.let(T.unsafe(nil), Integer)
66
+ Addressable::IDNA::UNICODE_DATA_COMPATIBILITY = T.let(T.unsafe(nil), Integer)
67
+ Addressable::IDNA::UNICODE_DATA_EXCLUSION = T.let(T.unsafe(nil), Integer)
68
+ Addressable::IDNA::UNICODE_DATA_LOWERCASE = T.let(T.unsafe(nil), Integer)
69
+ Addressable::IDNA::UNICODE_DATA_TITLECASE = T.let(T.unsafe(nil), Integer)
70
+ Addressable::IDNA::UNICODE_DATA_UPPERCASE = T.let(T.unsafe(nil), Integer)
71
+ Addressable::IDNA::UNICODE_MAX_LENGTH = T.let(T.unsafe(nil), Integer)
72
+ Addressable::IDNA::UNICODE_TABLE = T.let(T.unsafe(nil), String)
73
+ Addressable::IDNA::UTF8_REGEX = T.let(T.unsafe(nil), Regexp)
74
+ Addressable::IDNA::UTF8_REGEX_MULTIBYTE = T.let(T.unsafe(nil), Regexp)
75
+
76
+ class Addressable::Template
77
+ def initialize(pattern); end
78
+
79
+ def ==(template); end
80
+ def eql?(template); end
81
+ def expand(mapping, processor = T.unsafe(nil), normalize_values = T.unsafe(nil)); end
82
+ def extract(uri, processor = T.unsafe(nil)); end
83
+ def freeze; end
84
+ def inspect; end
85
+ def keys; end
86
+ def match(uri, processor = T.unsafe(nil)); end
87
+ def named_captures; end
88
+ def names; end
89
+ def partial_expand(mapping, processor = T.unsafe(nil), normalize_values = T.unsafe(nil)); end
90
+ def pattern; end
91
+ def source; end
92
+ def to_regexp; end
93
+ def variable_defaults; end
94
+ def variables; end
95
+
96
+ private
97
+
98
+ def join_values(operator, return_value); end
99
+ def normalize_keys(mapping); end
100
+ def normalize_value(value); end
101
+ def ordered_variable_defaults; end
102
+ def parse_new_template_pattern(pattern, processor = T.unsafe(nil)); end
103
+ def parse_template_pattern(pattern, processor = T.unsafe(nil)); end
104
+ def transform_capture(mapping, capture, processor = T.unsafe(nil), normalize_values = T.unsafe(nil)); end
105
+ def transform_partial_capture(mapping, capture, processor = T.unsafe(nil), normalize_values = T.unsafe(nil)); end
106
+ end
107
+
108
+ Addressable::Template::EXPRESSION = T.let(T.unsafe(nil), Regexp)
109
+ class Addressable::Template::InvalidTemplateOperatorError < ::StandardError; end
110
+ class Addressable::Template::InvalidTemplateValueError < ::StandardError; end
111
+ Addressable::Template::JOINERS = T.let(T.unsafe(nil), Hash)
112
+ Addressable::Template::LEADERS = T.let(T.unsafe(nil), Hash)
113
+
114
+ class Addressable::Template::MatchData
115
+ def initialize(uri, template, mapping); end
116
+
117
+ def [](key, len = T.unsafe(nil)); end
118
+ def captures; end
119
+ def inspect; end
120
+ def keys; end
121
+ def mapping; end
122
+ def names; end
123
+ def post_match; end
124
+ def pre_match; end
125
+ def string; end
126
+ def template; end
127
+ def to_a; end
128
+ def to_s; end
129
+ def uri; end
130
+ def values; end
131
+ def values_at(*indexes); end
132
+ def variables; end
133
+ end
134
+
135
+ Addressable::Template::RESERVED = T.let(T.unsafe(nil), String)
136
+ class Addressable::Template::TemplateOperatorAbortedError < ::StandardError; end
137
+ Addressable::Template::UNRESERVED = T.let(T.unsafe(nil), String)
138
+ Addressable::Template::VARIABLE_LIST = T.let(T.unsafe(nil), Regexp)
139
+ Addressable::Template::VARNAME = T.let(T.unsafe(nil), Regexp)
140
+ Addressable::Template::VARSPEC = T.let(T.unsafe(nil), Regexp)
141
+
142
+ class Addressable::URI
143
+ def initialize(options = T.unsafe(nil)); end
144
+
145
+ def +(uri); end
146
+ def ==(uri); end
147
+ def ===(uri); end
148
+ def absolute?; end
149
+ def authority; end
150
+ def authority=(new_authority); end
151
+ def basename; end
152
+ def default_port; end
153
+ def defer_validation; end
154
+ def display_uri; end
155
+ def domain; end
156
+ def dup; end
157
+ def empty?; end
158
+ def eql?(uri); end
159
+ def extname; end
160
+ def fragment; end
161
+ def fragment=(new_fragment); end
162
+ def freeze; end
163
+ def hash; end
164
+ def host; end
165
+ def host=(new_host); end
166
+ def hostname; end
167
+ def hostname=(new_hostname); end
168
+ def inferred_port; end
169
+ def inspect; end
170
+ def ip_based?; end
171
+ def join(uri); end
172
+ def join!(uri); end
173
+ def merge(hash); end
174
+ def merge!(uri); end
175
+ def normalize; end
176
+ def normalize!; end
177
+ def normalized_authority; end
178
+ def normalized_fragment; end
179
+ def normalized_host; end
180
+ def normalized_password; end
181
+ def normalized_path; end
182
+ def normalized_port; end
183
+ def normalized_query(*flags); end
184
+ def normalized_scheme; end
185
+ def normalized_site; end
186
+ def normalized_user; end
187
+ def normalized_userinfo; end
188
+ def omit(*components); end
189
+ def omit!(*components); end
190
+ def origin; end
191
+ def origin=(new_origin); end
192
+ def password; end
193
+ def password=(new_password); end
194
+ def path; end
195
+ def path=(new_path); end
196
+ def port; end
197
+ def port=(new_port); end
198
+ def query; end
199
+ def query=(new_query); end
200
+ def query_values(return_type = T.unsafe(nil)); end
201
+ def query_values=(new_query_values); end
202
+ def relative?; end
203
+ def request_uri; end
204
+ def request_uri=(new_request_uri); end
205
+ def route_from(uri); end
206
+ def route_to(uri); end
207
+ def scheme; end
208
+ def scheme=(new_scheme); end
209
+ def site; end
210
+ def site=(new_site); end
211
+ def tld; end
212
+ def tld=(new_tld); end
213
+ def to_hash; end
214
+ def to_s; end
215
+ def to_str; end
216
+ def user; end
217
+ def user=(new_user); end
218
+ def userinfo; end
219
+ def userinfo=(new_userinfo); end
220
+
221
+ protected
222
+
223
+ def remove_composite_values; end
224
+ def replace_self(uri); end
225
+ def split_path(path); end
226
+ def validate; end
227
+
228
+ class << self
229
+ def convert_path(path); end
230
+ def encode(uri, return_type = T.unsafe(nil)); end
231
+ def encode_component(component, character_class = T.unsafe(nil), upcase_encoded = T.unsafe(nil)); end
232
+ def escape(uri, return_type = T.unsafe(nil)); end
233
+ def escape_component(component, character_class = T.unsafe(nil), upcase_encoded = T.unsafe(nil)); end
234
+ def form_encode(form_values, sort = T.unsafe(nil)); end
235
+ def form_unencode(encoded_value); end
236
+ def heuristic_parse(uri, hints = T.unsafe(nil)); end
237
+ def ip_based_schemes; end
238
+ def join(*uris); end
239
+ def normalize_component(component, character_class = T.unsafe(nil), leave_encoded = T.unsafe(nil)); end
240
+ def normalize_path(path); end
241
+ def normalized_encode(uri, return_type = T.unsafe(nil)); end
242
+ def parse(uri); end
243
+ def port_mapping; end
244
+ def unencode(uri, return_type = T.unsafe(nil), leave_encoded = T.unsafe(nil)); end
245
+ def unencode_component(uri, return_type = T.unsafe(nil), leave_encoded = T.unsafe(nil)); end
246
+ def unescape(uri, return_type = T.unsafe(nil), leave_encoded = T.unsafe(nil)); end
247
+ def unescape_component(uri, return_type = T.unsafe(nil), leave_encoded = T.unsafe(nil)); end
248
+ end
249
+ end
250
+
251
+ module Addressable::URI::CharacterClasses; end
252
+ Addressable::URI::CharacterClasses::ALPHA = T.let(T.unsafe(nil), String)
253
+ Addressable::URI::CharacterClasses::AUTHORITY = T.let(T.unsafe(nil), String)
254
+ Addressable::URI::CharacterClasses::DIGIT = T.let(T.unsafe(nil), String)
255
+ Addressable::URI::CharacterClasses::FRAGMENT = T.let(T.unsafe(nil), String)
256
+ Addressable::URI::CharacterClasses::GEN_DELIMS = T.let(T.unsafe(nil), String)
257
+ Addressable::URI::CharacterClasses::HOST = T.let(T.unsafe(nil), String)
258
+ Addressable::URI::CharacterClasses::PATH = T.let(T.unsafe(nil), String)
259
+ Addressable::URI::CharacterClasses::PCHAR = T.let(T.unsafe(nil), String)
260
+ Addressable::URI::CharacterClasses::QUERY = T.let(T.unsafe(nil), String)
261
+ Addressable::URI::CharacterClasses::RESERVED = T.let(T.unsafe(nil), String)
262
+ Addressable::URI::CharacterClasses::SCHEME = T.let(T.unsafe(nil), String)
263
+ Addressable::URI::CharacterClasses::SUB_DELIMS = T.let(T.unsafe(nil), String)
264
+ Addressable::URI::CharacterClasses::UNRESERVED = T.let(T.unsafe(nil), String)
265
+ Addressable::URI::EMPTY_STR = T.let(T.unsafe(nil), String)
266
+ class Addressable::URI::InvalidURIError < ::StandardError; end
267
+ Addressable::URI::NORMPATH = T.let(T.unsafe(nil), Regexp)
268
+ module Addressable::URI::NormalizeCharacterClasses; end
269
+ Addressable::URI::NormalizeCharacterClasses::FRAGMENT = T.let(T.unsafe(nil), Regexp)
270
+ Addressable::URI::NormalizeCharacterClasses::HOST = T.let(T.unsafe(nil), Regexp)
271
+ Addressable::URI::NormalizeCharacterClasses::PCHAR = T.let(T.unsafe(nil), Regexp)
272
+ Addressable::URI::NormalizeCharacterClasses::QUERY = T.let(T.unsafe(nil), Regexp)
273
+ Addressable::URI::NormalizeCharacterClasses::SCHEME = T.let(T.unsafe(nil), Regexp)
274
+ Addressable::URI::NormalizeCharacterClasses::UNRESERVED = T.let(T.unsafe(nil), Regexp)
275
+ Addressable::URI::PARENT = T.let(T.unsafe(nil), String)
276
+ Addressable::URI::PORT_MAPPING = T.let(T.unsafe(nil), Hash)
277
+ Addressable::URI::RULE_2A = T.let(T.unsafe(nil), Regexp)
278
+ Addressable::URI::RULE_2B_2C = T.let(T.unsafe(nil), Regexp)
279
+ Addressable::URI::RULE_2D = T.let(T.unsafe(nil), Regexp)
280
+ Addressable::URI::RULE_PREFIXED_PARENT = T.let(T.unsafe(nil), Regexp)
281
+ Addressable::URI::SELF_REF = T.let(T.unsafe(nil), String)
282
+ Addressable::URI::SEQUENCE_ENCODING_TABLE = T.let(T.unsafe(nil), Hash)
283
+ Addressable::URI::SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = T.let(T.unsafe(nil), Hash)
284
+ Addressable::URI::SLASH = T.let(T.unsafe(nil), String)
285
+ Addressable::URI::URIREGEX = T.let(T.unsafe(nil), Regexp)
286
+ module Addressable::VERSION; end
287
+ Addressable::VERSION::MAJOR = T.let(T.unsafe(nil), Integer)
288
+ Addressable::VERSION::MINOR = T.let(T.unsafe(nil), Integer)
289
+ Addressable::VERSION::STRING = T.let(T.unsafe(nil), String)
290
+ Addressable::VERSION::TINY = T.let(T.unsafe(nil), Integer)