cloudinary 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/cloudinary/akamai.rb +50 -0
- data/lib/cloudinary/utils.rb +3 -1
- data/lib/cloudinary/version.rb +1 -1
- data/spec/api_spec.rb +4 -0
- data/spec/utils_methods_spec.rb +37 -3
- data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +9 -7
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a96fb520a45441c0cc40d980dc03836c6b7ffc4
|
4
|
+
data.tar.gz: 29924a2fa48916d03132b9bf6a080749471b558d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86b21f0e18c8759c79162d2b8f2cde2f1fd8807eae924c4fa6906f698f4a92e518763328a91dc36022c62edbf8772bad6b5f3885b41e4457831d1f11dcdd0d56
|
7
|
+
data.tar.gz: 94b7b4a747cb5bab25112cf0ac2041df8fa48009efbbc7f5719fe2df809ea3ae0d0f823928a3b0c6862839f4f3124db8ab3f0e6b2f2de52500d168570d118cb4
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module Cloudinary
|
4
|
+
module Akamai
|
5
|
+
SEPARATOR = '~'
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def generate_token(options)
|
13
|
+
key = options[:key] || Cloudinary.config.akamai_key
|
14
|
+
throw "Missing akamai_key configuration" unless key
|
15
|
+
name = options[:token_name] || "__cld_token__"
|
16
|
+
start = options[:start_time]
|
17
|
+
expiration = options[:end_time]
|
18
|
+
ip = options[:ip]
|
19
|
+
acl = options[:acl]
|
20
|
+
window = options[:window]
|
21
|
+
|
22
|
+
start = Time.new.getgm.to_i if start == 'now'
|
23
|
+
unless expiration
|
24
|
+
if window
|
25
|
+
expiration = (start || Time.new.getgm.to_i) + window
|
26
|
+
else
|
27
|
+
throw 'Must provide either end_time or window'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
token = []
|
32
|
+
token << "ip=#{ip}" if ip
|
33
|
+
token << "st=#{start}" if start
|
34
|
+
token << "exp=#{expiration}"
|
35
|
+
token << "acl=#{acl}"
|
36
|
+
auth = digest(token.join(SEPARATOR), key)
|
37
|
+
token << "hmac=#{auth}"
|
38
|
+
"#{name}=#{token.join(SEPARATOR)}"
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def digest(message, key = Cloudinary.config.akamai_key)
|
44
|
+
bin_key = Array(key).pack("H*")
|
45
|
+
digest = OpenSSL::Digest::SHA256.new
|
46
|
+
OpenSSL::HMAC.hexdigest(digest, bin_key, message)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -5,8 +5,10 @@ require 'uri'
|
|
5
5
|
require 'aws_cf_signer'
|
6
6
|
require 'json'
|
7
7
|
require 'cgi'
|
8
|
+
require 'cloudinary/akamai'
|
8
9
|
|
9
10
|
class Cloudinary::Utils
|
11
|
+
include Cloudinary::Akamai
|
10
12
|
# @deprecated Use Cloudinary::SHARED_CDN
|
11
13
|
SHARED_CDN = Cloudinary::SHARED_CDN
|
12
14
|
DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = {:width => :auto, :crop => :limit}
|
@@ -626,7 +628,7 @@ class Cloudinary::Utils
|
|
626
628
|
end
|
627
629
|
end
|
628
630
|
|
629
|
-
IMAGE_FORMATS = %w(ai bmp bpg djvu eps eps3 flif gif
|
631
|
+
IMAGE_FORMATS = %w(ai bmp bpg djvu eps eps3 flif gif hdp hpx ico j2k jp2 jpc jpe jpg miff pdf png psd svg tif tiff wdp webp zip )
|
630
632
|
|
631
633
|
AUDIO_FORMATS = %w(aac aifc aiff flac m4a mp3 ogg wav)
|
632
634
|
|
data/lib/cloudinary/version.rb
CHANGED
data/spec/api_spec.rb
CHANGED
@@ -373,6 +373,10 @@ describe Cloudinary::Api do
|
|
373
373
|
Cloudinary::Api.subfolders("test_folder1")
|
374
374
|
end
|
375
375
|
|
376
|
+
it "should throw if folder is missing" do
|
377
|
+
Cloudinary::Api.subfolders("I_do_not_exist")
|
378
|
+
end
|
379
|
+
|
376
380
|
describe '.restore' do
|
377
381
|
it 'should restore a deleted resource' do
|
378
382
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_ids] => "api_test_restore", [:url] => /.*\/restore$/))
|
data/spec/utils_methods_spec.rb
CHANGED
@@ -7,12 +7,46 @@ include Cloudinary
|
|
7
7
|
describe Utils do
|
8
8
|
|
9
9
|
it 'should parse integer range values' do
|
10
|
-
expect(Utils.instance_eval {norm_range_value("200")}).to eq(
|
10
|
+
expect(Utils.instance_eval { norm_range_value("200") }).to eq("200")
|
11
11
|
end
|
12
12
|
it "should parse float range values" do
|
13
|
-
expect(Utils.instance_eval {norm_range_value("200.0")}).to eq("200.0"), "parse a float"
|
13
|
+
expect(Utils.instance_eval { norm_range_value("200.0") }).to eq("200.0"), "parse a float"
|
14
14
|
end
|
15
15
|
it "should parse a percent range value" do
|
16
|
-
expect(Utils.instance_eval {norm_range_value("20p")}).to eq("20p")
|
16
|
+
expect(Utils.instance_eval { norm_range_value("20p") }).to eq("20p")
|
17
|
+
end
|
18
|
+
describe 'Utils.generate_token' do
|
19
|
+
config_backup = Cloudinary.config.clone
|
20
|
+
before do
|
21
|
+
Cloudinary.config.akamai_key = '00112233FF99'
|
22
|
+
end
|
23
|
+
after do
|
24
|
+
Cloudinary.config.each_pair { |k, _| Cloudinary.config.delete_field(k) }
|
25
|
+
Cloudinary.config(config_backup.to_h)
|
26
|
+
end
|
27
|
+
it "should generate an Akamai token with start_time and window" do
|
28
|
+
token = Utils.generate_token start_time: 1111111111, acl: '/image/*', window: 300
|
29
|
+
expect(token).to eq('__cld_token__=st=1111111111~exp=1111111411~acl=/image/*~hmac=0854e8b6b6a46471a80b2dc28c69bd352d977a67d031755cc6f3486c121b43af')
|
30
|
+
end
|
31
|
+
it "should generate an Akamai token with window" do
|
32
|
+
first_exp = Time.new.getgm.to_i + 300
|
33
|
+
# expiration is calculated automatically as now + window
|
34
|
+
token = Utils.generate_token acl: '*', window: 300
|
35
|
+
second_exp = Time.new.getgm.to_i + 300
|
36
|
+
match = /exp=(\d+)/.match(token)
|
37
|
+
expect(match[1]).to be_truthy
|
38
|
+
expiration = match[1].to_i
|
39
|
+
expect(expiration).to be_between(first_exp, second_exp)
|
40
|
+
expect(Utils.generate_token acl: '*', end_time: expiration).to eq(token)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should accept a key" do
|
44
|
+
expect(Utils.generate_token acl: '*', end_time: 10000000, key: '00aabbff')
|
45
|
+
.to eq('__cld_token__=exp=10000000~acl=*~hmac=030eafb6b19e499659d699b3d43e7595e35e3c0060e8a71904b3b8c8759f4890')
|
46
|
+
end
|
47
|
+
it "should throw if no end_time or window is provided" do
|
48
|
+
expect { Utils.generate_token acl: '*' }.to raise_error
|
49
|
+
|
50
|
+
end
|
17
51
|
end
|
18
52
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
/**
|
3
|
-
* Cloudinary's JavaScript library - Version 2.1.
|
3
|
+
* Cloudinary's JavaScript library - Version 2.1.9
|
4
4
|
* Copyright Cloudinary
|
5
5
|
* see https://github.com/cloudinary/cloudinary_js
|
6
6
|
*
|
@@ -1370,7 +1370,7 @@ var slice = [].slice,
|
|
1370
1370
|
secure: (typeof window !== "undefined" && window !== null ? (ref = window.location) != null ? ref.protocol : void 0 : void 0) === 'https:'
|
1371
1371
|
};
|
1372
1372
|
|
1373
|
-
Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
|
1373
|
+
Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
|
1374
1374
|
|
1375
1375
|
|
1376
1376
|
/**
|
@@ -2715,10 +2715,12 @@ var slice = [].slice,
|
|
2715
2715
|
/** @override */
|
2716
2716
|
|
2717
2717
|
ImageTag.prototype.attributes = function() {
|
2718
|
-
var attr;
|
2718
|
+
var attr, options, srcAttribute;
|
2719
2719
|
attr = ImageTag.__super__.attributes.call(this) || [];
|
2720
|
-
|
2721
|
-
|
2720
|
+
options = this.getOptions();
|
2721
|
+
srcAttribute = options.responsive && !options.client_hints ? 'data-src' : 'src';
|
2722
|
+
if (attr[srcAttribute] == null) {
|
2723
|
+
attr[srcAttribute] = new Cloudinary(this.getOptions()).url(this.publicId);
|
2722
2724
|
}
|
2723
2725
|
return attr;
|
2724
2726
|
};
|
@@ -2913,7 +2915,7 @@ var slice = [].slice,
|
|
2913
2915
|
Cloudinary = (function() {
|
2914
2916
|
var AKAMAI_SHARED_CDN, CF_SHARED_CDN, DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, OLD_AKAMAI_SHARED_CDN, SHARED_CDN, VERSION, absolutize, applyBreakpoints, cdnSubdomainNumber, closestAbove, cloudinaryUrlPrefix, defaultBreakpoints, finalizeResourceType, findContainerWidth, maxWidth, updateDpr;
|
2915
2917
|
|
2916
|
-
VERSION = "2.1.
|
2918
|
+
VERSION = "2.1.9";
|
2917
2919
|
|
2918
2920
|
CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
|
2919
2921
|
|
@@ -4148,7 +4150,7 @@ var slice = [].slice,
|
|
4148
4150
|
TextLayer: TextLayer,
|
4149
4151
|
SubtitlesLayer: SubtitlesLayer,
|
4150
4152
|
Cloudinary: Cloudinary,
|
4151
|
-
VERSION: "2.1.
|
4153
|
+
VERSION: "2.1.9",
|
4152
4154
|
CloudinaryJQuery: CloudinaryJQuery
|
4153
4155
|
};
|
4154
4156
|
return cloudinary;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nadav Soferman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2017-01-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws_cf_signer
|
@@ -129,6 +129,7 @@ files:
|
|
129
129
|
- Rakefile
|
130
130
|
- cloudinary.gemspec
|
131
131
|
- lib/cloudinary.rb
|
132
|
+
- lib/cloudinary/akamai.rb
|
132
133
|
- lib/cloudinary/api.rb
|
133
134
|
- lib/cloudinary/blob.rb
|
134
135
|
- lib/cloudinary/carrier_wave.rb
|