Open all Signal links in app
This commit is contained in:
parent
07968ea42b
commit
60d348e7cb
3 changed files with 90 additions and 7 deletions
|
@ -82,6 +82,7 @@ import {
|
||||||
parseSgnlHref,
|
parseSgnlHref,
|
||||||
parseCaptchaHref,
|
parseCaptchaHref,
|
||||||
parseSignalHttpsLink,
|
parseSignalHttpsLink,
|
||||||
|
rewriteSignalHrefsIfNecessary,
|
||||||
} from '../ts/util/sgnlHref';
|
} from '../ts/util/sgnlHref';
|
||||||
import { toggleMaximizedBrowserWindow } from '../ts/util/toggleMaximizedBrowserWindow';
|
import { toggleMaximizedBrowserWindow } from '../ts/util/toggleMaximizedBrowserWindow';
|
||||||
import {
|
import {
|
||||||
|
@ -334,13 +335,15 @@ function prepareUrl(
|
||||||
}).href;
|
}).href;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleUrl(event: Electron.Event, target: string) {
|
async function handleUrl(event: Electron.Event, rawTarget: string) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const parsedUrl = maybeParseUrl(target);
|
const parsedUrl = maybeParseUrl(rawTarget);
|
||||||
if (!parsedUrl) {
|
if (!parsedUrl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const target = rewriteSignalHrefsIfNecessary(rawTarget);
|
||||||
|
|
||||||
const { protocol, hostname } = parsedUrl;
|
const { protocol, hostname } = parsedUrl;
|
||||||
const isDevServer =
|
const isDevServer =
|
||||||
process.env.SIGNAL_ENABLE_HTTP && hostname === 'localhost';
|
process.env.SIGNAL_ENABLE_HTTP && hostname === 'localhost';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2020-2021 Signal Messenger, LLC
|
// Copyright 2020-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -13,6 +13,7 @@ import {
|
||||||
parseCaptchaHref,
|
parseCaptchaHref,
|
||||||
parseE164FromSignalDotMeHash,
|
parseE164FromSignalDotMeHash,
|
||||||
parseSignalHttpsLink,
|
parseSignalHttpsLink,
|
||||||
|
rewriteSignalHrefsIfNecessary,
|
||||||
} from '../../util/sgnlHref';
|
} from '../../util/sgnlHref';
|
||||||
|
|
||||||
function shouldNeverBeCalled() {
|
function shouldNeverBeCalled() {
|
||||||
|
@ -380,4 +381,62 @@ describe('sgnlHref', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('rewriteSignalHrefsIfNecessary', () => {
|
||||||
|
it('rewrites http://signal.group hrefs, making them use HTTPS', () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
rewriteSignalHrefsIfNecessary('http://signal.group/#abc123'),
|
||||||
|
'https://signal.group/#abc123'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rewrites http://signal.art hrefs, making them use HTTPS', () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
rewriteSignalHrefsIfNecessary(
|
||||||
|
'http://signal.art/addstickers/#pack_id=abc123'
|
||||||
|
),
|
||||||
|
'https://signal.art/addstickers/#pack_id=abc123'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rewrites http://signal.me hrefs, making them use HTTPS', () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
rewriteSignalHrefsIfNecessary('http://signal.me/#p/+18885551234'),
|
||||||
|
'https://signal.me/#p/+18885551234'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('removes auth if present', () => {
|
||||||
|
assert.strictEqual(
|
||||||
|
rewriteSignalHrefsIfNecessary(
|
||||||
|
'http://user:pass@signal.group/ab?c=d#ef'
|
||||||
|
),
|
||||||
|
'https://signal.group/ab?c=d#ef'
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
rewriteSignalHrefsIfNecessary(
|
||||||
|
'https://user:pass@signal.group/ab?c=d#ef'
|
||||||
|
),
|
||||||
|
'https://signal.group/ab?c=d#ef'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does nothing to other hrefs', () => {
|
||||||
|
[
|
||||||
|
// Normal URLs
|
||||||
|
'http://example.com',
|
||||||
|
// Already HTTPS
|
||||||
|
'https://signal.art/addstickers/#pack_id=abc123',
|
||||||
|
// Different port
|
||||||
|
'http://signal.group:1234/abc?d=e#fg',
|
||||||
|
// Different subdomain
|
||||||
|
'http://subdomain.signal.group/#abcdef',
|
||||||
|
// Different protocol
|
||||||
|
'ftp://signal.group/#abc123',
|
||||||
|
'ftp://user:pass@signal.group/#abc123',
|
||||||
|
].forEach(href => {
|
||||||
|
assert.strictEqual(rewriteSignalHrefsIfNecessary(href), href);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// Copyright 2020-2021 Signal Messenger, LLC
|
// Copyright 2020-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type { LoggerType } from '../types/Logging';
|
import type { LoggerType } from '../types/Logging';
|
||||||
import { maybeParseUrl } from './url';
|
import { maybeParseUrl } from './url';
|
||||||
import { isValidE164 } from './isValidE164';
|
import { isValidE164 } from './isValidE164';
|
||||||
|
|
||||||
|
const SIGNAL_HOSTS = new Set(['signal.group', 'signal.art', 'signal.me']);
|
||||||
const SIGNAL_DOT_ME_HASH_PREFIX = 'p/';
|
const SIGNAL_DOT_ME_HASH_PREFIX = 'p/';
|
||||||
|
|
||||||
function parseUrl(value: string | URL, logger: LoggerType): undefined | URL {
|
function parseUrl(value: string | URL, logger: LoggerType): undefined | URL {
|
||||||
|
@ -44,9 +45,7 @@ export function isSignalHttpsLink(
|
||||||
!url.password &&
|
!url.password &&
|
||||||
!url.port &&
|
!url.port &&
|
||||||
url.protocol === 'https:' &&
|
url.protocol === 'https:' &&
|
||||||
(url.host === 'signal.group' ||
|
SIGNAL_HOSTS.has(url.host)
|
||||||
url.host === 'signal.art' ||
|
|
||||||
url.host === 'signal.me')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,3 +142,25 @@ export function parseE164FromSignalDotMeHash(hash: string): undefined | string {
|
||||||
const maybeE164 = hash.slice(SIGNAL_DOT_ME_HASH_PREFIX.length);
|
const maybeE164 = hash.slice(SIGNAL_DOT_ME_HASH_PREFIX.length);
|
||||||
return isValidE164(maybeE164, true) ? maybeE164 : undefined;
|
return isValidE164(maybeE164, true) ? maybeE164 : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts `http://signal.group/#abc` to `https://signal.group/#abc`. Does the same for
|
||||||
|
* other Signal hosts, like signal.me. Does nothing to other URLs. Expects a valid href.
|
||||||
|
*/
|
||||||
|
export function rewriteSignalHrefsIfNecessary(href: string): string {
|
||||||
|
const resultUrl = new URL(href);
|
||||||
|
|
||||||
|
const isHttp = resultUrl.protocol === 'http:';
|
||||||
|
const isHttpOrHttps = isHttp || resultUrl.protocol === 'https:';
|
||||||
|
|
||||||
|
if (SIGNAL_HOSTS.has(resultUrl.host) && isHttpOrHttps) {
|
||||||
|
if (isHttp) {
|
||||||
|
resultUrl.protocol = 'https:';
|
||||||
|
}
|
||||||
|
resultUrl.username = '';
|
||||||
|
resultUrl.password = '';
|
||||||
|
return resultUrl.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
return href;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue