diff --git a/lib/shared/version-utils.js b/lib/shared/version-utils.js --- a/lib/shared/version-utils.js +++ b/lib/shared/version-utils.js @@ -1,6 +1,10 @@ // @flow -import { type PlatformDetails, isWebPlatform } from '../types/device-types.js'; +import { + type PlatformDetails, + isWebPlatform, + isDesktopPlatform, +} from '../types/device-types.js'; /** * A code version used for features that are waiting to be released @@ -16,20 +20,33 @@ function hasMinCodeVersion( platformDetails: ?PlatformDetails, - minCodeVersion: Partial<{ +native: number, +web: number }>, + minCodeVersion: Partial<{ + +native: number, + +web: number, + +majorDesktop: number, + }>, ): boolean { if (!platformDetails) { return true; } - const { codeVersion } = platformDetails; + + const { codeVersion, majorDesktopVersion } = platformDetails; const minVersion = isWebPlatform(platformDetails.platform) ? minCodeVersion.web : minCodeVersion.native; - if (!minVersion) { - return true; + const minMajorDesktopVersion = isDesktopPlatform(platformDetails.platform) + ? minCodeVersion.majorDesktop + : undefined; + + if (minVersion && (!codeVersion || codeVersion < minVersion)) { + return false; } - if (!codeVersion || codeVersion < minVersion) { + + if ( + minMajorDesktopVersion && + (!majorDesktopVersion || majorDesktopVersion < minMajorDesktopVersion) + ) { return false; } @@ -58,9 +75,14 @@ return true; } +function extractMajorDesktopVersion(desktopVersion: string): number { + return desktopVersion.split('.').map(Number)[0]; +} + export { FUTURE_CODE_VERSION, NEXT_CODE_VERSION, hasMinCodeVersion, hasMinStateVersion, + extractMajorDesktopVersion, }; diff --git a/lib/types/device-types.js b/lib/types/device-types.js --- a/lib/types/device-types.js +++ b/lib/types/device-types.js @@ -25,8 +25,12 @@ return deviceType; } +export function isDesktopPlatform(platform: ?string): boolean { + return platform === 'macos' || platform === 'windows'; +} + export function isWebPlatform(platform: ?string): boolean { - return platform === 'web' || platform === 'windows' || platform === 'macos'; + return platform === 'web' || isDesktopPlatform(platform); } export type DeviceTokenUpdateRequest = { @@ -39,6 +43,7 @@ +platform: Platform, +codeVersion?: ?number, +stateVersion?: ?number, + +majorDesktopVersion?: number, }; export type LastCommunicatedPlatformDetails = { diff --git a/lib/utils/validation-utils.js b/lib/utils/validation-utils.js --- a/lib/utils/validation-utils.js +++ b/lib/utils/validation-utils.js @@ -70,6 +70,7 @@ platform: tPlatform, codeVersion: t.maybe(t.Number), stateVersion: t.maybe(t.Number), + majorDesktopVersion: t.maybe(t.Number), }); const tPassword: TRefinement = t.refinement( t.String, diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -25,6 +25,7 @@ combineLoadingStatuses, } from 'lib/selectors/loading-selectors.js'; import { isLoggedIn } from 'lib/selectors/user-selectors.js'; +import { extractMajorDesktopVersion } from 'lib/shared/version-utils.js'; import { TunnelbrokerProvider } from 'lib/tunnelbroker/tunnelbroker-context.js'; import type { LoadingStatus } from 'lib/types/loading-types.js'; import type { Dispatch } from 'lib/types/redux-types.js'; @@ -82,6 +83,9 @@ import '@fortawesome/fontawesome-svg-core/styles.css'; faConfig.autoAddCss = false; +const desktopDetails = electron?.version + ? { majorDesktopVersion: extractMajorDesktopVersion(electron?.version) } + : null; registerConfig({ // We can't securely cache credentials on web, so we have no way to recover @@ -94,6 +98,7 @@ platform: electron?.platform ?? 'web', codeVersion: 45, stateVersion: persistConfig.version, + ...desktopDetails, }, });