keeper_secrets_manager 17.0.3 → 17.0.4

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.
@@ -1,139 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/keeper_secrets_manager'
4
-
5
- # Example: Basic usage of Keeper Secrets Manager Ruby SDK
6
-
7
- # Method 1: Initialize with one-time token
8
- # token = "US:ONE_TIME_TOKEN_HERE"
9
- # secrets_manager = KeeperSecretsManager.from_token(token)
10
-
11
- # Method 2: Initialize with existing config
12
- config = KeeperSecretsManager::Storage::InMemoryStorage.new({
13
- 'hostname' => 'keepersecurity.com',
14
- 'clientId' => 'your-client-id',
15
- 'privateKey' => 'your-private-key-base64',
16
- 'appKey' => 'your-app-key-base64'
17
- })
18
- secrets_manager = KeeperSecretsManager.new(config: config)
19
-
20
- # Get all secrets
21
- begin
22
- records = secrets_manager.get_secrets
23
- puts "Found #{records.length} records"
24
-
25
- records.each do |record|
26
- puts "\nRecord: #{record.title}"
27
- puts " Type: #{record.type}"
28
- puts " UID: #{record.uid}"
29
-
30
- # Access fields dynamically
31
- if record.get_field('login')
32
- puts " Login: #{record.get_field_value_single('login')}"
33
- end
34
-
35
- if record.get_field('password')
36
- puts " Password: [HIDDEN]"
37
- end
38
- end
39
- rescue => e
40
- puts "Error: #{e.message}"
41
- end
42
-
43
- # Get specific record by UID
44
- begin
45
- record_uid = "RECORD_UID_HERE"
46
- records = secrets_manager.get_secrets([record_uid])
47
-
48
- if records.any?
49
- record = records.first
50
- puts "\nRetrieved record: #{record.title}"
51
- end
52
- rescue => e
53
- puts "Error retrieving record: #{e.message}"
54
- end
55
-
56
- # Get record by title
57
- begin
58
- record = secrets_manager.get_secret_by_title("My Login")
59
- if record
60
- puts "\nFound record by title: #{record.uid}"
61
-
62
- # Access custom fields
63
- record.custom.each do |field|
64
- puts " Custom field '#{field['label']}': #{field['value'].first}"
65
- end
66
- end
67
- rescue => e
68
- puts "Error: #{e.message}"
69
- end
70
-
71
- # Use notation to access specific field values
72
- begin
73
- # Get password field from a record
74
- password = secrets_manager.get_notation("keeper://RECORD_UID/field/password")
75
- puts "\nPassword from notation: [HIDDEN]"
76
-
77
- # Get specific property from complex field
78
- hostname = secrets_manager.get_notation("keeper://RECORD_UID/field/host[hostName]")
79
- puts "Hostname: #{hostname}"
80
-
81
- # Get custom field
82
- custom_value = secrets_manager.get_notation("keeper://RECORD_UID/custom_field/My Label")
83
- puts "Custom field value: #{custom_value}"
84
- rescue => e
85
- puts "Notation error: #{e.message}"
86
- end
87
-
88
- # Create a new record
89
- begin
90
- new_record = KeeperSecretsManager::Dto::KeeperRecord.new(
91
- title: 'New Server Login',
92
- type: 'login',
93
- fields: [
94
- { 'type' => 'login', 'value' => ['admin'] },
95
- { 'type' => 'password', 'value' => ['SecurePass123!'] },
96
- { 'type' => 'url', 'value' => ['https://example.com'] },
97
- { 'type' => 'host',
98
- 'value' => [{ 'hostName' => '192.168.1.100', 'port' => '22' }],
99
- 'label' => 'SSH Connection' }
100
- ],
101
- notes: 'Created by Ruby SDK'
102
- )
103
-
104
- # Create the record
105
- # record_uid = secrets_manager.create_secret(new_record)
106
- # puts "\nCreated new record: #{record_uid}"
107
- rescue => e
108
- puts "Error creating record: #{e.message}"
109
- end
110
-
111
- # Update existing record
112
- begin
113
- # Get record to update
114
- record = secrets_manager.get_secret_by_title("Test Record")
115
-
116
- if record
117
- # Update fields
118
- record.set_field('password', 'NewPassword123!')
119
- record.notes = "Updated at #{Time.now}"
120
-
121
- # Save changes
122
- # secrets_manager.update_secret(record)
123
- # puts "\nRecord updated successfully"
124
- end
125
- rescue => e
126
- puts "Error updating record: #{e.message}"
127
- end
128
-
129
- # Working with folders
130
- begin
131
- folders = secrets_manager.get_folders
132
- puts "\nFound #{folders.length} folders"
133
-
134
- folders.each do |folder|
135
- puts " Folder: #{folder.name} (#{folder.uid})"
136
- end
137
- rescue => e
138
- puts "Error retrieving folders: #{e.message}"
139
- end
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Add the Ruby SDK to the load path
4
-
5
- require_relative '../lib/keeper_secrets_manager'
6
- require 'json'
7
- require 'base64'
8
-
9
- puts "=== Using Keeper SDK with Config String ==="
10
-
11
- # Example 1: JSON config string
12
- puts "\n1. Using JSON config string"
13
- puts "-" * 40
14
-
15
- # This would come from your secure configuration
16
- json_config = {
17
- "hostname" => "keepersecurity.com",
18
- "clientId" => "YOURCLIENTID",
19
- "appKey" => "YOURAPPKEYBASE64",
20
- "privateKey" => "YOURPRIVATEKEYBASE64",
21
- "appOwnerPublicKey" => "YOUROWNERPUBLICKEYBASE64",
22
- "serverPublicKeyId" => "7"
23
- }.to_json
24
-
25
- begin
26
- # Initialize with JSON string - NO TOKEN NEEDED!
27
- storage = KeeperSecretsManager::Storage::InMemoryStorage.new(json_config)
28
- sm = KeeperSecretsManager.new(config: storage)
29
- puts "āœ“ Would connect with pre-configured credentials (if real credentials were provided)"
30
- rescue => e
31
- puts "āœ— Expected error with dummy credentials: #{e.message}"
32
- end
33
-
34
- # Example 2: Base64 encoded config
35
- puts "\n2. Using Base64 encoded config"
36
- puts "-" * 40
37
-
38
- # Encode the config as base64 (like KSM_CONFIG environment variable)
39
- base64_config = Base64.strict_encode64(json_config)
40
- puts "Base64 config: #{base64_config[0..50]}..."
41
-
42
- begin
43
- # Initialize with base64 string - NO TOKEN NEEDED!
44
- storage = KeeperSecretsManager::Storage::InMemoryStorage.new(base64_config)
45
- sm = KeeperSecretsManager.new(config: storage)
46
- puts "āœ“ Would connect with base64 config (if real credentials were provided)"
47
- rescue => e
48
- puts "āœ— Expected error with dummy credentials: #{e.message}"
49
- end
50
-
51
- # Example 3: Using environment variable
52
- puts "\n3. Using KSM_CONFIG environment variable"
53
- puts "-" * 40
54
-
55
- # Set environment variable (normally done outside the script)
56
- ENV['KSM_CONFIG'] = base64_config
57
-
58
- begin
59
- # SDK automatically checks for KSM_CONFIG - NO TOKEN OR CONFIG NEEDED!
60
- sm = KeeperSecretsManager.new()
61
- puts "āœ“ Would connect with environment variable (if real credentials were provided)"
62
- rescue => e
63
- puts "āœ— Expected error with dummy credentials: #{e.message}"
64
- end
65
-
66
- # Example 4: Real workflow - first time with token, then reuse
67
- puts "\n4. Real workflow example"
68
- puts "-" * 40
69
-
70
- # First time - use token to get credentials
71
- puts "First connection with token:"
72
- puts "sm = KeeperSecretsManager.new(token: 'US:YOUR_TOKEN')"
73
- puts "config_to_save = sm.config.to_json"
74
- puts "# Save config_to_save securely"
75
-
76
- puts "\nSubsequent connections:"
77
- puts "saved_config = load_from_secure_storage()"
78
- puts "storage = KeeperSecretsManager::Storage::InMemoryStorage.new(saved_config)"
79
- puts "sm = KeeperSecretsManager.new(config: storage) # No token needed!"
80
-
81
- # Example 5: What the config looks like
82
- puts "\n5. Config structure"
83
- puts "-" * 40
84
- puts "After successful token authentication, the config contains:"
85
- puts JSON.pretty_generate({
86
- "clientId" => "Base64 encoded client ID (hash of token)",
87
- "appKey" => "Base64 encoded AES key for encryption",
88
- "privateKey" => "Base64 encoded EC private key (DER format)",
89
- "appOwnerPublicKey" => "Base64 encoded public key for record creation",
90
- "hostname" => "keepersecurity.com (or other region)",
91
- "serverPublicKeyId" => "7 (or other key ID)"
92
- })
93
-
94
- puts "\n" + "=" * 60
95
- puts "Key Points:"
96
- puts "- Once you have the config, you never need the token again"
97
- puts "- Config can be JSON or base64 encoded"
98
- puts "- Store the config securely - it contains your encryption keys!"
99
- puts "- The SDK will NOT ask for a token if valid config is provided"
@@ -1,84 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Add the Ruby SDK to the load path
4
- require_relative '../lib/keeper_secrets_manager'
5
-
6
- # Load the SDK
7
- require 'json'
8
-
9
- # Your token
10
- TOKEN = ENV['KSM_TOKEN'] || 'US:YOUR_ONE_TIME_TOKEN_HERE'
11
-
12
- puts "=== Debugging Keeper Secrets Manager ==="
13
-
14
- begin
15
- # Connect to Keeper with debug logging
16
- puts "\n1. Connecting to Keeper..."
17
- # Option 1: Use base64 config
18
- config_base64 = ENV['KSM_CONFIG_BASE64'] || 'YOUR_BASE64_CONFIG_HERE'
19
- storage_from_b64 = KeeperSecretsManager::Storage::InMemoryStorage.new(config_base64)
20
- sm = KeeperSecretsManager.new(config: storage_from_b64)
21
- # Alternative: Use in-memory storage
22
- # storage = KeeperSecretsManager::Storage::InMemoryStorage.new
23
- # sm = KeeperSecretsManager.new(token: TOKEN, config: storage)
24
- #
25
- # The storage now contains the credentials, so you can reuse it:
26
- # sm2 = KeeperSecretsManager.new(config: storage) # No token needed!
27
-
28
- # Get all secrets with raw response
29
- puts "\n2. Fetching secrets (this calls the internal method)..."
30
-
31
- # Let's look at what the SDK is actually doing internally
32
- # Get the raw response to see what's coming from the server
33
- response = sm.instance_eval do
34
- fetch_and_decrypt_secrets
35
- end
36
-
37
- puts "\n3. Response Analysis:"
38
- puts " - Total records returned: #{response[:records].length}"
39
- puts " - Total folders returned: #{response[:folders].length}"
40
- puts " - Warnings: #{response[:warnings]}"
41
-
42
- # Check if there are any records at all
43
- if response[:records].empty?
44
- puts "\n āš ļø No Secrets Manager-compatible records found!"
45
- puts " The warning indicates you have 4 'general' type records."
46
- puts " These are not accessible via the Secrets Manager SDK."
47
- else
48
- puts "\n4. Records found:"
49
- response[:records].each_with_index do |record, i|
50
- puts " #{i+1}. #{record.title} (Type: #{record.type}, UID: #{record.uid})"
51
- end
52
- end
53
-
54
- # Try to get records with specific UIDs from the warning
55
- puts "\n5. Attempting to fetch specific UIDs from warning..."
56
- warning_uids = ['AwOCl5W2RubtkFSuL72jXg', 'bX7uYVNsujLoPjrvEFA3Rg', 'gSnSFvd_UI9CnK_5kSZ85Q', 'wIT61_GnuBIpUOPxOrgPeQ']
57
-
58
- warning_uids.each do |uid|
59
- begin
60
- records = sm.get_secrets([uid])
61
- if records.any?
62
- puts " āœ“ Found: #{uid}"
63
- else
64
- puts " āœ— Not accessible: #{uid} (general type)"
65
- end
66
- rescue => e
67
- puts " āœ— Error fetching #{uid}: #{e.message}"
68
- end
69
- end
70
-
71
- puts "\n6. Summary:"
72
- puts " - Your vault contains 'general' type records"
73
- puts " - These are legacy Keeper records not designed for API access"
74
- puts " - To use Secrets Manager, create records with specific types like:"
75
- puts " • login"
76
- puts " • databaseCredentials"
77
- puts " • sshKeys"
78
- puts " • serverCredentials"
79
- puts " • etc."
80
-
81
- rescue => e
82
- puts "\nError: #{e.message}"
83
- puts e.backtrace.first(5).join("\n")
84
- end
@@ -1,182 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # This script demonstrates the Ruby SDK by listing all secrets in your vault
4
- # It uses the real config.base64 file to connect to Keeper
5
-
6
- require_relative 'lib/keeper_secrets_manager'
7
- require 'base64'
8
- require 'json'
9
-
10
- puts "=== Keeper Secrets Manager Ruby SDK Demo ==="
11
- puts "Connecting to Keeper and listing all secrets..."
12
- puts
13
-
14
- begin
15
- # Load the real configuration
16
- config_file = File.expand_path('config.base64', __dir__)
17
- unless File.exist?(config_file)
18
- puts "Error: config.base64 not found at #{config_file}"
19
- exit 1
20
- end
21
-
22
- config_base64 = File.read(config_file).strip
23
- config_json = Base64.decode64(config_base64)
24
- config_data = JSON.parse(config_json)
25
-
26
- # Display connection info (partial)
27
- puts "Configuration loaded:"
28
- puts " Hostname: #{config_data['hostname']}"
29
- puts " Client ID: #{config_data['clientId'][0..30]}..."
30
- puts " Has appKey: #{config_data.key?('appKey')}"
31
- puts " Has privateKey: #{config_data.key?('privateKey')}"
32
- puts " Has serverPublicKeyId: #{config_data['serverPublicKeyId']}"
33
- puts
34
-
35
- # Create storage and SDK instance
36
- storage = KeeperSecretsManager::Storage::InMemoryStorage.new(config_data)
37
-
38
- # Enable debug logging
39
- require 'logger'
40
- logger = Logger.new(STDOUT)
41
- logger.level = Logger::DEBUG
42
-
43
- secrets_manager = KeeperSecretsManager.new(config: storage, logger: logger, log_level: Logger::DEBUG)
44
-
45
- # Get all secrets
46
- puts "Fetching all secrets..."
47
- records = secrets_manager.get_secrets
48
-
49
- if records.empty?
50
- puts "\nNo secrets found in the vault."
51
- else
52
- puts "\nFound #{records.length} secret(s):"
53
- puts "-" * 80
54
-
55
- records.each_with_index do |record, index|
56
- puts "\n#{index + 1}. #{record.title}"
57
- puts " UID: #{record.uid}"
58
- puts " Type: #{record.type}"
59
-
60
- # Show fields (hide sensitive values)
61
- if record.fields.any?
62
- puts " Fields:"
63
- record.fields.each do |field|
64
- field_type = field['type']
65
- field_label = field['label'] ? " (#{field['label']})" : ""
66
-
67
- # Show field info but mask sensitive data
68
- case field_type
69
- when 'login', 'email'
70
- value = record.get_field_value_single(field_type)
71
- puts " - #{field_type}#{field_label}: #{value}"
72
- when 'password', 'secret', 'privateKey'
73
- puts " - #{field_type}#{field_label}: [HIDDEN]"
74
- when 'url'
75
- values = record.get_field_value(field_type)
76
- if values.length == 1
77
- puts " - #{field_type}#{field_label}: #{values.first}"
78
- else
79
- puts " - #{field_type}#{field_label}: #{values.length} URLs"
80
- end
81
- when 'host'
82
- host = record.get_field_value_single(field_type)
83
- if host.is_a?(Hash)
84
- puts " - #{field_type}#{field_label}: #{host['hostName']}:#{host['port'] || '22'}"
85
- end
86
- when 'phone'
87
- phone = record.get_field_value_single(field_type)
88
- if phone.is_a?(Hash)
89
- puts " - #{field_type}#{field_label}: #{phone['number']} (#{phone['region']})"
90
- end
91
- when 'name'
92
- name = record.get_field_value_single(field_type)
93
- if name.is_a?(Hash)
94
- full_name = [name['first'], name['middle'], name['last']].compact.join(' ')
95
- puts " - #{field_type}#{field_label}: #{full_name}"
96
- end
97
- else
98
- puts " - #{field_type}#{field_label}: [#{field['value']&.length || 0} value(s)]"
99
- end
100
- end
101
- end
102
-
103
- # Show custom fields
104
- if record.custom.any?
105
- puts " Custom Fields:"
106
- record.custom.each do |field|
107
- label = field['label'] || field['type']
108
- value_count = field['value']&.length || 0
109
- puts " - #{label}: [#{value_count} value(s)]"
110
- end
111
- end
112
-
113
- # Show notes (first 50 chars)
114
- if record.notes && !record.notes.empty?
115
- notes_preview = record.notes[0..50]
116
- notes_preview += "..." if record.notes.length > 50
117
- puts " Notes: #{notes_preview}"
118
- end
119
-
120
- # Show file count
121
- if record.files && record.files.any?
122
- puts " Files: #{record.files.length} attachment(s)"
123
- end
124
- end
125
-
126
- puts "\n" + "-" * 80
127
- end
128
-
129
- # Get folders
130
- puts "\nFetching folders..."
131
- folders = secrets_manager.get_folders
132
-
133
- if folders.empty?
134
- puts "No folders found."
135
- else
136
- puts "Found #{folders.length} folder(s):"
137
- folders.each do |folder|
138
- puts " - #{folder.name} (#{folder.uid})"
139
- end
140
- end
141
-
142
- # Demonstrate notation
143
- if records.any?
144
- puts "\n" + "=" * 80
145
- puts "Notation Examples (using first record):"
146
- puts "=" * 80
147
-
148
- first_record = records.first
149
-
150
- # Try various notations
151
- notations = [
152
- "keeper://#{first_record.uid}/type",
153
- "keeper://#{first_record.uid}/title",
154
- "keeper://#{first_record.uid}/field/login"
155
- ]
156
-
157
- notations.each do |notation|
158
- begin
159
- value = secrets_manager.get_notation(notation)
160
- puts "#{notation}"
161
- puts " => #{value}"
162
- rescue => e
163
- puts "#{notation}"
164
- puts " => Error: #{e.message}"
165
- end
166
- end
167
- end
168
-
169
- puts "\nāœ… SDK is working correctly!"
170
- puts "\nCapabilities demonstrated:"
171
- puts "- āœ“ Connected to Keeper"
172
- puts "- āœ“ Retrieved all secrets"
173
- puts "- āœ“ Accessed field values"
174
- puts "- āœ“ Listed folders"
175
- puts "- āœ“ Notation parsing"
176
-
177
- rescue => e
178
- puts "\nāŒ Error: #{e.class} - #{e.message}"
179
- puts "\nBacktrace:"
180
- puts e.backtrace.first(5).join("\n")
181
- exit 1
182
- end
@@ -1,100 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Add the Ruby SDK to the load path
4
- $LOAD_PATH.unshift('/Users/mustinov/Source/secrets-manager/sdk/ruby/lib')
5
-
6
- # Load the SDK
7
- require 'keeper_secrets_manager'
8
- require 'fileutils'
9
-
10
- # Helper method to sanitize filename
11
- def sanitize_filename(filename)
12
- # Remove or replace invalid characters
13
- filename.gsub(/[<>:"|?*\/\\]/, '_').strip
14
- end
15
-
16
- begin
17
- # Connect to Keeper
18
- puts "Connecting to Keeper..."
19
- # IMPORTANT: Replace with your own configuration
20
- # Option 1: Use one-time token
21
- # token = 'US:YOUR_ONE_TIME_TOKEN_HERE'
22
- # sm = KeeperSecretsManager.from_token(token)
23
- #
24
- # Option 2: Use base64 config
25
- config_base64 = ENV['KSM_CONFIG_BASE64'] || 'YOUR_BASE64_CONFIG_HERE'
26
- storage_from_b64 = KeeperSecretsManager::Storage::InMemoryStorage.new(config_base64)
27
- sm = KeeperSecretsManager.new(config: storage_from_b64)
28
-
29
- # Get all secrets
30
- puts "\nFetching secrets..."
31
- response = sm.get_secrets(full_response: true)
32
- secrets = response.records
33
-
34
- # Find secrets with files
35
- secrets_with_files = secrets.select { |s| s.files && s.files.any? }
36
-
37
- if secrets_with_files.empty?
38
- puts "\nNo secrets with files found."
39
- exit
40
- end
41
-
42
- puts "\nFound #{secrets_with_files.length} secrets with files:"
43
-
44
- # Create downloads directory
45
- download_dir = "downloads"
46
- FileUtils.mkdir_p(download_dir)
47
-
48
- total_files = 0
49
- downloaded_files = 0
50
- failed_files = 0
51
-
52
- secrets_with_files.each do |secret|
53
- puts "\nšŸ“ #{secret.title} (#{secret.files.length} files)"
54
-
55
- secret.files.each do |file|
56
- total_files += 1
57
- file_name = file['title'] || file['name'] || 'unnamed'
58
- file_size = file['size'] || 0
59
- file_uid = file['fileUid'] || file['uid']
60
-
61
- print " - #{file_name} (#{file_size} bytes) ... "
62
-
63
- if file_uid
64
- begin
65
- # Download the file (pass the whole file object)
66
- downloaded_file = sm.download_file(file)
67
-
68
- # Create subdirectory for the secret
69
- secret_dir = File.join(download_dir, sanitize_filename(secret.title))
70
- FileUtils.mkdir_p(secret_dir)
71
-
72
- # Save the file (sanitize the filename to remove path components)
73
- safe_filename = File.basename(downloaded_file['name'] || file_name)
74
- file_path = File.join(secret_dir, safe_filename)
75
- File.binwrite(file_path, downloaded_file['data'])
76
-
77
- downloaded_files += 1
78
- puts "āœ… Saved"
79
- rescue => e
80
- failed_files += 1
81
- puts "āŒ Failed: #{e.message}"
82
- end
83
- else
84
- failed_files += 1
85
- puts "āŒ No file UID"
86
- end
87
- end
88
- end
89
-
90
- puts "\n" + "=" * 60
91
- puts "Download Summary:"
92
- puts " Total files: #{total_files}"
93
- puts " āœ… Downloaded: #{downloaded_files}"
94
- puts " āŒ Failed: #{failed_files}"
95
- puts "\nFiles saved to: #{File.expand_path(download_dir)}/"
96
-
97
- rescue => e
98
- puts "\nError: #{e.message}"
99
- puts e.backtrace
100
- end
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative '../lib/keeper_secrets_manager'
4
-
5
- # Example showing flexible record creation in multiple ways
6
-
7
- # Method 1: Direct hash-based creation (JavaScript-style)
8
- record1 = KeeperSecretsManager::Dto::KeeperRecord.new(
9
- title: 'My Login',
10
- type: 'login',
11
- fields: [
12
- { 'type' => 'login', 'value' => ['my_username'] },
13
- { 'type' => 'password', 'value' => ['my_password'] },
14
- { 'type' => 'url', 'value' => ['https://example.com'] },
15
- {
16
- 'type' => 'host',
17
- 'value' => [{ 'hostName' => '192.168.1.1', 'port' => '8080' }],
18
- 'label' => 'Custom Host'
19
- }
20
- ],
21
- custom: [
22
- {
23
- 'type' => 'phone',
24
- 'value' => [{ 'region' => 'US', 'number' => '555-1234' }],
25
- 'label' => 'Work Phone'
26
- }
27
- ],
28
- notes: 'Example login record'
29
- )
30
-
31
- # Method 2: Using field helpers (optional convenience)
32
- record2 = KeeperSecretsManager::Dto::KeeperRecord.new(
33
- title: 'My Server',
34
- type: 'sshKeys'
35
- )
36
-
37
- # Add fields dynamically
38
- record2.set_field('login', 'root')
39
- record2.set_field('sshKey', {
40
- 'privateKey' => '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----',
41
- 'publicKey' => 'ssh-rsa AAAAB3...'
42
- })
43
-
44
- # Method 3: Using dynamic accessors (Ruby magic)
45
- record3 = KeeperSecretsManager::Dto::KeeperRecord.new(
46
- title: 'Dynamic Record',
47
- type: 'login'
48
- )
49
-
50
- # These create fields dynamically!
51
- record3.login = 'john_doe'
52
- record3.password = 'secure_pass123'
53
- record3.url = 'https://myapp.com'
54
-
55
- # Method 4: Mixing approaches
56
- record4 = KeeperSecretsManager::Dto::KeeperRecord.new(
57
- title: 'Payment Info',
58
- type: 'bankCard'
59
- )
60
-
61
- # Use helper for complex field
62
- card_field = KeeperSecretsManager::FieldTypes::Helpers.payment_card(
63
- number: '4111111111111111',
64
- expiration_date: '12/25',
65
- security_code: '123',
66
- cardholder_name: 'John Doe'
67
- )
68
-
69
- # Add to record
70
- record4.fields << card_field.to_h
71
-
72
- # Add custom field with any structure
73
- record4.set_field('customData', {
74
- 'someKey' => 'someValue',
75
- 'nested' => {
76
- 'data' => 'structure'
77
- }
78
- }, 'My Custom Data', true) # true = custom field
79
-
80
- # Access field values
81
- puts "Login: #{record1.get_field_value_single('login')}"
82
- puts "Password field: #{record1.get_field('password')}"
83
- puts "All custom fields: #{record1.custom}"
84
-
85
- # Dynamic accessor
86
- puts "URL from record3: #{record3.url}"
87
-
88
- # Access complex field values
89
- host_field = record1.get_field_value_single('host')
90
- puts "Host: #{host_field['hostName']}:#{host_field['port']}" if host_field
91
-
92
- # Convert to hash for API
93
- puts "\nRecord as hash for API:"
94
- puts record1.to_h.to_json