Compare commits

...

6 commits

Author SHA1 Message Date
unified-ci-app[bot]
b645c2bc2e
Bump app build number to 500 (#7721)
Some checks failed
github-release / test (push) Has been cancelled
github-release / build-ios-unsigned (push) Has been cancelled
github-release / build-android-unsigned (push) Has been cancelled
github-release / release (push) Has been cancelled
Co-authored-by: runner <runner@Mac-1702642798759.local>
2023-12-15 13:49:21 +01:00
Mario Vitale
46c0f59692
Cherrypick bump build 497 for 2.11 (#7693) 2023-11-29 14:18:40 +01:00
Caleb Roseland
502d304101
Merge pull request #7689 from mattermost/release-2.11-7613 2023-11-28 12:28:04 -06:00
Caleb Roseland
48f31e753b Merge pull request #7613 from mattermost/MM-53902-cont 2023-11-28 11:43:04 -06:00
Mario Vitale
9465cb199a
Manual cherrypick of PR #7668 (#7669) 2023-11-16 17:43:54 +01:00
Mattermost Build
bcbbc34f1e
Allow connecting to a previous server if credentials are not in the keychain (#7661) (#7662) 2023-11-14 22:04:20 +08:00
14 changed files with 426 additions and 131 deletions

View file

@ -110,8 +110,8 @@ android {
applicationId "com.mattermost.rnbeta"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 493
versionName "2.10.0"
versionCode 500
versionName "2.11.0"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}

View file

@ -143,7 +143,7 @@ export const handleGotoLocation = async (serverUrl: string, intl: IntlShape, loc
const match = matchDeepLink(location, serverUrl, config?.SiteURL);
if (match) {
handleDeepLink(match, intl, location);
handleDeepLink(match.url, intl, location);
} else {
const {formatMessage} = intl;
const onError = () => Alert.alert(

View file

@ -77,9 +77,9 @@ const MarkdownLink = ({children, experimentalNormalizeMarkdownLinks, href, siteU
const match = matchDeepLink(url, serverUrl, siteURL);
if (match) {
const {error} = await handleDeepLink(match, intl);
const {error} = await handleDeepLink(match.url, intl);
if (error) {
tryOpenURL(match, onError);
tryOpenURL(match.url, onError);
}
} else {
tryOpenURL(url, onError);

View file

@ -17,6 +17,7 @@ import AppVersion from '@components/app_version';
import {Screens, Launch} from '@constants';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {t} from '@i18n';
import {getServerCredentials} from '@init/credentials';
import PushNotifications from '@init/push_notifications';
import NetworkManager from '@managers/network_manager';
import {getServerByDisplayName, getServerByIdentifier} from '@queries/app/servers';
@ -244,7 +245,8 @@ const Server = ({
}
const server = await getServerByDisplayName(displayName);
if (server && server.lastActiveAt > 0) {
const credentials = await getServerCredentials(serverUrl);
if (server && server.lastActiveAt > 0 && credentials?.token) {
setButtonDisabled(true);
setDisplayNameError(formatMessage({
id: 'mobile.server_name.exists',
@ -330,9 +332,10 @@ const Server = ({
}
const server = await getServerByIdentifier(data.config.DiagnosticId);
const credentials = await getServerCredentials(serverUrl);
setConnecting(false);
if (server && server.lastActiveAt > 0) {
if (server && server.lastActiveAt > 0 && credentials?.token) {
setButtonDisabled(true);
setUrlError(formatMessage({
id: 'mobile.server_identifier.exists',

View file

@ -1,12 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {match} from 'path-to-regexp';
import {createIntl, type IntlShape} from 'react-intl';
import urlParse from 'url-parse';
import {makeDirectChannel, switchToChannelByName} from '@actions/remote/channel';
import {showPermalink} from '@actions/remote/permalink';
import {fetchUsersByUsernames} from '@actions/remote/user';
import DeepLinkType from '@app/constants/deep_linking';
import {DeepLink, Launch, Screens} from '@constants';
import {getDefaultThemeByAppearance} from '@context/theme';
import DatabaseManager from '@database/manager';
@ -21,7 +23,14 @@ import {alertErrorWithFallback, errorBadChannel, errorUnkownUser} from '@utils/d
import {logError} from '@utils/log';
import {escapeRegex} from '@utils/markdown';
import {addNewServer} from '@utils/server';
import {removeProtocol} from '@utils/url';
import {
TEAM_NAME_PATH_PATTERN,
IDENTIFIER_PATH_PATTERN,
ID_PATH_PATTERN,
PLUGIN_ID_PATH_PATTERN,
} from '@utils/url/path';
import {removeProtocol} from '../url';
import type {DeepLinkChannel, DeepLinkDM, DeepLinkGM, DeepLinkPermalink, DeepLinkWithData, LaunchProps} from '@typings/launch';
import type {AvailableScreens} from '@typings/screens/navigation';
@ -86,7 +95,7 @@ export async function handleDeepLink(deepLinkUrl: string, intlShape?: IntlShape,
}
case DeepLink.GroupMessage: {
const deepLinkData = parsed.data as DeepLinkGM;
switchToChannelByName(existingServerUrl, deepLinkData.channelId, deepLinkData.teamName, errorBadChannel, intl);
switchToChannelByName(existingServerUrl, deepLinkData.channelName, deepLinkData.teamName, errorBadChannel, intl);
break;
}
case DeepLink.Permalink: {
@ -114,80 +123,89 @@ export async function handleDeepLink(deepLinkUrl: string, intlShape?: IntlShape,
}
}
type ChannelPathParams = {
hostname: string;
serverUrl: string;
teamName: string;
path: 'channels' | 'messages';
identifier: string;
};
const CHANNEL_PATH = `:serverUrl(.*)/:teamName(${TEAM_NAME_PATH_PATTERN})/:path(channels|messages)/:identifier(${IDENTIFIER_PATH_PATTERN})`;
export const matchChannelDeeplink = match<ChannelPathParams>(CHANNEL_PATH);
type PermalinkPathParams = {
serverUrl: string;
teamName: string;
postId: string;
};
const PERMALINK_PATH = `:serverUrl(.*)/:teamName(${TEAM_NAME_PATH_PATTERN})/pl/:postId(${ID_PATH_PATTERN})`;
export const matchPermalinkDeeplink = match<PermalinkPathParams>(PERMALINK_PATH);
export function parseDeepLink(deepLinkUrl: string): DeepLinkWithData {
try {
const url = removeProtocol(decodeURIComponent(deepLinkUrl));
const url = removeProtocol(deepLinkUrl);
if (url.includes('../') || url.includes('/..')) {
return {type: DeepLink.Invalid, url: deepLinkUrl};
const channelMatch = matchChannelDeeplink(url);
if (channelMatch) {
const {params: {serverUrl, teamName, path, identifier}} = channelMatch;
if (path === 'channels') {
return {type: DeepLink.Channel, url: deepLinkUrl, data: {serverUrl, teamName, channelName: identifier}};
}
if (path === 'messages') {
if (identifier.startsWith('@')) {
return {type: DeepLink.DirectMessage, url: deepLinkUrl, data: {serverUrl, teamName, userName: identifier.substring(1)}};
}
return {type: DeepLink.GroupMessage, url: deepLinkUrl, data: {serverUrl, teamName, channelName: identifier}};
}
}
let match = new RegExp('(.*)\\/([^\\/]+)\\/channels\\/(\\S+)').exec(url);
if (match) {
return {type: DeepLink.Channel, url: deepLinkUrl, data: {serverUrl: match[1], teamName: match[2], channelName: match[3]}};
const permalinkMatch = matchPermalinkDeeplink(url);
if (permalinkMatch) {
const {params: {serverUrl, teamName, postId}} = permalinkMatch;
return {type: DeepLink.Permalink, url: deepLinkUrl, data: {serverUrl, teamName, postId}};
}
match = new RegExp('(.*)\\/([^\\/]+)\\/pl\\/(\\w+)').exec(url);
if (match) {
return {type: DeepLink.Permalink, url: deepLinkUrl, data: {serverUrl: match[1], teamName: match[2], postId: match[3]}};
const pluginMatch = match<{serverUrl: string; id: string; route?: string}>(`:serverUrl(.*)/plugins/:id(${PLUGIN_ID_PATH_PATTERN})/:route(.*)?`)(url);
if (pluginMatch) {
const {params: {serverUrl, id, route}} = pluginMatch;
return {type: DeepLink.Plugin, url: deepLinkUrl, data: {serverUrl, teamName: '', id, route}};
}
match = new RegExp('(.*)\\/([^\\/]+)\\/messages\\/@(\\S+)').exec(url);
if (match) {
return {type: DeepLink.DirectMessage, url: deepLinkUrl, data: {serverUrl: match[1], teamName: match[2], userName: match[3]}};
}
match = new RegExp('(.*)\\/([^\\/]+)\\/messages\\/(\\S+)').exec(url);
if (match) {
return {type: DeepLink.GroupMessage, url: deepLinkUrl, data: {serverUrl: match[1], teamName: match[2], channelId: match[3]}};
}
match = new RegExp('(.*)\\/plugins\\/([^\\/]+)\\/(\\S+)').exec(url);
if (match) {
return {type: DeepLink.Plugin, url: deepLinkUrl, data: {serverUrl: match[1], id: match[2], teamName: ''}};
}
} catch {
} catch (err) {
// do nothing just return invalid deeplink
}
return {type: DeepLink.Invalid, url: deepLinkUrl};
}
export function matchDeepLink(url?: string, serverURL?: string, siteURL?: string) {
export function matchDeepLink(url: string, serverURL?: string, siteURL?: string) {
if (!url || (!serverURL && !siteURL)) {
return '';
return null;
}
let urlToMatch = url;
const urlBase = serverURL || siteURL || '';
const parsedUrl = urlParse(url);
const parsedBase = urlParse(urlBase);
if (!parsedUrl.protocol) {
// If url doesn't contain site or server URL, tack it on.
// e.g. <jump to convo> URLs from autolink plugin.
const match = new RegExp(escapeRegex(urlBase)).exec(url);
if (!match) {
const deepLinkMatch = new RegExp(escapeRegex(urlBase)).exec(url);
if (!deepLinkMatch) {
urlToMatch = urlBase + url;
}
}
const finalUrl = urlParse(urlToMatch);
const baseSubpath = parsedBase.pathname.replace('/', '');
const baseHostname = parsedBase.hostname;
const urlSubpath = finalUrl.pathname.split('/')[1];
const urlHostname = finalUrl.hostname;
const parsed = parseDeepLink(urlToMatch);
if (baseSubpath) {
// if the server is in a subpath
if (urlHostname === baseHostname && urlSubpath === baseSubpath) {
return urlToMatch;
}
} else if (urlHostname === baseHostname) {
return urlToMatch;
if (parsed.type === DeepLinkType.Invalid) {
return null;
}
return '';
return parsed;
}
export const getLaunchPropsFromDeepLink = (deepLinkUrl: string, coldStart = false): LaunchProps => {

20
app/utils/url/path.ts Normal file
View file

@ -0,0 +1,20 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
export const ID_PATH_PATTERN = '[a-z0-9]{26}';
export const PLUGIN_ID_PATH_PATTERN = '[a-zA-Z0-9-_.]{3,190}';
// 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.]*';

View file

@ -5,7 +5,7 @@ import {Linking} from 'react-native';
import DeepLinkType from '@constants/deep_linking';
import TestHelper from '@test/test_helper';
import {matchDeepLink, parseDeepLink} from '@utils/deep_link';
import {matchDeepLink} from '@utils/deep_link';
import * as UrlUtils from '@utils/url';
/* eslint-disable max-nested-callbacks */
@ -129,32 +129,35 @@ describe('UrlUtils', () => {
describe('matchDeepLink', () => {
const URL_NO_PROTOCOL = 'localhost:8065';
const URL_PATH_NO_PROTOCOL = 'localhost:8065/subpath';
const URL_PATH_NO_PROTOCOL = 'localhost:8065/subpath/deepsubpath';
const SITE_URL = `http://${URL_NO_PROTOCOL}`;
const SERVER_URL = `http://${URL_NO_PROTOCOL}`;
const SERVER_WITH_SUBPATH = `http://${URL_PATH_NO_PROTOCOL}`;
const DEEPLINK_URL_ROOT = `mattermost://${URL_NO_PROTOCOL}`;
const DM_USER = TestHelper.fakeUserWithId();
const GM_CHANNEL_NAME = '4862db64e76a321d167fe6677f16e96e9275dabe';
const tests = [
{
name: 'should return null if all inputs are empty',
input: {url: '', serverURL: '', siteURL: ''},
expected: {type: 'invalid'},
expected: null,
},
{
name: 'should return null if any of the input is null',
input: {url: '', serverURL: '', siteURL: null},
expected: {type: 'invalid'},
expected: null,
},
{
name: 'should return null if any of the input is null',
input: {url: '', serverURL: null, siteURL: ''},
expected: {type: 'invalid'},
expected: null,
},
{
name: 'should return null if any of the input is null',
input: {url: null, serverURL: '', siteURL: ''},
expected: {type: 'invalid'},
expected: null,
},
{
name: 'should return null for not supported link',
@ -163,12 +166,12 @@ describe('UrlUtils', () => {
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: {type: 'invalid'},
expected: null,
},
{
name: 'should return null despite url subset match',
input: {url: 'http://myserver.com', serverURL: 'http://myserver.co'},
expected: {type: 'invalid'},
expected: null,
},
{
name: 'should match despite no server URL in input link',
@ -186,6 +189,51 @@ describe('UrlUtils', () => {
type: DeepLinkType.Permalink,
},
},
{
name: 'should return null for invalid deeplink',
input: {
url: DEEPLINK_URL_ROOT + '/ad-1/channels/../town-square',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: null,
},
{
name: 'should return null for backslash-invalid deeplink',
input: {
url: DEEPLINK_URL_ROOT + '/ad-1/channels/\\..town-square',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: null,
},
{
name: 'should return null for backslash-invalid-alt deeplink',
input: {
url: DEEPLINK_URL_ROOT + '/ad-1/channels/t..\\town-square',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: null,
},
{
name: 'should return null for double encoded invalid deeplink',
input: {
url: DEEPLINK_URL_ROOT + '/ad-1/channels/%252f%252e.town-square',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: null,
},
{
name: 'should return null for double encoded backslash-invalid deeplink',
input: {
url: DEEPLINK_URL_ROOT + '/ad-1/channels/%255C%252e.town-square',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: null,
},
{
name: 'should match channel link',
input: {
@ -234,10 +282,74 @@ describe('UrlUtils', () => {
type: DeepLinkType.Channel,
},
},
{
name: 'should match channel link (channel name: messages) with deeplink prefix',
input: {
url: DEEPLINK_URL_ROOT + '/ad-1/channels/messages',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: {
data: {
channelName: 'messages',
serverUrl: URL_NO_PROTOCOL,
teamName: 'ad-1',
},
type: DeepLinkType.Channel,
},
},
{
name: 'should match DM channel link with deeplink prefix',
input: {
url: DEEPLINK_URL_ROOT + `/pl/messages/@${DM_USER.username}`,
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: {
data: {
userName: DM_USER.username,
serverUrl: URL_NO_PROTOCOL,
teamName: 'pl',
},
type: DeepLinkType.DirectMessage,
},
},
{
name: 'should match GM channel link with deeplink prefix',
input: {
url: DEEPLINK_URL_ROOT + `/pl/messages/${GM_CHANNEL_NAME}`,
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: {
data: {
channelName: GM_CHANNEL_NAME,
serverUrl: URL_NO_PROTOCOL,
teamName: 'pl',
},
type: DeepLinkType.GroupMessage,
},
},
{
name: 'should match channel link (team name: pl, channel name: messages) with deeplink prefix',
input: {
url: DEEPLINK_URL_ROOT + '/pl/channels/messages',
serverURL: SERVER_URL,
siteURL: SITE_URL,
},
expected: {
data: {
channelName: 'messages',
serverUrl: URL_NO_PROTOCOL,
teamName: 'pl',
},
type: DeepLinkType.Channel,
},
},
{
name: 'should match permalink with deeplink prefix on a Server hosted in a Subpath',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/ad-1/pl/qe93kkfd7783iqwuwfcwcxbsrr',
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/ad-1/pl/qe93kkfd7783iqwuwfcwcxbsrr',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
@ -247,7 +359,23 @@ describe('UrlUtils', () => {
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: 'ad-1',
},
type: 'permalink',
type: DeepLinkType.Permalink,
},
},
{
name: 'should match permalink (team name: pl) with deeplink prefix on a Server hosted in a Subpath',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/pl/pl/qe93kkfd7783iqwuwfcwcxbsrr',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: {
data: {
postId: 'qe93kkfd7783iqwuwfcwcxbsrr',
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: 'pl',
},
type: DeepLinkType.Permalink,
},
},
{
@ -263,7 +391,7 @@ describe('UrlUtils', () => {
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: 'ad-1',
},
type: 'permalink',
type: DeepLinkType.Permalink,
},
},
{
@ -273,8 +401,75 @@ describe('UrlUtils', () => {
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: null,
},
{
name: 'should match plugin path on a Server hosted in a Subpath',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/com.acme.abc-test/api/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: {
type: 'invalid',
data: {
id: 'com.acme.abc-test',
route: 'api/testroute',
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: '',
},
type: DeepLinkType.Plugin,
},
},
{
name: 'should match plugin path with single-level route',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_ab/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: {
data: {
id: 'abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_ab',
route: 'testroute',
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: '',
},
type: DeepLinkType.Plugin,
},
},
{
name: 'should not match plugin path with invalid plugin id len=2',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/ab/api/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: null,
},
{
name: 'should not match plugin path with invalid plugin id len=191',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc_abc/api/testroute',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: null,
},
{
name: 'should match plugin path without a route',
input: {
url: DEEPLINK_URL_ROOT + '/subpath/deepsubpath/plugins/abc',
serverURL: SERVER_WITH_SUBPATH,
siteURL: SERVER_WITH_SUBPATH,
},
expected: {
data: {
id: 'abc',
route: undefined,
serverUrl: URL_PATH_NO_PROTOCOL,
teamName: '',
},
type: DeepLinkType.Plugin,
},
},
];
@ -283,10 +478,11 @@ describe('UrlUtils', () => {
const {name, input, expected} = test;
it(name, () => {
const match = matchDeepLink(input.url!, input.serverURL!, input.siteURL!);
const parsed = parseDeepLink(match);
Reflect.deleteProperty(parsed, 'url');
expect(parsed).toEqual(expected);
const matched = matchDeepLink(input.url!, input.serverURL!, input.siteURL!);
if (matched) {
Reflect.deleteProperty(matched, 'url');
}
expect(matched).toEqual(expected);
});
}
});

View file

@ -1929,7 +1929,7 @@
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 493;
CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@ -1973,7 +1973,7 @@
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 493;
CURRENT_PROJECT_VERSION = 500;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@ -2116,7 +2116,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 493;
CURRENT_PROJECT_VERSION = 500;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
GCC_C_LANGUAGE_STANDARD = gnu11;
@ -2165,7 +2165,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 493;
CURRENT_PROJECT_VERSION = 500;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
GCC_C_LANGUAGE_STANDARD = gnu11;

View file

@ -21,7 +21,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.10.0</string>
<string>2.11.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
@ -37,7 +37,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>493</string>
<string>500</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>

View file

@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>2.10.0</string>
<string>2.11.0</string>
<key>CFBundleVersion</key>
<string>493</string>
<string>500</string>
<key>UIAppFonts</key>
<array>
<string>OpenSans-Bold.ttf</string>

View file

@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>2.10.0</string>
<string>2.11.0</string>
<key>CFBundleVersion</key>
<string>493</string>
<string>500</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>

158
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "mattermost-mobile",
"version": "2.10.0",
"version": "2.11.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
@ -52,6 +52,7 @@
"mime-db": "1.52.0",
"moment-timezone": "0.5.43",
"pako": "2.1.0",
"path-to-regexp": "6.2.1",
"react": "18.2.0",
"react-freeze": "1.0.3",
"react-intl": "6.4.4",
@ -18577,6 +18578,11 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"node_modules/path-to-regexp": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
},
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@ -23596,7 +23602,8 @@
"version": "7.21.0-placeholder-for-preset-env.2",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
"requires": {}
"requires": {
}
},
"@babel/plugin-syntax-async-generators": {
"version": "7.8.4",
@ -25419,7 +25426,8 @@
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.3.5.tgz",
"integrity": "sha512-REdUEsm/RA6lI1Rt4b009jvWn28f7H+e27gd4hlNk6zesIh/dlfiHwYfInW/vwbNFBdSPpvHy7Qi2mdcvrNqhg==",
"requires": {}
"requires": {
}
},
"@mattermost/react-native-network-client": {
"version": "1.4.1",
@ -25442,7 +25450,8 @@
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-log/-/react-native-turbo-log-0.2.3.tgz",
"integrity": "sha512-usWyD8zVAHzrYqgPH1ne5I14gCOkhS2mefK58g5v4DewZfCm0/Uc0w8MRuPS/9jyOPPq1rUZj8U1AqKgEne9tQ==",
"requires": {}
"requires": {
}
},
"@msgpack/msgpack": {
"version": "2.8.0",
@ -25534,13 +25543,15 @@
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/@react-native-camera-roll/camera-roll/-/camera-roll-5.7.2.tgz",
"integrity": "sha512-s8VAUG1Kvi+tEJkLHObmOJdXAL/uclnXJ/IdnJtx2fCKiWA3Ho0ln9gDQqCYHHHHu+sXk7wovsH/I2/AYy0brg==",
"requires": {}
"requires": {
}
},
"@react-native-clipboard/clipboard": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz",
"integrity": "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ==",
"requires": {}
"requires": {
}
},
"@react-native-community/cli": {
"version": "10.2.4",
@ -27249,7 +27260,8 @@
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-9.4.1.tgz",
"integrity": "sha512-dAbY5mfw+6Kas/GJ6QX9AZyY+K+eq9ad4Su6utoph/nxyH3whp5cMSgRNgE2VhGQVRZ/OG0qq3IaD3+wzoqJXw==",
"requires": {}
"requires": {
}
},
"@react-native-cookies/cookies": {
"version": "6.2.1",
@ -27415,7 +27427,8 @@
"version": "1.3.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q==",
"requires": {}
"requires": {
}
},
"@react-navigation/native": {
"version": "6.1.7",
@ -27642,63 +27655,72 @@
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/@stream-io/flat-list-mvcp/-/flat-list-mvcp-0.10.3.tgz",
"integrity": "sha512-2ZK8piYlEfKIPZrH8BpZz9uj8HZcUvMCV0X7qSLSAc/vhLOANBfR0SSn0OaWPbqb2mFGAd4FxmLSPp1zKEYuaw==",
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
"integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-remove-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
"integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-remove-jsx-empty-expression": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
"integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-replace-jsx-attribute-value": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
"integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-svg-dynamic-title": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
"integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-svg-em-dimensions": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
"integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-transform-react-native-svg": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.0.0.tgz",
"integrity": "sha512-UKrY3860AQICgH7g+6h2zkoxeVEPLYwX/uAjmqo4PIq2FIHppwhIqZstIyTz0ZtlwreKR41O3W3BzsBBiJV2Aw==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-plugin-transform-svg-component": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
"integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
"dev": true,
"requires": {}
"requires": {
}
},
"@svgr/babel-preset": {
"version": "8.0.0",
@ -28505,7 +28527,8 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@voximplant/react-native-foreground-service/-/react-native-foreground-service-3.0.2.tgz",
"integrity": "sha512-ZIyccOAXPqznA1PAVAYlKZ+GI7kXYCuYgH+gmAkhPouyJbkgrSXaCJJzQ+uBkPr4FBa/PuC/yjzK8vf6tJREQA==",
"requires": {}
"requires": {
}
},
"@webassemblyjs/ast": {
"version": "1.11.1",
@ -28673,7 +28696,8 @@
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz",
"integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==",
"dev": true,
"requires": {}
"requires": {
}
},
"@webpack-cli/info": {
"version": "1.4.0",
@ -28689,7 +28713,8 @@
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz",
"integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==",
"dev": true,
"requires": {}
"requires": {
}
},
"@xtuc/ieee754": {
"version": "1.2.0",
@ -28744,13 +28769,15 @@
"integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
"dev": true,
"peer": true,
"requires": {}
"requires": {
}
},
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"requires": {}
"requires": {
}
},
"agent-base": {
"version": "6.0.2",
@ -28806,7 +28833,8 @@
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true,
"peer": true,
"requires": {}
"requires": {
}
},
"anser": {
"version": "1.4.10",
@ -29084,7 +29112,8 @@
"version": "7.0.0-bridge.0",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
"integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
"requires": {}
"requires": {
}
},
"babel-jest": {
"version": "29.6.2",
@ -30285,7 +30314,8 @@
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz",
"integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==",
"dev": true,
"requires": {}
"requires": {
}
},
"deep-equal": {
"version": "2.2.2",
@ -31188,7 +31218,8 @@
"version": "8.10.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
"integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
"requires": {}
"requires": {
}
},
"eslint-import-resolver-node": {
"version": "0.3.7",
@ -31273,7 +31304,8 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz",
"integrity": "sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==",
"dev": true,
"requires": {}
"requires": {
}
},
"eslint-plugin-import": {
"version": "2.28.0",
@ -31407,7 +31439,8 @@
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
"integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
"requires": {}
"requires": {
}
},
"eslint-plugin-react-native": {
"version": "4.0.0",
@ -33781,7 +33814,8 @@
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
"dev": true,
"requires": {}
"requires": {
}
},
"jest-regex-util": {
"version": "29.4.3",
@ -37009,7 +37043,8 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.3.tgz",
"integrity": "sha512-ZnXwLQnGzrDpHBHiC56TXFXvmolPeMjTn1UOm610M4EXGzbEDR7oOIyS2ZiItgbs6eZc4oU/a0hpk8PrcKvv5g==",
"requires": {}
"requires": {
}
},
"react-intl": {
"version": "6.4.4",
@ -37318,7 +37353,8 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/react-native-background-timer/-/react-native-background-timer-2.4.1.tgz",
"integrity": "sha512-TE4Kiy7jUyv+hugxDxitzu38sW1NqjCk4uE5IgU2WevLv7sZacaBc6PZKOShNRPGirLl1NWkaG3LDEkdb9Um5g==",
"requires": {}
"requires": {
}
},
"react-native-button": {
"version": "3.1.0",
@ -37371,13 +37407,15 @@
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/react-native-create-thumbnail/-/react-native-create-thumbnail-1.6.4.tgz",
"integrity": "sha512-JWuKXswDXtqUPfuqh6rjCVMvTSSG3kUtwvSK/YdaNU0i+nZKxeqHmt/CO2+TyI/WSUFynGVmWT1xOHhCZAFsRQ==",
"requires": {}
"requires": {
}
},
"react-native-device-info": {
"version": "10.8.0",
"resolved": "https://registry.npmjs.org/react-native-device-info/-/react-native-device-info-10.8.0.tgz",
"integrity": "sha512-DE4/X82ZVhdcnR1Y21iTP46WSSJA/rHK3lmeqWfGGq1RKLwXTIdxmfbZZnYwryqJ+esrw2l4ND19qlgxDGby8A==",
"requires": {}
"requires": {
}
},
"react-native-document-picker": {
"version": "9.0.1",
@ -37414,19 +37452,22 @@
"version": "2.10.10",
"resolved": "https://registry.npmjs.org/react-native-exception-handler/-/react-native-exception-handler-2.10.10.tgz",
"integrity": "sha512-otAXGoZDl1689OoUJWN/rXxVbdoZ3xcmyF1uq/CsizdLwwyZqVGd6d+p/vbYvnF996FfEyAEBnHrdFxulTn51w==",
"requires": {}
"requires": {
}
},
"react-native-fast-image": {
"version": "8.6.3",
"resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-8.6.3.tgz",
"integrity": "sha512-Sdw4ESidXCXOmQ9EcYguNY2swyoWmx53kym2zRsvi+VeFCHEdkO+WG1DK+6W81juot40bbfLNhkc63QnWtesNg==",
"requires": {}
"requires": {
}
},
"react-native-file-viewer": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/react-native-file-viewer/-/react-native-file-viewer-2.1.5.tgz",
"integrity": "sha512-MGC6sx9jsqHdefhVQ6o0akdsPGpkXgiIbpygb2Sg4g4bh7v6K1cardLV1NwGB9A6u1yICOSDT/MOC//9Ez6EUg==",
"requires": {}
"requires": {
}
},
"react-native-fs": {
"version": "2.20.0",
@ -37465,19 +37506,22 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/react-native-haptic-feedback/-/react-native-haptic-feedback-2.0.3.tgz",
"integrity": "sha512-7+qvcxXZts/hA+HOOIFyM1x9m9fn/TJVSTgXaoQ8uT4gLc97IMvqHQ559tDmnlth+hHMzd3HRMpmRLWoKPL0DA==",
"requires": {}
"requires": {
}
},
"react-native-hw-keyboard-event": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/react-native-hw-keyboard-event/-/react-native-hw-keyboard-event-0.0.4.tgz",
"integrity": "sha512-G8qp0nm17PHigLb/axgdF9xg51BKCG2p1AGeq//J/luLp5zNczIcQJh+nm02R1MeEUE3e53wqO4LMe0MV3raZg==",
"requires": {}
"requires": {
}
},
"react-native-image-picker": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-5.6.1.tgz",
"integrity": "sha512-LPPlgJi97EzCDY4NWp7z0oUWmCbagnB6HSoKcLJHJD/DaFYN/dJPrqjqKaqqw8K/5Ze6DIsNg9PZohjNEYQQWQ==",
"requires": {}
"requires": {
}
},
"react-native-in-app-review": {
"version": "4.3.3",
@ -37488,13 +37532,15 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/react-native-incall-manager/-/react-native-incall-manager-4.1.0.tgz",
"integrity": "sha512-v1c+XOGu5VudY5//E3i5xiaRA9v6RvevMzZ4RumLqI+hte+4XslB2z6HSek2FF0EmAnY1rCn4ckiwgkTI1Tmtw==",
"requires": {}
"requires": {
}
},
"react-native-iphone-x-helper": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz",
"integrity": "sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg==",
"requires": {}
"requires": {
}
},
"react-native-keyboard-aware-scroll-view": {
"version": "0.9.5",
@ -37509,7 +37555,8 @@
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/react-native-keyboard-tracking-view/-/react-native-keyboard-tracking-view-5.7.0.tgz",
"integrity": "sha512-MDeEwAbn9LJDOfHq0QLCGaZirVLk2X/tHqkAqz3y6uxryTRdSl9PwleOVar5Jx2oAPEg4J9BXbUD1wwOOi+5Kg==",
"requires": {}
"requires": {
}
},
"react-native-keychain": {
"version": "8.1.2",
@ -37520,13 +37567,15 @@
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.2.tgz",
"integrity": "sha512-hgmCsgzd58WNcDCyPtKrvxsaoETjb/jLGxis/dmU3Aqm2u4ICIduj4ECjbil7B7pm9OnuTkmpwXu08XV2mpg8g==",
"requires": {}
"requires": {
}
},
"react-native-localize": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/react-native-localize/-/react-native-localize-3.0.2.tgz",
"integrity": "sha512-/l/oE1LVNgIRRhLbhmfFMHiWV0xhUn0A0iz1ytLVRYywL7FTp8Rx2vkJS/q/RpExDvV7yLw2493XZBYIM1dnLQ==",
"requires": {}
"requires": {
}
},
"react-native-math-view": {
"version": "3.9.5",
@ -37562,7 +37611,8 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/react-native-notifications/-/react-native-notifications-5.1.0.tgz",
"integrity": "sha512-laqDSDlCvEASmJR6cXpqaryK855ejQd07vrfYERzhv68YDOoSkKy/URExRP4vAfAOVqHhix80tLbNUcfvZk2VQ==",
"requires": {}
"requires": {
}
},
"react-native-permissions": {
"version": "3.8.4",
@ -37603,7 +37653,8 @@
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.7.1.tgz",
"integrity": "sha512-X2pJG2ttmAbiGlItWedvDkZg1T1ikmEDiz+7HsiIwAIm2UbFqlhqn+B1JF53mSxPzdNaDcCQVHRNPvj8oFu6Yg==",
"requires": {}
"requires": {
}
},
"react-native-screens": {
"version": "3.24.0",
@ -37636,7 +37687,8 @@
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/react-native-size-matters/-/react-native-size-matters-0.3.1.tgz",
"integrity": "sha512-mKOfBLIBFBcs9br1rlZDvxD5+mAl8Gfr5CounwJtxI6Z82rGrMO+Kgl9EIg3RMVf3G855a85YVqHJL2f5EDRlw==",
"requires": {}
"requires": {
}
},
"react-native-svg": {
"version": "13.11.0",
@ -39310,7 +39362,8 @@
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz",
"integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==",
"dev": true,
"requires": {}
"requires": {
}
},
"ts-jest": {
"version": "29.1.1",
@ -39631,13 +39684,15 @@
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz",
"integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg==",
"requires": {}
"requires": {
}
},
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"requires": {}
"requires": {
}
},
"utf8": {
"version": "3.0.0",
@ -39970,7 +40025,8 @@
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
"integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
"requires": {}
"requires": {
}
},
"xdate": {
"version": "0.8.2",

View file

@ -1,6 +1,6 @@
{
"name": "mattermost-mobile",
"version": "2.10.0",
"version": "2.11.0",
"description": "Mattermost Mobile with React Native",
"repository": "git@github.com:mattermost/mattermost-mobile.git",
"author": "Mattermost, Inc.",
@ -53,6 +53,7 @@
"mime-db": "1.52.0",
"moment-timezone": "0.5.43",
"pako": "2.1.0",
"path-to-regexp": "6.2.1",
"react": "18.2.0",
"react-freeze": "1.0.3",
"react-intl": "6.4.4",

View file

@ -21,11 +21,12 @@ export interface DeepLinkPermalink extends DeepLink {
}
export interface DeepLinkGM extends DeepLink {
channelId: string;
channelName: string;
}
export interface DeepLinkPlugin extends DeepLink {
id: string;
route?: string;
}
export type DeepLinkType = typeof DeepLink[keyof typeof DeepLink];