bitwarden-sdk-secrets 0.1.0 → 1.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.
- checksums.yaml +4 -4
- data/lib/auth.rb +16 -0
- data/lib/bitwarden-sdk-secrets.rb +5 -9
- data/lib/extended_schemas/schemas.rb +16 -2
- data/lib/linux-x64/libbitwarden_c.so +0 -0
- data/lib/macos-arm64/libbitwarden_c.dylib +0 -0
- data/lib/macos-x64/libbitwarden_c.dylib +0 -0
- data/lib/projects.rb +4 -4
- data/lib/schemas.rb +395 -266
- data/lib/secrets.rb +19 -3
- data/lib/version.rb +1 -1
- data/lib/windows-x64/bitwarden_c.dll +0 -0
- data/sig/auth.rbs +9 -0
- data/sig/bitwarden-sdk-secrets.rbs +39 -0
- data/sig/bitwarden_error.rbs +5 -0
- data/sig/bitwarden_lib.rbs +7 -0
- data/sig/command_runner.rbs +11 -3
- data/sig/projects.rbs +25 -0
- data/sig/secrets.rbs +29 -0
- data/sig/version.rbs +3 -0
- metadata +10 -7
- data/sig/bitwarden-sdk.rbs +0 -13
- data/sig/bitwarden_settings.rbs +0 -8
- data/sig/projects_client.rbs +0 -17
- data/sig/sdk.rbs +0 -3
- data/sig/secrets_client.rbs +0 -18
data/lib/schemas.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
# puts device_type == DeviceType::Android
|
11
11
|
#
|
12
12
|
# command = Command.from_json! "{…}"
|
13
|
-
# puts command.
|
13
|
+
# puts command.generators&.generate_password.avoid_ambiguous
|
14
14
|
#
|
15
15
|
# password_login_request = PasswordLoginRequest.from_json! "{…}"
|
16
16
|
# puts password_login_request.kdf.argon2_id&.iterations.even?
|
@@ -40,7 +40,7 @@
|
|
40
40
|
# puts sync_request.exclude_subdomains.nil?
|
41
41
|
#
|
42
42
|
# secrets_command = SecretsCommand.from_json! "{…}"
|
43
|
-
# puts secrets_command.
|
43
|
+
# puts secrets_command.sync&.last_synced_date.nil?
|
44
44
|
#
|
45
45
|
# secret_get_request = SecretGetRequest.from_json! "{…}"
|
46
46
|
# puts secret_get_request.id
|
@@ -60,6 +60,9 @@
|
|
60
60
|
# secrets_delete_request = SecretsDeleteRequest.from_json! "{…}"
|
61
61
|
# puts secrets_delete_request.ids.first
|
62
62
|
#
|
63
|
+
# secrets_sync_request = SecretsSyncRequest.from_json! "{…}"
|
64
|
+
# puts secrets_sync_request.last_synced_date.nil?
|
65
|
+
#
|
63
66
|
# projects_command = ProjectsCommand.from_json! "{…}"
|
64
67
|
# puts projects_command.delete&.ids.first
|
65
68
|
#
|
@@ -78,6 +81,12 @@
|
|
78
81
|
# projects_delete_request = ProjectsDeleteRequest.from_json! "{…}"
|
79
82
|
# puts projects_delete_request.ids.first
|
80
83
|
#
|
84
|
+
# generators_command = GeneratorsCommand.from_json! "{…}"
|
85
|
+
# puts generators_command.generate_password.avoid_ambiguous
|
86
|
+
#
|
87
|
+
# password_generator_request = PasswordGeneratorRequest.from_json! "{…}"
|
88
|
+
# puts password_generator_request.avoid_ambiguous
|
89
|
+
#
|
81
90
|
# response_for_api_key_login_response = ResponseForAPIKeyLoginResponse.from_json! "{…}"
|
82
91
|
# puts response_for_api_key_login_response.data&.authenticated
|
83
92
|
#
|
@@ -150,6 +159,12 @@
|
|
150
159
|
# secret_delete_response = SecretDeleteResponse.from_json! "{…}"
|
151
160
|
# puts secret_delete_response.error.nil?
|
152
161
|
#
|
162
|
+
# response_for_secrets_sync_response = ResponseForSecretsSyncResponse.from_json! "{…}"
|
163
|
+
# puts response_for_secrets_sync_response.data&.has_changes
|
164
|
+
#
|
165
|
+
# secrets_sync_response = SecretsSyncResponse.from_json! "{…}"
|
166
|
+
# puts secrets_sync_response.has_changes
|
167
|
+
#
|
153
168
|
# response_for_project_response = ResponseForProjectResponse.from_json! "{…}"
|
154
169
|
# puts response_for_project_response.data&.creation_date
|
155
170
|
#
|
@@ -171,6 +186,9 @@
|
|
171
186
|
# project_delete_response = ProjectDeleteResponse.from_json! "{…}"
|
172
187
|
# puts project_delete_response.error.nil?
|
173
188
|
#
|
189
|
+
# response_for_string = ResponseForString.from_json! "{…}"
|
190
|
+
# puts response_for_string.data.nil?
|
191
|
+
#
|
174
192
|
# response_for_fingerprint_response = ResponseForFingerprintResponse.from_json! "{…}"
|
175
193
|
# puts response_for_fingerprint_response.data&.fingerprint
|
176
194
|
#
|
@@ -178,10 +196,10 @@
|
|
178
196
|
# puts fingerprint_response.fingerprint
|
179
197
|
#
|
180
198
|
# response_for_sync_response = ResponseForSyncResponse.from_json! "{…}"
|
181
|
-
# puts response_for_sync_response.data&.
|
199
|
+
# puts response_for_sync_response.data&.profile.organizations.first.id
|
182
200
|
#
|
183
201
|
# sync_response = SyncResponse.from_json! "{…}"
|
184
|
-
# puts sync_response.
|
202
|
+
# puts sync_response.profile.organizations.first.id
|
185
203
|
#
|
186
204
|
# profile_response = ProfileResponse.from_json! "{…}"
|
187
205
|
# puts profile_response.organizations.first.id
|
@@ -213,6 +231,9 @@
|
|
213
231
|
# uri_match_type = URIMatchType.from_json! "…"
|
214
232
|
# puts uri_match_type == URIMatchType::Domain
|
215
233
|
#
|
234
|
+
# fido2_credential = Fido2Credential.from_json! "{…}"
|
235
|
+
# puts fido2_credential.counter
|
236
|
+
#
|
216
237
|
# identity = Identity.from_json! "{…}"
|
217
238
|
# puts identity.address1.nil?
|
218
239
|
#
|
@@ -261,24 +282,6 @@
|
|
261
282
|
# global_domains = GlobalDomains.from_json! "{…}"
|
262
283
|
# puts global_domains.domains.first
|
263
284
|
#
|
264
|
-
# policy = Policy.from_json! "{…}"
|
265
|
-
# puts policy.data&["…"]
|
266
|
-
#
|
267
|
-
# policy_type = PolicyType.from_json! "…"
|
268
|
-
# puts policy_type == PolicyType::ActivateAutofill
|
269
|
-
#
|
270
|
-
# send = Send.from_json! "{…}"
|
271
|
-
# puts send.access_count.even?
|
272
|
-
#
|
273
|
-
# send_type = SendType.from_json! "…"
|
274
|
-
# puts send_type == SendType::File
|
275
|
-
#
|
276
|
-
# send_file = SendFile.from_json! "{…}"
|
277
|
-
# puts send_file.file_name
|
278
|
-
#
|
279
|
-
# send_text = SendText.from_json! "{…}"
|
280
|
-
# puts send_text.hidden
|
281
|
-
#
|
282
285
|
# response_for_user_api_key_response = ResponseForUserAPIKeyResponse.from_json! "{…}"
|
283
286
|
# puts response_for_user_api_key_response.data&.api_key
|
284
287
|
#
|
@@ -307,8 +310,6 @@ module Types
|
|
307
310
|
URIMatchType = Strict::String.enum("domain", "exact", "host", "never", "regularExpression", "startsWith")
|
308
311
|
CipherRepromptType = Strict::String.enum("None", "Password")
|
309
312
|
SecureNoteType = Strict::String.enum("Generic")
|
310
|
-
PolicyType = Strict::String.enum("ActivateAutofill", "DisablePersonalVaultExport", "DisableSend", "MasterPassword", "MaximumVaultTimeout", "PasswordGenerator", "PersonalOwnership", "RequireSso", "ResetPassword", "SendOptions", "SingleOrg", "TwoFactorAuthentication")
|
311
|
-
SendType = Strict::String.enum("File", "Text")
|
312
313
|
LoginLinkedIDType = Strict::String.enum("Password", "Username")
|
313
314
|
CardLinkedIDType = Strict::String.enum("Brand", "CardholderName", "Code", "ExpMonth", "ExpYear", "Number")
|
314
315
|
IdentityLinkedIDType = Strict::String.enum("Address1", "Address2", "Address3", "City", "Company", "Country", "Email", "FirstName", "FullName", "LastName", "LicenseNumber", "MiddleName", "PassportNumber", "Phone", "PostalCode", "Ssn", "State", "Title", "Username")
|
@@ -346,8 +347,8 @@ end
|
|
346
347
|
#
|
347
348
|
# Defaults to
|
348
349
|
#
|
349
|
-
# ``` # use
|
350
|
-
#
|
350
|
+
# ``` # use bitwarden_core::{ClientSettings, DeviceType}; let settings = ClientSettings {
|
351
|
+
# identity_url: "https://identity.bitwarden.com".to_string(), api_url:
|
351
352
|
# "https://api.bitwarden.com".to_string(), user_agent: "Bitwarden Rust-SDK".to_string(),
|
352
353
|
# device_type: DeviceType::SDK, }; let default = ClientSettings::default(); ```
|
353
354
|
class ClientSettings < Dry::Struct
|
@@ -393,38 +394,6 @@ class ClientSettings < Dry::Struct
|
|
393
394
|
end
|
394
395
|
end
|
395
396
|
|
396
|
-
# Login to Bitwarden with access token
|
397
|
-
class AccessTokenLoginRequest < Dry::Struct
|
398
|
-
|
399
|
-
# Bitwarden service API access token
|
400
|
-
attribute :access_token, Types::String
|
401
|
-
|
402
|
-
attribute :state_file, Types::String.optional.optional
|
403
|
-
|
404
|
-
def self.from_dynamic!(d)
|
405
|
-
d = Types::Hash[d]
|
406
|
-
new(
|
407
|
-
access_token: d.fetch("accessToken"),
|
408
|
-
state_file: d["stateFile"],
|
409
|
-
)
|
410
|
-
end
|
411
|
-
|
412
|
-
def self.from_json!(json)
|
413
|
-
from_dynamic!(JSON.parse(json))
|
414
|
-
end
|
415
|
-
|
416
|
-
def to_dynamic
|
417
|
-
{
|
418
|
-
"accessToken" => access_token,
|
419
|
-
"stateFile" => state_file,
|
420
|
-
}
|
421
|
-
end
|
422
|
-
|
423
|
-
def to_json(options = nil)
|
424
|
-
JSON.generate(to_dynamic, options)
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
428
397
|
# Login to Bitwarden with Api Key
|
429
398
|
class APIKeyLoginRequest < Dry::Struct
|
430
399
|
|
@@ -495,6 +464,113 @@ class FingerprintRequest < Dry::Struct
|
|
495
464
|
end
|
496
465
|
end
|
497
466
|
|
467
|
+
# Password generator request options.
|
468
|
+
class PasswordGeneratorRequest < Dry::Struct
|
469
|
+
|
470
|
+
# When set to true, the generated password will not contain ambiguous characters. The
|
471
|
+
# ambiguous characters are: I, O, l, 0, 1
|
472
|
+
attribute :avoid_ambiguous, Types::Bool
|
473
|
+
|
474
|
+
# The length of the generated password. Note that the password length must be greater than
|
475
|
+
# the sum of all the minimums.
|
476
|
+
attribute :length, Types::Integer
|
477
|
+
|
478
|
+
# Include lowercase characters (a-z).
|
479
|
+
attribute :lowercase, Types::Bool
|
480
|
+
|
481
|
+
# The minimum number of lowercase characters in the generated password. When set, the value
|
482
|
+
# must be between 1 and 9. This value is ignored if lowercase is false.
|
483
|
+
attribute :min_lowercase, Types::Integer.optional.optional
|
484
|
+
|
485
|
+
# The minimum number of numbers in the generated password. When set, the value must be
|
486
|
+
# between 1 and 9. This value is ignored if numbers is false.
|
487
|
+
attribute :min_number, Types::Integer.optional.optional
|
488
|
+
|
489
|
+
# The minimum number of special characters in the generated password. When set, the value
|
490
|
+
# must be between 1 and 9. This value is ignored if special is false.
|
491
|
+
attribute :min_special, Types::Integer.optional.optional
|
492
|
+
|
493
|
+
# The minimum number of uppercase characters in the generated password. When set, the value
|
494
|
+
# must be between 1 and 9. This value is ignored if uppercase is false.
|
495
|
+
attribute :min_uppercase, Types::Integer.optional.optional
|
496
|
+
|
497
|
+
# Include numbers (0-9).
|
498
|
+
attribute :numbers, Types::Bool
|
499
|
+
|
500
|
+
# Include special characters: ! @ # $ % ^ & *
|
501
|
+
attribute :special, Types::Bool
|
502
|
+
|
503
|
+
# Include uppercase characters (A-Z).
|
504
|
+
attribute :uppercase, Types::Bool
|
505
|
+
|
506
|
+
def self.from_dynamic!(d)
|
507
|
+
d = Types::Hash[d]
|
508
|
+
new(
|
509
|
+
avoid_ambiguous: d.fetch("avoidAmbiguous"),
|
510
|
+
length: d.fetch("length"),
|
511
|
+
lowercase: d.fetch("lowercase"),
|
512
|
+
min_lowercase: d["minLowercase"],
|
513
|
+
min_number: d["minNumber"],
|
514
|
+
min_special: d["minSpecial"],
|
515
|
+
min_uppercase: d["minUppercase"],
|
516
|
+
numbers: d.fetch("numbers"),
|
517
|
+
special: d.fetch("special"),
|
518
|
+
uppercase: d.fetch("uppercase"),
|
519
|
+
)
|
520
|
+
end
|
521
|
+
|
522
|
+
def self.from_json!(json)
|
523
|
+
from_dynamic!(JSON.parse(json))
|
524
|
+
end
|
525
|
+
|
526
|
+
def to_dynamic
|
527
|
+
{
|
528
|
+
"avoidAmbiguous" => avoid_ambiguous,
|
529
|
+
"length" => length,
|
530
|
+
"lowercase" => lowercase,
|
531
|
+
"minLowercase" => min_lowercase,
|
532
|
+
"minNumber" => min_number,
|
533
|
+
"minSpecial" => min_special,
|
534
|
+
"minUppercase" => min_uppercase,
|
535
|
+
"numbers" => numbers,
|
536
|
+
"special" => special,
|
537
|
+
"uppercase" => uppercase,
|
538
|
+
}
|
539
|
+
end
|
540
|
+
|
541
|
+
def to_json(options = nil)
|
542
|
+
JSON.generate(to_dynamic, options)
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
# Generate a password
|
547
|
+
#
|
548
|
+
# Returns: [String]
|
549
|
+
class GeneratorsCommand < Dry::Struct
|
550
|
+
attribute :generate_password, PasswordGeneratorRequest
|
551
|
+
|
552
|
+
def self.from_dynamic!(d)
|
553
|
+
d = Types::Hash[d]
|
554
|
+
new(
|
555
|
+
generate_password: PasswordGeneratorRequest.from_dynamic!(d.fetch("generatePassword")),
|
556
|
+
)
|
557
|
+
end
|
558
|
+
|
559
|
+
def self.from_json!(json)
|
560
|
+
from_dynamic!(JSON.parse(json))
|
561
|
+
end
|
562
|
+
|
563
|
+
def to_dynamic
|
564
|
+
{
|
565
|
+
"generatePassword" => generate_password.to_dynamic,
|
566
|
+
}
|
567
|
+
end
|
568
|
+
|
569
|
+
def to_json(options = nil)
|
570
|
+
JSON.generate(to_dynamic, options)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
498
574
|
class SecretVerificationRequest < Dry::Struct
|
499
575
|
|
500
576
|
# The user's master password to use for user verification. If supplied, this will be used
|
@@ -530,6 +606,38 @@ class SecretVerificationRequest < Dry::Struct
|
|
530
606
|
end
|
531
607
|
end
|
532
608
|
|
609
|
+
# Login to Bitwarden with access token
|
610
|
+
class AccessTokenLoginRequest < Dry::Struct
|
611
|
+
|
612
|
+
# Bitwarden service API access token
|
613
|
+
attribute :access_token, Types::String
|
614
|
+
|
615
|
+
attribute :state_file, Types::String.optional.optional
|
616
|
+
|
617
|
+
def self.from_dynamic!(d)
|
618
|
+
d = Types::Hash[d]
|
619
|
+
new(
|
620
|
+
access_token: d.fetch("accessToken"),
|
621
|
+
state_file: d["stateFile"],
|
622
|
+
)
|
623
|
+
end
|
624
|
+
|
625
|
+
def self.from_json!(json)
|
626
|
+
from_dynamic!(JSON.parse(json))
|
627
|
+
end
|
628
|
+
|
629
|
+
def to_dynamic
|
630
|
+
{
|
631
|
+
"accessToken" => access_token,
|
632
|
+
"stateFile" => state_file,
|
633
|
+
}
|
634
|
+
end
|
635
|
+
|
636
|
+
def to_json(options = nil)
|
637
|
+
JSON.generate(to_dynamic, options)
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
533
641
|
class Argon2ID < Dry::Struct
|
534
642
|
attribute :iterations, Types::Integer
|
535
643
|
attribute :memory, Types::Integer
|
@@ -587,6 +695,11 @@ class PBKDF2 < Dry::Struct
|
|
587
695
|
end
|
588
696
|
|
589
697
|
# Kdf from prelogin
|
698
|
+
#
|
699
|
+
# Key Derivation Function for Bitwarden Account
|
700
|
+
#
|
701
|
+
# In Bitwarden accounts can use multiple KDFs to derive their master key from their
|
702
|
+
# password. This Enum represents all the possible KDFs.
|
590
703
|
class Kdf < Dry::Struct
|
591
704
|
attribute :p_bkdf2, PBKDF2.optional
|
592
705
|
attribute :argon2_id, Argon2ID.optional
|
@@ -1065,6 +1178,38 @@ class SecretIdentifiersRequest < Dry::Struct
|
|
1065
1178
|
end
|
1066
1179
|
end
|
1067
1180
|
|
1181
|
+
class SecretsSyncRequest < Dry::Struct
|
1182
|
+
|
1183
|
+
# Optional date time a sync last occurred
|
1184
|
+
attribute :last_synced_date, Types::String.optional.optional
|
1185
|
+
|
1186
|
+
# Organization to sync secrets from
|
1187
|
+
attribute :organization_id, Types::String
|
1188
|
+
|
1189
|
+
def self.from_dynamic!(d)
|
1190
|
+
d = Types::Hash[d]
|
1191
|
+
new(
|
1192
|
+
last_synced_date: d["lastSyncedDate"],
|
1193
|
+
organization_id: d.fetch("organizationId"),
|
1194
|
+
)
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
def self.from_json!(json)
|
1198
|
+
from_dynamic!(JSON.parse(json))
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
def to_dynamic
|
1202
|
+
{
|
1203
|
+
"lastSyncedDate" => last_synced_date,
|
1204
|
+
"organizationId" => organization_id,
|
1205
|
+
}
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
def to_json(options = nil)
|
1209
|
+
JSON.generate(to_dynamic, options)
|
1210
|
+
end
|
1211
|
+
end
|
1212
|
+
|
1068
1213
|
class SecretPutRequest < Dry::Struct
|
1069
1214
|
|
1070
1215
|
# ID of the secret to modify
|
@@ -1143,6 +1288,13 @@ end
|
|
1143
1288
|
#
|
1144
1289
|
# Returns:
|
1145
1290
|
# [SecretsDeleteResponse](bitwarden::secrets_manager::secrets::SecretsDeleteResponse)
|
1291
|
+
#
|
1292
|
+
# > Requires Authentication > Requires using an Access Token for login Retrieve the secrets
|
1293
|
+
# accessible by the authenticated machine account Optionally, provide the last synced date
|
1294
|
+
# to assess whether any changes have occurred If changes are detected, retrieves all the
|
1295
|
+
# secrets accessible by the authenticated machine account
|
1296
|
+
#
|
1297
|
+
# Returns: [SecretsSyncResponse](bitwarden::secrets_manager::secrets::SecretsSyncResponse)
|
1146
1298
|
class SecretsCommand < Dry::Struct
|
1147
1299
|
attribute :get, SecretGetRequest.optional
|
1148
1300
|
attribute :get_by_ids, SecretsGetRequest.optional
|
@@ -1150,6 +1302,7 @@ class SecretsCommand < Dry::Struct
|
|
1150
1302
|
attribute :list, SecretIdentifiersRequest.optional
|
1151
1303
|
attribute :update, SecretPutRequest.optional
|
1152
1304
|
attribute :delete, SecretsDeleteRequest.optional
|
1305
|
+
attribute :sync, SecretsSyncRequest.optional
|
1153
1306
|
|
1154
1307
|
def self.from_dynamic!(d)
|
1155
1308
|
d = Types::Hash[d]
|
@@ -1160,6 +1313,7 @@ class SecretsCommand < Dry::Struct
|
|
1160
1313
|
list: d["list"] ? SecretIdentifiersRequest.from_dynamic!(d["list"]) : nil,
|
1161
1314
|
update: d["update"] ? SecretPutRequest.from_dynamic!(d["update"]) : nil,
|
1162
1315
|
delete: d["delete"] ? SecretsDeleteRequest.from_dynamic!(d["delete"]) : nil,
|
1316
|
+
sync: d["sync"] ? SecretsSyncRequest.from_dynamic!(d["sync"]) : nil,
|
1163
1317
|
)
|
1164
1318
|
end
|
1165
1319
|
|
@@ -1175,6 +1329,7 @@ class SecretsCommand < Dry::Struct
|
|
1175
1329
|
"list" => list&.to_dynamic,
|
1176
1330
|
"update" => update&.to_dynamic,
|
1177
1331
|
"delete" => delete&.to_dynamic,
|
1332
|
+
"sync" => sync&.to_dynamic,
|
1178
1333
|
}
|
1179
1334
|
end
|
1180
1335
|
|
@@ -1243,28 +1398,30 @@ end
|
|
1243
1398
|
# > Requires Authentication Retrieve all user data, ciphers and organizations the user is a
|
1244
1399
|
# part of
|
1245
1400
|
#
|
1246
|
-
# Returns: [SyncResponse](bitwarden::
|
1401
|
+
# Returns: [SyncResponse](bitwarden::vault::SyncResponse)
|
1247
1402
|
class Command < Dry::Struct
|
1248
1403
|
attribute :password_login, PasswordLoginRequest.optional
|
1249
1404
|
attribute :api_key_login, APIKeyLoginRequest.optional
|
1250
|
-
attribute :
|
1405
|
+
attribute :login_access_token, AccessTokenLoginRequest.optional
|
1251
1406
|
attribute :get_user_api_key, SecretVerificationRequest.optional
|
1252
1407
|
attribute :fingerprint, FingerprintRequest.optional
|
1253
1408
|
attribute :sync, SyncRequest.optional
|
1254
1409
|
attribute :secrets, SecretsCommand.optional
|
1255
1410
|
attribute :projects, ProjectsCommand.optional
|
1411
|
+
attribute :generators, GeneratorsCommand.optional
|
1256
1412
|
|
1257
1413
|
def self.from_dynamic!(d)
|
1258
1414
|
d = Types::Hash[d]
|
1259
1415
|
new(
|
1260
1416
|
password_login: d["passwordLogin"] ? PasswordLoginRequest.from_dynamic!(d["passwordLogin"]) : nil,
|
1261
1417
|
api_key_login: d["apiKeyLogin"] ? APIKeyLoginRequest.from_dynamic!(d["apiKeyLogin"]) : nil,
|
1262
|
-
|
1418
|
+
login_access_token: d["loginAccessToken"] ? AccessTokenLoginRequest.from_dynamic!(d["loginAccessToken"]) : nil,
|
1263
1419
|
get_user_api_key: d["getUserApiKey"] ? SecretVerificationRequest.from_dynamic!(d["getUserApiKey"]) : nil,
|
1264
1420
|
fingerprint: d["fingerprint"] ? FingerprintRequest.from_dynamic!(d["fingerprint"]) : nil,
|
1265
1421
|
sync: d["sync"] ? SyncRequest.from_dynamic!(d["sync"]) : nil,
|
1266
1422
|
secrets: d["secrets"] ? SecretsCommand.from_dynamic!(d["secrets"]) : nil,
|
1267
1423
|
projects: d["projects"] ? ProjectsCommand.from_dynamic!(d["projects"]) : nil,
|
1424
|
+
generators: d["generators"] ? GeneratorsCommand.from_dynamic!(d["generators"]) : nil,
|
1268
1425
|
)
|
1269
1426
|
end
|
1270
1427
|
|
@@ -1276,12 +1433,13 @@ class Command < Dry::Struct
|
|
1276
1433
|
{
|
1277
1434
|
"passwordLogin" => password_login&.to_dynamic,
|
1278
1435
|
"apiKeyLogin" => api_key_login&.to_dynamic,
|
1279
|
-
"
|
1436
|
+
"loginAccessToken" => login_access_token&.to_dynamic,
|
1280
1437
|
"getUserApiKey" => get_user_api_key&.to_dynamic,
|
1281
1438
|
"fingerprint" => fingerprint&.to_dynamic,
|
1282
1439
|
"sync" => sync&.to_dynamic,
|
1283
1440
|
"secrets" => secrets&.to_dynamic,
|
1284
1441
|
"projects" => projects&.to_dynamic,
|
1442
|
+
"generators" => generators&.to_dynamic,
|
1285
1443
|
}
|
1286
1444
|
end
|
1287
1445
|
|
@@ -2084,6 +2242,71 @@ class ResponseForSecretsDeleteResponse < Dry::Struct
|
|
2084
2242
|
end
|
2085
2243
|
end
|
2086
2244
|
|
2245
|
+
class SecretsSyncResponse < Dry::Struct
|
2246
|
+
attribute :has_changes, Types::Bool
|
2247
|
+
attribute :secrets, Types.Array(SecretResponse).optional.optional
|
2248
|
+
|
2249
|
+
def self.from_dynamic!(d)
|
2250
|
+
d = Types::Hash[d]
|
2251
|
+
new(
|
2252
|
+
has_changes: d.fetch("hasChanges"),
|
2253
|
+
secrets: d["secrets"]&.map { |x| SecretResponse.from_dynamic!(x) },
|
2254
|
+
)
|
2255
|
+
end
|
2256
|
+
|
2257
|
+
def self.from_json!(json)
|
2258
|
+
from_dynamic!(JSON.parse(json))
|
2259
|
+
end
|
2260
|
+
|
2261
|
+
def to_dynamic
|
2262
|
+
{
|
2263
|
+
"hasChanges" => has_changes,
|
2264
|
+
"secrets" => secrets&.map { |x| x.to_dynamic },
|
2265
|
+
}
|
2266
|
+
end
|
2267
|
+
|
2268
|
+
def to_json(options = nil)
|
2269
|
+
JSON.generate(to_dynamic, options)
|
2270
|
+
end
|
2271
|
+
end
|
2272
|
+
|
2273
|
+
class ResponseForSecretsSyncResponse < Dry::Struct
|
2274
|
+
|
2275
|
+
# The response data. Populated if `success` is true.
|
2276
|
+
attribute :data, SecretsSyncResponse.optional.optional
|
2277
|
+
|
2278
|
+
# A message for any error that may occur. Populated if `success` is false.
|
2279
|
+
attribute :error_message, Types::String.optional.optional
|
2280
|
+
|
2281
|
+
# Whether or not the SDK request succeeded.
|
2282
|
+
attribute :success, Types::Bool
|
2283
|
+
|
2284
|
+
def self.from_dynamic!(d)
|
2285
|
+
d = Types::Hash[d]
|
2286
|
+
new(
|
2287
|
+
data: d["data"] ? SecretsSyncResponse.from_dynamic!(d["data"]) : nil,
|
2288
|
+
error_message: d["errorMessage"],
|
2289
|
+
success: d.fetch("success"),
|
2290
|
+
)
|
2291
|
+
end
|
2292
|
+
|
2293
|
+
def self.from_json!(json)
|
2294
|
+
from_dynamic!(JSON.parse(json))
|
2295
|
+
end
|
2296
|
+
|
2297
|
+
def to_dynamic
|
2298
|
+
{
|
2299
|
+
"data" => data&.to_dynamic,
|
2300
|
+
"errorMessage" => error_message,
|
2301
|
+
"success" => success,
|
2302
|
+
}
|
2303
|
+
end
|
2304
|
+
|
2305
|
+
def to_json(options = nil)
|
2306
|
+
JSON.generate(to_dynamic, options)
|
2307
|
+
end
|
2308
|
+
end
|
2309
|
+
|
2087
2310
|
class ProjectResponse < Dry::Struct
|
2088
2311
|
attribute :creation_date, Types::String
|
2089
2312
|
attribute :id, Types::String
|
@@ -2310,6 +2533,43 @@ class ResponseForProjectsDeleteResponse < Dry::Struct
|
|
2310
2533
|
end
|
2311
2534
|
end
|
2312
2535
|
|
2536
|
+
class ResponseForString < Dry::Struct
|
2537
|
+
|
2538
|
+
# The response data. Populated if `success` is true.
|
2539
|
+
attribute :data, Types::String.optional.optional
|
2540
|
+
|
2541
|
+
# A message for any error that may occur. Populated if `success` is false.
|
2542
|
+
attribute :error_message, Types::String.optional.optional
|
2543
|
+
|
2544
|
+
# Whether or not the SDK request succeeded.
|
2545
|
+
attribute :success, Types::Bool
|
2546
|
+
|
2547
|
+
def self.from_dynamic!(d)
|
2548
|
+
d = Types::Hash[d]
|
2549
|
+
new(
|
2550
|
+
data: d["data"],
|
2551
|
+
error_message: d["errorMessage"],
|
2552
|
+
success: d.fetch("success"),
|
2553
|
+
)
|
2554
|
+
end
|
2555
|
+
|
2556
|
+
def self.from_json!(json)
|
2557
|
+
from_dynamic!(JSON.parse(json))
|
2558
|
+
end
|
2559
|
+
|
2560
|
+
def to_dynamic
|
2561
|
+
{
|
2562
|
+
"data" => data,
|
2563
|
+
"errorMessage" => error_message,
|
2564
|
+
"success" => success,
|
2565
|
+
}
|
2566
|
+
end
|
2567
|
+
|
2568
|
+
def to_json(options = nil)
|
2569
|
+
JSON.generate(to_dynamic, options)
|
2570
|
+
end
|
2571
|
+
end
|
2572
|
+
|
2313
2573
|
class FingerprintResponse < Dry::Struct
|
2314
2574
|
attribute :fingerprint, Types::String
|
2315
2575
|
|
@@ -2636,6 +2896,67 @@ class LocalData < Dry::Struct
|
|
2636
2896
|
end
|
2637
2897
|
end
|
2638
2898
|
|
2899
|
+
class Fido2Credential < Dry::Struct
|
2900
|
+
attribute :counter, Types::String
|
2901
|
+
attribute :creation_date, Types::String
|
2902
|
+
attribute :credential_id, Types::String
|
2903
|
+
attribute :discoverable, Types::String
|
2904
|
+
attribute :key_algorithm, Types::String
|
2905
|
+
attribute :key_curve, Types::String
|
2906
|
+
attribute :key_type, Types::String
|
2907
|
+
attribute :key_value, Types::String
|
2908
|
+
attribute :rp_id, Types::String
|
2909
|
+
attribute :rp_name, Types::String.optional.optional
|
2910
|
+
attribute :user_display_name, Types::String.optional.optional
|
2911
|
+
attribute :user_handle, Types::String.optional.optional
|
2912
|
+
attribute :user_name, Types::String.optional.optional
|
2913
|
+
|
2914
|
+
def self.from_dynamic!(d)
|
2915
|
+
d = Types::Hash[d]
|
2916
|
+
new(
|
2917
|
+
counter: d.fetch("counter"),
|
2918
|
+
creation_date: d.fetch("creationDate"),
|
2919
|
+
credential_id: d.fetch("credentialId"),
|
2920
|
+
discoverable: d.fetch("discoverable"),
|
2921
|
+
key_algorithm: d.fetch("keyAlgorithm"),
|
2922
|
+
key_curve: d.fetch("keyCurve"),
|
2923
|
+
key_type: d.fetch("keyType"),
|
2924
|
+
key_value: d.fetch("keyValue"),
|
2925
|
+
rp_id: d.fetch("rpId"),
|
2926
|
+
rp_name: d["rpName"],
|
2927
|
+
user_display_name: d["userDisplayName"],
|
2928
|
+
user_handle: d["userHandle"],
|
2929
|
+
user_name: d["userName"],
|
2930
|
+
)
|
2931
|
+
end
|
2932
|
+
|
2933
|
+
def self.from_json!(json)
|
2934
|
+
from_dynamic!(JSON.parse(json))
|
2935
|
+
end
|
2936
|
+
|
2937
|
+
def to_dynamic
|
2938
|
+
{
|
2939
|
+
"counter" => counter,
|
2940
|
+
"creationDate" => creation_date,
|
2941
|
+
"credentialId" => credential_id,
|
2942
|
+
"discoverable" => discoverable,
|
2943
|
+
"keyAlgorithm" => key_algorithm,
|
2944
|
+
"keyCurve" => key_curve,
|
2945
|
+
"keyType" => key_type,
|
2946
|
+
"keyValue" => key_value,
|
2947
|
+
"rpId" => rp_id,
|
2948
|
+
"rpName" => rp_name,
|
2949
|
+
"userDisplayName" => user_display_name,
|
2950
|
+
"userHandle" => user_handle,
|
2951
|
+
"userName" => user_name,
|
2952
|
+
}
|
2953
|
+
end
|
2954
|
+
|
2955
|
+
def to_json(options = nil)
|
2956
|
+
JSON.generate(to_dynamic, options)
|
2957
|
+
end
|
2958
|
+
end
|
2959
|
+
|
2639
2960
|
module URIMatchType
|
2640
2961
|
Domain = "domain"
|
2641
2962
|
Exact = "exact"
|
@@ -2646,14 +2967,16 @@ module URIMatchType
|
|
2646
2967
|
end
|
2647
2968
|
|
2648
2969
|
class LoginURI < Dry::Struct
|
2649
|
-
attribute :match,
|
2650
|
-
attribute :uri,
|
2970
|
+
attribute :match, Types::URIMatchType.optional.optional
|
2971
|
+
attribute :uri, Types::String.optional.optional
|
2972
|
+
attribute :uri_checksum, Types::String.optional.optional
|
2651
2973
|
|
2652
2974
|
def self.from_dynamic!(d)
|
2653
2975
|
d = Types::Hash[d]
|
2654
2976
|
new(
|
2655
|
-
match:
|
2656
|
-
uri:
|
2977
|
+
match: d["match"],
|
2978
|
+
uri: d["uri"],
|
2979
|
+
uri_checksum: d["uriChecksum"],
|
2657
2980
|
)
|
2658
2981
|
end
|
2659
2982
|
|
@@ -2663,8 +2986,9 @@ class LoginURI < Dry::Struct
|
|
2663
2986
|
|
2664
2987
|
def to_dynamic
|
2665
2988
|
{
|
2666
|
-
"match"
|
2667
|
-
"uri"
|
2989
|
+
"match" => match,
|
2990
|
+
"uri" => uri,
|
2991
|
+
"uriChecksum" => uri_checksum,
|
2668
2992
|
}
|
2669
2993
|
end
|
2670
2994
|
|
@@ -2675,6 +2999,7 @@ end
|
|
2675
2999
|
|
2676
3000
|
class Login < Dry::Struct
|
2677
3001
|
attribute :autofill_on_page_load, Types::Bool.optional.optional
|
3002
|
+
attribute :fido2_credentials, Types.Array(Fido2Credential).optional.optional
|
2678
3003
|
attribute :password, Types::String.optional.optional
|
2679
3004
|
attribute :password_revision_date, Types::String.optional.optional
|
2680
3005
|
attribute :totp, Types::String.optional.optional
|
@@ -2685,6 +3010,7 @@ class Login < Dry::Struct
|
|
2685
3010
|
d = Types::Hash[d]
|
2686
3011
|
new(
|
2687
3012
|
autofill_on_page_load: d["autofillOnPageLoad"],
|
3013
|
+
fido2_credentials: d["fido2Credentials"]&.map { |x| Fido2Credential.from_dynamic!(x) },
|
2688
3014
|
password: d["password"],
|
2689
3015
|
password_revision_date: d["passwordRevisionDate"],
|
2690
3016
|
totp: d["totp"],
|
@@ -2700,6 +3026,7 @@ class Login < Dry::Struct
|
|
2700
3026
|
def to_dynamic
|
2701
3027
|
{
|
2702
3028
|
"autofillOnPageLoad" => autofill_on_page_load,
|
3029
|
+
"fido2Credentials" => fido2_credentials&.map { |x| x.to_dynamic },
|
2703
3030
|
"password" => password,
|
2704
3031
|
"passwordRevisionDate" => password_revision_date,
|
2705
3032
|
"totp" => totp,
|
@@ -3003,58 +3330,6 @@ class Folder < Dry::Struct
|
|
3003
3330
|
end
|
3004
3331
|
end
|
3005
3332
|
|
3006
|
-
module PolicyType
|
3007
|
-
ActivateAutofill = "ActivateAutofill"
|
3008
|
-
DisablePersonalVaultExport = "DisablePersonalVaultExport"
|
3009
|
-
DisableSend = "DisableSend"
|
3010
|
-
MasterPassword = "MasterPassword"
|
3011
|
-
MaximumVaultTimeout = "MaximumVaultTimeout"
|
3012
|
-
PasswordGenerator = "PasswordGenerator"
|
3013
|
-
PersonalOwnership = "PersonalOwnership"
|
3014
|
-
RequireSso = "RequireSso"
|
3015
|
-
ResetPassword = "ResetPassword"
|
3016
|
-
SendOptions = "SendOptions"
|
3017
|
-
SingleOrg = "SingleOrg"
|
3018
|
-
TwoFactorAuthentication = "TwoFactorAuthentication"
|
3019
|
-
end
|
3020
|
-
|
3021
|
-
class Policy < Dry::Struct
|
3022
|
-
attribute :data, Types::Hash.meta(of: Types::Any).optional.optional
|
3023
|
-
attribute :enabled, Types::Bool
|
3024
|
-
attribute :id, Types::String
|
3025
|
-
attribute :organization_id, Types::String
|
3026
|
-
attribute :policy_type, Types::PolicyType
|
3027
|
-
|
3028
|
-
def self.from_dynamic!(d)
|
3029
|
-
d = Types::Hash[d]
|
3030
|
-
new(
|
3031
|
-
data: Types::Hash.optional[d["data"]]&.map { |k, v| [k, Types::Any[v]] }&.to_h,
|
3032
|
-
enabled: d.fetch("enabled"),
|
3033
|
-
id: d.fetch("id"),
|
3034
|
-
organization_id: d.fetch("organization_id"),
|
3035
|
-
policy_type: d.fetch("type"),
|
3036
|
-
)
|
3037
|
-
end
|
3038
|
-
|
3039
|
-
def self.from_json!(json)
|
3040
|
-
from_dynamic!(JSON.parse(json))
|
3041
|
-
end
|
3042
|
-
|
3043
|
-
def to_dynamic
|
3044
|
-
{
|
3045
|
-
"data" => data,
|
3046
|
-
"enabled" => enabled,
|
3047
|
-
"id" => id,
|
3048
|
-
"organization_id" => organization_id,
|
3049
|
-
"type" => policy_type,
|
3050
|
-
}
|
3051
|
-
end
|
3052
|
-
|
3053
|
-
def to_json(options = nil)
|
3054
|
-
JSON.generate(to_dynamic, options)
|
3055
|
-
end
|
3056
|
-
end
|
3057
|
-
|
3058
3333
|
class ProfileOrganizationResponse < Dry::Struct
|
3059
3334
|
attribute :id, Types::String
|
3060
3335
|
|
@@ -3116,145 +3391,6 @@ class ProfileResponse < Dry::Struct
|
|
3116
3391
|
end
|
3117
3392
|
end
|
3118
3393
|
|
3119
|
-
class SendFile < Dry::Struct
|
3120
|
-
attribute :file_name, Types::String
|
3121
|
-
attribute :id, Types::String.optional.optional
|
3122
|
-
attribute :size, Types::String.optional.optional
|
3123
|
-
|
3124
|
-
# Readable size, ex: "4.2 KB" or "1.43 GB"
|
3125
|
-
attribute :size_name, Types::String.optional.optional
|
3126
|
-
|
3127
|
-
def self.from_dynamic!(d)
|
3128
|
-
d = Types::Hash[d]
|
3129
|
-
new(
|
3130
|
-
file_name: d.fetch("fileName"),
|
3131
|
-
id: d["id"],
|
3132
|
-
size: d["size"],
|
3133
|
-
size_name: d["sizeName"],
|
3134
|
-
)
|
3135
|
-
end
|
3136
|
-
|
3137
|
-
def self.from_json!(json)
|
3138
|
-
from_dynamic!(JSON.parse(json))
|
3139
|
-
end
|
3140
|
-
|
3141
|
-
def to_dynamic
|
3142
|
-
{
|
3143
|
-
"fileName" => file_name,
|
3144
|
-
"id" => id,
|
3145
|
-
"size" => size,
|
3146
|
-
"sizeName" => size_name,
|
3147
|
-
}
|
3148
|
-
end
|
3149
|
-
|
3150
|
-
def to_json(options = nil)
|
3151
|
-
JSON.generate(to_dynamic, options)
|
3152
|
-
end
|
3153
|
-
end
|
3154
|
-
|
3155
|
-
module SendType
|
3156
|
-
File = "File"
|
3157
|
-
Text = "Text"
|
3158
|
-
end
|
3159
|
-
|
3160
|
-
class SendText < Dry::Struct
|
3161
|
-
attribute :hidden, Types::Bool
|
3162
|
-
attribute :text, Types::String.optional.optional
|
3163
|
-
|
3164
|
-
def self.from_dynamic!(d)
|
3165
|
-
d = Types::Hash[d]
|
3166
|
-
new(
|
3167
|
-
hidden: d.fetch("hidden"),
|
3168
|
-
text: d["text"],
|
3169
|
-
)
|
3170
|
-
end
|
3171
|
-
|
3172
|
-
def self.from_json!(json)
|
3173
|
-
from_dynamic!(JSON.parse(json))
|
3174
|
-
end
|
3175
|
-
|
3176
|
-
def to_dynamic
|
3177
|
-
{
|
3178
|
-
"hidden" => hidden,
|
3179
|
-
"text" => text,
|
3180
|
-
}
|
3181
|
-
end
|
3182
|
-
|
3183
|
-
def to_json(options = nil)
|
3184
|
-
JSON.generate(to_dynamic, options)
|
3185
|
-
end
|
3186
|
-
end
|
3187
|
-
|
3188
|
-
class Send < Dry::Struct
|
3189
|
-
attribute :access_count, Types::Integer
|
3190
|
-
attribute :access_id, Types::String.optional.optional
|
3191
|
-
attribute :deletion_date, Types::String
|
3192
|
-
attribute :disabled, Types::Bool
|
3193
|
-
attribute :expiration_date, Types::String.optional.optional
|
3194
|
-
attribute :file, SendFile.optional.optional
|
3195
|
-
attribute :hide_email, Types::Bool
|
3196
|
-
attribute :id, Types::String.optional.optional
|
3197
|
-
attribute :key, Types::String
|
3198
|
-
attribute :max_access_count, Types::Integer.optional.optional
|
3199
|
-
attribute :send_name, Types::String
|
3200
|
-
attribute :notes, Types::String.optional.optional
|
3201
|
-
attribute :password, Types::String.optional.optional
|
3202
|
-
attribute :revision_date, Types::String
|
3203
|
-
attribute :text, SendText.optional.optional
|
3204
|
-
attribute :send_type, Types::SendType
|
3205
|
-
|
3206
|
-
def self.from_dynamic!(d)
|
3207
|
-
d = Types::Hash[d]
|
3208
|
-
new(
|
3209
|
-
access_count: d.fetch("accessCount"),
|
3210
|
-
access_id: d["accessId"],
|
3211
|
-
deletion_date: d.fetch("deletionDate"),
|
3212
|
-
disabled: d.fetch("disabled"),
|
3213
|
-
expiration_date: d["expirationDate"],
|
3214
|
-
file: d["file"] ? SendFile.from_dynamic!(d["file"]) : nil,
|
3215
|
-
hide_email: d.fetch("hideEmail"),
|
3216
|
-
id: d["id"],
|
3217
|
-
key: d.fetch("key"),
|
3218
|
-
max_access_count: d["maxAccessCount"],
|
3219
|
-
send_name: d.fetch("name"),
|
3220
|
-
notes: d["notes"],
|
3221
|
-
password: d["password"],
|
3222
|
-
revision_date: d.fetch("revisionDate"),
|
3223
|
-
text: d["text"] ? SendText.from_dynamic!(d["text"]) : nil,
|
3224
|
-
send_type: d.fetch("type"),
|
3225
|
-
)
|
3226
|
-
end
|
3227
|
-
|
3228
|
-
def self.from_json!(json)
|
3229
|
-
from_dynamic!(JSON.parse(json))
|
3230
|
-
end
|
3231
|
-
|
3232
|
-
def to_dynamic
|
3233
|
-
{
|
3234
|
-
"accessCount" => access_count,
|
3235
|
-
"accessId" => access_id,
|
3236
|
-
"deletionDate" => deletion_date,
|
3237
|
-
"disabled" => disabled,
|
3238
|
-
"expirationDate" => expiration_date,
|
3239
|
-
"file" => file&.to_dynamic,
|
3240
|
-
"hideEmail" => hide_email,
|
3241
|
-
"id" => id,
|
3242
|
-
"key" => key,
|
3243
|
-
"maxAccessCount" => max_access_count,
|
3244
|
-
"name" => send_name,
|
3245
|
-
"notes" => notes,
|
3246
|
-
"password" => password,
|
3247
|
-
"revisionDate" => revision_date,
|
3248
|
-
"text" => text&.to_dynamic,
|
3249
|
-
"type" => send_type,
|
3250
|
-
}
|
3251
|
-
end
|
3252
|
-
|
3253
|
-
def to_json(options = nil)
|
3254
|
-
JSON.generate(to_dynamic, options)
|
3255
|
-
end
|
3256
|
-
end
|
3257
|
-
|
3258
3394
|
class SyncResponse < Dry::Struct
|
3259
3395
|
|
3260
3396
|
# List of ciphers accessible by the user
|
@@ -3263,14 +3399,11 @@ class SyncResponse < Dry::Struct
|
|
3263
3399
|
attribute :collections, Types.Array(Collection)
|
3264
3400
|
attribute :domains, DomainResponse.optional.optional
|
3265
3401
|
attribute :folders, Types.Array(Folder)
|
3266
|
-
attribute :policies, Types.Array(Policy)
|
3267
3402
|
|
3268
3403
|
# Data about the user, including their encryption keys and the organizations they are a
|
3269
3404
|
# part of
|
3270
3405
|
attribute :profile, ProfileResponse
|
3271
3406
|
|
3272
|
-
attribute :sends, Types.Array(Send)
|
3273
|
-
|
3274
3407
|
def self.from_dynamic!(d)
|
3275
3408
|
d = Types::Hash[d]
|
3276
3409
|
new(
|
@@ -3278,9 +3411,7 @@ class SyncResponse < Dry::Struct
|
|
3278
3411
|
collections: d.fetch("collections").map { |x| Collection.from_dynamic!(x) },
|
3279
3412
|
domains: d["domains"] ? DomainResponse.from_dynamic!(d["domains"]) : nil,
|
3280
3413
|
folders: d.fetch("folders").map { |x| Folder.from_dynamic!(x) },
|
3281
|
-
policies: d.fetch("policies").map { |x| Policy.from_dynamic!(x) },
|
3282
3414
|
profile: ProfileResponse.from_dynamic!(d.fetch("profile")),
|
3283
|
-
sends: d.fetch("sends").map { |x| Send.from_dynamic!(x) },
|
3284
3415
|
)
|
3285
3416
|
end
|
3286
3417
|
|
@@ -3294,9 +3425,7 @@ class SyncResponse < Dry::Struct
|
|
3294
3425
|
"collections" => collections.map { |x| x.to_dynamic },
|
3295
3426
|
"domains" => domains&.to_dynamic,
|
3296
3427
|
"folders" => folders.map { |x| x.to_dynamic },
|
3297
|
-
"policies" => policies.map { |x| x.to_dynamic },
|
3298
3428
|
"profile" => profile.to_dynamic,
|
3299
|
-
"sends" => sends.map { |x| x.to_dynamic },
|
3300
3429
|
}
|
3301
3430
|
end
|
3302
3431
|
|