noresponse 2.0.19 → 2.1.1
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/lib/no_response/assessments.rb +1 -1
- data/lib/no_response/integrations.rb +1 -1
- data/lib/no_response/late_results.rb +23 -17
- data/lib/no_response/models/shared/assessment.rb +12 -2
- data/lib/no_response/models/shared/assessment.rbi +6 -0
- data/lib/no_response/models/shared/assessmentauthcontext.rb +121 -0
- data/lib/no_response/models/shared/assessmentauthcontext.rbi +56 -0
- data/lib/no_response/models/shared/assessmentrequest.rb +1 -1
- data/lib/no_response/models/shared/authcontext.rb +4 -4
- data/lib/no_response/models/shared/hookpoint.rb +5 -2
- data/lib/no_response/models/shared/security.rb +3 -3
- data/lib/no_response/models/shared/transport.rb +5 -2
- data/lib/no_response/models/shared.rb +1 -0
- data/lib/no_response/sdkconfiguration.rb +5 -2
- data/lib/no_response/webhookendpoints.rb +1 -1
- data/lib/no_response/webhooks.rb +7 -2
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa2ff6a681aaee7b0f9bd98478724782cb18249cc8c48942f034fbc8d867679d
|
|
4
|
+
data.tar.gz: 9bcb31d1a5a209bbaaf42d3b6bdf726dc7cd2ebdcb55751bb612351b40b0f185
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8c253f5a8feb2f89d93d6075ccd782bb6021b02c4b0758046e111f387352d757605fa291cd24ad4a2094694f64dfaaa152b79b08ce3aae08e37685e63bf90be
|
|
7
|
+
data.tar.gz: e6d609c3ed68b38e8f7882d68f3f62699f26c02597be788ce329499bd0ad2c4cbe611c7a76c1b52b42d4f32eebd2247364bd62147480dc2fa79dc01c0b272753
|
|
@@ -50,7 +50,7 @@ module NoResponse
|
|
|
50
50
|
}
|
|
51
51
|
def create(body:, idempotency_key: nil, retries: nil, timeout_ms: nil, http_headers: nil)
|
|
52
52
|
# create - Assess identifiers for a signup or gateway decision.
|
|
53
|
-
# Returns within the deadline (
|
|
53
|
+
# Returns within the deadline (3000 ms at most) with a complete, partial or pending assessment: 200 carries complete or partial, 202 carries pending with Location and Retry-After. A pending answer has no recommendation; apply your own fallback for pending, 429, 503 or a timeout. risk.block says when your block threshold was reached. Requires the assess scope. Idempotency-Key is optional in the SDK and is bound to the body for 24 hours: the same key with the same body replays the latest assessment with Idempotent-Replayed: true and starts no new work; the same key with a different body answers 409 idempotency_key_reused. response_mode defaults to standard; detailed needs the detailed scope.
|
|
54
54
|
request = Models::Operations::CreateAssessmentRequest.new(
|
|
55
55
|
body: body,
|
|
56
56
|
idempotency_key: idempotency_key
|
|
@@ -706,7 +706,7 @@ module NoResponse
|
|
|
706
706
|
response: http_response
|
|
707
707
|
)
|
|
708
708
|
return Models::Operations::DeleteIntegrationResponse.new(
|
|
709
|
-
headers:
|
|
709
|
+
headers: http_response.headers
|
|
710
710
|
)
|
|
711
711
|
elsif Utils.match_status_code(http_response.status, ["400"])
|
|
712
712
|
if Utils.match_content_type(content_type, "application/problem+json")
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
# user.
|
|
12
12
|
#
|
|
13
13
|
# The handler verifies the delivery itself, so it never acts on an unverified
|
|
14
|
-
# event
|
|
14
|
+
# event, and it never acts on a test event from the send-test-event call. Every
|
|
15
|
+
# provider call treats a 404 (user or session already gone) as done, so a
|
|
16
|
+
# repeated delivery is safe. The provider calls are thin: you pass the credentials, and each
|
|
15
17
|
# action is the provider's documented admin endpoint.
|
|
16
18
|
|
|
17
19
|
require 'erb'
|
|
@@ -54,12 +56,12 @@ module NoResponse
|
|
|
54
56
|
|
|
55
57
|
class << self
|
|
56
58
|
# The action your policy names for a verified event. Only a served
|
|
57
|
-
# assessment with a recommendation can act
|
|
58
|
-
# and review (as strings or symbols) to NONE,
|
|
59
|
-
# recommendation you leave out does nothing. An
|
|
60
|
-
# ArgumentError.
|
|
59
|
+
# assessment with a recommendation can act; a test event never does.
|
|
60
|
+
# policy maps allow, step_up and review (as strings or symbols) to NONE,
|
|
61
|
+
# REVOKE_SESSIONS or BAN; a recommendation you leave out does nothing. An
|
|
62
|
+
# unknown action raises ArgumentError.
|
|
61
63
|
def action_for(event, policy = DEFAULT_POLICY)
|
|
62
|
-
return NONE if event.type != 'assessment.updated' || event.expired?
|
|
64
|
+
return NONE if event.type != 'assessment.updated' || event.test? || event.expired?
|
|
63
65
|
|
|
64
66
|
data = event.data
|
|
65
67
|
recommendation = data.recommendation || data.risk&.recommendation
|
|
@@ -111,7 +113,8 @@ module NoResponse
|
|
|
111
113
|
# Clerk Backend API. revoke_sessions lists the user's active sessions
|
|
112
114
|
# (GET /sessions?user_id&status=active) and revokes each
|
|
113
115
|
# (POST /sessions/{id}/revoke). ban is POST /users/{id}/ban, which
|
|
114
|
-
# revokes every session and blocks sign-in.
|
|
116
|
+
# revokes every session and blocks sign-in. A 404 on any call (user or
|
|
117
|
+
# session already gone) counts as done, so a repeated delivery is safe.
|
|
115
118
|
#
|
|
116
119
|
# base_url defaults to https://api.clerk.com/v1. http_client is an
|
|
117
120
|
# optional callable (method, uri, headers, body) returning
|
|
@@ -126,7 +129,9 @@ module NoResponse
|
|
|
126
129
|
# GET /user_management/users/{id}/sessions and revokes each active one
|
|
127
130
|
# with POST /user_management/sessions/revoke. WorkOS has no block or ban,
|
|
128
131
|
# so ban revokes the sessions and then deletes the user
|
|
129
|
-
# (DELETE /user_management/users/{id}); deletion is permanent.
|
|
132
|
+
# (DELETE /user_management/users/{id}); deletion is permanent. A 404 on
|
|
133
|
+
# any call (user or session already gone) counts as done, so a repeated
|
|
134
|
+
# delivery is safe.
|
|
130
135
|
#
|
|
131
136
|
# base_url defaults to https://api.workos.com.
|
|
132
137
|
def workos(api_key:, base_url: 'https://api.workos.com', http_client: nil)
|
|
@@ -141,7 +146,8 @@ module NoResponse
|
|
|
141
146
|
# (PATCH /users/{id}), then does the same. Pass domain (such as
|
|
142
147
|
# example.eu.auth0.com; the API is https://{domain}/api/v2) or base_url.
|
|
143
148
|
# token is a Management API access token with update:users,
|
|
144
|
-
# delete:sessions and delete:refresh_tokens.
|
|
149
|
+
# delete:sessions and delete:refresh_tokens. A 404 on any call (user
|
|
150
|
+
# already gone) counts as done, so a repeated delivery is safe.
|
|
145
151
|
def auth0(token:, domain: nil, base_url: nil, http_client: nil)
|
|
146
152
|
raise ArgumentError, 'auth0 needs token' if token.to_s.empty?
|
|
147
153
|
|
|
@@ -232,16 +238,16 @@ module NoResponse
|
|
|
232
238
|
(0...1000).each do |round|
|
|
233
239
|
page = Segment.sessions(@call.call('GET', '/sessions', query: [['user_id', user_id], %w[status active],
|
|
234
240
|
['limit', PAGE.to_s],
|
|
235
|
-
['offset', (round * PAGE).to_s]]))
|
|
241
|
+
['offset', (round * PAGE).to_s]], allow_404: true))
|
|
236
242
|
active.concat(Segment.active_ids(page))
|
|
237
243
|
break if page.length < PAGE
|
|
238
244
|
end
|
|
239
|
-
active.each { |id| @call.call('POST', "/sessions/#{ERB::Util.url_encode(id)}/revoke") }
|
|
245
|
+
active.each { |id| @call.call('POST', "/sessions/#{ERB::Util.url_encode(id)}/revoke", allow_404: true) }
|
|
240
246
|
nil
|
|
241
247
|
end
|
|
242
248
|
|
|
243
249
|
def ban(user_id)
|
|
244
|
-
@call.call('POST', "/users/#{Segment.encode(user_id)}/ban")
|
|
250
|
+
@call.call('POST', "/users/#{Segment.encode(user_id)}/ban", allow_404: true)
|
|
245
251
|
nil
|
|
246
252
|
end
|
|
247
253
|
end
|
|
@@ -260,14 +266,14 @@ module NoResponse
|
|
|
260
266
|
1000.times do
|
|
261
267
|
query = T.let([%w[limit 100]], T::Array[T::Array[String]])
|
|
262
268
|
query << ['after', after] if after
|
|
263
|
-
body = @call.call('GET', "/user_management/users/#{user}/sessions", query: query)
|
|
269
|
+
body = @call.call('GET', "/user_management/users/#{user}/sessions", query: query, allow_404: true)
|
|
264
270
|
active.concat(Segment.active_ids(Segment.sessions(body)))
|
|
265
271
|
nxt = body.is_a?(Hash) && body['list_metadata'].is_a?(Hash) ? body['list_metadata']['after'] : nil
|
|
266
272
|
break unless nxt.is_a?(String) && !nxt.empty?
|
|
267
273
|
|
|
268
274
|
after = nxt
|
|
269
275
|
end
|
|
270
|
-
active.each { |id| @call.call('POST', '/user_management/sessions/revoke', body: { 'session_id' => id }) }
|
|
276
|
+
active.each { |id| @call.call('POST', '/user_management/sessions/revoke', body: { 'session_id' => id }, allow_404: true) }
|
|
271
277
|
nil
|
|
272
278
|
end
|
|
273
279
|
|
|
@@ -287,13 +293,13 @@ module NoResponse
|
|
|
287
293
|
|
|
288
294
|
def revoke_sessions(user_id)
|
|
289
295
|
user = Segment.encode(user_id)
|
|
290
|
-
@call.call('DELETE', "/users/#{user}/sessions")
|
|
291
|
-
@call.call('DELETE', "/users/#{user}/refresh-tokens")
|
|
296
|
+
@call.call('DELETE', "/users/#{user}/sessions", allow_404: true)
|
|
297
|
+
@call.call('DELETE', "/users/#{user}/refresh-tokens", allow_404: true)
|
|
292
298
|
nil
|
|
293
299
|
end
|
|
294
300
|
|
|
295
301
|
def ban(user_id)
|
|
296
|
-
@call.call('PATCH', "/users/#{Segment.encode(user_id)}", body: { 'blocked' => true })
|
|
302
|
+
@call.call('PATCH', "/users/#{Segment.encode(user_id)}", body: { 'blocked' => true }, allow_404: true)
|
|
297
303
|
revoke_sessions(user_id)
|
|
298
304
|
end
|
|
299
305
|
end
|
|
@@ -134,6 +134,12 @@ module NoResponse
|
|
|
134
134
|
Crystalline::Nilable.new(::String),
|
|
135
135
|
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("assessment_url")}}
|
|
136
136
|
)
|
|
137
|
+
# The identity fields of the auth context the assessment was made with, echoed for the tenant's own correlation: the request's auth_context, or the one a hosted provider hook (POST /hooks/{integration_id}) built, with transport provider_hook and its hook_point. Present exactly when the request carried an auth_context, and the same on every revision of the assessment. Values are as the request or the hook sent them; tokens, timestamps, roles and scopes are not echoed, and the echo does not change the score.
|
|
138
|
+
field(
|
|
139
|
+
:auth_context,
|
|
140
|
+
Crystalline::Nilable.new(Models::Shared::AssessmentAuthContext),
|
|
141
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("auth_context")}}
|
|
142
|
+
)
|
|
137
143
|
|
|
138
144
|
sig {
|
|
139
145
|
params(
|
|
@@ -154,7 +160,8 @@ module NoResponse
|
|
|
154
160
|
risk: T.nilable(Models::Shared::Risk),
|
|
155
161
|
signals: T.nilable(T::Array[Models::Shared::Signal]),
|
|
156
162
|
policy_basis: ::String,
|
|
157
|
-
assessment_url: T.nilable(::String)
|
|
163
|
+
assessment_url: T.nilable(::String),
|
|
164
|
+
auth_context: T.nilable(Models::Shared::AssessmentAuthContext)
|
|
158
165
|
)
|
|
159
166
|
.void
|
|
160
167
|
}
|
|
@@ -176,7 +183,8 @@ module NoResponse
|
|
|
176
183
|
risk: nil,
|
|
177
184
|
signals: nil,
|
|
178
185
|
policy_basis: "heuristic_unvalidated",
|
|
179
|
-
assessment_url: nil
|
|
186
|
+
assessment_url: nil,
|
|
187
|
+
auth_context: nil
|
|
180
188
|
)
|
|
181
189
|
@assessment_id = assessment_id
|
|
182
190
|
@account_id = account_id
|
|
@@ -204,6 +212,7 @@ module NoResponse
|
|
|
204
212
|
|
|
205
213
|
@policy_basis = "heuristic_unvalidated"
|
|
206
214
|
@assessment_url = assessment_url
|
|
215
|
+
@auth_context = auth_context
|
|
207
216
|
end
|
|
208
217
|
|
|
209
218
|
sig { params(other: T.untyped).returns(T::Boolean) }
|
|
@@ -227,6 +236,7 @@ module NoResponse
|
|
|
227
236
|
return false unless @signals == other.signals
|
|
228
237
|
return false unless @policy_basis == other.policy_basis
|
|
229
238
|
return false unless @assessment_url == other.assessment_url
|
|
239
|
+
return false unless @auth_context == other.auth_context
|
|
230
240
|
true
|
|
231
241
|
end
|
|
232
242
|
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module NoResponse
|
|
5
|
+
module Models
|
|
6
|
+
module Shared
|
|
7
|
+
# The identity fields of the auth context the assessment was made with, echoed for the tenant's own correlation: the request's auth_context, or the one a hosted provider hook (POST /hooks/{integration_id}) built, with transport provider_hook and its hook_point. Present exactly when the request carried an auth_context, and the same on every revision of the assessment. Values are as the request or the hook sent them; tokens, timestamps, roles and scopes are not echoed, and the echo does not change the score.
|
|
8
|
+
class AssessmentAuthContext
|
|
9
|
+
extend T::Sig
|
|
10
|
+
include Crystalline::MetadataFields
|
|
11
|
+
|
|
12
|
+
# The provider slug the context named.
|
|
13
|
+
field(
|
|
14
|
+
:provider,
|
|
15
|
+
::String,
|
|
16
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("provider"), required: true}}
|
|
17
|
+
)
|
|
18
|
+
# The issuer the context named.
|
|
19
|
+
field(
|
|
20
|
+
:issuer,
|
|
21
|
+
::String,
|
|
22
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("issuer"), required: true}}
|
|
23
|
+
)
|
|
24
|
+
# The verified flag the context carried. A provider_hook context is always false.
|
|
25
|
+
field(
|
|
26
|
+
:verified,
|
|
27
|
+
Crystalline::Boolean.new,
|
|
28
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("verified"), required: true}}
|
|
29
|
+
)
|
|
30
|
+
# Where the context was derived: backend (also when the request named no transport), browser, or provider_hook for a hosted provider hook.
|
|
31
|
+
field(
|
|
32
|
+
:transport,
|
|
33
|
+
Models::Shared::Transport,
|
|
34
|
+
{
|
|
35
|
+
'format_json': {
|
|
36
|
+
'letter_case': ::NoResponse::Utils.field_name("transport"),
|
|
37
|
+
required: true,
|
|
38
|
+
'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::Transport, false)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
# The subject the context named; absent when it named none (a pre_registration hook).
|
|
43
|
+
field(
|
|
44
|
+
:subject,
|
|
45
|
+
Crystalline::Nilable.new(::String),
|
|
46
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("subject")}}
|
|
47
|
+
)
|
|
48
|
+
# The session identifier the context named, when it named one.
|
|
49
|
+
field(
|
|
50
|
+
:session_id,
|
|
51
|
+
Crystalline::Nilable.new(::String),
|
|
52
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("session_id")}}
|
|
53
|
+
)
|
|
54
|
+
# The organization identifier the context named, when it named one.
|
|
55
|
+
field(
|
|
56
|
+
:organization_id,
|
|
57
|
+
Crystalline::Nilable.new(::String),
|
|
58
|
+
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("organization_id")}}
|
|
59
|
+
)
|
|
60
|
+
# The provider event a provider_hook context was sent for; absent for any other transport.
|
|
61
|
+
field(
|
|
62
|
+
:hook_point,
|
|
63
|
+
Crystalline::Nilable.new(Models::Shared::HookPoint),
|
|
64
|
+
{
|
|
65
|
+
'format_json': {
|
|
66
|
+
'letter_case': ::NoResponse::Utils.field_name("hook_point"),
|
|
67
|
+
'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::HookPoint, true)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
sig {
|
|
73
|
+
params(
|
|
74
|
+
provider: ::String,
|
|
75
|
+
issuer: ::String,
|
|
76
|
+
verified: T::Boolean,
|
|
77
|
+
transport: Models::Shared::Transport,
|
|
78
|
+
subject: T.nilable(::String),
|
|
79
|
+
session_id: T.nilable(::String),
|
|
80
|
+
organization_id: T.nilable(::String),
|
|
81
|
+
hook_point: T.nilable(Models::Shared::HookPoint)
|
|
82
|
+
)
|
|
83
|
+
.void
|
|
84
|
+
}
|
|
85
|
+
def initialize(
|
|
86
|
+
provider:,
|
|
87
|
+
issuer:,
|
|
88
|
+
verified:,
|
|
89
|
+
transport:,
|
|
90
|
+
subject: nil,
|
|
91
|
+
session_id: nil,
|
|
92
|
+
organization_id: nil,
|
|
93
|
+
hook_point: nil
|
|
94
|
+
)
|
|
95
|
+
@provider = provider
|
|
96
|
+
@issuer = issuer
|
|
97
|
+
@verified = verified
|
|
98
|
+
@transport = transport
|
|
99
|
+
@subject = subject
|
|
100
|
+
@session_id = session_id
|
|
101
|
+
@organization_id = organization_id
|
|
102
|
+
@hook_point = hook_point
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
sig { params(other: T.untyped).returns(T::Boolean) }
|
|
106
|
+
def ==(other)
|
|
107
|
+
return false unless other.is_a?(self.class)
|
|
108
|
+
return false unless @provider == other.provider
|
|
109
|
+
return false unless @issuer == other.issuer
|
|
110
|
+
return false unless @verified == other.verified
|
|
111
|
+
return false unless @transport == other.transport
|
|
112
|
+
return false unless @subject == other.subject
|
|
113
|
+
return false unless @session_id == other.session_id
|
|
114
|
+
return false unless @organization_id == other.organization_id
|
|
115
|
+
return false unless @hook_point == other.hook_point
|
|
116
|
+
true
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
class NoResponse::Models::Shared::AssessmentAuthContext
|
|
5
|
+
extend ::Crystalline::MetadataFields::ClassMethods
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class NoResponse::Models::Shared::AssessmentAuthContext
|
|
9
|
+
def provider
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def provider=(str_)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def issuer
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def issuer=(str_)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def verified
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def verified=(str_)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def transport
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def transport=(str_)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def subject
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def subject=(str_)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def session_id
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def session_id=(str_)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def organization_id
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def organization_id=(str_)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def hook_point
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def hook_point=(str_)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -33,7 +33,7 @@ module NoResponse
|
|
|
33
33
|
Crystalline::Nilable.new(::String),
|
|
34
34
|
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("request_id")}}
|
|
35
35
|
)
|
|
36
|
-
# Optional tighter budget, 50 to
|
|
36
|
+
# Optional tighter budget, 50 to 3000 ms, measured from the moment the request reaches NoResponse. Absent means the 3000 ms ceiling; a value above it is refused with 400 rather than clamped.
|
|
37
37
|
field(
|
|
38
38
|
:deadline_ms,
|
|
39
39
|
Crystalline::Nilable.new(::Integer),
|
|
@@ -128,25 +128,25 @@ module NoResponse
|
|
|
128
128
|
Crystalline::Nilable.new(Crystalline::Boolean.new),
|
|
129
129
|
{'format_json': {'letter_case': ::NoResponse::Utils.field_name("impersonated")}}
|
|
130
130
|
)
|
|
131
|
-
# Where
|
|
131
|
+
# Where the context was derived: backend (also when the request named no transport), browser, or provider_hook for a hosted provider hook.
|
|
132
132
|
field(
|
|
133
133
|
:transport,
|
|
134
134
|
Crystalline::Nilable.new(Models::Shared::Transport),
|
|
135
135
|
{
|
|
136
136
|
'format_json': {
|
|
137
137
|
'letter_case': ::NoResponse::Utils.field_name("transport"),
|
|
138
|
-
'decoder': ::NoResponse::Utils.
|
|
138
|
+
'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::Transport, true)
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
)
|
|
142
|
-
# The provider event a provider_hook context was sent for
|
|
142
|
+
# The provider event a provider_hook context was sent for; absent for any other transport.
|
|
143
143
|
field(
|
|
144
144
|
:hook_point,
|
|
145
145
|
Crystalline::Nilable.new(Models::Shared::HookPoint),
|
|
146
146
|
{
|
|
147
147
|
'format_json': {
|
|
148
148
|
'letter_case': ::NoResponse::Utils.field_name("hook_point"),
|
|
149
|
-
'decoder': ::NoResponse::Utils.
|
|
149
|
+
'decoder': ::NoResponse::Utils.open_enum_from_string(Models::Shared::HookPoint, true)
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
)
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
module NoResponse
|
|
5
5
|
module Models
|
|
6
6
|
module Shared
|
|
7
|
-
# HookPoint - The provider event a provider_hook context was sent for
|
|
8
|
-
class HookPoint
|
|
7
|
+
# HookPoint - The provider event a provider_hook context was sent for; absent for any other transport.
|
|
8
|
+
class HookPoint
|
|
9
|
+
include ::Crystalline::Enum
|
|
9
10
|
enums do
|
|
10
11
|
PRE_REGISTRATION = new("pre_registration")
|
|
11
12
|
POST_REGISTRATION = new("post_registration")
|
|
@@ -13,6 +14,8 @@ module NoResponse
|
|
|
13
14
|
POST_LOGIN = new("post_login")
|
|
14
15
|
TOKEN_ISSUANCE = new("token_issuance")
|
|
15
16
|
end
|
|
17
|
+
|
|
18
|
+
open!
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
end
|
|
@@ -11,12 +11,12 @@ module NoResponse
|
|
|
11
11
|
|
|
12
12
|
field(
|
|
13
13
|
:api_key,
|
|
14
|
-
::String,
|
|
14
|
+
Crystalline::Nilable.new(::String),
|
|
15
15
|
{'security': {'scheme': true, 'type': "http", 'sub_type': "bearer", 'field_name': "Authorization"}}
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
sig { params(api_key: ::String).void }
|
|
19
|
-
def initialize(api_key:)
|
|
18
|
+
sig { params(api_key: T.nilable(::String)).void }
|
|
19
|
+
def initialize(api_key: nil)
|
|
20
20
|
@api_key = api_key
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
module NoResponse
|
|
5
5
|
module Models
|
|
6
6
|
module Shared
|
|
7
|
-
# Transport - Where
|
|
8
|
-
class Transport
|
|
7
|
+
# Transport - Where the context was derived: backend (also when the request named no transport), browser, or provider_hook for a hosted provider hook.
|
|
8
|
+
class Transport
|
|
9
|
+
include ::Crystalline::Enum
|
|
9
10
|
enums do
|
|
10
11
|
BACKEND = new("backend")
|
|
11
12
|
BROWSER = new("browser")
|
|
12
13
|
PROVIDER_HOOK = new("provider_hook")
|
|
13
14
|
end
|
|
15
|
+
|
|
16
|
+
open!
|
|
14
17
|
end
|
|
15
18
|
end
|
|
16
19
|
end
|
|
@@ -5,6 +5,7 @@ module NoResponse
|
|
|
5
5
|
module Models
|
|
6
6
|
module Shared
|
|
7
7
|
autoload :Assessment, "no_response/models/shared/assessment.rb"
|
|
8
|
+
autoload :AssessmentAuthContext, "no_response/models/shared/assessmentauthcontext.rb"
|
|
8
9
|
autoload :AssessmentList, "no_response/models/shared/assessmentlist.rb"
|
|
9
10
|
autoload :AssessmentOutcome, "no_response/models/shared/assessmentoutcome.rb"
|
|
10
11
|
autoload :AssessmentOutcomeRequest, "no_response/models/shared/assessmentoutcomerequest.rb"
|
|
@@ -88,13 +88,16 @@ module NoResponse
|
|
|
88
88
|
@security_source = security_source
|
|
89
89
|
elsif !api_key.nil?
|
|
90
90
|
@security_source = -> { Models::Shared::Security.new(api_key: api_key) }
|
|
91
|
+
elsif !ENV.fetch("NORESPONSE_API_KEY", "").empty?
|
|
92
|
+
env_security = Models::Shared::Security.new(api_key: ENV.fetch("NORESPONSE_API_KEY"))
|
|
93
|
+
@security_source = -> { env_security }
|
|
91
94
|
end
|
|
92
95
|
|
|
93
96
|
@language = "ruby"
|
|
94
97
|
@openapi_doc_version = "1"
|
|
95
|
-
@sdk_version = "2.
|
|
98
|
+
@sdk_version = "2.1.1"
|
|
96
99
|
@gen_version = "internal"
|
|
97
|
-
@user_agent = "noresponse-sdk/ruby 2.
|
|
100
|
+
@user_agent = "noresponse-sdk/ruby 2.1.1 internal 1 noresponse"
|
|
98
101
|
end
|
|
99
102
|
|
|
100
103
|
sig { returns([String, T::Hash[Symbol, String]]) }
|
|
@@ -706,7 +706,7 @@ module NoResponse
|
|
|
706
706
|
response: http_response
|
|
707
707
|
)
|
|
708
708
|
return Models::Operations::DeleteWebhookEndpointResponse.new(
|
|
709
|
-
headers:
|
|
709
|
+
headers: http_response.headers
|
|
710
710
|
)
|
|
711
711
|
elsif Utils.match_status_code(http_response.status, ["400"])
|
|
712
712
|
if Utils.match_content_type(content_type, "application/problem+json")
|
data/lib/no_response/webhooks.rb
CHANGED
|
@@ -50,9 +50,13 @@ module NoResponse
|
|
|
50
50
|
# "assessment.updated", and an EndpointVerification for
|
|
51
51
|
# "endpoint.verification". Deliveries are at least once and unordered:
|
|
52
52
|
# deduplicate on id and keep the highest assessment_version.
|
|
53
|
-
Event = Struct.new(:id, :type, :created_at, :data, keyword_init: true) do
|
|
53
|
+
Event = Struct.new(:id, :type, :created_at, :data, :test, keyword_init: true) do
|
|
54
54
|
# True for the terminal expiry event: delete what you hold and fetch nothing.
|
|
55
55
|
def expired? = data.is_a?(AssessmentExpired)
|
|
56
|
+
|
|
57
|
+
# True on an event sent by the send-test-event call: data is a fixed
|
|
58
|
+
# example assessment, not one of yours. Acknowledge it and apply nothing.
|
|
59
|
+
def test? = test == true
|
|
56
60
|
end
|
|
57
61
|
|
|
58
62
|
class << self
|
|
@@ -132,7 +136,8 @@ module NoResponse
|
|
|
132
136
|
raise VerificationError.new(:invalid_payload, 'Webhook event envelope is malformed')
|
|
133
137
|
end
|
|
134
138
|
|
|
135
|
-
Event.new(id: body['id'], type: body['type'], created_at: body['created_at'], data: event_data(body['type'], data)
|
|
139
|
+
Event.new(id: body['id'], type: body['type'], created_at: body['created_at'], data: event_data(body['type'], data),
|
|
140
|
+
test: body['test'] == true && body['type'] == 'assessment.updated')
|
|
136
141
|
end
|
|
137
142
|
|
|
138
143
|
def event_data(type, data)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: noresponse
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- NoResponse
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -326,6 +326,8 @@ files:
|
|
|
326
326
|
- lib/no_response/models/shared/alternate_name_union.rbi
|
|
327
327
|
- lib/no_response/models/shared/assessment.rb
|
|
328
328
|
- lib/no_response/models/shared/assessment.rbi
|
|
329
|
+
- lib/no_response/models/shared/assessmentauthcontext.rb
|
|
330
|
+
- lib/no_response/models/shared/assessmentauthcontext.rbi
|
|
329
331
|
- lib/no_response/models/shared/assessmentlist.rb
|
|
330
332
|
- lib/no_response/models/shared/assessmentlist.rbi
|
|
331
333
|
- lib/no_response/models/shared/assessmentoutcome.rb
|