mirror of
https://github.com/Spengreb/sync.git
synced 2026-05-14 19:42:06 +00:00
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.
43 lines
1.5 KiB
JavaScript
43 lines
1.5 KiB
JavaScript
// @flow
|
|
import crypto from 'crypto';
|
|
import { LoggerFactory } from '@calzoneman/jsli';
|
|
import * as urlparse from 'url';
|
|
import { CamoConfig } from './configuration/camoconfig';
|
|
|
|
const LOGGER = LoggerFactory.getLogger('camo');
|
|
|
|
function isWhitelisted(camoConfig: CamoConfig, url: string): boolean {
|
|
const whitelistedDomains = camoConfig.getWhitelistedDomains();
|
|
const parsed = urlparse.parse(url);
|
|
return whitelistedDomains.includes(parsed.hostname);
|
|
}
|
|
|
|
export function camoify(camoConfig: CamoConfig, url: string): string {
|
|
if (typeof url !== 'string') {
|
|
throw new TypeError(`camoify expected a string, not [${url}]`);
|
|
}
|
|
|
|
if (isWhitelisted(camoConfig, url)) {
|
|
return url.replace(/^http:/, 'https:');
|
|
}
|
|
|
|
const hmac = crypto.createHmac('sha1', camoConfig.getKey());
|
|
hmac.update(url);
|
|
const digest = hmac.digest('hex');
|
|
const hexUrl = Buffer.from(url, 'utf8').toString('hex');
|
|
return `${camoConfig.getServer()}/${digest}/${hexUrl}`;
|
|
}
|
|
|
|
export function transformImgTags(camoConfig: CamoConfig, tagName: string, attribs: Object) {
|
|
if (typeof attribs.src === 'string') {
|
|
try {
|
|
const oldSrc = attribs.src;
|
|
attribs.src = camoify(camoConfig, attribs.src);
|
|
LOGGER.debug('Camoified "%s" to "%s"', oldSrc, attribs.src);
|
|
} catch (error) {
|
|
LOGGER.error(`Failed to generate camo URL for "${attribs.src}": ${error}`);
|
|
}
|
|
}
|
|
|
|
return { tagName, attribs };
|
|
}
|