diff --git a/app/actions/remote/entry/common.ts b/app/actions/remote/entry/common.ts index 46ab1dc2c4a..6a6e56be38a 100644 --- a/app/actions/remote/entry/common.ts +++ b/app/actions/remote/entry/common.ts @@ -1,6 +1,9 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {nativeApplicationVersion} from 'expo-application'; +import {RESULTS, checkNotifications} from 'react-native-permissions'; + import {fetchMissingDirectChannelsInfo, fetchMyChannelsForTeam, handleKickFromChannel, type MyChannelsRequest} from '@actions/remote/channel'; import {fetchGroupsForMember} from '@actions/remote/groups'; import {fetchPostsForUnreadChannels} from '@actions/remote/post'; @@ -22,12 +25,12 @@ import {getDeviceToken} from '@queries/app/global'; import {getChannelById, queryAllChannelsForTeam, queryChannelsById} from '@queries/servers/channel'; import {prepareModels, truncateCrtRelatedTables} from '@queries/servers/entry'; import {getHasCRTChanged} from '@queries/servers/preference'; -import {getConfig, getCurrentChannelId, getCurrentTeamId, getIsDataRetentionEnabled, getPushVerificationStatus, getLastFullSync, setCurrentTeamAndChannelId} from '@queries/servers/system'; +import {getConfig, getCurrentChannelId, getCurrentTeamId, getIsDataRetentionEnabled, getPushVerificationStatus, getLastFullSync, setCurrentTeamAndChannelId, getConfigValue} from '@queries/servers/system'; import {deleteMyTeams, getAvailableTeamIds, getTeamChannelHistory, queryMyTeams, queryMyTeamsByIds, queryTeamsById} from '@queries/servers/team'; import NavigationStore from '@store/navigation_store'; import {isDMorGM, sortChannelsByDisplayName} from '@utils/channel'; import {getFullErrorMessage, isErrorWithStatusCode} from '@utils/errors'; -import {isTablet} from '@utils/helpers'; +import {isMinimumServerVersion, isTablet} from '@utils/helpers'; import {logDebug} from '@utils/log'; import {processIsCRTEnabled} from '@utils/thread'; @@ -413,17 +416,25 @@ async function restDeferredAppEntryActions( }, FETCH_MISSING_DM_TIMEOUT); } -export const registerDeviceToken = async (serverUrl: string) => { +export const setExtraSessionProps = async (serverUrl: string) => { try { - const client = NetworkManager.getClient(serverUrl); - + const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl); + const serverVersion = await getConfigValue(database, 'Version'); const deviceToken = await getDeviceToken(); - if (deviceToken) { - client.attachDevice(deviceToken); + + // For new servers, we want to send all the information. + // For old servers, we only want to send the information when there + // is a device token. Sending the rest of the information should not + // create any issue. + if (isMinimumServerVersion(serverVersion, 10, 1, 0) || deviceToken) { + const res = await checkNotifications(); + const granted = res.status === RESULTS.GRANTED || res.status === RESULTS.LIMITED; + const client = NetworkManager.getClient(serverUrl); + client.setExtraSessionProps(deviceToken, !granted, nativeApplicationVersion); } return {}; } catch (error) { - logDebug('error on registerDeviceToken', getFullErrorMessage(error)); + logDebug('error on setExtraSessionProps', getFullErrorMessage(error)); return {error}; } }; diff --git a/app/actions/websocket/index.ts b/app/actions/websocket/index.ts index 0c233c6dd5b..39177ce7447 100644 --- a/app/actions/websocket/index.ts +++ b/app/actions/websocket/index.ts @@ -8,7 +8,7 @@ import { deferredAppEntryActions, entry, handleEntryAfterLoadNavigation, - registerDeviceToken, + setExtraSessionProps, } from '@actions/remote/entry/common'; import {fetchPostsForChannel, fetchPostThread} from '@actions/remote/post'; import {openAllUnreadChannels} from '@actions/remote/preference'; @@ -37,7 +37,7 @@ import {isTablet} from '@utils/helpers'; import {logDebug, logInfo} from '@utils/log'; export async function handleFirstConnect(serverUrl: string) { - registerDeviceToken(serverUrl); + setExtraSessionProps(serverUrl); autoUpdateTimezone(serverUrl); return doReconnect(serverUrl); } diff --git a/app/client/rest/users.ts b/app/client/rest/users.ts index c4058bb0247..79eeef851ef 100644 --- a/app/client/rest/users.ts +++ b/app/client/rest/users.ts @@ -38,7 +38,7 @@ export interface ClientUsersMix { autocompleteUsers: (name: string, teamId: string, channelId?: string, options?: Record) => Promise<{users: UserProfile[]; out_of_channel?: UserProfile[]}>; getSessions: (userId: string) => Promise; checkUserMfa: (loginId: string) => Promise<{mfa_required: boolean}>; - attachDevice: (deviceId: string) => Promise; + setExtraSessionProps: (deviceId: string, notificationsEnabled: boolean, version: string | null) => Promise<{}>; searchUsers: (term: string, options: SearchUserOptions) => Promise; getStatusesByIds: (userIds: string[]) => Promise; getStatus: (userId: string) => Promise; @@ -325,10 +325,17 @@ const ClientUsers = >(superclass: TBase) = ); }; - attachDevice = async (deviceId: string) => { + setExtraSessionProps = async (deviceId: string, deviceNotificationDisabled: boolean, version: string | null) => { return this.doFetch( `${this.getUsersRoute()}/sessions/device`, - {method: 'put', body: {device_id: deviceId}}, + { + method: 'put', + body: { + device_id: deviceId, + device_notification_disabled: deviceNotificationDisabled ? 'true' : 'false', + mobile_version: version || '', + }, + }, ); };