diff --git a/src/HtmlUtils.tsx b/src/HtmlUtils.tsx
index 5e83fdc2a0..a37b7f0ac9 100644
--- a/src/HtmlUtils.tsx
+++ b/src/HtmlUtils.tsx
@@ -25,7 +25,6 @@ import _linkifyElement from 'linkifyjs/element';
import _linkifyString from 'linkifyjs/string';
import classNames from 'classnames';
import EMOJIBASE_REGEX from 'emojibase-regex';
-import url from 'url';
import katex from 'katex';
import { AllHtmlEntities } from 'html-entities';
import { IContent } from 'matrix-js-sdk/src/models/event';
@@ -153,10 +152,8 @@ export function getHtmlText(insaneHtml: string): string {
*/
export function isUrlPermitted(inputUrl: string): boolean {
try {
- const parsed = url.parse(inputUrl);
- if (!parsed.protocol) return false;
// URL parser protocol includes the trailing colon
- return PERMITTED_URL_SCHEMES.includes(parsed.protocol.slice(0, -1));
+ return PERMITTED_URL_SCHEMES.includes(new URL(inputUrl).protocol.slice(0, -1));
} catch (e) {
return false;
}
diff --git a/src/Lifecycle.ts b/src/Lifecycle.ts
index 61ded93833..410124a637 100644
--- a/src/Lifecycle.ts
+++ b/src/Lifecycle.ts
@@ -21,6 +21,7 @@ import { createClient } from 'matrix-js-sdk/src/matrix';
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { decryptAES, encryptAES, IEncryptedPayload } from "matrix-js-sdk/src/crypto/aes";
+import { QueryDict } from 'matrix-js-sdk/src/utils';
import { IMatrixClientCreds, MatrixClientPeg } from './MatrixClientPeg';
import SecurityCustomisations from "./customisations/Security";
@@ -65,7 +66,7 @@ interface ILoadSessionOpts {
guestIsUrl?: string;
ignoreGuest?: boolean;
defaultDeviceDisplayName?: string;
- fragmentQueryParams?: Record;
+ fragmentQueryParams?: QueryDict;
}
/**
@@ -118,8 +119,8 @@ export async function loadSession(opts: ILoadSessionOpts = {}): Promise
) {
console.log("Using guest access credentials");
return doSetLoggedIn({
- userId: fragmentQueryParams.guest_user_id,
- accessToken: fragmentQueryParams.guest_access_token,
+ userId: fragmentQueryParams.guest_user_id as string,
+ accessToken: fragmentQueryParams.guest_access_token as string,
homeserverUrl: guestHsUrl,
identityServerUrl: guestIsUrl,
guest: true,
@@ -173,7 +174,7 @@ export async function getStoredSessionOwner(): Promise<[string, boolean]> {
* login, else false
*/
export function attemptTokenLogin(
- queryParams: Record,
+ queryParams: QueryDict,
defaultDeviceDisplayName?: string,
fragmentAfterLogin?: string,
): Promise {
@@ -198,7 +199,7 @@ export function attemptTokenLogin(
homeserver,
identityServer,
"m.login.token", {
- token: queryParams.loginToken,
+ token: queryParams.loginToken as string,
initial_device_display_name: defaultDeviceDisplayName,
},
).then(function(creds) {
diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx
index 15536f260d..785838ffca 100644
--- a/src/components/structures/MatrixChat.tsx
+++ b/src/components/structures/MatrixChat.tsx
@@ -19,7 +19,7 @@ import { createClient } from "matrix-js-sdk/src/matrix";
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
-import { sleep, defer, IDeferred } from "matrix-js-sdk/src/utils";
+import { sleep, defer, IDeferred, QueryDict } from "matrix-js-sdk/src/utils";
// focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss
import 'focus-visible';
@@ -155,7 +155,7 @@ const ONBOARDING_FLOW_STARTERS = [
interface IScreen {
screen: string;
- params?: object;
+ params?: QueryDict;
}
/* eslint-disable camelcase */
@@ -185,9 +185,9 @@ interface IProps { // TODO type things better
onNewScreen: (screen: string, replaceLast: boolean) => void;
enableGuest?: boolean;
// the queryParams extracted from the [real] query-string of the URI
- realQueryParams?: Record;
+ realQueryParams?: QueryDict;
// the initial queryParams extracted from the hash-fragment of the URI
- startingFragmentQueryParams?: Record;
+ startingFragmentQueryParams?: QueryDict;
// called when we have completed a token login
onTokenLoginCompleted?: () => void;
// Represents the screen to display as a result of parsing the initial window.location
@@ -195,7 +195,7 @@ interface IProps { // TODO type things better
// displayname, if any, to set on the device when logging in/registering.
defaultDeviceDisplayName?: string;
// A function that makes a registration URL
- makeRegistrationUrl: (object) => string;
+ makeRegistrationUrl: (params: QueryDict) => string;
}
interface IState {
@@ -298,7 +298,7 @@ export default class MatrixChat extends React.PureComponent {
if (this.screenAfterLogin.screen.startsWith("room/") && params['signurl'] && params['email']) {
// probably a threepid invite - try to store it
const roomId = this.screenAfterLogin.screen.substring("room/".length);
- ThreepidInviteStore.instance.storeInvite(roomId, params as IThreepidInviteWireFormat);
+ ThreepidInviteStore.instance.storeInvite(roomId, params as unknown as IThreepidInviteWireFormat);
}
}
@@ -1952,7 +1952,7 @@ export default class MatrixChat extends React.PureComponent {
this.setState({ serverConfig });
};
- private makeRegistrationUrl = (params: {[key: string]: string}) => {
+ private makeRegistrationUrl = (params: QueryDict) => {
if (this.props.startingFragmentQueryParams.referrer) {
params.referrer = this.props.startingFragmentQueryParams.referrer;
}
@@ -2107,7 +2107,7 @@ export default class MatrixChat extends React.PureComponent {
onForgotPasswordClick={showPasswordReset ? this.onForgotPasswordClick : undefined}
onServerConfigChange={this.onServerConfigChange}
fragmentAfterLogin={fragmentAfterLogin}
- defaultUsername={this.props.startingFragmentQueryParams.defaultUsername}
+ defaultUsername={this.props.startingFragmentQueryParams.defaultUsername as string}
{...this.getServerProperties()}
/>
);
diff --git a/src/utils/HostingLink.js b/src/utils/HostingLink.js
index ff7b0c221c..134e045ca2 100644
--- a/src/utils/HostingLink.js
+++ b/src/utils/HostingLink.js
@@ -14,9 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import url from 'url';
-import qs from 'qs';
-
import SdkConfig from '../SdkConfig';
import { MatrixClientPeg } from '../MatrixClientPeg';
@@ -28,11 +25,8 @@ export function getHostingLink(campaign) {
if (MatrixClientPeg.get().getDomain() !== 'matrix.org') return null;
try {
- const hostingUrl = url.parse(hostingLink);
- const params = qs.parse(hostingUrl.query);
- params.utm_campaign = campaign;
- hostingUrl.search = undefined;
- hostingUrl.query = params;
+ const hostingUrl = new URL(hostingLink);
+ hostingUrl.searchParams.set("utm_campaign", campaign);
return hostingUrl.format();
} catch (e) {
return hostingLink;