mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 08:20:39 +00:00
UBERF-8139: Check server version when connecting from client (#6608)
This commit is contained in:
parent
a1cee24473
commit
c96318d415
1
.vscode/launch.json
vendored
1
.vscode/launch.json
vendored
@ -73,6 +73,7 @@
|
|||||||
// "SERVER_PROVIDER":"uweb"
|
// "SERVER_PROVIDER":"uweb"
|
||||||
"SERVER_PROVIDER":"ws",
|
"SERVER_PROVIDER":"ws",
|
||||||
"MODEL_VERSION": "0.6.287",
|
"MODEL_VERSION": "0.6.287",
|
||||||
|
// "VERSION": "0.6.289",
|
||||||
"ELASTIC_INDEX_NAME": "local_storage_index",
|
"ELASTIC_INDEX_NAME": "local_storage_index",
|
||||||
"UPLOAD_URL": "/files",
|
"UPLOAD_URL": "/files",
|
||||||
|
|
||||||
|
@ -232,6 +232,10 @@ class Connection implements ClientConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleMsg (socketId: number, resp: Response<any>): void {
|
handleMsg (socketId: number, resp: Response<any>): void {
|
||||||
|
if (this.closed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (resp.error !== undefined) {
|
if (resp.error !== undefined) {
|
||||||
if (resp.error?.code === UNAUTHORIZED.code || resp.terminate === true) {
|
if (resp.error?.code === UNAUTHORIZED.code || resp.terminate === true) {
|
||||||
Analytics.handleError(new PlatformError(resp.error))
|
Analytics.handleError(new PlatformError(resp.error))
|
||||||
@ -252,9 +256,24 @@ class Connection implements ClientConnection {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (resp.result === 'hello') {
|
if (resp.result === 'hello') {
|
||||||
|
const helloResp = resp as HelloResponse
|
||||||
|
if (helloResp.binary) {
|
||||||
|
this.binaryMode = true
|
||||||
|
}
|
||||||
|
|
||||||
// We need to clear dial timer, since we recieve hello response.
|
// We need to clear dial timer, since we recieve hello response.
|
||||||
clearTimeout(this.dialTimer)
|
clearTimeout(this.dialTimer)
|
||||||
this.dialTimer = null
|
this.dialTimer = null
|
||||||
|
|
||||||
|
const serverVersion = helloResp.serverVersion
|
||||||
|
console.log('Connected to server:', serverVersion)
|
||||||
|
|
||||||
|
if (this.opt?.onHello !== undefined && !this.opt.onHello(serverVersion)) {
|
||||||
|
this.closed = true
|
||||||
|
this.websocket?.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.helloRecieved = true
|
this.helloRecieved = true
|
||||||
if (this.upgrading) {
|
if (this.upgrading) {
|
||||||
// We need to call upgrade since connection is upgraded
|
// We need to call upgrade since connection is upgraded
|
||||||
@ -262,9 +281,6 @@ class Connection implements ClientConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.upgrading = false
|
this.upgrading = false
|
||||||
if ((resp as HelloResponse).binary) {
|
|
||||||
this.binaryMode = true
|
|
||||||
}
|
|
||||||
// Notify all waiting connection listeners
|
// Notify all waiting connection listeners
|
||||||
const handlers = this.onConnectHandlers.splice(0, this.onConnectHandlers.length)
|
const handlers = this.onConnectHandlers.splice(0, this.onConnectHandlers.length)
|
||||||
for (const h of handlers) {
|
for (const h of handlers) {
|
||||||
|
@ -56,6 +56,7 @@ export enum ClientSocketReadyState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ClientFactoryOptions {
|
export interface ClientFactoryOptions {
|
||||||
|
onHello?: (serverVersion?: string) => boolean
|
||||||
onUpgrade?: () => void
|
onUpgrade?: () => void
|
||||||
onUnauthorized?: () => void
|
onUnauthorized?: () => void
|
||||||
onConnect?: (event: ClientConnectEvent, data: any) => void
|
onConnect?: (event: ClientConnectEvent, data: any) => void
|
||||||
|
@ -67,6 +67,32 @@ export async function connect (title: string): Promise<Client | undefined> {
|
|||||||
let version: Version | undefined
|
let version: Version | undefined
|
||||||
const clientFactory = await getResource(client.function.GetClient)
|
const clientFactory = await getResource(client.function.GetClient)
|
||||||
_client = await clientFactory(token, workspaceLoginInfo.endpoint, {
|
_client = await clientFactory(token, workspaceLoginInfo.endpoint, {
|
||||||
|
onHello: (serverVersion?: string) => {
|
||||||
|
const frontVersion = getMetadata(presentation.metadata.FrontVersion)
|
||||||
|
if (
|
||||||
|
serverVersion !== undefined &&
|
||||||
|
serverVersion !== '' &&
|
||||||
|
frontVersion !== undefined &&
|
||||||
|
frontVersion !== serverVersion
|
||||||
|
) {
|
||||||
|
const reloaded = localStorage.getItem(`versionUpgrade:s${serverVersion}:f${frontVersion}`)
|
||||||
|
|
||||||
|
if (reloaded === null) {
|
||||||
|
localStorage.setItem(`versionUpgrade:s${serverVersion}:f${frontVersion}`, 't')
|
||||||
|
location.reload()
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
versionError.set(`Front version ${frontVersion} is not in sync with server version ${serverVersion}`)
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload()
|
||||||
|
}, 5000)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
onUpgrade: () => {
|
onUpgrade: () => {
|
||||||
location.reload()
|
location.reload()
|
||||||
},
|
},
|
||||||
|
@ -153,6 +153,32 @@ export async function connect (title: string): Promise<Client | undefined> {
|
|||||||
{},
|
{},
|
||||||
async (ctx) =>
|
async (ctx) =>
|
||||||
await clientFactory(token, endpoint, {
|
await clientFactory(token, endpoint, {
|
||||||
|
onHello: (serverVersion?: string) => {
|
||||||
|
const frontVersion = getMetadata(presentation.metadata.FrontVersion)
|
||||||
|
if (
|
||||||
|
serverVersion !== undefined &&
|
||||||
|
serverVersion !== '' &&
|
||||||
|
frontVersion !== undefined &&
|
||||||
|
frontVersion !== serverVersion
|
||||||
|
) {
|
||||||
|
const reloaded = localStorage.getItem(`versionUpgrade:s${serverVersion}:f${frontVersion}`)
|
||||||
|
|
||||||
|
if (reloaded === null) {
|
||||||
|
localStorage.setItem(`versionUpgrade:s${serverVersion}:f${frontVersion}`, 't')
|
||||||
|
location.reload()
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
versionError.set(`Front version ${frontVersion} is not in sync with server version ${serverVersion}`)
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload()
|
||||||
|
}, 5000)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
onUpgrade: () => {
|
onUpgrade: () => {
|
||||||
location.reload()
|
location.reload()
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"_phase:bundle": "rushx bundle",
|
"_phase:bundle": "rushx bundle",
|
||||||
"_phase:docker-build": "rushx docker:build",
|
"_phase:docker-build": "rushx docker:build",
|
||||||
"_phase:docker-staging": "rushx docker:staging",
|
"_phase:docker-staging": "rushx docker:staging",
|
||||||
"bundle": "mkdir -p bundle && esbuild src/__start.ts --sourcemap=inline --bundle --keep-names --platform=node --external:*.node --external:bufferutil --external:snappy --external:utf-8-validate --external:msgpackr-extract --define:process.env.MODEL_VERSION=$(node ../../common/scripts/show_version.js) --define:process.env.GIT_REVISION=$(../../common/scripts/git_version.sh) --outfile=bundle/bundle.js --log-level=error --sourcemap=external",
|
"bundle": "mkdir -p bundle && esbuild src/__start.ts --sourcemap=inline --bundle --keep-names --platform=node --external:*.node --external:bufferutil --external:snappy --external:utf-8-validate --external:msgpackr-extract --define:process.env.MODEL_VERSION=$(node ../../common/scripts/show_version.js) --define:process.env.VERSION=$(node ../../common/scripts/show_tag.js) --define:process.env.GIT_REVISION=$(../../common/scripts/git_version.sh) --outfile=bundle/bundle.js --log-level=error --sourcemap=external",
|
||||||
"docker:build": "../../common/scripts/docker_build.sh hardcoreeng/transactor",
|
"docker:build": "../../common/scripts/docker_build.sh hardcoreeng/transactor",
|
||||||
"docker:tbuild": "docker build -t hardcoreeng/transactor . --platform=linux/amd64 && ../../common/scripts/docker_tag_push.sh hardcoreeng/transactor",
|
"docker:tbuild": "docker build -t hardcoreeng/transactor . --platform=linux/amd64 && ../../common/scripts/docker_tag_push.sh hardcoreeng/transactor",
|
||||||
"docker:abuild": "docker build -t hardcoreeng/transactor . --platform=linux/arm64 && ../../common/scripts/docker_tag_push.sh hardcoreeng/transactor",
|
"docker:abuild": "docker build -t hardcoreeng/transactor . --platform=linux/arm64 && ../../common/scripts/docker_tag_push.sh hardcoreeng/transactor",
|
||||||
|
@ -45,6 +45,7 @@ export interface HelloRequest extends Request<any[]> {
|
|||||||
export interface HelloResponse extends Response<any> {
|
export interface HelloResponse extends Response<any> {
|
||||||
binary: boolean
|
binary: boolean
|
||||||
reconnect?: boolean
|
reconnect?: boolean
|
||||||
|
serverVersion: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function replacer (key: string, value: any): any {
|
function replacer (key: string, value: any): any {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import { UNAUTHORIZED } from '@hcengineering/platform'
|
import { UNAUTHORIZED } from '@hcengineering/platform'
|
||||||
import { RPCHandler } from '@hcengineering/rpc'
|
import { RPCHandler, type Response } from '@hcengineering/rpc'
|
||||||
import { generateToken } from '@hcengineering/server-token'
|
import { generateToken } from '@hcengineering/server-token'
|
||||||
import WebSocket from 'ws'
|
import WebSocket from 'ws'
|
||||||
import { start } from '../server'
|
import { start } from '../server'
|
||||||
@ -129,7 +129,7 @@ describe('server', () => {
|
|||||||
conn.close(1000)
|
conn.close(1000)
|
||||||
})
|
})
|
||||||
conn.on('message', (msg: string) => {
|
conn.on('message', (msg: string) => {
|
||||||
const resp = handler.readResponse(msg, false)
|
const resp: Response<any> = handler.readResponse(msg, false)
|
||||||
expect(resp.result === 'hello')
|
expect(resp.result === 'hello')
|
||||||
expect(resp.error?.code).toBe(UNAUTHORIZED.code)
|
expect(resp.error?.code).toBe(UNAUTHORIZED.code)
|
||||||
conn.close(1000)
|
conn.close(1000)
|
||||||
@ -240,7 +240,7 @@ describe('server', () => {
|
|||||||
newConn.on('message', (msg: Buffer) => {
|
newConn.on('message', (msg: Buffer) => {
|
||||||
try {
|
try {
|
||||||
console.log('resp:', msg.toString())
|
console.log('resp:', msg.toString())
|
||||||
const parsedMsg = handler.readResponse(msg.toString(), false) // Hello
|
const parsedMsg: Response<any> = handler.readResponse(msg.toString(), false) // Hello
|
||||||
if (!helloReceived) {
|
if (!helloReceived) {
|
||||||
expect(parsedMsg.result === 'hello')
|
expect(parsedMsg.result === 'hello')
|
||||||
helloReceived = true
|
helloReceived = true
|
||||||
|
@ -91,6 +91,7 @@ class TSessionManager implements SessionManager {
|
|||||||
timeMinutes = 0
|
timeMinutes = 0
|
||||||
|
|
||||||
modelVersion = process.env.MODEL_VERSION ?? ''
|
modelVersion = process.env.MODEL_VERSION ?? ''
|
||||||
|
serverVersion = process.env.VERSION ?? ''
|
||||||
|
|
||||||
oldClientErrors: number = 0
|
oldClientErrors: number = 0
|
||||||
clientErrors: number = 0
|
clientErrors: number = 0
|
||||||
@ -914,7 +915,8 @@ class TSessionManager implements SessionManager {
|
|||||||
id: -1,
|
id: -1,
|
||||||
result: 'hello',
|
result: 'hello',
|
||||||
binary: service.binaryMode,
|
binary: service.binaryMode,
|
||||||
reconnect
|
reconnect,
|
||||||
|
serverVersion: this.serverVersion
|
||||||
}
|
}
|
||||||
ws.send(requestCtx, helloResponse, false, false)
|
ws.send(requestCtx, helloResponse, false, false)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user