Support proxying chat images via camo
Camo: https://github.com/atmos/camo. This has a couple advantages over just allowing images to be dumped as-is: - Prevents mixed-content warnings by allowing the server to proxy HTTP images to an HTTPS camo instance - Protects users' privacy by not exposing their browser directly to the image host - Allows the camo proxy to intercept and reject bad image sources (URLs that are not actually images, gigapixel-sized images likely to DoS users' browsers, etc.) Whitelisting specific domains is supported for cases where the source is known to be trustworthy.
This commit is contained in:
parent
f968521936
commit
22a9acfc90
8 changed files with 194 additions and 4 deletions
54
test/camo.js
Normal file
54
test/camo.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
const assert = require('assert');
|
||||
const Camo = require('../lib/camo');
|
||||
const CamoConfig = require('../lib/configuration/camoconfig').CamoConfig;
|
||||
|
||||
describe('Camo', () => {
|
||||
const config = new CamoConfig({
|
||||
camo: {
|
||||
server: 'http://localhost:8081',
|
||||
key: '9LKC7708ZHOVRCTLOLE3G2YJ0U1T8F96',
|
||||
'whitelisted-domains': ['def.xyz']
|
||||
}
|
||||
});
|
||||
|
||||
describe('#camoify', () => {
|
||||
it('constructs a camo url', () => {
|
||||
const result = Camo.camoify(config, 'http://abc.xyz/image.jpeg');
|
||||
assert.strictEqual(result, 'http://localhost:8081/a9c295dd7d8dcbc8247dec97ac5d9b4ee8baeb31/687474703a2f2f6162632e78797a2f696d6167652e6a706567');
|
||||
});
|
||||
|
||||
it('bypasses camo for whitelisted domains', () => {
|
||||
const result = Camo.camoify(config, 'http://def.xyz/image.jpeg');
|
||||
assert.strictEqual(result, 'https://def.xyz/image.jpeg');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#transformImgTags', () => {
|
||||
it('transforms an img tag with a src', () => {
|
||||
const attribs = {
|
||||
src: 'http://abc.xyz/image.jpeg',
|
||||
'class': 'some-image'
|
||||
};
|
||||
const expectedAttribs = {
|
||||
src: 'http://localhost:8081/a9c295dd7d8dcbc8247dec97ac5d9b4ee8baeb31/687474703a2f2f6162632e78797a2f696d6167652e6a706567',
|
||||
'class': 'some-image'
|
||||
};
|
||||
const result = Camo.transformImgTags(config, 'img', attribs);
|
||||
assert.deepStrictEqual(result, { tagName: 'img', attribs: expectedAttribs });
|
||||
});
|
||||
|
||||
it('skips img tags with no src', () => {
|
||||
const attribs = { 'class': 'some-image' };
|
||||
const result = Camo.transformImgTags(config, 'img', attribs);
|
||||
assert.deepStrictEqual(result, { tagName: 'img', attribs: attribs });
|
||||
});
|
||||
|
||||
it('fails gracefully', () => {
|
||||
const attribs = { src: 'http://abc.xyz/image.jpeg' };
|
||||
const config = new CamoConfig({ camo: { enabled: true }});
|
||||
config.getKey = () => { throw new Error('something happened'); };
|
||||
const result = Camo.transformImgTags(config, 'img', attribs);
|
||||
assert.deepStrictEqual(result, { tagName: 'img', attribs: attribs });
|
||||
});
|
||||
});
|
||||
});
|
||||
25
test/configuration/camoconfig.js
Normal file
25
test/configuration/camoconfig.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const assert = require('assert');
|
||||
const CamoConfig = require('../../lib/configuration/camoconfig').CamoConfig;
|
||||
|
||||
describe('CamoConfig', () => {
|
||||
describe('#constructor', () => {
|
||||
it('strips trailing slashes from the server', () => {
|
||||
const config = new CamoConfig({
|
||||
camo: {
|
||||
server: 'http://abc.xyz/'
|
||||
}
|
||||
});
|
||||
assert.strictEqual(config.getServer(), 'http://abc.xyz');
|
||||
});
|
||||
|
||||
it('defaults to enabled=false', () => {
|
||||
assert.strictEqual(new CamoConfig().isEnabled(), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getWhitelistedDomains', () => {
|
||||
it('defaults to an empty array', () => {
|
||||
assert.deepStrictEqual(new CamoConfig().getWhitelistedDomains(), []);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue