From cfd1b67d8c22ea9225585b64c4deda05db2e837e Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:04:12 +0800 Subject: [PATCH] fix(core): version guard (#15226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #15225 #### PR Dependency Tree * **PR #15226** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) ## Summary by CodeRabbit * **Bug Fixes** * Improved self-hosted server version validation. * Correctly supports compatible beta and release-candidate versions. * Rejects outdated pre-release versions consistently. * Provides the appropriate unsupported-version guidance when compatibility requirements are not met. --- .../use-selfhost-login-version-guard.tsx | 8 +++++--- .../cloud/stores/server-config.spec.ts | 10 +++++++--- .../src/modules/cloud/stores/server-config.ts | 20 ++++++++++--------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx b/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx index 75ada08cb0..341b676ebc 100644 --- a/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx +++ b/packages/frontend/core/src/components/hooks/affine/use-selfhost-login-version-guard.tsx @@ -1,9 +1,11 @@ import type { Server } from '@affine/core/modules/cloud'; -import { MIN_SUPPORTED_SERVER_VERSION } from '@affine/core/modules/cloud/stores/server-config'; +import { + isSupportedServerVersion, + MIN_SUPPORTED_SERVER_VERSION, +} from '@affine/core/modules/cloud/stores/server-config'; import { useI18n } from '@affine/i18n'; import { useLiveData } from '@toeverything/infra'; import { cssVarV2 } from '@toeverything/theme/v2'; -import semver from 'semver'; const rules = [ { @@ -46,7 +48,7 @@ export const useSelfhostLoginVersionGuard = (server: Server) => { useLiveData(server.config$.selector(c => c.version)) ?? '0.0.0'; for (const rule of rules) { - if (semver.lt(serverVersion, rule.min)) { + if (!isSupportedServerVersion(serverVersion)) { return rule.tip( t['error.UNSUPPORTED_SERVER_VERSION']({ requiredVersion: `>=${rule.min}`, diff --git a/packages/frontend/core/src/modules/cloud/stores/server-config.spec.ts b/packages/frontend/core/src/modules/cloud/stores/server-config.spec.ts index 0aa67afb86..3b3b833b70 100644 --- a/packages/frontend/core/src/modules/cloud/stores/server-config.spec.ts +++ b/packages/frontend/core/src/modules/cloud/stores/server-config.spec.ts @@ -9,13 +9,17 @@ import { describe('server config version guard', () => { test('accepts supported server versions', () => { expect(() => assertSupportedServerVersion('0.27.0')).not.toThrow(); + expect(() => assertSupportedServerVersion('0.27.0-beta.5')).not.toThrow(); + expect(() => assertSupportedServerVersion('0.27.0-rc.1')).not.toThrow(); expect(() => assertSupportedServerVersion('0.28.0')).not.toThrow(); }); test('rejects old server versions', () => { - expect(() => assertSupportedServerVersion('0.26.9')).toThrow( - UserFriendlyError - ); + for (const version of ['0.26.9', '0.26.9-beta.5']) { + expect(() => assertSupportedServerVersion(version)).toThrow( + UserFriendlyError + ); + } }); test('rejects missing or invalid server versions', () => { diff --git a/packages/frontend/core/src/modules/cloud/stores/server-config.ts b/packages/frontend/core/src/modules/cloud/stores/server-config.ts index d4085f6e04..38f27425f5 100644 --- a/packages/frontend/core/src/modules/cloud/stores/server-config.ts +++ b/packages/frontend/core/src/modules/cloud/stores/server-config.ts @@ -47,16 +47,18 @@ export function createUnsupportedServerVersionError(version?: string | null) { }); } -export function assertSupportedServerVersion(version?: string | null) { - if (!version) { - throw createUnsupportedServerVersionError(version); - } +export function isSupportedServerVersion(version?: string | null) { + const normalized = version && semver.valid(version, { loose: true }); + return ( + !!normalized && + semver.gte(normalized, `${MIN_SUPPORTED_SERVER_VERSION}-0`, { + loose: true, + }) + ); +} - const normalized = semver.valid(version, { loose: true }); - if ( - !normalized || - semver.lt(normalized, MIN_SUPPORTED_SERVER_VERSION, { loose: true }) - ) { +export function assertSupportedServerVersion(version?: string | null) { + if (!isSupportedServerVersion(version)) { throw createUnsupportedServerVersionError(version); } }