onc_certification_g10_test_kit 2.3.0 → 3.0.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/terminology/expected_manifest.yml +242 -29
  3. data/lib/inferno/terminology/fhir_package_manager.rb +27 -0
  4. data/lib/inferno/terminology/loader.rb +22 -1
  5. data/lib/inferno/terminology/tasks/create_value_set_validators.rb +1 -1
  6. data/lib/inferno/terminology/tasks/download_fhir_terminology.rb +5 -0
  7. data/lib/inferno/terminology/value_set.rb +51 -5
  8. data/lib/onc_certification_g10_test_kit/base_token_refresh_group.rb +5 -4
  9. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu1.rb +5 -0
  10. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_stu2.rb +2 -0
  11. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +206 -28
  12. data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +25 -40
  13. data/lib/onc_certification_g10_test_kit/encounter_context_test.rb +30 -0
  14. data/lib/onc_certification_g10_test_kit/feature.rb +5 -8
  15. data/lib/onc_certification_g10_test_kit/limited_scope_grant_test.rb +18 -5
  16. data/lib/onc_certification_g10_test_kit/profile_selector.rb +175 -0
  17. data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +54 -4
  18. data/lib/onc_certification_g10_test_kit/single_patient_us_core_5_api_group.rb +93 -0
  19. data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +50 -5
  20. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group.rb +94 -0
  21. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2.rb +94 -0
  22. data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +197 -13
  23. data/lib/onc_certification_g10_test_kit/smart_invalid_pkce_group.rb +310 -0
  24. data/lib/onc_certification_g10_test_kit/smart_invalid_token_group_stu2.rb +211 -0
  25. data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +135 -9
  26. data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group.rb +16 -4
  27. data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group_stu2.rb +130 -0
  28. data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +134 -67
  29. data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +166 -11
  30. data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +119 -135
  31. data/lib/onc_certification_g10_test_kit/version.rb +1 -1
  32. data/lib/onc_certification_g10_test_kit/visual_inspection_and_attestations_group.rb +19 -0
  33. data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +7 -1
  34. data/lib/onc_certification_g10_test_kit.rb +115 -74
  35. metadata +19 -11
  36. data/lib/onc_certification_g10_test_kit/profile_guesser.rb +0 -72
@@ -0,0 +1,211 @@
1
+ module ONCCertificationG10TestKit
2
+ class SMARTInvalidTokenGroupSTU2 < Inferno::TestGroup
3
+ title 'SMART App Launch Error: Invalid Access Token Request'
4
+ short_title 'SMART Invalid Token Request'
5
+ input_instructions %(
6
+ Register Inferno as a standalone application using the following information:
7
+
8
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
9
+ )
10
+ description %(
11
+ # Background
12
+
13
+ The Invalid Access Token Request Sequence verifies that a SMART Launch
14
+ Sequence, specifically the [Standalone
15
+ Launch](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
16
+ Sequence, does not work in the case where the client sends an invalid
17
+ Authorization code or client ID during the code exchange step. This must
18
+ not result in a successful launch.
19
+
20
+ This test is not included as part of a regular SMART Launch Sequence
21
+ because some servers may not accept an authorization code after it has
22
+ been used unsuccessfully in this manner.
23
+ )
24
+ id :g10_smart_invalid_token_request_stu2
25
+ run_as_group
26
+
27
+ input :use_pkce,
28
+ title: 'Proof Key for Code Exchange (PKCE)',
29
+ type: 'radio',
30
+ default: 'true',
31
+ locked: true,
32
+ options: {
33
+ list_options: [
34
+ {
35
+ label: 'Enabled',
36
+ value: 'true'
37
+ },
38
+ {
39
+ label: 'Disabled',
40
+ value: 'false'
41
+ }
42
+ ]
43
+ }
44
+ input :pkce_code_challenge_method,
45
+ optional: true,
46
+ title: 'PKCE Code Challenge Method',
47
+ type: 'radio',
48
+ default: 'S256',
49
+ locked: true,
50
+ options: {
51
+ list_options: [
52
+ {
53
+ label: 'S256',
54
+ value: 'S256'
55
+ },
56
+ {
57
+ label: 'Plain',
58
+ value: 'plain'
59
+ }
60
+ ]
61
+ }
62
+
63
+ input_order :url,
64
+ :standalone_client_id,
65
+ :standalone_client_secret,
66
+ :standalone_requested_scopes,
67
+ :use_pkce,
68
+ :pkce_code_challenge_method,
69
+ :smart_authorization_url,
70
+ :smart_token_url
71
+
72
+ config(
73
+ inputs: {
74
+ client_id: {
75
+ name: :standalone_client_id,
76
+ title: 'Standalone Client ID',
77
+ description: 'Client ID provided during registration of Inferno as a standalone application'
78
+ },
79
+ client_secret: {
80
+ name: :standalone_client_secret,
81
+ title: 'Standalone Client Secret',
82
+ description: 'Client Secret provided during registration of Inferno as a standalone application'
83
+ },
84
+ requested_scopes: {
85
+ name: :standalone_requested_scopes,
86
+ title: 'Standalone Scope',
87
+ description: 'OAuth 2.0 scope provided by system to enable all required functionality',
88
+ type: 'textarea',
89
+ default: %(
90
+ launch/patient openid fhirUser offline_access
91
+ patient/Medication.read patient/AllergyIntolerance.read
92
+ patient/CarePlan.read patient/CareTeam.read patient/Condition.read
93
+ patient/Device.read patient/DiagnosticReport.read
94
+ patient/DocumentReference.read patient/Encounter.read
95
+ patient/Goal.read patient/Immunization.read patient/Location.read
96
+ patient/MedicationRequest.read patient/Observation.read
97
+ patient/Organization.read patient/Patient.read
98
+ patient/Practitioner.read patient/Procedure.read
99
+ patient/Provenance.read patient/PractitionerRole.read
100
+ ).gsub(/\s{2,}/, ' ').strip
101
+ },
102
+ url: {
103
+ title: 'Standalone FHIR Endpoint',
104
+ description: 'URL of the FHIR endpoint used by standalone applications'
105
+ },
106
+ code: {
107
+ name: :invalid_token_code
108
+ },
109
+ state: {
110
+ name: :invalid_token_state
111
+ },
112
+ smart_authorization_url: {
113
+ title: 'OAuth 2.0 Authorize Endpoint',
114
+ description: 'OAuth 2.0 Authorize Endpoint provided during the patient standalone launch'
115
+ },
116
+ smart_token_url: {
117
+ title: 'OAuth 2.0 Token Endpoint',
118
+ description: 'OAuth 2.0 Token Endpoint provided during the patient standalone launch'
119
+ },
120
+ pkce_code_verifier: {
121
+ name: :invalid_token_pkce_code_verifier
122
+ }
123
+ },
124
+ outputs: {
125
+ code: { name: :invalid_token_code },
126
+ state: { name: :invalid_token_state },
127
+ expires_in: { name: :invalid_token_expires_in },
128
+ pkce_code_verifier: { name: :invalid_token_pkce_code_verifier }
129
+ },
130
+ requests: {
131
+ redirect: { name: :invalid_token_redirect },
132
+ token: { name: :invalid_token_token }
133
+ }
134
+ )
135
+
136
+ test from: :smart_app_redirect_stu2
137
+ test from: :smart_code_received
138
+
139
+ test do
140
+ title ' OAuth token exchange fails when supplied invalid code'
141
+ description %(
142
+ If the request failed verification or is invalid, the authorization
143
+ server returns an error response.
144
+ )
145
+ uses_request :redirect
146
+
147
+ input :use_pkce, :pkce_code_verifier, :client_id, :client_secret, :smart_token_url
148
+
149
+ run do
150
+ skip_if request.query_parameters['error'].present?, 'Error during authorization request'
151
+
152
+ oauth2_params = {
153
+ grant_type: 'authorization_code',
154
+ code: 'BAD_CODE',
155
+ redirect_uri: config.options[:redirect_uri]
156
+ }
157
+ oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
158
+
159
+ if client_secret.present?
160
+ client_credentials = "#{client_id}:#{client_secret}"
161
+ oauth2_headers['Authorization'] = "Basic #{Base64.strict_encode64(client_credentials)}"
162
+ else
163
+ oauth2_params[:client_id] = client_id
164
+ end
165
+
166
+ oauth2_params[:code_verifier] = pkce_code_verifier if use_pkce == 'true'
167
+
168
+ post(smart_token_url, body: oauth2_params, name: :token, headers: oauth2_headers)
169
+
170
+ assert_response_status(400)
171
+ end
172
+ end
173
+
174
+ test do
175
+ title 'OAuth token exchange fails when supplied invalid client ID'
176
+ description %(
177
+ If the request failed verification or is invalid, the authorization
178
+ server returns an error response.
179
+ )
180
+ uses_request :redirect
181
+
182
+ input :use_pkce, :pkce_code_verifier, :code, :smart_token_url, :client_secret
183
+
184
+ run do
185
+ skip_if request.query_parameters['error'].present?, 'Error during authorization request'
186
+
187
+ client_id = 'BAD_CLIENT_ID'
188
+
189
+ oauth2_params = {
190
+ grant_type: 'authorization_code',
191
+ code: code,
192
+ redirect_uri: config.options[:redirect_uri]
193
+ }
194
+ oauth2_headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
195
+
196
+ if client_secret.present?
197
+ client_credentials = "#{client_id}:#{client_secret}"
198
+ oauth2_headers['Authorization'] = "Basic #{Base64.strict_encode64(client_credentials)}"
199
+ else
200
+ oauth2_params[:client_id] = client_id
201
+ end
202
+
203
+ oauth2_params[:code_verifier] = pkce_code_verifier if use_pkce == 'true'
204
+
205
+ post(smart_token_url, body: oauth2_params, name: :token, headers: oauth2_headers)
206
+
207
+ assert_response_status([400, 401])
208
+ end
209
+ end
210
+ end
211
+ end
@@ -20,13 +20,17 @@ module ONCCertificationG10TestKit
20
20
 
21
21
  description %(
22
22
  This scenario demonstrates the ability to perform a Patient Standalone
23
- Launch to a [SMART on FHIR](http://hl7.org/fhir/smart-app-launch/1.0.0/)
24
- confidential client with limited access granted to the app based on user
25
- input. The tester is expected to grant the application access to a subset
26
- of desired resource types. The launch is performed using the same app
27
- configuration as in the Standalone Patient App test, demonstrating that
28
- the user is control over what scopes are granted to the app as required in
29
- the (g)(10) Standardized API criterion.
23
+ Launch to a SMART on FHIR confidential client with limited access granted
24
+ to the app based on user input. The tester is expected to grant the
25
+ application access to a subset of desired resource types. The launch is
26
+ performed using the same app configuration as in the Standalone Patient
27
+ App test, demonstrating that the user is control over what scopes are
28
+ granted to the app as required in the (g)(10) Standardized API criterion.
29
+
30
+ * [SMART on FHIR
31
+ (STU1)](http://www.hl7.org/fhir/smart-app-launch/1.0.0/)
32
+ * [SMART on FHIR
33
+ (STU2)](http://hl7.org/fhir/smart-app-launch/STU2)
30
34
  )
31
35
  id :g10_smart_limited_app
32
36
  run_as_group
@@ -76,14 +80,14 @@ module ONCCertificationG10TestKit
76
80
  Sequence](http://hl7.org/fhir/smart-app-launch/1.0.0/index.html#standalone-launch-sequence)
77
81
  )
78
82
 
83
+ required_suite_options smart_app_launch_version: 'smart_app_launch_1'
84
+
79
85
  config(
80
86
  inputs: {
81
87
  client_id: { locked: true },
82
88
  client_secret: { locked: true, optional: false },
83
89
  url: { locked: true },
84
90
  requested_scopes: { locked: true },
85
- use_pkce: { locked: true },
86
- pkce_code_challenge_method: { locked: true },
87
91
  code: { name: :limited_code },
88
92
  state: { name: :limited_state },
89
93
  patient_id: { name: :limited_patient_id },
@@ -161,6 +165,128 @@ module ONCCertificationG10TestKit
161
165
  end
162
166
  end
163
167
 
168
+ group from: :smart_standalone_launch_stu2,
169
+ config: {
170
+ inputs: {
171
+ use_pkce: {
172
+ default: 'true',
173
+ locked: true
174
+ },
175
+ pkce_code_challenge_method: {
176
+ locked: true
177
+ }
178
+ }
179
+ } do
180
+ title 'Standalone Launch With Limited Scope'
181
+ description %(
182
+ # Background
183
+
184
+ The [Standalone
185
+ Launch Sequence](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
186
+ allows an app, like Inferno, to be launched independent of an
187
+ existing EHR session. It is one of the two launch methods described in
188
+ the SMART App Launch Framework alongside EHR Launch. The app will
189
+ request authorization for the provided scope from the authorization
190
+ endpoint, ultimately receiving an authorization token which can be used
191
+ to gain access to resources on the FHIR server.
192
+
193
+ # Test Methodology
194
+
195
+ Inferno will redirect the user to the the authorization endpoint so that
196
+ they may provide any required credentials and authorize the application.
197
+ Upon successful authorization, Inferno will exchange the authorization
198
+ code provided for an access token.
199
+
200
+ For more information on the #{title}:
201
+
202
+ * [Standalone Launch
203
+ Sequence](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
204
+ )
205
+
206
+ required_suite_options smart_app_launch_version: 'smart_app_launch_2'
207
+
208
+ config(
209
+ inputs: {
210
+ client_id: { locked: true },
211
+ client_secret: { locked: true },
212
+ url: { locked: true },
213
+ requested_scopes: { locked: true },
214
+ code: { name: :limited_code },
215
+ state: { name: :limited_state },
216
+ patient_id: { name: :limited_patient_id },
217
+ access_token: { name: :limited_access_token },
218
+ # TODO: separate standalone/ehr discovery outputs
219
+ smart_authorization_url: { locked: true, title: 'SMART Authorization Url' },
220
+ smart_token_url: { locked: true, title: 'SMART Token Url' },
221
+ received_scopes: { name: :limited_received_scopes },
222
+ smart_credentials: { name: :limited_smart_credentials }
223
+ },
224
+ outputs: {
225
+ code: { name: :limited_code },
226
+ token_retrieval_time: { name: :limited_token_retrieval_time },
227
+ state: { name: :limited_state },
228
+ id_token: { name: :limited_id_token },
229
+ refresh_token: { name: :limited_refresh_token },
230
+ access_token: { name: :limited_access_token },
231
+ expires_in: { name: :limited_expires_in },
232
+ patient_id: { name: :limited_patient_id },
233
+ encounter_id: { name: :limited_encounter_id },
234
+ received_scopes: { name: :limited_received_scopes },
235
+ intent: { name: :limited_intent },
236
+ smart_credentials: { name: :limited_smart_credentials }
237
+ },
238
+ requests: {
239
+ redirect: { name: :limited_redirect },
240
+ token: { name: :limited_token }
241
+ },
242
+ options: {
243
+ redirect_message_proc: lambda do |auth_url|
244
+ expected_resource_string =
245
+ expected_resources
246
+ .split(',')
247
+ .map(&:strip)
248
+ .map { |resource_type| "* #{resource_type}\n" }
249
+ .join
250
+
251
+ <<~MESSAGE
252
+ ### #{self.class.parent.parent.title}
253
+
254
+ [Follow this link to authorize with the SMART
255
+ server](#{auth_url}).
256
+
257
+ Tests will resume once Inferno receives a request at
258
+ `#{config.options[:redirect_uri]}` with a state of `#{state}`.
259
+
260
+ Access should only be granted to the following resources:
261
+
262
+ #{expected_resource_string}
263
+ MESSAGE
264
+ end
265
+ }
266
+ )
267
+
268
+ input :expected_resources,
269
+ title: 'Expected Resource Grant for Limited Access Launch',
270
+ description: 'The user will only grant access to the following resources during authorization.',
271
+ default: 'Patient, Condition, Observation'
272
+
273
+ test from: :g10_patient_context,
274
+ config: {
275
+ inputs: {
276
+ patient_id: { name: :limited_patient_id },
277
+ smart_credentials: { name: :limited_smart_credentials }
278
+ }
279
+ }
280
+
281
+ test from: :g10_limited_scope_grant do
282
+ config(
283
+ inputs: {
284
+ received_scopes: { name: :limited_received_scopes }
285
+ }
286
+ )
287
+ end
288
+ end
289
+
164
290
  group from: :g10_restricted_resource_type_access,
165
291
  config: {
166
292
  inputs: {
@@ -8,9 +8,9 @@ module ONCCertificationG10TestKit
8
8
  * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
9
9
 
10
10
  Enter in the appropriate scope to enable patient-level access to all
11
- relevant resources. In addition, support for the OpenID Connect (openid
12
- fhirUser), refresh tokens (offline_access), and patient context
13
- (launch/patient) are required.
11
+ relevant resources. If using SMART v2, v2-style scopes must be used. In
12
+ addition, support for the OpenID Connect (openid fhirUser), refresh tokens
13
+ (offline_access), and patient context (launch/patient) are required.
14
14
  )
15
15
  description %(
16
16
  # Background
@@ -53,7 +53,19 @@ module ONCCertificationG10TestKit
53
53
  },
54
54
  requested_scopes: {
55
55
  name: :public_requested_scopes,
56
- title: 'Public Launch Scope'
56
+ title: 'Public Launch Scope',
57
+ default: %(
58
+ launch/patient openid fhirUser offline_access
59
+ patient/Medication.read patient/AllergyIntolerance.read
60
+ patient/CarePlan.read patient/CareTeam.read patient/Condition.read
61
+ patient/Device.read patient/DiagnosticReport.read
62
+ patient/DocumentReference.read patient/Encounter.read
63
+ patient/Goal.read patient/Immunization.read patient/Location.read
64
+ patient/MedicationRequest.read patient/Observation.read
65
+ patient/Organization.read patient/Patient.read
66
+ patient/Practitioner.read patient/Procedure.read
67
+ patient/Provenance.read patient/PractitionerRole.read
68
+ ).gsub(/\s{2,}/, ' ').strip
57
69
  },
58
70
  url: {
59
71
  title: 'Public Launch FHIR Endpoint',
@@ -0,0 +1,130 @@
1
+ module ONCCertificationG10TestKit
2
+ class SMARTPublicStandaloneLaunchGroupSTU2 < SMARTAppLaunch::StandaloneLaunchGroupSTU2
3
+ title 'Public Client Standalone Launch with OpenID Connect'
4
+ short_title 'SMART Public Client Launch'
5
+ input_instructions %(
6
+ Register Inferno as a standalone application using the following information:
7
+
8
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
9
+
10
+ Enter in the appropriate scope to enable patient-level access to all
11
+ relevant resources. In addition, support for the OpenID Connect (openid
12
+ fhirUser), refresh tokens (offline_access), and patient context
13
+ (launch/patient) are required.
14
+ )
15
+ id :g10_public_standalone_launch_stu2
16
+ run_as_group
17
+
18
+ config(
19
+ inputs: {
20
+ client_id: {
21
+ name: :public_client_id,
22
+ title: 'Public Launch Client ID'
23
+ },
24
+ client_secret: {
25
+ name: :public_client_secret,
26
+ title: 'Public Launch Client Secret',
27
+ default: nil,
28
+ optional: true,
29
+ locked: true
30
+ },
31
+ requested_scopes: {
32
+ name: :public_requested_scopes,
33
+ title: 'Public Launch Scope',
34
+ default: %(
35
+ launch/patient openid fhirUser offline_access patient/Medication.rs
36
+ patient/AllergyIntolerance.rs patient/CarePlan.rs
37
+ patient/CareTeam.rs patient/Condition.rs patient/Device.rs
38
+ patient/DiagnosticReport.rs patient/DocumentReference.rs
39
+ patient/Encounter.rs patient/Goal.rs patient/Immunization.rs
40
+ patient/Location.rs patient/MedicationRequest.rs
41
+ patient/Observation.rs patient/Organization.rs patient/Patient.rs
42
+ patient/Practitioner.rs patient/Procedure.rs patient/Provenance.rs
43
+ patient/PractitionerRole.rs
44
+ ).gsub(/\s{2,}/, ' ').strip
45
+ },
46
+ url: {
47
+ title: 'Public Launch FHIR Endpoint',
48
+ description: 'URL of the FHIR endpoint used by standalone applications'
49
+ },
50
+ code: {
51
+ name: :public_code
52
+ },
53
+ state: {
54
+ name: :public_state
55
+ },
56
+ smart_authorization_url: {
57
+ title: 'OAuth 2.0 Authorize Endpoint',
58
+ description: 'OAuth 2.0 Authorize Endpoint provided during the patient standalone launch'
59
+ },
60
+ smart_token_url: {
61
+ title: 'OAuth 2.0 Token Endpoint',
62
+ description: 'OAuth 2.0 Token Endpoint provided during the patient standalone launch'
63
+ },
64
+ smart_credentials: {
65
+ name: :public_smart_credentials
66
+ },
67
+ use_pkce: {
68
+ default: 'true',
69
+ locked: true
70
+ },
71
+ pkce_code_challenge_method: {
72
+ locked: true
73
+ }
74
+ },
75
+ outputs: {
76
+ code: { name: :public_code },
77
+ token_retrieval_time: { name: :public_token_retrieval_time },
78
+ state: { name: :public_state },
79
+ id_token: { name: :public_id_token },
80
+ refresh_token: { name: :public_refresh_token },
81
+ access_token: { name: :public_access_token },
82
+ expires_in: { name: :public_expires_in },
83
+ patient_id: { name: :public_patient_id },
84
+ encounter_id: { name: :public_encounter_id },
85
+ received_scopes: { name: :public_received_scopes },
86
+ intent: { name: :public_intent },
87
+ smart_credentials: { name: :public_smart_credentials }
88
+ },
89
+ requests: {
90
+ redirect: { name: :public_redirect },
91
+ token: { name: :public_token }
92
+ }
93
+ )
94
+
95
+ input_order :url,
96
+ :public_client_id,
97
+ :public_client_secret,
98
+ :public_requested_scopes,
99
+ :use_pkce,
100
+ :pkce_code_challenge_method,
101
+ :smart_authorization_url,
102
+ :smart_token_url
103
+
104
+ test from: :g10_patient_context,
105
+ config: {
106
+ inputs: {
107
+ patient_id: { name: :public_patient_id },
108
+ smart_credentials: { name: :public_smart_credentials }
109
+ }
110
+ }
111
+
112
+ test do
113
+ title 'OAuth token exchange response contains OpenID Connect id_token'
114
+ description %(
115
+ This test requires that an OpenID Connect id_token is provided to
116
+ demonstrate authentication capabilies for public clients.
117
+ )
118
+ id :g10_public_launch_id_token
119
+
120
+ input :id_token,
121
+ name: :public_id_token,
122
+ locked: true,
123
+ optional: true
124
+
125
+ run do
126
+ assert id_token.present?, 'Token response did not provide an id_token as required.'
127
+ end
128
+ end
129
+ end
130
+ end