feat(snjs): add retrieving web sockets token for establishing connection (#1602)

* feat(snjs): add retrieving web sockets token for establishing connection

* fix(snjs): imports

* fix(snjs): use only web sockets connection token

* fix(snjs): linter issue
This commit is contained in:
Karol Sójko
2022-09-21 14:39:43 +02:00
committed by GitHub
parent 784cefa26f
commit e809328fa8
4 changed files with 55 additions and 9 deletions

View File

@@ -10,6 +10,10 @@ import {
UserRegistrationResponseBody, UserRegistrationResponseBody,
UserServer, UserServer,
UserServerInterface, UserServerInterface,
WebSocketApiService,
WebSocketApiServiceInterface,
WebSocketServer,
WebSocketServerInterface,
} from '@standardnotes/api' } from '@standardnotes/api'
import * as Common from '@standardnotes/common' import * as Common from '@standardnotes/common'
import * as ExternalServices from '@standardnotes/services' import * as ExternalServices from '@standardnotes/services'
@@ -108,6 +112,8 @@ export class SNApplication
private declare subscriptionApiService: SubscriptionApiServiceInterface private declare subscriptionApiService: SubscriptionApiServiceInterface
private declare subscriptionServer: SubscriptionServerInterface private declare subscriptionServer: SubscriptionServerInterface
private declare subscriptionManager: SubscriptionClientInterface private declare subscriptionManager: SubscriptionClientInterface
private declare webSocketApiService: WebSocketApiServiceInterface
private declare webSocketServer: WebSocketServerInterface
private sessionManager!: InternalServices.SNSessionManager private sessionManager!: InternalServices.SNSessionManager
private syncService!: InternalServices.SNSyncService private syncService!: InternalServices.SNSyncService
private challengeService!: InternalServices.ChallengeService private challengeService!: InternalServices.ChallengeService
@@ -329,7 +335,7 @@ export class SNApplication
this.apiService.loadHost() this.apiService.loadHost()
this.webSocketsService.loadWebSocketUrl() this.webSocketsService.loadWebSocketUrl()
this.sessionManager.initializeFromDisk() await this.sessionManager.initializeFromDisk()
this.settingsService.initializeFromDisk() this.settingsService.initializeFromDisk()
@@ -1094,6 +1100,8 @@ export class SNApplication
this.createUserApiService() this.createUserApiService()
this.createSubscriptionServer() this.createSubscriptionServer()
this.createSubscriptionApiService() this.createSubscriptionApiService()
this.createWebSocketServer()
this.createWebSocketApiService()
this.createSubscriptionManager() this.createSubscriptionManager()
this.createWebSocketsService() this.createWebSocketsService()
this.createSessionManager() this.createSessionManager()
@@ -1135,6 +1143,8 @@ export class SNApplication
;(this.userServer as unknown) = undefined ;(this.userServer as unknown) = undefined
;(this.subscriptionApiService as unknown) = undefined ;(this.subscriptionApiService as unknown) = undefined
;(this.subscriptionServer as unknown) = undefined ;(this.subscriptionServer as unknown) = undefined
;(this.webSocketApiService as unknown) = undefined
;(this.webSocketServer as unknown) = undefined
;(this.subscriptionManager as unknown) = undefined ;(this.subscriptionManager as unknown) = undefined
;(this.sessionManager as unknown) = undefined ;(this.sessionManager as unknown) = undefined
;(this.syncService as unknown) = undefined ;(this.syncService as unknown) = undefined
@@ -1252,6 +1262,7 @@ export class SNApplication
this.webSocketsService = new InternalServices.SNWebSocketsService( this.webSocketsService = new InternalServices.SNWebSocketsService(
this.diskStorageService, this.diskStorageService,
this.options.webSocketUrl, this.options.webSocketUrl,
this.webSocketApiService,
this.internalEventBus, this.internalEventBus,
) )
this.services.push(this.webSocketsService) this.services.push(this.webSocketsService)
@@ -1337,6 +1348,14 @@ export class SNApplication
this.subscriptionServer = new SubscriptionServer(this.httpService) this.subscriptionServer = new SubscriptionServer(this.httpService)
} }
private createWebSocketApiService() {
this.webSocketApiService = new WebSocketApiService(this.webSocketServer)
}
private createWebSocketServer() {
this.webSocketServer = new WebSocketServer(this.httpService)
}
private createSubscriptionManager() { private createSubscriptionManager() {
this.subscriptionManager = new SubscriptionManager(this.subscriptionApiService, this.internalEventBus) this.subscriptionManager = new SubscriptionManager(this.subscriptionApiService, this.internalEventBus)
} }

View File

@@ -1,4 +1,6 @@
import { InternalEventBusInterface } from '@standardnotes/services' import { InternalEventBusInterface } from '@standardnotes/services'
import { WebSocketApiServiceInterface } from '@standardnotes/api'
import { StorageKey, DiskStorageService } from '@Lib/index' import { StorageKey, DiskStorageService } from '@Lib/index'
import { SNWebSocketsService } from './WebsocketsService' import { SNWebSocketsService } from './WebsocketsService'
@@ -6,10 +8,11 @@ describe('webSocketsService', () => {
const webSocketUrl = '' const webSocketUrl = ''
let storageService: DiskStorageService let storageService: DiskStorageService
let webSocketApiService: WebSocketApiServiceInterface
let internalEventBus: InternalEventBusInterface let internalEventBus: InternalEventBusInterface
const createService = () => { const createService = () => {
return new SNWebSocketsService(storageService, webSocketUrl, internalEventBus) return new SNWebSocketsService(storageService, webSocketUrl, webSocketApiService, internalEventBus)
} }
beforeEach(() => { beforeEach(() => {
@@ -18,6 +21,9 @@ describe('webSocketsService', () => {
internalEventBus = {} as jest.Mocked<InternalEventBusInterface> internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
internalEventBus.publish = jest.fn() internalEventBus.publish = jest.fn()
webSocketApiService = {} as jest.Mocked<WebSocketApiServiceInterface>
webSocketApiService.createConnectionToken = jest.fn().mockReturnValue({ token: 'foobar' })
}) })
describe('setWebSocketUrl()', () => { describe('setWebSocketUrl()', () => {

View File

@@ -1,6 +1,8 @@
import { UserRolesChangedEvent } from '@standardnotes/domain-events' import { UserRolesChangedEvent } from '@standardnotes/domain-events'
import { DiskStorageService } from '../Storage/DiskStorageService'
import { AbstractService, InternalEventBusInterface, StorageKey } from '@standardnotes/services' import { AbstractService, InternalEventBusInterface, StorageKey } from '@standardnotes/services'
import { WebSocketApiServiceInterface } from '@standardnotes/api'
import { DiskStorageService } from '../Storage/DiskStorageService'
export enum WebSocketsServiceEvent { export enum WebSocketsServiceEvent {
UserRoleMessageReceived = 'WebSocketMessageReceived', UserRoleMessageReceived = 'WebSocketMessageReceived',
@@ -12,6 +14,7 @@ export class SNWebSocketsService extends AbstractService<WebSocketsServiceEvent,
constructor( constructor(
private storageService: DiskStorageService, private storageService: DiskStorageService,
private webSocketUrl: string | undefined, private webSocketUrl: string | undefined,
private webSocketApiService: WebSocketApiServiceInterface,
protected override internalEventBus: InternalEventBusInterface, protected override internalEventBus: InternalEventBusInterface,
) { ) {
super(internalEventBus) super(internalEventBus)
@@ -34,10 +37,15 @@ export class SNWebSocketsService extends AbstractService<WebSocketsServiceEvent,
)._websocket_url )._websocket_url
} }
public startWebSocketConnection(authToken: string): void { async startWebSocketConnection(): Promise<void> {
const webSocketConectionToken = await this.createWebSocketConnectionToken()
if (webSocketConectionToken === undefined) {
return
}
if (this.webSocketUrl) { if (this.webSocketUrl) {
try { try {
this.webSocket = new WebSocket(`${this.webSocketUrl}?authToken=Bearer+${authToken}`) this.webSocket = new WebSocket(`${this.webSocketUrl}?authToken=${webSocketConectionToken}`)
this.webSocket.onmessage = this.onWebSocketMessage.bind(this) this.webSocket.onmessage = this.onWebSocketMessage.bind(this)
this.webSocket.onclose = this.onWebSocketClose.bind(this) this.webSocket.onclose = this.onWebSocketClose.bind(this)
} catch (e) { } catch (e) {
@@ -59,9 +67,22 @@ export class SNWebSocketsService extends AbstractService<WebSocketsServiceEvent,
this.webSocket = undefined this.webSocket = undefined
} }
private async createWebSocketConnectionToken(): Promise<string | undefined> {
try {
const response = await this.webSocketApiService.createConnectionToken()
return response.data.token
} catch (error) {
console.error((error as Error).message)
return undefined
}
}
override deinit(): void { override deinit(): void {
super.deinit() super.deinit()
;(this.storageService as unknown) = undefined ;(this.storageService as unknown) = undefined
;(this.webSocketApiService as unknown) = undefined
this.closeWebSocketConnection() this.closeWebSocketConnection()
} }
} }

View File

@@ -107,7 +107,7 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
this.apiService.setUser(user) this.apiService.setUser(user)
} }
public initializeFromDisk() { async initializeFromDisk() {
this.setUser(this.diskStorageService.getValue(StorageKey.User)) this.setUser(this.diskStorageService.getValue(StorageKey.User))
if (!this.user) { if (!this.user) {
@@ -121,7 +121,7 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
if (rawSession) { if (rawSession) {
const session = SessionFromRawStorageValue(rawSession) const session = SessionFromRawStorageValue(rawSession)
this.setSession(session, false) this.setSession(session, false)
this.webSocketsService.startWebSocketConnection(session.authorizationValue) await this.webSocketsService.startWebSocketConnection()
} }
} }
@@ -623,9 +623,9 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
this.httpService.setHost(host) this.httpService.setHost(host)
await this.setSession(session) this.setSession(session)
this.webSocketsService.startWebSocketConnection(session.authorizationValue) await this.webSocketsService.startWebSocketConnection()
} }
private async handleAuthResponse(body: UserRegistrationResponseBody, rootKey: SNRootKey, wrappingKey?: SNRootKey) { private async handleAuthResponse(body: UserRegistrationResponseBody, rootKey: SNRootKey, wrappingKey?: SNRootKey) {