Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Made ImboChrome work with new accessToken implementation.

  • Loading branch information...
commit 5eddca382b31c79ef1c1895b0d91fb3d7e1ffb27 1 parent 565c8c8
@rexxars authored
View
1  background.html
@@ -9,6 +9,7 @@
<!-- Clipboard helper -->
<textarea id="clipboardHolder"></textarea>
+ <script src="js/utils/class.js"></script>
<script src="js/utils/binary.js"></script>
<script src="js/utils/crypto.js"></script>
<script src="js/client.js"></script>
View
1  config.html
@@ -47,6 +47,7 @@ <h1 id="navbar-content-title">Instances</h1>
</div>
</div>
+ <script src="js/utils/class.js"></script>
<script src="js/utils/dom.js"></script>
<script src="js/config.js"></script>
<script src="js/templates.js"></script>
View
1  dashboard.html
@@ -75,6 +75,7 @@ <h1 id="navbar-content-title">Instances</h1>
</div>
</div>
+ <script src="js/utils/class.js"></script>
<script src="js/utils/dom.js"></script>
<script src="js/utils/paginator.js"></script>
<script src="js/utils/jsonToHtml.js"></script>
View
2  js/background.js
@@ -83,7 +83,7 @@ this.imbo = {
return imbo.showNotification({
header : 'Upload successful!',
message : 'Successfully uploaded image!',
- url : client.getResourceUrl(res.imageIdentifier)
+ url : client.getImageUrl(res.imageIdentifier).toString()
});
} else if (statusCode == 400 && res.error) {
var url = res.imageIdentifier ? client.getResourceUrl(res.imageIdentifier) : null;
View
312 js/client.js
@@ -30,8 +30,6 @@ ImboClient.prototype.request = function(type, uri, data, cb) {
data = null;
}
- uri += this.options.cacheBreak ? ((uri.indexOf('?') > -1 ? '&' : '?') + 'cachebreak=' + Date.now()) : '';
-
var xhr = new XMLHttpRequest(), client = this;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
@@ -76,17 +74,20 @@ ImboClient.prototype.put = function(url, imgData, cbs) {
*/
ImboClient.prototype.addImage = function(imgData, callbacks) {
var imageIdentifier = this.getImageIdentifier(imgData);
- var url = this.getSignedResourceUrl('PUT', this.getResourceUrl(imageIdentifier));
+ var imageUrl = this.getImageUrl(imageIdentifier).toString();
+
+ var url = this.getSignedUrl('PUT', imageUrl);
this.put(url, imgData, callbacks);
};
ImboClient.prototype.deleteImage = function(imageIdentifier, callback) {
- var url = this.getSignedResourceUrl('DELETE', this.getResourceUrl(imageIdentifier));
+ var imageUrl = this.getImageUrl(imageIdentifier).toString();
+ var url = this.getSignedUrl('DELETE', imageUrl);
this.request('DELETE', url, callback);
};
ImboClient.prototype.headImage = function(imageIdentifier, callback) {
- var url = this.getResourceUrl(imageIdentifier);
+ var url = this.getImageUrl(imageIdentifier).toString();
this.request('HEAD', url, callback);
};
@@ -102,7 +103,7 @@ ImboClient.prototype.imageIdentifierExists = function(identifier, callback) {
};
ImboClient.prototype.getInfo = function(cb) {
- this.request('GET', this.getInstanceUrl(), function(res, status) {
+ this.request('GET', this.getUserUrl().toString(), function(res, status) {
if (!res || (status !== 200 && status !== 304)) {
return cb(false);
}
@@ -113,7 +114,7 @@ ImboClient.prototype.getInfo = function(cb) {
ImboClient.prototype.getImages = function(cb, q) {
// Build the complete URL
- var url = this.getImagesUrl() + (q ? ('?' + q) : '');
+ var url = this.getImagesUrl(q).toString();
// Fetch the response
this.request('GET', url, function(res, status) {
@@ -129,25 +130,27 @@ ImboClient.prototype.getImages = function(cb, q) {
* Metadata methods
*/
ImboClient.prototype.getMetadata = function(imageIdentifier, callback) {
- var url = this.getResourceUrl(imageIdentifier + '/meta');
+ var url = this.getMetadataUrl(imageIdentifier).toString();
this.request('GET', url, callback);
};
ImboClient.prototype.replaceMetadata = function(imageIdentifier, data, callback) {
var self = this;
this.deleteMetadata(imageIdentifier, function() {
- var url = self.getSignedResourceUrl('POST', self.getResourceUrl(imageIdentifier) + '/meta');
+ var url = self.getSignedUrl('POST', self.getResourceUrl(imageIdentifier) + '/meta');
self.request('POST', url, JSON.stringify(data), callback);
});
};
ImboClient.prototype.editMetadata = function(imageIdentifier, data, callback) {
- var url = this.getSignedResourceUrl('POST', this.getResourceUrl(imageIdentifier) + '/meta');
+ var metaUrl = this.getMetadataUrl(imageIdentifier).toString();
+ var url = this.getSignedUrl('POST', metaUrl);
this.request('POST', url, JSON.stringify(data), callback);
};
ImboClient.prototype.deleteMetadata = function(imageIdentifier, callback) {
- var url = this.getSignedResourceUrl('DELETE', this.getResourceUrl(imageIdentifier) + '/meta');
+ var metaUrl = this.getMetadataUrl(imageIdentifier).toString();
+ var url = this.getSignedUrl('DELETE', metaUrl);
this.request('DELETE', url, callback);
};
@@ -160,27 +163,32 @@ ImboClient.prototype.getImageIdentifier = function(imgData) {
ImboClient.prototype.getImageUrl = function(imageIdentifier) {
var host = this.getHostForImageIdentifier(imageIdentifier);
- return new ImboUrl(host, this.options.publicKey, this.options.privateKey, imageIdentifier);
+ return new ImboImageUrl(host, this.options.publicKey, this.options.privateKey, imageIdentifier);
};
-ImboClient.prototype.getInstanceUrl = function() {
- return this.options.hosts[0] + '/users/' + this.options.publicKey;
+ImboClient.prototype.getUserUrl = function() {
+ return new ImboUserUrl(this.options.hosts[0], this.options.publicKey, this.options.privateKey);
};
-ImboClient.prototype.getImagesUrl = function() {
- return this.getInstanceUrl() + '/images/';
+ImboClient.prototype.getImagesUrl = function(query) {
+ return new ImboImagesUrl(this.options.hosts[0], this.options.publicKey, this.options.privateKey, query, this.options.cacheBreak);
};
ImboClient.prototype.getResourceUrl = function(resourceIdentifier) {
return this.getImagesUrl() + resourceIdentifier;
};
-ImboClient.prototype.getSignedResourceUrl = function(method, url) {
+ImboClient.prototype.getMetadataUrl = function(imageIdentifier) {
+ var host = this.getHostForImageIdentifier(imageIdentifier);
+ return new ImboMetadataUrl(host, this.options.publicKey, this.options.privateKey, imageIdentifier);
+};
+
+ImboClient.prototype.getSignedUrl = function(method, url) {
var timestamp = new Date().toISOString().replace(/\.\d+Z$/, 'Z');
var signature = this.generateSignature(method, url, timestamp);
- var qs = '';
- qs += '?signature=' + encodeURIComponent(signature);
+ var qs = url.indexOf('?') > 0 ? '&' : '?';
+ qs += 'signature=' + encodeURIComponent(signature);
qs += '&timestamp=' + encodeURIComponent(timestamp);
return url + qs;
@@ -283,153 +291,189 @@ ImboQuery.prototype.toString = ImboQuery.prototype.toQueryString;
/**
* Imbo URL helper
*/
-function ImboUrl(baseUrl, publicKey, privateKey, imageIdentifier) {
- this.data = [];
- this.baseUrl = baseUrl;
- this.publicKey = publicKey;
- this.imageIdentifier = imageIdentifier;
- this.privateKey = privateKey;
-};
+ImboUrl = Class.extend({
+ init: function(baseUrl, publicKey, privateKey) {
+ this.baseUrl = baseUrl;
+ this.publicKey = publicKey;
+ this.privateKey = privateKey;
+ this.accessKey = null;
+ },
+
+ getUrl: function() {
+ var url = this.getRawUrl();
+ var token = this.getAccessToken(url, this.privateKey);
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + 'accessToken=' + token;
+ },
+
+ getAccessToken: function(url, key) {
+ return Crypto.HMAC(Crypto.SHA256, url, key);
+ },
+
+ toString: function() {
+ return this.getUrl();
+ }
+});
-ImboUrl.prototype.border = function(color, width, height) {
- color = (color || '000000').replace(/^#/, '');
- width = parseInt(!isNaN(width) ? 1 : width, 10);
- height = parseInt(!isNaN(height) ? 1 : height, 10);
- return this.append('border:color=' + encodeURIComponent(color) + ',width=' + width + ',height=' + height);
-}
+ImboUserUrl = ImboUrl.extend({
+ getRawUrl: function() {
+ return [this.baseUrl, 'users', this.publicKey].join('/');
+ }
+});
-ImboUrl.prototype.compress = function(quality) {
- quality = parseInt(quality, 10);
- return this.append('compress:quality=' + (quality ? quality : 75));
-}
+ImboImagesUrl = ImboUrl.extend({
+ cacheBreak: false,
-ImboUrl.prototype.convert = function(type) {
- this.imageIdentifier = this.imageIdentifier.substr(0, 32) + '.' + type;
- return this;
-}
+ init: function(baseUrl, publicKey, privateKey, query, cacheBreak) {
+ this.parent(baseUrl, publicKey, privateKey);
+ this.query = query;
+ this.cacheBreak = cacheBreak;
+ },
-ImboUrl.prototype.gif = function() {
- return this.convert('gif');
-}
+ getRawUrl: function() {
+ var url = [this.baseUrl, 'users', this.publicKey, 'images'].join('/');
+ url += this.query ? ((url.indexOf('?') === -1) ? '?' : '&') + this.query.toQueryString() : '';
+ url += this.cacheBreak ? '&cachebreak=' + Math.floor(Date.now() * Math.random()) : '';
+ return url;
+ }
+});
-ImboUrl.prototype.jpg = function() {
- return this.convert('jpg');
-}
+ImboMetadataUrl = ImboUrl.extend({
+ init: function(baseUrl, publicKey, privateKey, imageIdentifier) {
+ this.parent(baseUrl, publicKey, privateKey);
+ this.imageIdentifier = imageIdentifier;
+ },
-ImboUrl.prototype.png = function() {
- return this.convert('png');
-}
+ getRawUrl: function() {
+ return [this.baseUrl, 'users', this.publicKey, 'images', this.imageIdentifier, 'meta'].join('/');
+ }
+});
+
+ImboImageUrl = ImboUrl.extend({
+
+ init: function(baseUrl, publicKey, privateKey, imageIdentifier) {
+ this.parent(baseUrl, publicKey, privateKey);
+ this.imageIdentifier = imageIdentifier;
+ this.data = [];
+ },
+
+ getRawUrl: function() {
+ var queryString = this.getQueryString();
+ var url = [this.baseUrl, 'users', this.publicKey, 'images', this.imageIdentifier].join('/');
+ return url + (queryString.length ? '?' + queryString : '');
+ },
+
+ border: function(color, width, height) {
+ color = (color || '000000').replace(/^#/, '');
+ width = parseInt(!isNaN(width) ? 1 : width, 10);
+ height = parseInt(!isNaN(height) ? 1 : height, 10);
+ return this.append('border:color=' + encodeURIComponent(color) + ',width=' + width + ',height=' + height);
+ },
+
+ compress: function(quality) {
+ quality = parseInt(quality, 10);
+ return this.append('compress:quality=' + (quality ? quality : 75));
+ },
+
+ convert: function(type) {
+ this.imageIdentifier = this.imageIdentifier.substr(0, 32) + '.' + type;
+ return this;
+ },
-ImboUrl.prototype.crop = function(x, y, width, height) {
- return this.append('crop:x=' + x + ',y=' + y + ',width=' + width + ',height=' + height);
-}
+ gif: function() {
+ return this.convert('gif');
+ },
-ImboUrl.prototype.flipHorizontally = function() {
- return this.append('flipHorizontally');
-}
+ jpg: function() {
+ return this.convert('jpg');
+ },
-ImboUrl.prototype.flipVertically = function() {
- return this.append('flipVertically');
-}
+ png: function() {
+ return this.convert('png');
+ },
-ImboUrl.prototype.resize = function(width, height) {
- params = [];
+ crop: function(x, y, width, height) {
+ return this.append('crop:x=' + x + ',y=' + y + ',width=' + width + ',height=' + height);
+ },
- if (width) {
- params.push('width=' + parseInt(width, 10));
- }
+ flipHorizontally: function() {
+ return this.append('flipHorizontally');
+ },
- if (height) {
- params.push('height=' + parseInt(height, 10));
- }
+ flipVertically: function() {
+ return this.append('flipVertically');
+ },
- return this.append('resize:' + params.join(','));
-}
+ resize: function(width, height) {
+ params = [];
-ImboUrl.prototype.maxSize = function(maxWidth, maxHeight) {
- params = [];
+ if (width) {
+ params.push('width=' + parseInt(width, 10));
+ }
- if (maxWidth) {
- params.push('width=' + parseInt(maxWidth, 10));
- }
+ if (height) {
+ params.push('height=' + parseInt(height, 10));
+ }
- if (maxHeight) {
- params.push('height=' + parseInt(maxHeight, 10));
- }
+ return this.append('resize:' + params.join(','));
+ },
- return this.append('maxSize:' + params.join(','));
-}
+ maxSize: function(maxWidth, maxHeight) {
+ params = [];
-ImboUrl.prototype.rotate = function(angle, bg) {
- if (isNaN(angle)) {
- return this;
- }
+ if (maxWidth) {
+ params.push('width=' + parseInt(maxWidth, 10));
+ }
- bg = (bg || '000000').replace(/^#/, '');
- return this.append('rotate:angle=' + angle + ',bg=' + bg);
-}
+ if (maxHeight) {
+ params.push('height=' + parseInt(maxHeight, 10));
+ }
-ImboUrl.prototype.thumbnail = function(width, height, fit) {
- return this.append('thumbnail:width=' + (width || 50) + ',height=' + (height || 50) + ',fit=' + (fit || 'outbound'));
-}
+ return this.append('maxSize:' + params.join(','));
+ },
-ImboUrl.prototype.reset = function() {
- this.imageIdentifier = this.imageIdentifier.substr(0, 32);
- this.data = [];
- return this;
-};
+ rotate: function(angle, bg) {
+ if (isNaN(angle)) {
+ return this;
+ }
-ImboUrl.prototype.append = function(part) {
- this.data.push(part);
- return this;
-};
+ bg = (bg || '000000').replace(/^#/, '');
+ return this.append('rotate:angle=' + angle + ',bg=' + bg);
+ },
-ImboUrl.prototype.getQueryString = function() {
+ thumbnail: function(width, height, fit) {
+ return this.append('thumbnail:width=' + (width || 50) + ',height=' + (height || 50) + ',fit=' + (fit || 'outbound'));
+ },
- if (!this.data.length && this.imageIdentifier.length < 33) {
- // No transformations or custom extensions
- return '';
- }
+ reset: function() {
+ this.imageIdentifier = this.imageIdentifier.substr(0, 32);
+ this.data = [];
+ return this;
+ },
- // Initialize data for the transformation key hash
- var data = [this.publicKey, this.imageIdentifier];
- var query = '';
+ append: function(part) {
+ this.data.push(encodeURIComponent(part));
+ return this;
+ },
+
+ getQueryString: function() {
+ if (!this.data.length) {
+ // No transformations or custom extensions
+ return '';
+ }
- if (this.data.length) {
- // We have some transformations. Generate a transformation key that will be sent to the
- // server so the server can verify if the transformations are valid or not.
- query = 't[]=' + this.data.reduce(function(query, element) {
+ // Initialize data for the transformation key hash
+ var query = 't[]=' + this.data.reduce(function(query, element) {
return query + '&t[]=' + element;
});
- data.push(query);
- }
-
- // Prepare data for the hash
- var transformationKey = Crypto.HMAC(Crypto.MD5, data.join('|'), this.privateKey);
-
- if (!query.length) {
- // No query string. Return only the transformation key
- return 'tk=' + transformationKey;
- }
-
- // Return the query string with the transformation key appended
- return query + '&tk=' + transformationKey;
-};
-
-ImboUrl.prototype.getUrl = function() {
- var url = this.baseUrl + '/users/' + this.publicKey + '/images/' + this.imageIdentifier;
+ return query;
+ },
- if (!this.data.length) {
- return url;
+ toString: function() {
+ return this.getUrl();
}
- return url + '?' + this.getQueryString();
-};
-
-ImboUrl.prototype.toString = function() {
- return this.getUrl();
-};
+});
/**
* Do we have a BlobBuilder? SendAsBinary?
View
64 js/utils/class.js
@@ -0,0 +1,64 @@
+/* Simple JavaScript Inheritance
+ * By John Resig http://ejohn.org/
+ * MIT Licensed.
+ */
+// Inspired by base2 and Prototype
+// slightly changed from original implementation (_super => parent)
+(function(){
+ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\bparent\b/ : /.*/;
+ // The base Class implementation (does nothing)
+ this.Class = function(){};
+
+ // Create a new Class that inherits from this class
+ Class.extend = function(prop) {
+ var parent = this.prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor)
+ initializing = true;
+ var prototype = new this();
+ initializing = false;
+
+ // Copy the properties over onto the new prototype
+ for (var name in prop) {
+ // Check if we're overwriting an existing function
+ prototype[name] = typeof prop[name] == "function" &&
+ typeof parent[name] == "function" && fnTest.test(prop[name]) ?
+ (function(name, fn){
+ return function() {
+ var tmp = this.parent;
+
+ // Add a new .parent() method that is the same method
+ // but on the super-class
+ this.parent = parent[name];
+
+ // The method only need to be bound temporarily, so we
+ // remove it when we're done executing
+ var ret = fn.apply(this, arguments);
+ this.parent = tmp;
+
+ return ret;
+ };
+ })(name, prop[name]) :
+ prop[name];
+ }
+
+ // The dummy class constructor
+ function Class() {
+ // All construction is actually done in the init method
+ if ( !initializing && this.init )
+ this.init.apply(this, arguments);
+ }
+
+ // Populate our constructed prototype object
+ Class.prototype = prototype;
+
+ // Enforce the constructor to be what we expect
+ Class.prototype.constructor = Class;
+
+ // And make this class extendable
+ Class.extend = arguments.callee;
+
+ return Class;
+ };
+})();
View
1  notification.html
@@ -26,6 +26,7 @@
</div>
</section>
+<script src="js/utils/class.js"></script>
<script src="js/utils/dom.js"></script>
<script src="js/notifications.js"></script>
Please sign in to comment.
Something went wrong with that request. Please try again.