mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-53904] Fix MM-53904 (#24622)
* Fix MM-53904 * Simplify regex * Simplify utils regex * Fix lint * Address feedback and polish regex --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
6f4d362f9f
commit
f62634622f
@ -11,6 +11,8 @@ import PlaybookRunner from 'components/channel_layout/playbook_runner';
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
import PermalinkView from 'components/permalink_view';
|
||||
|
||||
import {IDENTIFIER_PATH_PATTERN, ID_PATH_PATTERN, TEAM_NAME_PATH_PATTERN} from 'utils/path';
|
||||
|
||||
import type {OwnProps, PropsFromRedux} from './index';
|
||||
|
||||
const LazyChannelHeaderMobile = makeAsyncComponent(
|
||||
@ -92,7 +94,7 @@ export default class CenterChannel extends React.PureComponent<Props, State> {
|
||||
<div className='row main'>
|
||||
<Switch>
|
||||
<Route
|
||||
path={`${url}/pl/:postid`}
|
||||
path={`${url}/pl/:postid(${ID_PATH_PATTERN})`}
|
||||
render={(props) => (
|
||||
<PermalinkView
|
||||
{...props}
|
||||
@ -101,22 +103,22 @@ export default class CenterChannel extends React.PureComponent<Props, State> {
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path='/:team/:path(channels|messages)/:identifier/:postid?'
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/:path(channels|messages)/:identifier(${IDENTIFIER_PATH_PATTERN})/:postid(${ID_PATH_PATTERN})?`}
|
||||
component={ChannelIdentifierRouter}
|
||||
/>
|
||||
<Route
|
||||
path='/:team/_playbooks/:playbookId/run'
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/_playbooks/:playbookId(${ID_PATH_PATTERN})/run`}
|
||||
>
|
||||
<PlaybookRunner/>
|
||||
</Route>
|
||||
{isCollapsedThreadsEnabled ? (
|
||||
<Route
|
||||
path='/:team/threads/:threadIdentifier?'
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/threads/:threadIdentifier(${ID_PATH_PATTERN})?`}
|
||||
component={LazyGlobalThreads}
|
||||
/>
|
||||
) : null}
|
||||
<Route
|
||||
path='/:team/drafts'
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/drafts`}
|
||||
component={LazyDrafts}
|
||||
/>
|
||||
|
||||
|
@ -117,7 +117,7 @@ exports[`components/Root Routes Should mount public product routes 1`] = `
|
||||
/>
|
||||
<LoggedInRoute
|
||||
component={[Function]}
|
||||
path="/:team"
|
||||
path="/:team([a-z0-9\\\\-_]+)"
|
||||
theme={Object {}}
|
||||
/>
|
||||
<Connect(RootRedirect) />
|
||||
|
@ -55,6 +55,7 @@ import Pluggable from 'plugins/pluggable';
|
||||
import A11yController from 'utils/a11y_controller';
|
||||
import {PageLoadContext, StoragePrefixes} from 'utils/constants';
|
||||
import {EmojiIndicesByAlias} from 'utils/emoji';
|
||||
import {TEAM_NAME_PATH_PATTERN} from 'utils/path';
|
||||
import {getSiteURL} from 'utils/url';
|
||||
import * as UserAgent from 'utils/user_agent';
|
||||
import * as Utils from 'utils/utils';
|
||||
@ -111,7 +112,7 @@ const OnBoardingTaskList = makeAsyncComponent('OnboardingTaskList', LazyOnBoardi
|
||||
|
||||
type LoggedInRouteProps<T> = {
|
||||
component: React.ComponentType<T>;
|
||||
path: string;
|
||||
path: string | string[];
|
||||
theme?: Theme; // the routes that send the theme are the ones that will actually need to show the onboarding tasklist
|
||||
};
|
||||
function LoggedInRoute<T>(props: LoggedInRouteProps<T>) {
|
||||
@ -644,7 +645,7 @@ export default class Root extends React.PureComponent<Props, State> {
|
||||
))}
|
||||
<LoggedInRoute
|
||||
theme={this.props.theme}
|
||||
path={'/:team'}
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})`}
|
||||
component={TeamController}
|
||||
/>
|
||||
<RootRedirect/>
|
||||
|
@ -19,6 +19,7 @@ import useTelemetryIdentitySync from 'components/common/hooks/useTelemetryIdenti
|
||||
|
||||
import Constants from 'utils/constants';
|
||||
import {cmdOrCtrlPressed, isKeyPressed} from 'utils/keyboard';
|
||||
import {TEAM_NAME_PATH_PATTERN} from 'utils/path';
|
||||
import {isIosSafari} from 'utils/user_agent';
|
||||
|
||||
import type {OwnProps, PropsFromRedux} from './index';
|
||||
@ -208,17 +209,17 @@ function TeamController(props: Props) {
|
||||
return (
|
||||
<Switch>
|
||||
<Route
|
||||
path={'/:team/integrations'}
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/integrations`}
|
||||
component={BackstageController}
|
||||
/>
|
||||
<Route
|
||||
path={'/:team/emoji'}
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/emoji`}
|
||||
component={BackstageController}
|
||||
/>
|
||||
{props.plugins?.map((plugin) => (
|
||||
<Route
|
||||
key={plugin.id}
|
||||
path={'/:team/' + (plugin as any).route}
|
||||
path={`/:team(${TEAM_NAME_PATH_PATTERN})/` + (plugin as any).route}
|
||||
render={() => (
|
||||
<Pluggable
|
||||
pluggableName={'NeedsTeamComponent'}
|
||||
|
19
webapp/channels/src/utils/path.ts
Normal file
19
webapp/channels/src/utils/path.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const ID_PATH_PATTERN = '[a-z0-9]{26}';
|
||||
|
||||
// This should cover:
|
||||
// - Team name (lowercase english characters, numbers or -)
|
||||
// - Two ids separated by __ (userID__userID)
|
||||
export const TEAM_NAME_PATH_PATTERN = '[a-z0-9\\-_]+';
|
||||
|
||||
// This should cover:
|
||||
// - Channel name
|
||||
// - Channel ID
|
||||
// - Group Channel Name (40 length UID)
|
||||
// - DM Name (userID__userID)
|
||||
// - Username prefixed by a @
|
||||
// - User ID
|
||||
// - Email
|
||||
export const IDENTIFIER_PATH_PATTERN = '[@a-zA-Z\\-_0-9][@a-zA-Z\\-_0-9.]*';
|
@ -1333,7 +1333,7 @@ export function isValidPassword(password: string, passwordConfig: ReturnType<typ
|
||||
}
|
||||
|
||||
function isChannelOrPermalink(link: string) {
|
||||
let match = (/\/([^/]+)\/channels\/(\S+)/).exec(link);
|
||||
let match = (/\/([a-z0-9\-_]+)\/channels\/([a-z0-9\-__][a-z0-9\-__.]+)/).exec(link);
|
||||
if (match) {
|
||||
return {
|
||||
type: 'channel',
|
||||
@ -1341,7 +1341,7 @@ function isChannelOrPermalink(link: string) {
|
||||
channelName: match[2],
|
||||
};
|
||||
}
|
||||
match = (/\/([^/]+)\/pl\/(\w+)/).exec(link);
|
||||
match = (/\/([a-z0-9\-__]+)\/pl\/([a-z0-9]+)/).exec(link);
|
||||
if (match) {
|
||||
return {
|
||||
type: 'permalink',
|
||||
|
Loading…
Reference in New Issue
Block a user