epics 2.8.0 → 2.10.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/CHANGELOG.md +9 -0
- data/README.md +73 -3
- data/lib/epics/client.rb +41 -9
- data/lib/epics/generic_request.rb +14 -0
- data/lib/epics/hev.rb +19 -0
- data/lib/epics/hia.rb +2 -0
- data/lib/epics/ini.rb +1 -0
- data/lib/epics/letter_renderer.rb +23 -3
- data/lib/epics/response.rb +8 -0
- data/lib/epics/signer.rb +3 -3
- data/lib/epics/version.rb +1 -1
- data/lib/epics/x_509_certificate.rb +15 -0
- data/lib/epics/z01.rb +17 -0
- data/lib/epics.rb +3 -0
- data/lib/letter/ini_with_certs.erb +335 -0
- data/lib/letter/locales/de.yml +1 -0
- data/lib/letter/locales/en.yml +1 -0
- data/lib/letter/locales/fr.yml +1 -0
- data/spec/client_spec.rb +150 -58
- data/spec/orders/hev_spec.rb +14 -0
- data/spec/orders/hia_spec.rb +31 -7
- data/spec/orders/ini_spec.rb +27 -8
- data/spec/orders/x_509_certificate_spec.rb +26 -0
- data/spec/orders/z01_spec.rb +11 -0
- data/spec/support/x_509_crt_generator.rb +22 -0
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33e735bd9012ec4df1bc24d5f1621345adfa6aeba90dbf5c3adcc9be9673c696
|
4
|
+
data.tar.gz: f8c5b93115aeb9b60d3be9cbcd36251b6046f5093ed92482c2b4b1d8d4555e90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6021ed35c892dc544032a95e89ef5a8361f27ea022a5a2776dfea3adea1e7ebbbb2642e145a0c4efb01157c228953c171a511747d21087e520a1b59411f82f81
|
7
|
+
data.tar.gz: 71ef90f98028d9e4bff31aa077d52fdbd7cadc12e8126792f7e71bb6e00b4b409a1ad9e36b54e2e345115e602734a7ddaaa26f3b214e54503055929a5600f114
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
### Unreleased
|
2
2
|
|
3
|
+
### 2.10.0
|
4
|
+
|
5
|
+
- [ENHANCEMENT] Added X.509 certificates support for INI and HIA (thanks to @vnoviskyi)
|
6
|
+
- [ENHANCEMENT] Added Z01 order type (thanks to @Nymuxyzo)
|
7
|
+
|
8
|
+
### 2.9.0
|
9
|
+
|
10
|
+
- [ENHANCEMENT] Added HEV order type (thanks to @jplot)
|
11
|
+
|
3
12
|
### 2.8.0
|
4
13
|
|
5
14
|
- [ENHANCEMENT] Added BKA order type
|
data/README.md
CHANGED
@@ -41,7 +41,7 @@ Once the paperwork is done, your bank should provide you with:
|
|
41
41
|
Take these parameters and start setting up an UserID (repeat this for every user you want to initialize):
|
42
42
|
|
43
43
|
```ruby
|
44
|
-
e = Epics::Client.setup("my-super-secret", "https://ebics.sandbox", "EBICS_HOST_ID", "EBICS_USER_ID", "EBICS_PARTNER_ID")
|
44
|
+
e = Epics::Client.setup("my-super-secret", "https://ebics.sandbox", "EBICS_HOST_ID", "EBICS_USER_ID", "EBICS_PARTNER_ID", 4096)
|
45
45
|
```
|
46
46
|
|
47
47
|
To use the keys later, just store them in a file
|
@@ -200,6 +200,76 @@ that are hiding some strange names from you:
|
|
200
200
|
If you need more sophisticated EBICS order types, please read the next section
|
201
201
|
about the supported functionalities.
|
202
202
|
|
203
|
+
### Using X.509 Certificates
|
204
|
+
|
205
|
+
Epics supports using X.509 self-signed certificates for INI and HIA requests, as required by some banks. This is in addition to the classic key-based workflow.
|
206
|
+
|
207
|
+
#### When to Use
|
208
|
+
|
209
|
+
Some banks require X.509 certificates for EBICS initialization (INI/HIA).
|
210
|
+
|
211
|
+
You can generate your own X.509 certificate using Ruby’s OpenSSL library:
|
212
|
+
|
213
|
+
This examples showcases the generation of the X.509 certificate A file and can be applied the same way for the others.
|
214
|
+
```ruby
|
215
|
+
key = client.a.key # or e key, or x key
|
216
|
+
name = OpenSSL::X509::Name.parse('/CN=Test Certificate/O=MyOrg/C=DE')
|
217
|
+
cert = OpenSSL::X509::Certificate.new
|
218
|
+
cert.version = 2
|
219
|
+
cert.serial = SecureRandom.random_number(2**64)
|
220
|
+
cert.subject = name
|
221
|
+
cert.issuer = name
|
222
|
+
cert.public_key = key.public_key
|
223
|
+
cert.not_before = Time.current
|
224
|
+
cert.not_after = cert.not_before + 1.year
|
225
|
+
|
226
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
227
|
+
ef.subject_certificate = cert
|
228
|
+
ef.issuer_certificate = cert
|
229
|
+
cert.add_extension(ef.create_extension('basicConstraints', 'CA:FALSE', true))
|
230
|
+
cert.add_extension(ef.create_extension('keyUsage', 'digitalSignature,nonRepudiation,keyEncipherment', true))
|
231
|
+
|
232
|
+
cert.sign(key, OpenSSL::Digest.new('SHA256'))
|
233
|
+
cert
|
234
|
+
|
235
|
+
# Save to file
|
236
|
+
File.write("cert_a.pem", cert.to_pem)
|
237
|
+
```
|
238
|
+
You can now use the contents of the generated certificate file in PEM format as your
|
239
|
+
`x_509_certificate_a_content`, `x_509_certificate_x_content`, or `x_509_certificate_e_content`
|
240
|
+
in the client initialization.
|
241
|
+
|
242
|
+
**Note:** For production environments, your bank may require certificates issued by a trusted authority. Be sure to confirm your bank’s requirements before proceeding.
|
243
|
+
|
244
|
+
#### Initializing the Client with X.509 Certificates
|
245
|
+
```ruby
|
246
|
+
# Load your certificate data (PEM or DER encoded)
|
247
|
+
certificate_a = File.read("cert_a.pem")
|
248
|
+
certificate_x = File.read("cert_x.pem")
|
249
|
+
certificate_e = File.read("cert_e.pem")
|
250
|
+
|
251
|
+
client = Epics::Client.new(
|
252
|
+
keys, # your key data as before
|
253
|
+
'passphrase',
|
254
|
+
'url',
|
255
|
+
'host',
|
256
|
+
'user',
|
257
|
+
'partner',
|
258
|
+
x_509_certificate_a_content: certificate_a,
|
259
|
+
x_509_certificate_x_content: certificate_x,
|
260
|
+
x_509_certificate_e_content: certificate_e,
|
261
|
+
debug_mode: true # Optional: enables verbose logging of EBICS requests/responses
|
262
|
+
)
|
263
|
+
```
|
264
|
+
### Example: Generating the Initialization Letter with Certificates
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
renderer = Epics::LetterRenderer.new(client)
|
268
|
+
letter = renderer.render("Your Bank Name")
|
269
|
+
File.write("initialization_letter.txt", letter)
|
270
|
+
```
|
271
|
+
If all three certificates are present, the INI letter will use certificate hashes as required for certificate-based registration.
|
272
|
+
|
203
273
|
## Issues and Feature Requests
|
204
274
|
|
205
275
|
[Railslove](http://railslove.com) is commited to provide the best developer tools for integrating
|
@@ -258,8 +328,8 @@ EPICS_VERIFY_SSL=false
|
|
258
328
|
## Contributing
|
259
329
|
Railslove has a [Contributor License Agreement (CLA)](https://github.com/railslove/epics/blob/master/CONTRIBUTING.md) which clarifies the intellectual property rights for contributions from individuals or entities. To ensure every developer has signed the CLA, we use [CLA Assistant](https://cla-assistant.io/).
|
260
330
|
|
261
|
-
After checking out the repo, run `bin/setup` to install dependencies.
|
262
|
-
Then, run `rspec` to run the tests.
|
331
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
332
|
+
Then, run `rspec` to run the tests.
|
263
333
|
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
264
334
|
|
265
335
|
0. Contact team@railslove.com for information about the CLA
|
data/lib/epics/client.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
class Epics::Client
|
2
2
|
extend Forwardable
|
3
3
|
|
4
|
-
attr_accessor :passphrase, :url, :host_id, :user_id, :partner_id, :keys, :keys_content, :locale, :product_name
|
5
|
-
|
4
|
+
attr_accessor :passphrase, :url, :host_id, :user_id, :partner_id, :keys, :keys_content, :locale, :product_name,
|
5
|
+
:x_509_certificates_content, :debug_mode
|
6
6
|
|
7
|
+
attr_writer :iban, :bic, :name
|
8
|
+
|
7
9
|
def_delegators :connection, :post
|
8
|
-
|
9
|
-
def initialize(keys_content, passphrase, url, host_id, user_id, partner_id,
|
10
|
+
|
11
|
+
def initialize(keys_content, passphrase, url, host_id, user_id, partner_id, options = {})
|
10
12
|
self.keys_content = keys_content.respond_to?(:read) ? keys_content.read : keys_content if keys_content
|
11
13
|
self.passphrase = passphrase
|
12
14
|
self.keys = extract_keys if keys_content
|
@@ -14,8 +16,14 @@ class Epics::Client
|
|
14
16
|
self.host_id = host_id
|
15
17
|
self.user_id = user_id
|
16
18
|
self.partner_id = partner_id
|
17
|
-
self.locale = locale
|
18
|
-
self.product_name = product_name
|
19
|
+
self.locale = options[:locale] || Epics::DEFAULT_LOCALE
|
20
|
+
self.product_name = options[:product_name] || Epics::DEFAULT_PRODUCT_NAME
|
21
|
+
self.debug_mode = !!options[:debug_mode]
|
22
|
+
self.x_509_certificates_content = {
|
23
|
+
a: options[:x_509_certificate_a_content],
|
24
|
+
x: options[:x_509_certificate_x_content],
|
25
|
+
e: options[:x_509_certificate_e_content]
|
26
|
+
}
|
19
27
|
end
|
20
28
|
|
21
29
|
def inspect
|
@@ -61,8 +69,8 @@ class Epics::Client
|
|
61
69
|
@order_types ||= (self.HTD; @order_types)
|
62
70
|
end
|
63
71
|
|
64
|
-
def self.setup(passphrase, url, host_id, user_id, partner_id, keysize = 2048)
|
65
|
-
client = new(nil, passphrase, url, host_id, user_id, partner_id)
|
72
|
+
def self.setup(passphrase, url, host_id, user_id, partner_id, keysize = 2048, options = {})
|
73
|
+
client = new(nil, passphrase, url, host_id, user_id, partner_id, options)
|
66
74
|
client.keys = %w(A006 X002 E002).each_with_object({}) do |type, memo|
|
67
75
|
memo[type] = Epics::Key.new( OpenSSL::PKey::RSA.generate(keysize) )
|
68
76
|
end
|
@@ -107,6 +115,13 @@ class Epics::Client
|
|
107
115
|
post(url, Epics::INI.new(self).to_xml).body.ok?
|
108
116
|
end
|
109
117
|
|
118
|
+
def HEV
|
119
|
+
res = post(url, Epics::HEV.new(self).to_xml).body
|
120
|
+
res.doc.xpath("//xmlns:VersionNumber", xmlns: 'http://www.ebics.org/H000').each_with_object({}) do |node, versions|
|
121
|
+
versions[node['ProtocolVersion']] = node.content
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
110
125
|
def HPB
|
111
126
|
Nokogiri::XML(download(Epics::HPB)).xpath("//xmlns:PubKeyValue", xmlns: "urn:org:ebics:H004").each do |node|
|
112
127
|
type = node.parent.last_element_child.content
|
@@ -218,6 +233,10 @@ class Epics::Client
|
|
218
233
|
download_and_unzip(Epics::C5N, from: from, to: to)
|
219
234
|
end
|
220
235
|
|
236
|
+
def Z01(from, to)
|
237
|
+
download_and_unzip(Epics::Z01, from: from, to: to)
|
238
|
+
end
|
239
|
+
|
221
240
|
def Z52(from, to)
|
222
241
|
download_and_unzip(Epics::Z52, from: from, to: to)
|
223
242
|
end
|
@@ -266,6 +285,19 @@ class Epics::Client
|
|
266
285
|
def save_keys(path)
|
267
286
|
File.write(path, dump_keys)
|
268
287
|
end
|
288
|
+
|
289
|
+
def x_509_certificate(type)
|
290
|
+
content = x_509_certificates_content[type.to_sym]
|
291
|
+
return if content.nil? || content.empty?
|
292
|
+
Epics::X509Certificate.new(content)
|
293
|
+
end
|
294
|
+
|
295
|
+
def x_509_certificate_hash(type)
|
296
|
+
content = x_509_certificates_content[type.to_sym]
|
297
|
+
return if content.nil? || content.empty?
|
298
|
+
cert = OpenSSL::X509::Certificate.new(content)
|
299
|
+
Digest::SHA256.hexdigest(cert.to_der).upcase
|
300
|
+
end
|
269
301
|
|
270
302
|
private
|
271
303
|
|
@@ -306,7 +338,7 @@ class Epics::Client
|
|
306
338
|
faraday.use Epics::XMLSIG, { client: self }
|
307
339
|
faraday.use Epics::ParseEbics, { client: self}
|
308
340
|
# faraday.use MyAdapter
|
309
|
-
|
341
|
+
faraday.response :logger, ::Logger.new(STDOUT), bodies: true if debug_mode # log requests/response to STDOUT
|
310
342
|
end
|
311
343
|
end
|
312
344
|
|
@@ -105,4 +105,18 @@ class Epics::GenericRequest
|
|
105
105
|
}
|
106
106
|
end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
|
107
107
|
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def x509_data_xml(xml, x_509_certificate)
|
112
|
+
return unless x_509_certificate
|
113
|
+
|
114
|
+
xml.send('ds:X509Data') do
|
115
|
+
xml.send('ds:X509IssuerSerial') do
|
116
|
+
xml.send('ds:X509IssuerName', x_509_certificate.issuer)
|
117
|
+
xml.send('ds:X509SerialNumber', x_509_certificate.version)
|
118
|
+
end
|
119
|
+
xml.send('ds:X509Certificate', x_509_certificate.data)
|
120
|
+
end
|
121
|
+
end
|
108
122
|
end
|
data/lib/epics/hev.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Epics::HEV < Epics::GenericRequest
|
2
|
+
def root
|
3
|
+
"ebicsHEVRequest"
|
4
|
+
end
|
5
|
+
|
6
|
+
def body
|
7
|
+
Nokogiri::XML::Builder.new do |xml|
|
8
|
+
xml.HostID host_id
|
9
|
+
end.doc.root
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_xml
|
13
|
+
Nokogiri::XML::Builder.new do |xml|
|
14
|
+
xml.send(root, 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://www.ebics.org/H000 http://www.ebics.org/H000/ebics_hev.xsd', 'xmlns' => 'http://www.ebics.org/H000') {
|
15
|
+
xml.parent.add_child(body)
|
16
|
+
}
|
17
|
+
end.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML, encoding: 'utf-8')
|
18
|
+
end
|
19
|
+
end
|
data/lib/epics/hia.rb
CHANGED
@@ -26,6 +26,7 @@ class Epics::HIA < Epics::GenericRequest
|
|
26
26
|
Nokogiri::XML::Builder.new do |xml|
|
27
27
|
xml.HIARequestOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'urn:org:ebics:H004') {
|
28
28
|
xml.AuthenticationPubKeyInfo {
|
29
|
+
x509_data_xml(xml, client.x_509_certificate(:x))
|
29
30
|
xml.PubKeyValue {
|
30
31
|
xml.send('ds:RSAKeyValue') {
|
31
32
|
xml.send('ds:Modulus', Base64.strict_encode64([client.x.n].pack("H*")))
|
@@ -35,6 +36,7 @@ class Epics::HIA < Epics::GenericRequest
|
|
35
36
|
xml.AuthenticationVersion 'X002'
|
36
37
|
}
|
37
38
|
xml.EncryptionPubKeyInfo{
|
39
|
+
x509_data_xml(xml, client.x_509_certificate(:e))
|
38
40
|
xml.PubKeyValue {
|
39
41
|
xml.send('ds:RSAKeyValue') {
|
40
42
|
xml.send('ds:Modulus', Base64.strict_encode64([client.e.n].pack("H*")))
|
data/lib/epics/ini.rb
CHANGED
@@ -26,6 +26,7 @@ class Epics::INI < Epics::GenericRequest
|
|
26
26
|
Nokogiri::XML::Builder.new do |xml|
|
27
27
|
xml.SignaturePubKeyOrderData('xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#', 'xmlns' => 'http://www.ebics.org/S001') {
|
28
28
|
xml.SignaturePubKeyInfo {
|
29
|
+
x509_data_xml(xml, client.x_509_certificate(:a))
|
29
30
|
xml.PubKeyValue {
|
30
31
|
xml.send('ds:RSAKeyValue') {
|
31
32
|
xml.send('ds:Modulus', Base64.strict_encode64([client.a.n].pack("H*")))
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class Epics::LetterRenderer
|
2
2
|
extend Forwardable
|
3
3
|
|
4
|
-
TEMPLATE_PATH = File.join(File.dirname(__FILE__), '../letter/', 'ini.erb')
|
5
4
|
I18N_SCOPE = 'epics.letter'
|
6
5
|
|
7
6
|
def initialize(client)
|
@@ -12,11 +11,32 @@ class Epics::LetterRenderer
|
|
12
11
|
I18n.translate(key, **{ locale: @client.locale, scope: I18N_SCOPE }.merge(options))
|
13
12
|
end
|
14
13
|
|
15
|
-
|
14
|
+
alias t translate
|
16
15
|
|
17
16
|
def_delegators :@client, :host_id, :user_id, :partner_id, :a, :x, :e
|
18
17
|
|
19
18
|
def render(bankname)
|
20
|
-
|
19
|
+
template_path = File.join(File.dirname(__FILE__), '../letter/', template_filename)
|
20
|
+
ERB.new(File.read(template_path)).result(binding)
|
21
|
+
end
|
22
|
+
|
23
|
+
def template_filename
|
24
|
+
use_x_509_certificate_template? ? 'ini_with_certs.erb' : 'ini.erb'
|
25
|
+
end
|
26
|
+
|
27
|
+
def use_x_509_certificate_template?
|
28
|
+
x_509_certificate_a_hash && x_509_certificate_x_hash && x_509_certificate_e_hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def x_509_certificate_a_hash
|
32
|
+
@client.x_509_certificate_hash(:a)
|
33
|
+
end
|
34
|
+
|
35
|
+
def x_509_certificate_x_hash
|
36
|
+
@client.x_509_certificate_hash(:x)
|
37
|
+
end
|
38
|
+
|
39
|
+
def x_509_certificate_e_hash
|
40
|
+
@client.x_509_certificate_hash(:e)
|
21
41
|
end
|
22
42
|
end
|
data/lib/epics/response.rb
CHANGED
@@ -12,9 +12,17 @@ class Epics::Response
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def technical_code
|
15
|
+
mutable_return_code.empty? ? system_return_code : mutable_return_code
|
16
|
+
end
|
17
|
+
|
18
|
+
def mutable_return_code
|
15
19
|
doc.xpath("//xmlns:header/xmlns:mutable/xmlns:ReturnCode", xmlns: "urn:org:ebics:H004").text
|
16
20
|
end
|
17
21
|
|
22
|
+
def system_return_code
|
23
|
+
doc.xpath("//xmlns:SystemReturnCode/xmlns:ReturnCode", xmlns: 'http://www.ebics.org/H000').text
|
24
|
+
end
|
25
|
+
|
18
26
|
def business_error?
|
19
27
|
!["", "000000"].include?(business_code)
|
20
28
|
end
|
data/lib/epics/signer.rb
CHANGED
@@ -17,7 +17,7 @@ class Epics::Signer
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def sign!
|
20
|
-
signature_value_node = doc.xpath("//ds:SignatureValue").first
|
20
|
+
signature_value_node = doc.xpath("//ds:SignatureValue", ds: "http://www.w3.org/2000/09/xmldsig#").first
|
21
21
|
|
22
22
|
if signature_node
|
23
23
|
signature_value_node.content = Base64.encode64(client.x.key.sign(digester, signature_node.canonicalize)).gsub(/\n/,'')
|
@@ -27,11 +27,11 @@ class Epics::Signer
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def digest_node
|
30
|
-
@d ||= doc.xpath("//ds:DigestValue").first
|
30
|
+
@d ||= doc.xpath("//ds:DigestValue", ds: "http://www.w3.org/2000/09/xmldsig#").first
|
31
31
|
end
|
32
32
|
|
33
33
|
def signature_node
|
34
|
-
@s ||= doc.xpath("//ds:SignedInfo").first
|
34
|
+
@s ||= doc.xpath("//ds:SignedInfo", ds: "http://www.w3.org/2000/09/xmldsig#").first
|
35
35
|
end
|
36
36
|
|
37
37
|
def digester
|
data/lib/epics/version.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Epics::X509Certificate
|
2
|
+
extend Forwardable
|
3
|
+
|
4
|
+
attr_reader :certificate
|
5
|
+
|
6
|
+
def_delegators :certificate, :issuer, :version
|
7
|
+
|
8
|
+
def initialize(crt_content)
|
9
|
+
@certificate = OpenSSL::X509::Certificate.new(crt_content)
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
Base64.strict_encode64(@certificate.to_der)
|
14
|
+
end
|
15
|
+
end
|
data/lib/epics/z01.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Epics::Z01 < Epics::GenericRequest
|
2
|
+
def header
|
3
|
+
client.header_request.build(
|
4
|
+
nonce: nonce,
|
5
|
+
timestamp: timestamp,
|
6
|
+
order_type: 'Z01',
|
7
|
+
order_attribute: 'DZHNN',
|
8
|
+
order_params: {
|
9
|
+
DateRange: {
|
10
|
+
Start: options[:from],
|
11
|
+
End: options[:to]
|
12
|
+
}
|
13
|
+
},
|
14
|
+
mutable: { TransactionPhase: 'Initialisation' }
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
data/lib/epics.rb
CHANGED
@@ -32,6 +32,7 @@ require "epics/c52"
|
|
32
32
|
require "epics/c53"
|
33
33
|
require "epics/c54"
|
34
34
|
require "epics/c5n"
|
35
|
+
require "epics/z01"
|
35
36
|
require "epics/z52"
|
36
37
|
require "epics/z53"
|
37
38
|
require "epics/z54"
|
@@ -56,7 +57,9 @@ require "epics/crz"
|
|
56
57
|
require "epics/xct"
|
57
58
|
require "epics/hia"
|
58
59
|
require "epics/ini"
|
60
|
+
require "epics/hev"
|
59
61
|
require "epics/signer"
|
62
|
+
require "epics/x_509_certificate"
|
60
63
|
require "epics/client"
|
61
64
|
|
62
65
|
I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'letter/locales', '*.yml')]
|