camo: support URL encoding option
This commit is contained in:
parent
54045766f2
commit
486ce04a3e
|
@ -11,3 +11,5 @@ whitelisted-domains = [
|
||||||
'i.imgur.com',
|
'i.imgur.com',
|
||||||
'i.4cdn.org'
|
'i.4cdn.org'
|
||||||
]
|
]
|
||||||
|
# Whether to use URL encoding ("url") or hex encoding ("hex") for the target URL.
|
||||||
|
encoding = 'url'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.39.3",
|
"version": "3.39.4",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
10
src/camo.js
10
src/camo.js
|
@ -24,8 +24,14 @@ export function camoify(camoConfig: CamoConfig, url: string): string {
|
||||||
const hmac = crypto.createHmac('sha1', camoConfig.getKey());
|
const hmac = crypto.createHmac('sha1', camoConfig.getKey());
|
||||||
hmac.update(url);
|
hmac.update(url);
|
||||||
const digest = hmac.digest('hex');
|
const digest = hmac.digest('hex');
|
||||||
const hexUrl = Buffer.from(url, 'utf8').toString('hex');
|
// https://github.com/atmos/camo#url-formats
|
||||||
return `${camoConfig.getServer()}/${digest}/${hexUrl}`;
|
if (camoConfig.getEncoding() === 'hex') {
|
||||||
|
const hexUrl = Buffer.from(url, 'utf8').toString('hex');
|
||||||
|
return `${camoConfig.getServer()}/${digest}/${hexUrl}`;
|
||||||
|
} else {
|
||||||
|
const encoded = encodeURIComponent(url);
|
||||||
|
return `${camoConfig.getServer()}/${digest}?url=${encoded}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformImgTags(camoConfig: CamoConfig, tagName: string, attribs: Object) {
|
export function transformImgTags(camoConfig: CamoConfig, tagName: string, attribs: Object) {
|
||||||
|
|
|
@ -4,6 +4,14 @@ class CamoConfig {
|
||||||
if (this.config.server) {
|
if (this.config.server) {
|
||||||
this.config.server = this.config.server.replace(/\/+$/, '');
|
this.config.server = this.config.server.replace(/\/+$/, '');
|
||||||
}
|
}
|
||||||
|
this.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
validate() {
|
||||||
|
if (this.config.encoding
|
||||||
|
&& !~['url', 'hex'].indexOf(this.config.encoding)) {
|
||||||
|
throw new Error(`Value for key 'encoding' must be either 'url' or 'hex', not '${this.config.encoding}'`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
|
@ -21,6 +29,10 @@ class CamoConfig {
|
||||||
getWhitelistedDomains() {
|
getWhitelistedDomains() {
|
||||||
return this.config['whitelisted-domains'] || [];
|
return this.config['whitelisted-domains'] || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEncoding() {
|
||||||
|
return this.config.encoding || 'url';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { CamoConfig };
|
export { CamoConfig };
|
||||||
|
|
17
test/camo.js
17
test/camo.js
|
@ -7,7 +7,8 @@ describe('Camo', () => {
|
||||||
camo: {
|
camo: {
|
||||||
server: 'http://localhost:8081',
|
server: 'http://localhost:8081',
|
||||||
key: '9LKC7708ZHOVRCTLOLE3G2YJ0U1T8F96',
|
key: '9LKC7708ZHOVRCTLOLE3G2YJ0U1T8F96',
|
||||||
'whitelisted-domains': ['def.xyz']
|
'whitelisted-domains': ['def.xyz'],
|
||||||
|
encoding: 'hex'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,6 +18,20 @@ describe('Camo', () => {
|
||||||
assert.strictEqual(result, 'http://localhost:8081/a9c295dd7d8dcbc8247dec97ac5d9b4ee8baeb31/687474703a2f2f6162632e78797a2f696d6167652e6a706567');
|
assert.strictEqual(result, 'http://localhost:8081/a9c295dd7d8dcbc8247dec97ac5d9b4ee8baeb31/687474703a2f2f6162632e78797a2f696d6167652e6a706567');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('constructs a camo url using url encoding', () => {
|
||||||
|
const config = new CamoConfig({
|
||||||
|
camo: {
|
||||||
|
server: 'http://localhost:8081',
|
||||||
|
key: '9LKC7708ZHOVRCTLOLE3G2YJ0U1T8F96',
|
||||||
|
'whitelisted-domains': ['def.xyz'],
|
||||||
|
encoding: 'url'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = Camo.camoify(config, 'http://abc.xyz/image.jpeg');
|
||||||
|
assert.strictEqual(result, 'http://localhost:8081/a9c295dd7d8dcbc8247dec97ac5d9b4ee8baeb31?url=http%3A%2F%2Fabc.xyz%2Fimage.jpeg');
|
||||||
|
});
|
||||||
|
|
||||||
it('bypasses camo for whitelisted domains', () => {
|
it('bypasses camo for whitelisted domains', () => {
|
||||||
const result = Camo.camoify(config, 'http://def.xyz/image.jpeg');
|
const result = Camo.camoify(config, 'http://def.xyz/image.jpeg');
|
||||||
assert.strictEqual(result, 'https://def.xyz/image.jpeg');
|
assert.strictEqual(result, 'https://def.xyz/image.jpeg');
|
||||||
|
|
|
@ -15,6 +15,17 @@ describe('CamoConfig', () => {
|
||||||
it('defaults to enabled=false', () => {
|
it('defaults to enabled=false', () => {
|
||||||
assert.strictEqual(new CamoConfig().isEnabled(), false);
|
assert.strictEqual(new CamoConfig().isEnabled(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('validates that encoding must be either url or hex', () => {
|
||||||
|
|
||||||
|
assert.throws(() => {
|
||||||
|
new CamoConfig({
|
||||||
|
camo: {
|
||||||
|
encoding: 'asdjfnasdf'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, /must be either 'url' or 'hex'/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#getWhitelistedDomains', () => {
|
describe('#getWhitelistedDomains', () => {
|
||||||
|
@ -22,4 +33,10 @@ describe('CamoConfig', () => {
|
||||||
assert.deepStrictEqual(new CamoConfig().getWhitelistedDomains(), []);
|
assert.deepStrictEqual(new CamoConfig().getWhitelistedDomains(), []);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getEncoding', () => {
|
||||||
|
it('defaults to url', () => {
|
||||||
|
assert.deepStrictEqual(new CamoConfig().getEncoding(), 'url');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue