doorflow 1.0.0 → 1.1.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 (197) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/README.md +222 -316
  4. data/bin/post-generate +3 -1
  5. data/doorflow.gemspec +1 -1
  6. data/lib/doorflow/client/credentials_proxy.rb +6 -9
  7. data/lib/doorflow/client/element_sessions_proxy.rb +91 -0
  8. data/lib/doorflow/client.rb +13 -0
  9. data/lib/doorflow/errors/doorflow_error.rb +1 -1
  10. data/lib/doorflow/resources/credential.rb +4 -3
  11. data/lib/doorflow/resources/element_session.rb +28 -0
  12. data/lib/doorflow/webhooks/handler.rb +6 -6
  13. data/lib/doorflow/webhooks/signature_verifier.rb +8 -5
  14. data/lib/doorflow-api/api/accounts_api.rb +1 -1
  15. data/lib/doorflow-api/api/admission_requests_api.rb +2 -2
  16. data/lib/doorflow-api/api/card_designs_api.rb +347 -0
  17. data/lib/doorflow-api/api/card_template_types_api.rb +350 -0
  18. data/lib/doorflow-api/api/card_templates_api.rb +811 -0
  19. data/lib/doorflow-api/api/channels_api.rb +11 -11
  20. data/lib/doorflow-api/api/credential_types_api.rb +1 -1
  21. data/lib/doorflow-api/api/credentials_api.rb +6 -6
  22. data/lib/doorflow-api/api/element_sessions_api.rb +90 -0
  23. data/lib/doorflow-api/api/events_api.rb +2 -2
  24. data/lib/doorflow-api/api/group_reservations_api.rb +68 -5
  25. data/lib/doorflow-api/api/groups_api.rb +1 -1
  26. data/lib/doorflow-api/api/notification_rules_api.rb +7 -7
  27. data/lib/doorflow-api/api/oauth_api.rb +1 -1
  28. data/lib/doorflow-api/api/people_api.rb +7 -7
  29. data/lib/doorflow-api/api/reservations_api.rb +5 -5
  30. data/lib/doorflow-api/api/roles_api.rb +1 -1
  31. data/lib/doorflow-api/api/sites_api.rb +1 -1
  32. data/lib/doorflow-api/api/sync_api.rb +4 -4
  33. data/lib/doorflow-api/api_client.rb +8 -4
  34. data/lib/doorflow-api/api_error.rb +9 -14
  35. data/lib/doorflow-api/api_model_base.rb +1 -1
  36. data/lib/doorflow-api/configuration.rb +1 -1
  37. data/lib/doorflow-api/models/account.rb +1 -1
  38. data/lib/doorflow-api/models/account_passport.rb +1 -1
  39. data/lib/doorflow-api/models/account_reseller.rb +1 -1
  40. data/lib/doorflow-api/models/account_sync.rb +1 -1
  41. data/lib/doorflow-api/models/account_user.rb +1 -1
  42. data/lib/doorflow-api/models/admission_request.rb +1 -1
  43. data/lib/doorflow-api/models/admission_request_door_controller.rb +1 -1
  44. data/lib/doorflow-api/models/admission_request_person.rb +1 -1
  45. data/lib/doorflow-api/models/admit_channel202_response.rb +1 -1
  46. data/lib/doorflow-api/models/admit_person202_response.rb +1 -1
  47. data/lib/doorflow-api/models/admit_person403_response.rb +1 -1
  48. data/lib/doorflow-api/models/admit_person_request.rb +1 -1
  49. data/lib/doorflow-api/models/auto_unlock_channel400_response.rb +1 -1
  50. data/lib/doorflow-api/models/auto_unlock_channel_request.rb +1 -1
  51. data/lib/doorflow-api/models/card_design.rb +243 -0
  52. data/lib/doorflow-api/models/card_design_image_back.rb +179 -0
  53. data/lib/doorflow-api/models/card_design_image_front.rb +179 -0
  54. data/lib/doorflow-api/models/card_design_input.rb +181 -0
  55. data/lib/doorflow-api/models/card_template.rb +475 -0
  56. data/lib/doorflow-api/models/card_template_input.rb +147 -0
  57. data/lib/doorflow-api/models/card_template_input_card_template.rb +347 -0
  58. data/lib/doorflow-api/models/card_template_type.rb +321 -0
  59. data/lib/doorflow-api/models/card_template_type_input.rb +147 -0
  60. data/lib/doorflow-api/models/card_template_type_input_card_template_type.rb +251 -0
  61. data/lib/doorflow-api/models/card_template_type_input_card_template_type_non_printable_zones_inner.rb +183 -0
  62. data/lib/doorflow-api/models/card_template_type_non_printable_zones_inner.rb +188 -0
  63. data/lib/doorflow-api/models/channel.rb +1 -1
  64. data/lib/doorflow-api/models/channel_auto_unlock.rb +1 -1
  65. data/lib/doorflow-api/models/channel_lockdown.rb +1 -1
  66. data/lib/doorflow-api/models/channel_lockdown_aux_lockdown.rb +1 -1
  67. data/lib/doorflow-api/models/channel_lockdown_card_lockdown.rb +1 -1
  68. data/lib/doorflow-api/models/channel_lockdown_rex_lockdown.rb +1 -1
  69. data/lib/doorflow-api/models/channel_mode.rb +1 -1
  70. data/lib/doorflow-api/models/channel_sync.rb +5 -2
  71. data/lib/doorflow-api/models/{create_credential422_response.rb → create_card_design422_response.rb} +5 -5
  72. data/lib/doorflow-api/models/{create_credential422_response_errors.rb → create_card_design422_response_errors.rb} +4 -4
  73. data/lib/doorflow-api/models/credential.rb +4 -4
  74. data/lib/doorflow-api/models/credential_input.rb +1 -1
  75. data/lib/doorflow-api/models/credential_input_person_credential.rb +1 -1
  76. data/lib/doorflow-api/models/credential_type.rb +1 -1
  77. data/lib/doorflow-api/models/credential_update_input.rb +1 -1
  78. data/lib/doorflow-api/models/credential_update_input_person_credential.rb +1 -1
  79. data/lib/doorflow-api/models/{delete_group_reservation200_response.rb → delete_card_design200_response.rb} +4 -4
  80. data/lib/doorflow-api/models/delete_card_template_type409_response.rb +147 -0
  81. data/lib/doorflow-api/models/element_session.rb +192 -0
  82. data/lib/doorflow-api/models/element_session_config.rb +265 -0
  83. data/lib/doorflow-api/models/element_session_error.rb +199 -0
  84. data/lib/doorflow-api/models/element_session_input.rb +271 -0
  85. data/lib/doorflow-api/models/element_session_member.rb +186 -0
  86. data/lib/doorflow-api/models/error.rb +1 -1
  87. data/lib/doorflow-api/models/event.rb +1 -1
  88. data/lib/doorflow-api/models/get_access_token200_response.rb +1 -1
  89. data/lib/doorflow-api/models/get_access_token400_response.rb +1 -1
  90. data/lib/doorflow-api/models/get_access_token401_response.rb +1 -1
  91. data/lib/doorflow-api/models/get_admission_request401_response.rb +1 -1
  92. data/lib/doorflow-api/models/get_admission_request403_response.rb +1 -1
  93. data/lib/doorflow-api/models/get_admission_request404_response.rb +1 -1
  94. data/lib/doorflow-api/models/get_admission_request500_response.rb +1 -1
  95. data/lib/doorflow-api/models/get_token_info200_response.rb +1 -1
  96. data/lib/doorflow-api/models/get_token_info200_response_application.rb +1 -1
  97. data/lib/doorflow-api/models/get_token_info401_response.rb +1 -1
  98. data/lib/doorflow-api/models/group.rb +1 -1
  99. data/lib/doorflow-api/models/group_reservation.rb +1 -1
  100. data/lib/doorflow-api/models/group_reservation_input.rb +1 -1
  101. data/lib/doorflow-api/models/group_reservation_input_group_reservation.rb +1 -1
  102. data/lib/doorflow-api/models/initiate_sync429_response.rb +1 -1
  103. data/lib/doorflow-api/models/linked_file.rb +217 -0
  104. data/lib/doorflow-api/models/list_events400_response.rb +1 -1
  105. data/lib/doorflow-api/models/lockdown_channel_request.rb +1 -1
  106. data/lib/doorflow-api/models/notification_rule.rb +1 -1
  107. data/lib/doorflow-api/models/notification_rule_actions_inner.rb +1 -1
  108. data/lib/doorflow-api/models/notification_rule_conditions_inner.rb +1 -1
  109. data/lib/doorflow-api/models/notification_rule_events_inner.rb +1 -1
  110. data/lib/doorflow-api/models/notification_rule_input.rb +1 -1
  111. data/lib/doorflow-api/models/person.rb +30 -8
  112. data/lib/doorflow-api/models/person_input.rb +1 -1
  113. data/lib/doorflow-api/models/reservation.rb +1 -1
  114. data/lib/doorflow-api/models/reservation_input.rb +1 -1
  115. data/lib/doorflow-api/models/revoke_token403_response.rb +1 -1
  116. data/lib/doorflow-api/models/role.rb +1 -1
  117. data/lib/doorflow-api/models/site.rb +1 -1
  118. data/lib/doorflow-api/models/site_site_ips_inner.rb +1 -1
  119. data/lib/doorflow-api/models/unlock_channel_request.rb +1 -1
  120. data/lib/doorflow-api/version.rb +2 -2
  121. data/lib/doorflow-api.rb +28 -9
  122. data/lib/doorflow.rb +8 -2
  123. metadata +45 -154
  124. data/spec/api/admission_requests_api_spec.rb +0 -47
  125. data/spec/api/channels_api_spec.rb +0 -174
  126. data/spec/api/credential_types_api_spec.rb +0 -49
  127. data/spec/api/group_reservations_api_spec.rb +0 -75
  128. data/spec/api/oauth_api_spec.rb +0 -97
  129. data/spec/doorflow/client_spec.rb +0 -109
  130. data/spec/doorflow_spec.rb +0 -22
  131. data/spec/fixtures/vcr_cassettes/channel/list.yml +0 -70
  132. data/spec/fixtures/vcr_cassettes/channel/retrieve.yml +0 -131
  133. data/spec/fixtures/vcr_cassettes/person/auto_pagination.yml +0 -87
  134. data/spec/fixtures/vcr_cassettes/person/create.yml +0 -64
  135. data/spec/fixtures/vcr_cassettes/person/delete.yml +0 -125
  136. data/spec/fixtures/vcr_cassettes/person/list.yml +0 -90
  137. data/spec/fixtures/vcr_cassettes/person/not_found.yml +0 -62
  138. data/spec/fixtures/vcr_cassettes/person/retrieve.yml +0 -136
  139. data/spec/fixtures/vcr_cassettes/person/update.yml +0 -260
  140. data/spec/fixtures/vcr_cassettes/person/validation_error.yml +0 -62
  141. data/spec/integration/channel_spec.rb +0 -88
  142. data/spec/integration/person_spec.rb +0 -99
  143. data/spec/models/account_passport_spec.rb +0 -42
  144. data/spec/models/account_reseller_spec.rb +0 -60
  145. data/spec/models/account_sync_spec.rb +0 -52
  146. data/spec/models/account_user_spec.rb +0 -54
  147. data/spec/models/admission_request_door_controller_spec.rb +0 -42
  148. data/spec/models/admission_request_person_spec.rb +0 -42
  149. data/spec/models/admission_request_spec.rb +0 -82
  150. data/spec/models/admit_channel202_response_spec.rb +0 -46
  151. data/spec/models/admit_person202_response_spec.rb +0 -46
  152. data/spec/models/admit_person403_response_spec.rb +0 -42
  153. data/spec/models/admit_person_request_spec.rb +0 -36
  154. data/spec/models/auto_unlock_channel400_response_spec.rb +0 -42
  155. data/spec/models/auto_unlock_channel_request_spec.rb +0 -36
  156. data/spec/models/channel_auto_unlock_spec.rb +0 -42
  157. data/spec/models/channel_lockdown_aux_lockdown_spec.rb +0 -36
  158. data/spec/models/channel_lockdown_card_lockdown_spec.rb +0 -36
  159. data/spec/models/channel_lockdown_rex_lockdown_spec.rb +0 -36
  160. data/spec/models/channel_lockdown_spec.rb +0 -54
  161. data/spec/models/channel_mode_spec.rb +0 -52
  162. data/spec/models/channel_sync_spec.rb +0 -46
  163. data/spec/models/create_credential422_response_errors_spec.rb +0 -48
  164. data/spec/models/create_credential422_response_spec.rb +0 -42
  165. data/spec/models/credential_input_person_credential_spec.rb +0 -48
  166. data/spec/models/credential_input_spec.rb +0 -36
  167. data/spec/models/credential_spec.rb +0 -86
  168. data/spec/models/credential_update_input_person_credential_spec.rb +0 -36
  169. data/spec/models/credential_update_input_spec.rb +0 -36
  170. data/spec/models/delete_group_reservation200_response_spec.rb +0 -36
  171. data/spec/models/error_spec.rb +0 -42
  172. data/spec/models/get_access_token200_response_spec.rb +0 -66
  173. data/spec/models/get_access_token400_response_spec.rb +0 -46
  174. data/spec/models/get_access_token401_response_spec.rb +0 -42
  175. data/spec/models/get_admission_request401_response_spec.rb +0 -42
  176. data/spec/models/get_admission_request403_response_spec.rb +0 -42
  177. data/spec/models/get_admission_request404_response_spec.rb +0 -42
  178. data/spec/models/get_admission_request500_response_spec.rb +0 -42
  179. data/spec/models/get_token_info200_response_application_spec.rb +0 -36
  180. data/spec/models/get_token_info200_response_spec.rb +0 -66
  181. data/spec/models/get_token_info401_response_spec.rb +0 -42
  182. data/spec/models/group_reservation_input_group_reservation_spec.rb +0 -54
  183. data/spec/models/group_reservation_input_spec.rb +0 -36
  184. data/spec/models/group_reservation_spec.rb +0 -82
  185. data/spec/models/initiate_sync429_response_spec.rb +0 -52
  186. data/spec/models/list_events400_response_spec.rb +0 -42
  187. data/spec/models/lockdown_channel_request_spec.rb +0 -48
  188. data/spec/models/notification_rule_actions_inner_spec.rb +0 -48
  189. data/spec/models/notification_rule_conditions_inner_spec.rb +0 -48
  190. data/spec/models/notification_rule_events_inner_spec.rb +0 -42
  191. data/spec/models/notification_rule_input_spec.rb +0 -60
  192. data/spec/models/person_input_spec.rb +0 -180
  193. data/spec/models/reservation_input_spec.rb +0 -60
  194. data/spec/models/revoke_token403_response_spec.rb +0 -42
  195. data/spec/models/site_site_ips_inner_spec.rb +0 -36
  196. data/spec/models/unlock_channel_request_spec.rb +0 -36
  197. data/spec/spec_helper.rb +0 -160
@@ -1,97 +0,0 @@
1
- =begin
2
- #DoorFlow API
3
-
4
- #Access control and door management API for DoorFlow
5
-
6
- The version of the OpenAPI document: 3.0
7
-
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.18.0-SNAPSHOT
10
-
11
- =end
12
-
13
- require 'spec_helper'
14
- require 'json'
15
-
16
- # Unit tests for DoorFlow::OauthApi
17
- # Automatically generated by openapi-generator (https://openapi-generator.tech)
18
- # Please update as you see appropriate
19
- describe 'OauthApi' do
20
- before do
21
- # run before each test
22
- @api_instance = DoorFlow::OauthApi.new
23
- end
24
-
25
- after do
26
- # run after each test
27
- end
28
-
29
- describe 'test an instance of OauthApi' do
30
- it 'should create an instance of OauthApi' do
31
- expect(@api_instance).to be_instance_of(DoorFlow::OauthApi)
32
- end
33
- end
34
-
35
- # unit tests for authorize_o_auth
36
- # Authorization endpoint
37
- # Initiates the OAuth 2.0 authorization code flow. Direct users to this endpoint to request authorization. **Authorization Code Flow Steps:** 1. Direct the user's browser to this endpoint with required parameters 2. User logs in (if not already authenticated) and authorizes your application 3. User is redirected to your `redirect_uri` with an authorization `code` parameter 4. Exchange the code for an access token at `/oauth/token` **PKCE (Proof Key for Code Exchange):** For public clients (mobile/SPA applications), PKCE is recommended for security: 1. Generate a random `code_verifier` (43-128 characters) 2. Create `code_challenge` = BASE64URL(SHA256(code_verifier)) 3. Include `code_challenge` and `code_challenge_method=S256` in this request 4. Include `code_verifier` when exchanging the code at `/oauth/token` **Important Notes:** - This is a browser-based flow - users will see a login/authorization screen - The `redirect_uri` must be pre-registered with your OAuth application - The authorization code expires after 10 minutes - Some applications may be configured to skip the authorization screen (auto-approve)
38
- # @param response_type OAuth response type (must be \"code\" for authorization code flow)
39
- # @param client_id Your OAuth application's client ID
40
- # @param redirect_uri URI to redirect to after authorization (must match registered redirect URI)
41
- # @param scope Space-separated list of requested scopes (see available scopes in security schemes section)
42
- # @param [Hash] opts the optional parameters
43
- # @option opts [String] :state Opaque value to maintain state between request and callback (recommended for CSRF protection)
44
- # @option opts [String] :code_challenge PKCE code challenge (BASE64URL(SHA256(code_verifier)))
45
- # @option opts [String] :code_challenge_method PKCE code challenge method (must be S256)
46
- # @return [nil]
47
- describe 'authorize_o_auth test' do
48
- it 'should work' do
49
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
50
- end
51
- end
52
-
53
- # unit tests for get_access_token
54
- # Obtain access token
55
- # Exchange authorization code for an access token, or refresh an existing token. **Authorization Code Flow:** 1. Direct users to `/oauth/authorize` with your client_id, redirect_uri, and requested scopes 2. User authorizes your application 3. You receive an authorization code at your redirect_uri 4. Exchange the code for an access token using this endpoint with `grant_type=authorization_code` **Refreshing Tokens:** - Use `grant_type=refresh_token` with a valid refresh_token to obtain a new access token - Access tokens expire after 1 hour - Refresh tokens are long-lived and should be stored securely
56
- # @param grant_type OAuth grant type (use \\\"authorization_code\\\" to exchange an authorization code, or \\\"refresh_token\\\" to refresh an access token)
57
- # @param [Hash] opts the optional parameters
58
- # @option opts [String] :client_id OAuth client ID (required for all grant types)
59
- # @option opts [String] :client_secret OAuth client secret (required for confidential clients)
60
- # @option opts [String] :code Authorization code (required when grant_type=authorization_code)
61
- # @option opts [String] :redirect_uri Redirect URI (required when grant_type=authorization_code, must match the one used in authorization request)
62
- # @option opts [String] :code_verifier PKCE code verifier (required if PKCE was used in authorization request)
63
- # @option opts [String] :refresh_token Refresh token (required when grant_type=refresh_token)
64
- # @option opts [String] :scope Space-separated list of requested scopes (optional, defaults to application's configured scopes)
65
- # @return [GetAccessToken200Response]
66
- describe 'get_access_token test' do
67
- it 'should work' do
68
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
69
- end
70
- end
71
-
72
- # unit tests for get_token_info
73
- # Get token information
74
- # Returns information about the current access token being used for authentication. This endpoint provides metadata about the access token including the resource owner, account, scopes, and expiration. **Authentication:** Requires a valid OAuth2 access token in the Authorization header.
75
- # @param [Hash] opts the optional parameters
76
- # @return [GetTokenInfo200Response]
77
- describe 'get_token_info test' do
78
- it 'should work' do
79
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
80
- end
81
- end
82
-
83
- # unit tests for revoke_token
84
- # Revoke access token or refresh token
85
- # Revokes an access token or refresh token, immediately invalidating it and blocking associated tokens from making further requests. **When to revoke:** - User disconnects their DoorFlow account from your integration - User logs out - Security breach - revoke compromised tokens - Application uninstall **Important:** - **We recommend revoking the refresh_token** - this will invalidate all associated access tokens - Returns HTTP 200 even if the token was already invalid (prevents token scanning attacks) - Client authentication is required via HTTP Basic Auth header **Authentication:** You must authenticate using HTTP Basic Authentication with your client credentials: 1. Combine your client_id and client_secret as: `{client_id}:{client_secret}` 2. Encode using URL-safe Base64 3. Include in Authorization header: `Authorization: Basic {encoded_credentials}`
86
- # @param authorization HTTP Basic Authentication using client_id:client_secret encoded with URL-safe Base64
87
- # @param token The access token or refresh token to revoke (we recommend using refresh_token)
88
- # @param [Hash] opts the optional parameters
89
- # @option opts [String] :token_type_hint Optional hint about the type of token being revoked. We recommend using 'refresh_token' for all revocations as it invalidates all associated tokens. Invalid token type hint values are ignored and do not affect the revocation response.
90
- # @return [Object]
91
- describe 'revoke_token test' do
92
- it 'should work' do
93
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
94
- end
95
- end
96
-
97
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe DoorFlow::Client do
6
- describe 'resource instance methods use instance client' do
7
- it 'Person#update uses the instance client, not class-level client' do
8
- # Create a mock people_api
9
- people_api = double('people_api')
10
- allow(people_api).to receive(:update_person).and_return(
11
- double('response', to_hash: { 'id' => 123, 'first_name' => 'Updated' })
12
- )
13
-
14
- # Create a client with the mock
15
- auth = double('auth', access_token: 'instance_token', authenticated?: true)
16
- client = DoorFlow::Client.new(auth: auth)
17
- allow(client).to receive(:people_api).and_return(people_api)
18
-
19
- # Create a person as if retrieved via client.people.retrieve
20
- person = DoorFlow::Resources::Person.new({ 'id' => 123, 'first_name' => 'Test' })
21
- person.instance_variable_set(:@_client, client)
22
-
23
- # Call update - this should use the instance client's people_api
24
- person.update(first_name: 'Updated')
25
-
26
- # Verify the instance client's people_api was called, not class-level
27
- expect(people_api).to have_received(:update_person).with(123, { first_name: 'Updated' })
28
- end
29
- end
30
-
31
-
32
- describe '#access_token' do
33
- context 'with an auth object' do
34
- it 'delegates to auth.access_token' do
35
- auth = double('auth', access_token: 'token_from_auth')
36
- client = DoorFlow::Client.new(auth: auth)
37
-
38
- expect(client.access_token).to eq('token_from_auth')
39
- end
40
- end
41
-
42
- context 'with a static access token' do
43
- it 'returns the static token' do
44
- client = DoorFlow::Client.new(access_token: 'static_token')
45
-
46
- expect(client.access_token).to eq('static_token')
47
- end
48
- end
49
- end
50
-
51
- describe '#authenticated?' do
52
- context 'with an auth object that responds to authenticated?' do
53
- it 'delegates to auth.authenticated?' do
54
- auth = double('auth', authenticated?: true)
55
- client = DoorFlow::Client.new(auth: auth)
56
-
57
- expect(client.authenticated?).to be true
58
- end
59
- end
60
-
61
- context 'with a static access token' do
62
- it 'returns true when token is present' do
63
- client = DoorFlow::Client.new(access_token: 'token')
64
- # The SDK uses .present? which requires ActiveSupport
65
- # In non-Rails context, we just check if it doesn't raise
66
- expect { client.authenticated? }.not_to raise_error
67
- end
68
-
69
- it 'returns false when token is nil' do
70
- client = DoorFlow::Client.new(access_token: nil)
71
-
72
- expect(client.authenticated?).to be false
73
- end
74
- end
75
- end
76
-
77
- describe 'dynamic token refresh' do
78
- it 'fetches fresh token on each API call, not cached at client creation' do
79
- call_count = 0
80
- tokens = ['first_token', 'refreshed_token']
81
-
82
- # Auth object that returns different tokens on each call (simulating refresh)
83
- auth = double('auth')
84
- allow(auth).to receive(:access_token) do
85
- token = tokens[call_count] || tokens.last
86
- call_count += 1
87
- token
88
- end
89
- allow(auth).to receive(:authenticated?).and_return(true)
90
-
91
- client = DoorFlow::Client.new(auth: auth)
92
-
93
- # Access the api_client to trigger config setup
94
- api_client = client.send(:api_client)
95
- config = api_client.config
96
-
97
- # First call should get first token
98
- first_token = config.access_token_with_refresh
99
- expect(first_token).to eq('first_token')
100
-
101
- # Second call should get refreshed token (not cached first token)
102
- second_token = config.access_token_with_refresh
103
- expect(second_token).to eq('refreshed_token')
104
-
105
- # Verify auth.access_token was called multiple times
106
- expect(call_count).to be >= 2
107
- end
108
- end
109
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe DoorFlow do
4
- describe '.access_token=' do
5
- it 'sets the access token' do
6
- DoorFlow.access_token = 'test_token'
7
- expect(DoorFlow.access_token).to eq('test_token')
8
- end
9
-
10
- it 'configures the generated client' do
11
- DoorFlow.access_token = 'test_token'
12
- expect(DoorFlow.configuration.access_token).to eq('test_token')
13
- end
14
- end
15
-
16
- describe '.api_base=' do
17
- it 'sets the API base' do
18
- DoorFlow.api_base = 'https://api.test.com'
19
- expect(DoorFlow.api_base).to eq('https://api.test.com')
20
- end
21
- end
22
- end
@@ -1,70 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: get
5
- uri: https://api.doorflow.com/api/3/channels
6
- body:
7
- encoding: US-ASCII
8
- string: ''
9
- headers:
10
- Content-Type:
11
- - application/json
12
- User-Agent:
13
- - doorflow-ruby/1.0.0
14
- Accept:
15
- - application/json
16
- Authorization:
17
- - "<ACCESS_TOKEN>"
18
- Accept-Encoding:
19
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
- response:
21
- status:
22
- code: 200
23
- message: OK
24
- headers:
25
- Date:
26
- - Thu, 05 Feb 2026 20:21:52 GMT
27
- Content-Type:
28
- - application/json; charset=utf-8
29
- Content-Length:
30
- - '1111'
31
- Connection:
32
- - keep-alive
33
- Cache-Control:
34
- - max-age=0, private, must-revalidate
35
- Etag:
36
- - W/"548dffeeb5158920a534882c96f449ba"
37
- Referrer-Policy:
38
- - strict-origin-when-cross-origin
39
- Strict-Transport-Security:
40
- - max-age=31536000; includeSubDomains
41
- Vary:
42
- - Origin
43
- X-Cache:
44
- - miss
45
- X-Content-Type-Options:
46
- - nosniff
47
- X-Download-Options:
48
- - noopen
49
- X-Frame-Options:
50
- - ALLOWALL
51
- X-Page:
52
- - '1'
53
- X-Per-Page:
54
- - '500'
55
- X-Permitted-Cross-Domain-Policies:
56
- - none
57
- X-Request-Id:
58
- - 3feec5159c7ed68cbb8bb01d317b7ccc
59
- X-Runtime:
60
- - '0.036802'
61
- X-Total-Results:
62
- - '2'
63
- X-Xss-Protection:
64
- - 1; mode=block
65
- body:
66
- encoding: ASCII-8BIT
67
- string: '[{"id":8114,"name":"Meeting Room","mac_address":"df:df:df:ef:cb:1b","status":"online","unit":1,"model":"A9188","model_long":"Unknown","serial_number":"","card_format":"","pin_format":"","freescale_version":null,"pic_version":null,"reader_device_class_name":"AA-C100-B","site_id":625,"updated_at":"2026-02-05T20:21:13+00:00","created_at":"2024-08-09T11:56:22+01:00","sync":{"status":"sync_complete","last_sync_completed_at":"2025-04-11T20:42:16+01:00"},"lockdown":null,"mode":{"description":"normal","relock_at":null,"change_stamp":null},"auto_unlock":null},{"id":8113,"name":"Front
68
- Door","mac_address":"df:df:df:82:41:ab","status":"online","unit":1,"model":"A9188","model_long":"Unknown","serial_number":"","card_format":"","pin_format":"","freescale_version":null,"pic_version":null,"reader_device_class_name":"AA-C100-B","site_id":625,"updated_at":"2026-02-05T20:21:12+00:00","created_at":"2024-08-09T11:56:22+01:00","sync":{"status":"sync_complete","last_sync_completed_at":"2025-04-11T20:42:17+01:00"},"lockdown":null,"mode":{"description":"normal","relock_at":null,"change_stamp":null},"auto_unlock":null}]'
69
- recorded_at: Thu, 05 Feb 2026 20:21:52 GMT
70
- recorded_with: VCR 6.4.0
@@ -1,131 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: get
5
- uri: https://api.doorflow.com/api/3/channels?per_page=1
6
- body:
7
- encoding: US-ASCII
8
- string: ''
9
- headers:
10
- Content-Type:
11
- - application/json
12
- User-Agent:
13
- - doorflow-ruby/1.0.0
14
- Accept:
15
- - application/json
16
- Authorization:
17
- - "<ACCESS_TOKEN>"
18
- Accept-Encoding:
19
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
- response:
21
- status:
22
- code: 200
23
- message: OK
24
- headers:
25
- Date:
26
- - Thu, 05 Feb 2026 21:43:50 GMT
27
- Content-Type:
28
- - application/json; charset=utf-8
29
- Content-Length:
30
- - '557'
31
- Connection:
32
- - keep-alive
33
- Cache-Control:
34
- - max-age=0, private, must-revalidate
35
- Etag:
36
- - W/"fa3ddfab29d4ba9307a1047ec43d1239"
37
- Link:
38
- - <https://api.doorflow.com/api/3/channels?page=2&per_page=1>; rel="last", <https://api.doorflow.com/api/3/channels?page=2&per_page=1>;
39
- rel="next"
40
- Referrer-Policy:
41
- - strict-origin-when-cross-origin
42
- Strict-Transport-Security:
43
- - max-age=31536000; includeSubDomains
44
- Vary:
45
- - Origin
46
- X-Cache:
47
- - miss
48
- X-Content-Type-Options:
49
- - nosniff
50
- X-Download-Options:
51
- - noopen
52
- X-Frame-Options:
53
- - ALLOWALL
54
- X-Page:
55
- - '1'
56
- X-Per-Page:
57
- - '1'
58
- X-Permitted-Cross-Domain-Policies:
59
- - none
60
- X-Request-Id:
61
- - 304323d4151f5ae21c46403457f19c16
62
- X-Runtime:
63
- - '0.031737'
64
- X-Total-Results:
65
- - '2'
66
- X-Xss-Protection:
67
- - 1; mode=block
68
- body:
69
- encoding: UTF-8
70
- string: '[{"id":8114,"name":"Meeting Room","mac_address":"df:df:df:ef:cb:1b","status":"online","unit":1,"model":"A9188","model_long":"Unknown","serial_number":"","card_format":"","pin_format":"","freescale_version":null,"pic_version":null,"reader_device_class_name":"AA-C100-B","site_id":625,"updated_at":"2026-02-05T21:42:34+00:00","created_at":"2024-08-09T11:56:22+01:00","sync":{"status":"sync_complete","last_sync_completed_at":"2025-04-11T20:42:16+01:00"},"lockdown":null,"mode":{"description":"normal","relock_at":null,"change_stamp":null},"auto_unlock":null}]'
71
- recorded_at: Thu, 05 Feb 2026 21:43:50 GMT
72
- - request:
73
- method: get
74
- uri: https://api.doorflow.com/api/3/channels/8114
75
- body:
76
- encoding: US-ASCII
77
- string: ''
78
- headers:
79
- Content-Type:
80
- - application/json
81
- User-Agent:
82
- - doorflow-ruby/1.0.0
83
- Accept:
84
- - application/json
85
- Authorization:
86
- - "<ACCESS_TOKEN>"
87
- Accept-Encoding:
88
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
89
- response:
90
- status:
91
- code: 404
92
- message: Not Found
93
- headers:
94
- Date:
95
- - Thu, 05 Feb 2026 21:43:50 GMT
96
- Content-Type:
97
- - application/json; charset=utf-8
98
- Content-Length:
99
- - '95'
100
- Connection:
101
- - keep-alive
102
- Cache-Control:
103
- - no-cache
104
- Referrer-Policy:
105
- - strict-origin-when-cross-origin
106
- Strict-Transport-Security:
107
- - max-age=31536000; includeSubDomains
108
- Vary:
109
- - Origin
110
- X-Cache:
111
- - miss
112
- X-Content-Type-Options:
113
- - nosniff
114
- X-Download-Options:
115
- - noopen
116
- X-Frame-Options:
117
- - ALLOWALL
118
- X-Permitted-Cross-Domain-Policies:
119
- - none
120
- X-Request-Id:
121
- - 420fac64a47fe32c58cbe3f7fd332fa7
122
- X-Runtime:
123
- - '0.014178'
124
- X-Xss-Protection:
125
- - 1; mode=block
126
- body:
127
- encoding: UTF-8
128
- string: '{"error":"The resource you requested could not be found, please check
129
- your url and try again."}'
130
- recorded_at: Thu, 05 Feb 2026 21:43:50 GMT
131
- recorded_with: VCR 6.4.0
@@ -1,87 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: get
5
- uri: https://api.doorflow.com/api/3/people
6
- body:
7
- encoding: US-ASCII
8
- string: ''
9
- headers:
10
- Content-Type:
11
- - application/json
12
- User-Agent:
13
- - doorflow-ruby/1.0.0
14
- Accept:
15
- - application/json
16
- Authorization:
17
- - "<ACCESS_TOKEN>"
18
- Accept-Encoding:
19
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
- response:
21
- status:
22
- code: 200
23
- message: OK
24
- headers:
25
- Date:
26
- - Thu, 05 Feb 2026 19:05:51 GMT
27
- Content-Type:
28
- - application/json; charset=utf-8
29
- Content-Length:
30
- - '11246'
31
- Connection:
32
- - keep-alive
33
- Cache-Control:
34
- - max-age=0, private, must-revalidate
35
- Etag:
36
- - W/"6c470fc40508db9ddb61cef2a0f2b46a"
37
- Referrer-Policy:
38
- - strict-origin-when-cross-origin
39
- Strict-Transport-Security:
40
- - max-age=31536000; includeSubDomains
41
- Vary:
42
- - Origin
43
- X-Cache:
44
- - miss
45
- X-Content-Type-Options:
46
- - nosniff
47
- X-Download-Options:
48
- - noopen
49
- X-Frame-Options:
50
- - ALLOWALL
51
- X-Page:
52
- - '1'
53
- X-Per-Page:
54
- - '50'
55
- X-Permitted-Cross-Domain-Policies:
56
- - none
57
- X-Request-Id:
58
- - 1eb7eac1cb391b91fecef568a07bd410
59
- X-Runtime:
60
- - '0.149406'
61
- X-Total-Results:
62
- - '14'
63
- X-Xss-Protection:
64
- - 1; mode=block
65
- body:
66
- encoding: ASCII-8BIT
67
- string: '[{"id":833760,"first_name":"Benjamin","last_name":"Carter","salutation":"","job_title":"","email":"","organisation_id":"","system_id":null,"department":"","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":"","key_fob_number":"","pin":"5641","mobile":"","image_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/833760/medium/0556a7e006d9b99b417598589c987df5f57a11b5.png?1723200983","image_thumbnail_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/833760/thumb/40c3a8b597c01692cc7ebe5c7b08098cc7ef6ef4.png?1723200983","telephone":null,"notes":"Updated
68
- at 2026-02-05 15:52:28 +0000","barcode":"","custom_1":"","custom_2":"","custom_3":"","custom_4":"","custom_5":"","created_at":"2024-08-09T11:56:22+01:00","updated_at":"2026-02-05T19:05:50+00:00","groups":[],"roles":[],"credentials":[{"id":"wmsd1rM","credential_type_id":852,"label":"Credentials
69
- number","person_id":833760,"value":""},{"id":"6ps3Ob9","credential_type_id":854,"label":"Pin","person_id":833760,"value":"5641"},{"id":"qKsXq1N","credential_type_id":853,"label":"Key
70
- fob number","person_id":833760,"value":""}]},{"id":833761,"first_name":"Charlotte","last_name":"Smith","salutation":"","job_title":"","email":"","organisation_id":"","system_id":null,"department":"","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":"5445784562","key_fob_number":"","pin":"","mobile":"","image_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/833761/medium/abffec982cf4b473a8dc82ec666f91e6d10acf2e.png?1723200985","image_thumbnail_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/833761/thumb/9aee440af8519c41591f0b63579d229e95a7a22d.png?1723200985","telephone":null,"notes":"","barcode":"","custom_1":"","custom_2":"","custom_3":"","custom_4":"","custom_5":"","created_at":"2024-08-09T11:56:24+01:00","updated_at":"2024-08-09T18:55:14+01:00","groups":[],"roles":[],"credentials":[{"id":"kEsq32X","credential_type_id":853,"label":"Key
71
- fob number","person_id":833761,"value":""},{"id":"Z0sDYMg","credential_type_id":852,"label":"Credentials
72
- number","person_id":833761,"value":"5445784562"},{"id":"7DsJqMW","credential_type_id":854,"label":"Pin","person_id":833761,"value":""}]},{"id":833762,"first_name":"Alice","last_name":"Johnson","salutation":"","job_title":"","email":"","organisation_id":"","system_id":null,"department":"","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":"5945154368","key_fob_number":"","pin":"","mobile":"","image_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/833762/medium/ff125b29a4d0907d79b8c254269ffb2b46f8fbd1.png?1723200986","image_thumbnail_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/833762/thumb/c669abfc3a307debcab2957b90c154f80008c141.png?1723200986","telephone":null,"notes":"","barcode":"","custom_1":"","custom_2":"","custom_3":"","custom_4":"","custom_5":"","created_at":"2024-08-09T11:56:26+01:00","updated_at":"2024-08-09T18:55:14+01:00","groups":[],"roles":[],"credentials":[{"id":"LNsmbNG","credential_type_id":852,"label":"Credentials
73
- number","person_id":833762,"value":"5945154368"},{"id":"j9s6kD6","credential_type_id":854,"label":"Pin","person_id":833762,"value":""},{"id":"XXsLekR","credential_type_id":853,"label":"Key
74
- fob number","person_id":833762,"value":""}]},{"id":871994,"first_name":"Terry","last_name":"Doe","salutation":"","job_title":"","email":"simonpreed+newdeveloper@gmail.com","organisation_id":"","system_id":null,"department":"","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":"","key_fob_number":null,"pin":"","mobile":"","image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":"","barcode":"","custom_1":"","custom_2":"","custom_3":"","custom_4":"","custom_5":"","created_at":"2024-11-22T08:42:58+00:00","updated_at":"2025-01-28T11:00:44+00:00","groups":[64660,64661],"roles":[],"credentials":[{"id":"VZsQOgK","credential_type_id":856,"label":"Mobile
75
- Access","person_id":871994,"status":"invited","url":"https://redeem.passflow.io/passes/jzUNDP"},{"id":"qKsZQM0","credential_type_id":854,"label":"Pin","person_id":871994,"value":""},{"id":"OrsWeJ6","credential_type_id":852,"label":"Credentials
76
- number","person_id":871994,"value":""}]},{"id":970890,"first_name":"Alice","last_name":"Smith","salutation":null,"job_title":"Senior
77
- Developer","email":"alice.smith@example.com","organisation_id":null,"system_id":"1","department":"Engineering","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":"3391","mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":"Team
78
- lead for the mobile app project","barcode":null,"custom_1":"premium","custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2025-12-11T15:05:15+00:00","updated_at":"2026-02-04T15:56:16+00:00","groups":[],"roles":[],"credentials":[{"id":"kEsQGLn","credential_type_id":856,"label":"Mobile
79
- Access","person_id":970890,"status":"invited","url":"https://redeem.passflow.io/passes/YNUBjqD"},{"id":"eysq3v2","credential_type_id":854,"label":"Pin","person_id":970890,"value":"3391"}]},{"id":970891,"first_name":"Hughw","last_name":"Johnson","salutation":null,"job_title":"Account
80
- Executive","email":"bob.johnson@example.com","organisation_id":null,"system_id":"2","department":"Sales","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":"+15551003","image_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/970891/medium/7d4a5eea0e1caeb80cf01c41d97f85635ff64365.png?1770284353","image_thumbnail_url":"https://doorguard-us-production.s3.amazonaws.com/person/images/970891/thumb/6f2b2a0782c34f83eae1b990116ce5c087b39ed4.png?1770284353","telephone":null,"notes":"","barcode":null,"custom_1":"standard","custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2025-12-11T15:05:16+00:00","updated_at":"2026-02-05T09:39:13+00:00","groups":[64660,64661],"roles":[],"credentials":[{"id":"eysYKDy","credential_type_id":856,"label":"Mobile
81
- Access","person_id":970891,"status":"invited","url":"https://redeem.passflow.io/passes/BaUgVG3"}]},{"id":970892,"first_name":"Carol","last_name":"Williams","salutation":null,"job_title":"DevOps
82
- Engineer","email":"carol.williams@example.com","organisation_id":null,"system_id":"3","department":"Engineering","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":"On-call
83
- rotation lead","barcode":null,"custom_1":"premium","custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2025-12-11T15:05:16+00:00","updated_at":"2026-02-04T19:02:53+00:00","groups":[64661],"roles":[],"credentials":[]},{"id":970894,"first_name":"Eva","last_name":"Martinez","salutation":null,"job_title":"Office
84
- Manager","email":"eva.martinez@example.com","organisation_id":null,"system_id":"4","department":"Operations","enabled":true,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":"standard","custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2025-12-11T15:05:16+00:00","updated_at":"2026-02-04T15:56:17+00:00","groups":[],"roles":[],"credentials":[{"id":"r4svzR4","credential_type_id":856,"label":"Mobile
85
- Access","person_id":970894,"status":"invited","url":"https://redeem.passflow.io/passes/rJUkpeX"}]},{"id":981358,"first_name":"John","last_name":"Doe","salutation":null,"job_title":null,"email":"john.doe@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T15:33:11+00:00","updated_at":"2026-02-05T15:33:11+00:00","groups":[],"roles":[],"credentials":[]},{"id":981360,"first_name":"Test","last_name":"User","salutation":null,"job_title":null,"email":"test.user.1770306464@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T15:47:45+00:00","updated_at":"2026-02-05T15:47:45+00:00","groups":[],"roles":[],"credentials":[]},{"id":981366,"first_name":"Test","last_name":"User","salutation":null,"job_title":null,"email":"test.user.1770306746@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T15:52:26+00:00","updated_at":"2026-02-05T15:52:26+00:00","groups":[],"roles":[],"credentials":[]},{"id":981379,"first_name":"Test","last_name":"User","salutation":null,"job_title":null,"email":"test.user.1770308160@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T16:16:01+00:00","updated_at":"2026-02-05T16:16:01+00:00","groups":[],"roles":[],"credentials":[]},{"id":981380,"first_name":"Delete","last_name":"Me","salutation":null,"job_title":null,"email":"delete.me.1770308161@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T16:16:01+00:00","updated_at":"2026-02-05T16:16:01+00:00","groups":[],"roles":[],"credentials":[]},{"id":981414,"first_name":"Test","last_name":"User","salutation":null,"job_title":null,"email":"test.user.1770318347@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T19:05:47+00:00","updated_at":"2026-02-05T19:05:47+00:00","groups":[],"roles":[],"credentials":[]}]'
86
- recorded_at: Thu, 05 Feb 2026 19:05:51 GMT
87
- recorded_with: VCR 6.4.0
@@ -1,64 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: post
5
- uri: https://api.doorflow.com/api/3/people
6
- body:
7
- encoding: UTF-8
8
- string: '{"first_name":"Test","last_name":"User","email":"test.user.1770318347@example.com"}'
9
- headers:
10
- Content-Type:
11
- - application/json
12
- User-Agent:
13
- - doorflow-ruby/1.0.0
14
- Accept:
15
- - application/json
16
- Authorization:
17
- - "<ACCESS_TOKEN>"
18
- Accept-Encoding:
19
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
- response:
21
- status:
22
- code: 201
23
- message: Created
24
- headers:
25
- Date:
26
- - Thu, 05 Feb 2026 19:05:47 GMT
27
- Content-Type:
28
- - application/json; charset=utf-8
29
- Content-Length:
30
- - '584'
31
- Connection:
32
- - keep-alive
33
- Cache-Control:
34
- - max-age=0, private, must-revalidate
35
- Etag:
36
- - W/"7a478b33ae5ceaddc32eb533e6cf5f0d"
37
- Referrer-Policy:
38
- - strict-origin-when-cross-origin
39
- Strict-Transport-Security:
40
- - max-age=31536000; includeSubDomains
41
- Vary:
42
- - Accept-Encoding
43
- - Origin
44
- X-Cache:
45
- - bypass
46
- X-Content-Type-Options:
47
- - nosniff
48
- X-Download-Options:
49
- - noopen
50
- X-Frame-Options:
51
- - ALLOWALL
52
- X-Permitted-Cross-Domain-Policies:
53
- - none
54
- X-Request-Id:
55
- - 713b5c5e324d5ffaced2375c7eb2bfb6
56
- X-Runtime:
57
- - '0.247564'
58
- X-Xss-Protection:
59
- - 1; mode=block
60
- body:
61
- encoding: UTF-8
62
- string: '{"id":981414,"first_name":"Test","last_name":"User","salutation":null,"job_title":null,"email":"test.user.1770318347@example.com","organisation_id":null,"system_id":null,"department":null,"enabled":null,"valid_from":null,"valid_to":null,"credentials_number":null,"key_fob_number":null,"pin":null,"mobile":null,"image_url":null,"image_thumbnail_url":null,"telephone":null,"notes":null,"barcode":null,"custom_1":null,"custom_2":null,"custom_3":null,"custom_4":null,"custom_5":null,"created_at":"2026-02-05T19:05:47+00:00","updated_at":"2026-02-05T19:05:47+00:00","groups":[],"roles":[]}'
63
- recorded_at: Thu, 05 Feb 2026 19:05:47 GMT
64
- recorded_with: VCR 6.4.0