smart_app_launch_test_kit 0.5.1 → 0.6.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/inferno_reference_server_preset.json +15 -86
  3. data/config/presets/inferno_reference_server_stu2_2_preset.json +20 -69
  4. data/config/presets/inferno_reference_server_stu2_preset.json +20 -69
  5. data/lib/smart_app_launch/app_redirect_test.rb +12 -44
  6. data/lib/smart_app_launch/app_redirect_test_stu2.rb +2 -17
  7. data/lib/smart_app_launch/backend_services_authorization_group.rb +33 -57
  8. data/lib/smart_app_launch/backend_services_authorization_request_builder.rb +22 -9
  9. data/lib/smart_app_launch/backend_services_authorization_request_success_test.rb +26 -21
  10. data/lib/smart_app_launch/backend_services_authorization_response_body_test.rb +19 -5
  11. data/lib/smart_app_launch/backend_services_invalid_client_assertion_test.rb +30 -25
  12. data/lib/smart_app_launch/backend_services_invalid_grant_type_test.rb +30 -24
  13. data/lib/smart_app_launch/backend_services_invalid_jwt_test.rb +31 -26
  14. data/lib/smart_app_launch/client_assertion_builder.rb +27 -12
  15. data/lib/smart_app_launch/cors_openid_fhir_user_claim_test.rb +2 -2
  16. data/lib/smart_app_launch/cors_token_exchange_test.rb +2 -2
  17. data/lib/smart_app_launch/discovery_stu1_group.rb +6 -2
  18. data/lib/smart_app_launch/ehr_launch_group.rb +41 -24
  19. data/lib/smart_app_launch/ehr_launch_group_stu2.rb +26 -10
  20. data/lib/smart_app_launch/ehr_launch_group_stu2_2.rb +0 -16
  21. data/lib/smart_app_launch/openid_fhir_user_claim_test.rb +5 -4
  22. data/lib/smart_app_launch/openid_token_payload_test.rb +6 -8
  23. data/lib/smart_app_launch/smart_stu1_suite.rb +32 -24
  24. data/lib/smart_app_launch/smart_stu2_2_suite.rb +56 -30
  25. data/lib/smart_app_launch/smart_stu2_suite.rb +56 -31
  26. data/lib/smart_app_launch/smart_tls_test.rb +14 -0
  27. data/lib/smart_app_launch/standalone_launch_group.rb +42 -25
  28. data/lib/smart_app_launch/standalone_launch_group_stu2.rb +26 -10
  29. data/lib/smart_app_launch/standalone_launch_group_stu2_2.rb +0 -16
  30. data/lib/smart_app_launch/token_exchange_stu2_2_test.rb +5 -17
  31. data/lib/smart_app_launch/token_exchange_stu2_test.rb +8 -67
  32. data/lib/smart_app_launch/token_exchange_test.rb +18 -38
  33. data/lib/smart_app_launch/token_introspection_access_token_group.rb +12 -4
  34. data/lib/smart_app_launch/token_introspection_access_token_group_stu2_2.rb +9 -1
  35. data/lib/smart_app_launch/token_introspection_group.rb +2 -4
  36. data/lib/smart_app_launch/token_introspection_request_group.rb +2 -4
  37. data/lib/smart_app_launch/token_introspection_response_group.rb +64 -49
  38. data/lib/smart_app_launch/token_refresh_body_test.rb +9 -2
  39. data/lib/smart_app_launch/token_refresh_stu2_test.rb +10 -17
  40. data/lib/smart_app_launch/token_refresh_test.rb +19 -20
  41. data/lib/smart_app_launch/token_response_body_test.rb +14 -4
  42. data/lib/smart_app_launch/token_response_body_test_stu2_2.rb +3 -2
  43. data/lib/smart_app_launch/version.rb +2 -2
  44. data/lib/smart_app_launch/well_known_endpoint_test.rb +11 -1
  45. metadata +5 -4
@@ -1,8 +1,8 @@
1
1
  require_relative 'backend_services_authorization_request_builder'
2
2
  require_relative 'backend_services_authorization_group'
3
3
 
4
- module SMARTAppLaunch
5
- class BackendServicesAuthorizationRequestSuccessTest < Inferno::Test
4
+ module SMARTAppLaunch
5
+ class BackendServicesAuthorizationRequestSuccessTest < Inferno::Test
6
6
  id :smart_backend_services_auth_request_success
7
7
  title 'Authorization request succeeds when supplied correct information'
8
8
  description <<~DESCRIPTION
@@ -10,32 +10,37 @@ module SMARTAppLaunch
10
10
  states "If the access token request is valid and authorized, the authorization server SHALL issue an access token in response."
11
11
  DESCRIPTION
12
12
 
13
- input :client_auth_encryption_method,
14
- :backend_services_requested_scope,
15
- :backend_services_client_id,
16
- :smart_token_url
17
- input :backend_services_jwks_kid,
18
- optional: true
13
+ input :smart_auth_info,
14
+ type: :auth_info,
15
+ options: {
16
+ mode: 'auth',
17
+ components: [
18
+ {
19
+ name: :auth_type,
20
+ default: 'backend_services',
21
+ locked: 'true'
22
+ }
23
+ ]
24
+ }
19
25
 
20
26
  output :authentication_response
21
27
 
22
- http_client :token_endpoint do
23
- url :smart_token_url
24
- end
25
-
26
28
  run do
27
- post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
28
- scope: backend_services_requested_scope,
29
- iss: backend_services_client_id,
30
- sub: backend_services_client_id,
31
- aud: smart_token_url,
32
- kid: backend_services_jwks_kid)
33
-
34
- authentication_response = post(**{ client: :token_endpoint }.merge(post_request_content))
29
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(
30
+ encryption_method: smart_auth_info.encryption_algorithm,
31
+ scope: smart_auth_info.requested_scopes,
32
+ iss: smart_auth_info.client_id,
33
+ sub: smart_auth_info.client_id,
34
+ aud: smart_auth_info.token_url,
35
+ kid: smart_auth_info.kid,
36
+ custom_jwks: smart_auth_info.jwks
37
+ )
38
+
39
+ authentication_response = post(smart_auth_info.token_url, **post_request_content)
35
40
 
36
41
  assert_response_status([200, 201])
37
42
 
38
43
  output authentication_response: authentication_response.response_body
39
44
  end
40
45
  end
41
- end
46
+ end
@@ -1,7 +1,7 @@
1
1
  require_relative 'backend_services_authorization_request_builder'
2
2
 
3
- module SMARTAppLaunch
4
- class BackendServicesAuthorizationResponseBodyTest < Inferno::Test
3
+ module SMARTAppLaunch
4
+ class BackendServicesAuthorizationResponseBodyTest < Inferno::Test
5
5
  id :smart_backend_services_auth_response_body
6
6
  title 'Authorization request response body contains required information encoded in JSON'
7
7
  description <<~DESCRIPTION
@@ -17,7 +17,19 @@ module SMARTAppLaunch
17
17
  DESCRIPTION
18
18
 
19
19
  input :authentication_response
20
- output :bearer_token
20
+ input :smart_auth_info,
21
+ type: :auth_info,
22
+ options: {
23
+ mode: 'auth',
24
+ components: [
25
+ {
26
+ name: :auth_type,
27
+ default: 'backend_services',
28
+ locked: 'true'
29
+ }
30
+ ]
31
+ }
32
+ output :bearer_token, :smart_auth_info
21
33
 
22
34
  run do
23
35
  skip_if authentication_response.blank?, 'No authentication response received.'
@@ -28,7 +40,9 @@ module SMARTAppLaunch
28
40
  access_token = response_body['access_token']
29
41
  assert access_token.present?, 'Token response did not contain access_token as required'
30
42
 
31
- output bearer_token: access_token
43
+ smart_auth_info.access_token = access_token
44
+
45
+ output bearer_token: access_token, smart_auth_info: smart_auth_info
32
46
 
33
47
  required_keys = ['token_type', 'expires_in', 'scope']
34
48
 
@@ -37,4 +51,4 @@ module SMARTAppLaunch
37
51
  end
38
52
  end
39
53
  end
40
- end
54
+ end
@@ -1,45 +1,50 @@
1
1
  require_relative 'backend_services_authorization_request_builder'
2
2
 
3
- module SMARTAppLaunch
4
- class BackendServicesInvalidClientAssertionTest < Inferno::Test
3
+ module SMARTAppLaunch
4
+ class BackendServicesInvalidClientAssertionTest < Inferno::Test
5
5
  id :smart_backend_services_invalid_client_assertion
6
6
  title 'Authorization request fails when supplied invalid client_assertion_type'
7
7
  description <<~DESCRIPTION
8
8
  The [SMART App Launch 2.0.0 IG specification for Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
9
- defines the required fields for the authorization request, made via HTTP POST to authorization
9
+ defines the required fields for the authorization request, made via HTTP POST to authorization
10
10
  token endpoint.
11
11
  This includes the `client_assertion_type` parameter, where the value must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`.
12
12
 
13
- The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
13
+ The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
14
14
  describes the proper response for an invalid request in the client credentials grant flow:
15
15
 
16
16
  "If the request failed client authentication or is invalid, the authorization server returns an
17
17
  error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)."
18
18
  DESCRIPTION
19
19
 
20
- input :client_auth_encryption_method,
21
- :backend_services_requested_scope,
22
- :backend_services_client_id,
23
- :smart_token_url
24
- input :backend_services_jwks_kid,
25
- optional: true
26
-
27
- http_client :token_endpoint do
28
- url :smart_token_url
29
- end
20
+ input :smart_auth_info,
21
+ type: :auth_info,
22
+ options: {
23
+ mode: 'auth',
24
+ components: [
25
+ {
26
+ name: :auth_type,
27
+ default: 'backend_services',
28
+ locked: 'true'
29
+ }
30
+ ]
31
+ }
30
32
 
31
33
  run do
32
- post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
33
- scope: backend_services_requested_scope,
34
- iss: backend_services_client_id,
35
- sub: backend_services_client_id,
36
- aud: smart_token_url,
37
- client_assertion_type: 'not_an_assertion_type',
38
- kid: backend_services_jwks_kid)
39
-
40
- post(**{ client: :token_endpoint }.merge(post_request_content))
34
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(
35
+ encryption_method: smart_auth_info.encryption_algorithm,
36
+ scope: smart_auth_info.requested_scopes,
37
+ iss: smart_auth_info.client_id,
38
+ sub: smart_auth_info.client_id,
39
+ aud: smart_auth_info.token_url,
40
+ client_assertion_type: 'not_an_assertion_type',
41
+ kid: smart_auth_info.kid,
42
+ custom_jwks: smart_auth_info.jwks
43
+ )
44
+
45
+ post(smart_auth_info.token_url, **post_request_content)
41
46
 
42
47
  assert_response_status(400)
43
- end
48
+ end
44
49
  end
45
- end
50
+ end
@@ -1,45 +1,51 @@
1
1
  require_relative 'backend_services_authorization_request_builder'
2
2
 
3
- module SMARTAppLaunch
4
- class BackendServicesInvalidGrantTypeTest < Inferno::Test
3
+ module SMARTAppLaunch
4
+ class BackendServicesInvalidGrantTypeTest < Inferno::Test
5
5
  id :smart_backend_services_invalid_grant_type
6
6
  title 'Authorization request fails when client supplies invalid grant_type'
7
7
  description <<~DESCRIPTION
8
8
  The [SMART App Launch 2.0.0 IG section on Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
9
- defines the required fields for the authorization request, made via HTTP POST to authorization
9
+ defines the required fields for the authorization request, made via HTTP POST to authorization
10
10
  token endpoint.
11
11
  This includes the `grant_type` parameter, where the value must be `client_credentials`.
12
12
 
13
- The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
13
+ The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
14
14
  describes the proper response for an invalid request in the client credentials grant flow:
15
15
 
16
16
  "If the request failed client authentication or is invalid, the authorization server returns an
17
17
  error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)."
18
18
  DESCRIPTION
19
19
 
20
- input :client_auth_encryption_method,
21
- :backend_services_requested_scope,
22
- :backend_services_client_id,
23
- :smart_token_url
24
- input :backend_services_jwks_kid,
25
- optional: true
20
+ input :smart_auth_info,
21
+ type: :auth_info,
22
+ options: {
23
+ mode: 'auth',
24
+ components: [
25
+ {
26
+ name: :auth_type,
27
+ default: 'backend_services',
28
+ locked: 'true'
29
+ }
30
+ ]
31
+ }
26
32
 
27
- http_client :token_endpoint do
28
- url :smart_token_url
29
- end
30
33
 
31
34
  run do
32
- post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
33
- scope: backend_services_requested_scope,
34
- iss: backend_services_client_id,
35
- sub: backend_services_client_id,
36
- aud: smart_token_url,
37
- grant_type: 'not_a_grant_type',
38
- kid: backend_services_jwks_kid)
39
-
40
- post(**{ client: :token_endpoint }.merge(post_request_content))
35
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(
36
+ encryption_method: smart_auth_info.encryption_algorithm,
37
+ scope: smart_auth_info.requested_scopes,
38
+ iss: smart_auth_info.client_id,
39
+ sub: smart_auth_info.client_id,
40
+ aud: smart_auth_info.token_url,
41
+ grant_type: 'not_a_grant_type',
42
+ kid: smart_auth_info.kid,
43
+ custom_jwks: smart_auth_info.jwks
44
+ )
45
+
46
+ post(smart_auth_info.token_url, **post_request_content)
41
47
 
42
48
  assert_response_status(400)
43
- end
49
+ end
44
50
  end
45
- end
51
+ end
@@ -1,15 +1,15 @@
1
1
  require_relative 'backend_services_authorization_request_builder'
2
2
 
3
- module SMARTAppLaunch
4
- class BackendServicesInvalidJWTTest < Inferno::Test
3
+ module SMARTAppLaunch
4
+ class BackendServicesInvalidJWTTest < Inferno::Test
5
5
  id :smart_backend_services_invalid_jwt
6
6
  title 'Authorization request fails when client supplies invalid JWT token'
7
7
  description <<~DESCRIPTION
8
8
  The [SMART App Launch 2.0.0 IG section on Backend Services](https://hl7.org/fhir/smart-app-launch/STU2/backend-services.html#request-1)
9
- defines the required fields for the authorization request, made via HTTP POST to authorization
9
+ defines the required fields for the authorization request, made via HTTP POST to authorization
10
10
  token endpoint.
11
11
  This includes the `client_assertion` parameter, where the value must be
12
- a valid JWT as specified in
12
+ a valid JWT as specified in
13
13
  [Asymmetric (public key) Client Authentication](https://hl7.org/fhir/smart-app-launch/STU2/client-confidential-asymmetric.html#authenticating-to-the-token-endpoint)
14
14
  The JWT SHALL include the following claims, and SHALL be signed with the client’s private key.
15
15
 
@@ -21,36 +21,41 @@ module SMARTAppLaunch
21
21
  | `exp` | required | Expiration time integer for this authentication JWT, expressed in seconds since the "Epoch" (1970-01-01T00:00:00Z UTC). This time SHALL be no more than five minutes in the future. |
22
22
  | `jti` | required | A nonce string value that uniquely identifies this authentication JWT. |
23
23
 
24
- The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
24
+ The [OAuth 2.0 Authorization Framework Section 4.3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3.3)
25
25
  describes the proper response for an invalid request in the client credentials grant flow:
26
26
 
27
27
  "If the request failed client authentication or is invalid, the authorization server returns an
28
28
  error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)."
29
29
  DESCRIPTION
30
30
 
31
- input :client_auth_encryption_method,
32
- :backend_services_requested_scope,
33
- :backend_services_client_id,
34
- :smart_token_url
35
- input :backend_services_jwks_kid,
36
- optional: true
31
+ input :smart_auth_info,
32
+ type: :auth_info,
33
+ options: {
34
+ mode: 'auth',
35
+ components: [
36
+ {
37
+ name: :auth_type,
38
+ default: 'backend_services',
39
+ locked: 'true'
40
+ }
41
+ ]
42
+ }
37
43
 
38
- http_client :token_endpoint do
39
- url :smart_token_url
40
- end
41
-
42
44
  run do
43
- post_request_content = BackendServicesAuthorizationRequestBuilder.build(encryption_method: client_auth_encryption_method,
44
- scope: backend_services_requested_scope,
45
- iss: backend_services_client_id,
46
- sub: backend_services_client_id,
47
- aud: smart_token_url,
48
- client_assertion_type: 'not_an_assertion_type',
49
- kid: backend_services_jwks_kid)
50
-
51
- post(**{ client: :token_endpoint }.merge(post_request_content))
45
+ post_request_content = BackendServicesAuthorizationRequestBuilder.build(
46
+ encryption_method: smart_auth_info.encryption_algorithm,
47
+ scope: smart_auth_info.requested_scopes,
48
+ iss: smart_auth_info.client_id,
49
+ sub: smart_auth_info.client_id,
50
+ aud: smart_auth_info.token_url,
51
+ client_assertion_type: 'not_an_assertion_type',
52
+ kid: smart_auth_info.kid,
53
+ custom_jwks: smart_auth_info.jwks
54
+ )
55
+
56
+ post(smart_auth_info.token_url, **post_request_content)
52
57
 
53
58
  assert_response_status(400)
54
- end
59
+ end
55
60
  end
56
- end
61
+ end
@@ -17,7 +17,8 @@ module SMARTAppLaunch
17
17
  :iss,
18
18
  :jti,
19
19
  :sub,
20
- :kid
20
+ :kid,
21
+ :custom_jwks
21
22
 
22
23
  def initialize(
23
24
  client_auth_encryption_method:,
@@ -26,7 +27,8 @@ module SMARTAppLaunch
26
27
  aud:,
27
28
  exp: 5.minutes.from_now.to_i,
28
29
  jti: SecureRandom.hex(32),
29
- kid: nil
30
+ kid: nil,
31
+ custom_jwks: nil
30
32
  )
31
33
  @client_auth_encryption_method = client_auth_encryption_method
32
34
  @iss = iss
@@ -37,14 +39,25 @@ module SMARTAppLaunch
37
39
  @client_assertion_type = client_assertion_type
38
40
  @exp = exp
39
41
  @jti = jti
40
- @kid = kid
42
+ @kid = kid.presence
43
+ @custom_jwks = custom_jwks
44
+ end
45
+
46
+ def jwks
47
+ @jwks ||=
48
+ if custom_jwks.present?
49
+ JWT::JWK::Set.new(JSON.parse(custom_jwks))
50
+ else
51
+ JWKS.jwks
52
+ end
41
53
  end
42
54
 
43
55
  def private_key
44
- @private_key ||= JWKS.jwks
45
- .select { |key| key[:key_ops]&.include?('sign') }
46
- .select { |key| key[:alg] == client_auth_encryption_method }
47
- .find { |key| !kid || key[:kid] == kid }
56
+ @private_key ||=
57
+ jwks
58
+ .select { |key| key[:key_ops]&.include?('sign') }
59
+ .select { |key| key[:alg] == client_auth_encryption_method }
60
+ .find { |key| !kid || key[:kid] == kid }
48
61
  end
49
62
 
50
63
  def jwt_payload
@@ -52,11 +65,12 @@ module SMARTAppLaunch
52
65
  end
53
66
 
54
67
  def signing_key
55
- private_key()
56
- if @private_key.nil?
57
- raise Inferno::Exceptions::AssertionException, "No signing key found for inputs: encryption method = '#{client_auth_encryption_method}' and kid = '#{kid}'"
68
+ if private_key.nil?
69
+ raise Inferno::Exceptions::AssertionException,
70
+ "No signing key found for inputs: encryption method = '#{client_auth_encryption_method}' and kid = '#{kid}'"
58
71
  end
59
- return @private_key.signing_key
72
+
73
+ @private_key.signing_key
60
74
  end
61
75
 
62
76
  def key_id
@@ -65,7 +79,8 @@ module SMARTAppLaunch
65
79
 
66
80
  def client_assertion
67
81
  @client_assertion ||=
68
- JWT.encode jwt_payload, signing_key, client_auth_encryption_method, { alg: client_auth_encryption_method, kid: key_id, typ: 'JWT' }
82
+ JWT.encode jwt_payload, signing_key, client_auth_encryption_method,
83
+ { alg: client_auth_encryption_method, kid: key_id, typ: 'JWT' }
69
84
  end
70
85
  end
71
86
  end
@@ -16,11 +16,11 @@ module SMARTAppLaunch
16
16
  optional
17
17
 
18
18
  input :url, :id_token_fhir_user
19
- input :smart_credentials, type: :oauth_credentials
19
+ input :smart_auth_info, type: :auth_info
20
20
 
21
21
  fhir_client do
22
22
  url :url
23
- oauth_credentials :smart_credentials
23
+ auth_info :smart_auth_info
24
24
  headers 'Origin' => Inferno::Application['inferno_host']
25
25
  end
26
26
 
@@ -15,10 +15,10 @@ module SMARTAppLaunch
15
15
 
16
16
  uses_request :cors_token_request
17
17
 
18
- input :client_auth_type
18
+ input :smart_auth_info, type: :auth_info, options: { mode: 'auth' }
19
19
 
20
20
  run do
21
- omit_if client_auth_type != 'public', %(
21
+ omit_if smart_auth_info.auth_type != 'public', %(
22
22
  Client type is not public, Cross-Origin Resource Sharing (CORS) is not required to be supported for
23
23
  non-public client types
24
24
  )
@@ -40,8 +40,12 @@ module SMARTAppLaunch
40
40
  * [OpenID Connect Core](https://openid.net/specs/openid-connect-core-1_0.html)
41
41
  )
42
42
 
43
- test from: :well_known_endpoint,
44
- id: 'Test01'
43
+ test from: :well_known_endpoint do
44
+ id 'Test01'
45
+ input :smart_auth_info,
46
+ type: :auth_info
47
+ end
48
+
45
49
  test from: :well_known_capabilities_stu1,
46
50
  id: 'Test02'
47
51
 
@@ -40,23 +40,35 @@ module SMARTAppLaunch
40
40
 
41
41
  config(
42
42
  inputs: {
43
- client_id: {
44
- name: :ehr_client_id,
45
- title: 'EHR Launch Client ID',
46
- description: 'Client ID provided during registration of Inferno as an EHR launch application'
47
- },
48
- client_secret: {
49
- name: :ehr_client_secret,
50
- title: 'EHR Launch Client Secret',
51
- description: 'Client Secret provided during registration of Inferno as an EHR launch application. ' \
52
- 'Only for clients using confidential symmetric authentication.'
53
- },
54
- requested_scopes: {
55
- name: :ehr_requested_scopes,
56
- title: 'EHR Launch Scope',
57
- description: 'OAuth 2.0 scope provided by system to enable all required functionality',
58
- type: 'textarea',
59
- default: 'launch openid fhirUser offline_access user/*.read'
43
+ smart_auth_info: {
44
+ name: :ehr_smart_auth_info,
45
+ title: 'EHR Launch Credentials',
46
+ options: {
47
+ components: [
48
+ {
49
+ name: :auth_type,
50
+ options: {
51
+ list_options: [
52
+ { label: 'Public', value: 'public' },
53
+ { label: 'Confidential Symmetric', value: 'symmetric' }
54
+ ]
55
+ }
56
+ },
57
+ {
58
+ name: :requested_scopes,
59
+ default: 'launch openid fhirUser offline_access user/*.read'
60
+ },
61
+ {
62
+ name: :use_discovery,
63
+ locked: true
64
+ },
65
+ {
66
+ name: :auth_request_method,
67
+ default: 'GET',
68
+ locked: true
69
+ }
70
+ ]
71
+ }
60
72
  },
61
73
  url: {
62
74
  title: 'EHR Launch FHIR Endpoint',
@@ -88,7 +100,8 @@ module SMARTAppLaunch
88
100
  encounter_id: { name: :ehr_encounter_id },
89
101
  received_scopes: { name: :ehr_received_scopes },
90
102
  intent: { name: :ehr_intent },
91
- smart_credentials: { name: :ehr_smart_credentials }
103
+ smart_credentials: { name: :ehr_smart_credentials },
104
+ smart_auth_info: { name: :ehr_smart_auth_info }
92
105
  },
93
106
  requests: {
94
107
  launch: { name: :ehr_launch },
@@ -99,7 +112,7 @@ module SMARTAppLaunch
99
112
 
100
113
  test from: :smart_app_launch
101
114
  test from: :smart_launch_received
102
- test from: :tls_version_test,
115
+ test from: :smart_tls,
103
116
  id: :ehr_auth_tls,
104
117
  title: 'OAuth 2.0 authorize endpoint secured by transport layer security',
105
118
  description: %(
@@ -108,14 +121,16 @@ module SMARTAppLaunch
108
121
  servers, over TLS-secured channels.
109
122
  ),
110
123
  config: {
111
- inputs: { url: { name: :smart_authorization_url } },
112
- options: { minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION }
124
+ options: {
125
+ minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION,
126
+ smart_endpoint_key: :auth_url
127
+ }
113
128
  }
114
129
  test from: :smart_app_redirect do
115
130
  input :launch
116
131
  end
117
132
  test from: :smart_code_received
118
- test from: :tls_version_test,
133
+ test from: :smart_tls,
119
134
  id: :ehr_token_tls,
120
135
  title: 'OAuth 2.0 token endpoint secured by transport layer security',
121
136
  description: %(
@@ -124,8 +139,10 @@ module SMARTAppLaunch
124
139
  servers, over TLS-secured channels.
125
140
  ),
126
141
  config: {
127
- inputs: { url: { name: :smart_token_url } },
128
- options: { minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION }
142
+ options: {
143
+ minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION,
144
+ smart_endpoint_key: :token_url
145
+ }
129
146
  }
130
147
  test from: :smart_token_exchange
131
148
  test from: :smart_token_response_body
@@ -33,16 +33,32 @@ module SMARTAppLaunch
33
33
 
34
34
  config(
35
35
  inputs: {
36
- use_pkce: {
37
- default: 'true',
38
- locked: true
39
- },
40
- pkce_code_challenge_method: {
41
- default: 'S256',
42
- locked: true
43
- },
44
- requested_scopes: {
45
- default: 'launch openid fhirUser offline_access user/*.rs'
36
+ smart_auth_info: {
37
+ name: :ehr_smart_auth_info,
38
+ title: 'EHR Launch Credentials',
39
+ options: {
40
+ components: [
41
+ {
42
+ name: :requested_scopes,
43
+ default: 'launch openid fhirUser offline_access patient/*.rs'
44
+ },
45
+ {
46
+ name: :pkce_support,
47
+ default: 'enabled',
48
+ locked: true
49
+ },
50
+ {
51
+ name: :pkce_code_challenge_method,
52
+ default: 'S256',
53
+ locked: true
54
+ },
55
+ Inferno::DSL::AuthInfo.default_auth_type_component_without_backend_services,
56
+ {
57
+ name: :use_discovery,
58
+ locked: true
59
+ }
60
+ ]
61
+ }
46
62
  }
47
63
  }
48
64
  )
@@ -32,22 +32,6 @@ module SMARTAppLaunch
32
32
  * [SMART EHR Launch Sequence](http://hl7.org/fhir/smart-app-launch/STU2.2/app-launch.html#launch-app-ehr-launch)
33
33
  )
34
34
 
35
- config(
36
- inputs: {
37
- use_pkce: {
38
- default: 'true',
39
- locked: true
40
- },
41
- pkce_code_challenge_method: {
42
- default: 'S256',
43
- locked: true
44
- },
45
- requested_scopes: {
46
- default: 'launch openid fhirUser offline_access user/*.rs'
47
- }
48
- }
49
- )
50
-
51
35
  test from: :smart_token_exchange_stu2_2
52
36
 
53
37
  token_exchange_index = children.find_index { |child| child.id.to_s.end_with? 'smart_token_exchange' }