Merge pull request #4399 from matrix-org/t3chguy/querystring

pull/21833/head
Michael Telatynski 2021-07-16 19:57:24 +01:00 committed by GitHub
commit 45e0515b39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 25 deletions

View File

@ -25,7 +25,6 @@ import _linkifyElement from 'linkifyjs/element';
import _linkifyString from 'linkifyjs/string'; import _linkifyString from 'linkifyjs/string';
import classNames from 'classnames'; import classNames from 'classnames';
import EMOJIBASE_REGEX from 'emojibase-regex'; import EMOJIBASE_REGEX from 'emojibase-regex';
import url from 'url';
import katex from 'katex'; import katex from 'katex';
import { AllHtmlEntities } from 'html-entities'; import { AllHtmlEntities } from 'html-entities';
import { IContent } from 'matrix-js-sdk/src/models/event'; 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 { export function isUrlPermitted(inputUrl: string): boolean {
try { try {
const parsed = url.parse(inputUrl);
if (!parsed.protocol) return false;
// URL parser protocol includes the trailing colon // 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) { } catch (e) {
return false; return false;
} }

View File

@ -21,6 +21,7 @@ import { createClient } from 'matrix-js-sdk/src/matrix';
import { InvalidStoreError } from "matrix-js-sdk/src/errors"; import { InvalidStoreError } from "matrix-js-sdk/src/errors";
import { MatrixClient } from "matrix-js-sdk/src/client"; import { MatrixClient } from "matrix-js-sdk/src/client";
import { decryptAES, encryptAES, IEncryptedPayload } from "matrix-js-sdk/src/crypto/aes"; 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 { IMatrixClientCreds, MatrixClientPeg } from './MatrixClientPeg';
import SecurityCustomisations from "./customisations/Security"; import SecurityCustomisations from "./customisations/Security";
@ -65,7 +66,7 @@ interface ILoadSessionOpts {
guestIsUrl?: string; guestIsUrl?: string;
ignoreGuest?: boolean; ignoreGuest?: boolean;
defaultDeviceDisplayName?: string; defaultDeviceDisplayName?: string;
fragmentQueryParams?: Record<string, string>; fragmentQueryParams?: QueryDict;
} }
/** /**
@ -118,8 +119,8 @@ export async function loadSession(opts: ILoadSessionOpts = {}): Promise<boolean>
) { ) {
console.log("Using guest access credentials"); console.log("Using guest access credentials");
return doSetLoggedIn({ return doSetLoggedIn({
userId: fragmentQueryParams.guest_user_id, userId: fragmentQueryParams.guest_user_id as string,
accessToken: fragmentQueryParams.guest_access_token, accessToken: fragmentQueryParams.guest_access_token as string,
homeserverUrl: guestHsUrl, homeserverUrl: guestHsUrl,
identityServerUrl: guestIsUrl, identityServerUrl: guestIsUrl,
guest: true, guest: true,
@ -173,7 +174,7 @@ export async function getStoredSessionOwner(): Promise<[string, boolean]> {
* login, else false * login, else false
*/ */
export function attemptTokenLogin( export function attemptTokenLogin(
queryParams: Record<string, string>, queryParams: QueryDict,
defaultDeviceDisplayName?: string, defaultDeviceDisplayName?: string,
fragmentAfterLogin?: string, fragmentAfterLogin?: string,
): Promise<boolean> { ): Promise<boolean> {
@ -198,7 +199,7 @@ export function attemptTokenLogin(
homeserver, homeserver,
identityServer, identityServer,
"m.login.token", { "m.login.token", {
token: queryParams.loginToken, token: queryParams.loginToken as string,
initial_device_display_name: defaultDeviceDisplayName, initial_device_display_name: defaultDeviceDisplayName,
}, },
).then(function(creds) { ).then(function(creds) {

View File

@ -19,7 +19,7 @@ import { createClient } from "matrix-js-sdk/src/matrix";
import { InvalidStoreError } from "matrix-js-sdk/src/errors"; import { InvalidStoreError } from "matrix-js-sdk/src/errors";
import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; 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 // focus-visible is a Polyfill for the :focus-visible CSS pseudo-attribute used by _AccessibleButton.scss
import 'focus-visible'; import 'focus-visible';
@ -155,7 +155,7 @@ const ONBOARDING_FLOW_STARTERS = [
interface IScreen { interface IScreen {
screen: string; screen: string;
params?: object; params?: QueryDict;
} }
/* eslint-disable camelcase */ /* eslint-disable camelcase */
@ -185,9 +185,9 @@ interface IProps { // TODO type things better
onNewScreen: (screen: string, replaceLast: boolean) => void; onNewScreen: (screen: string, replaceLast: boolean) => void;
enableGuest?: boolean; enableGuest?: boolean;
// the queryParams extracted from the [real] query-string of the URI // the queryParams extracted from the [real] query-string of the URI
realQueryParams?: Record<string, string>; realQueryParams?: QueryDict;
// the initial queryParams extracted from the hash-fragment of the URI // the initial queryParams extracted from the hash-fragment of the URI
startingFragmentQueryParams?: Record<string, string>; startingFragmentQueryParams?: QueryDict;
// called when we have completed a token login // called when we have completed a token login
onTokenLoginCompleted?: () => void; onTokenLoginCompleted?: () => void;
// Represents the screen to display as a result of parsing the initial window.location // 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. // displayname, if any, to set on the device when logging in/registering.
defaultDeviceDisplayName?: string; defaultDeviceDisplayName?: string;
// A function that makes a registration URL // A function that makes a registration URL
makeRegistrationUrl: (object) => string; makeRegistrationUrl: (params: QueryDict) => string;
} }
interface IState { interface IState {
@ -298,7 +298,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
if (this.screenAfterLogin.screen.startsWith("room/") && params['signurl'] && params['email']) { if (this.screenAfterLogin.screen.startsWith("room/") && params['signurl'] && params['email']) {
// probably a threepid invite - try to store it // probably a threepid invite - try to store it
const roomId = this.screenAfterLogin.screen.substring("room/".length); 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<IProps, IState> {
this.setState({ serverConfig }); this.setState({ serverConfig });
}; };
private makeRegistrationUrl = (params: {[key: string]: string}) => { private makeRegistrationUrl = (params: QueryDict) => {
if (this.props.startingFragmentQueryParams.referrer) { if (this.props.startingFragmentQueryParams.referrer) {
params.referrer = this.props.startingFragmentQueryParams.referrer; params.referrer = this.props.startingFragmentQueryParams.referrer;
} }
@ -2107,7 +2107,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
onForgotPasswordClick={showPasswordReset ? this.onForgotPasswordClick : undefined} onForgotPasswordClick={showPasswordReset ? this.onForgotPasswordClick : undefined}
onServerConfigChange={this.onServerConfigChange} onServerConfigChange={this.onServerConfigChange}
fragmentAfterLogin={fragmentAfterLogin} fragmentAfterLogin={fragmentAfterLogin}
defaultUsername={this.props.startingFragmentQueryParams.defaultUsername} defaultUsername={this.props.startingFragmentQueryParams.defaultUsername as string}
{...this.getServerProperties()} {...this.getServerProperties()}
/> />
); );

View File

@ -14,9 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import url from 'url';
import qs from 'qs';
import SdkConfig from '../SdkConfig'; import SdkConfig from '../SdkConfig';
import { MatrixClientPeg } from '../MatrixClientPeg'; import { MatrixClientPeg } from '../MatrixClientPeg';
@ -28,11 +25,8 @@ export function getHostingLink(campaign) {
if (MatrixClientPeg.get().getDomain() !== 'matrix.org') return null; if (MatrixClientPeg.get().getDomain() !== 'matrix.org') return null;
try { try {
const hostingUrl = url.parse(hostingLink); const hostingUrl = new URL(hostingLink);
const params = qs.parse(hostingUrl.query); hostingUrl.searchParams.set("utm_campaign", campaign);
params.utm_campaign = campaign;
hostingUrl.search = undefined;
hostingUrl.query = params;
return hostingUrl.format(); return hostingUrl.format();
} catch (e) { } catch (e) {
return hostingLink; return hostingLink;