From 06de9cbac941743649a48f04265b388d9cee6761 Mon Sep 17 00:00:00 2001 From: Michal Szczepanski Date: Wed, 11 Oct 2023 07:43:53 +0200 Subject: [PATCH] feat: dynamic authentication url and authentication using website token --- .env.development | 2 +- src/common/environment.ts | 8 +-- src/common/model/bus.model.ts | 1 + src/common/model/obj/obj-server.dto.ts | 1 + .../command/login/login-extension.command.ts | 30 ++++++++ src/content-script/content-script.ts | 4 ++ .../command/api/api-auth-url.command.ts | 27 ++++++++ .../command/api/api-call.base.ts | 39 +++++------ .../command/api/api-login.command.ts | 4 +- .../command/api/api-logout.command.ts | 6 +- .../command/api/api-verify-2fa.command.ts | 4 +- .../api/store/api-store-begin.command.ts | 5 +- .../api/store/api-store-commit.command.ts | 4 +- .../api/store/obj/api-obj-add.command.ts | 5 +- .../store/obj/api-obj-get-by-hash.command.ts | 24 ++++--- .../store/obj/api-obj-get-changes.command.ts | 4 +- .../api/store/obj/api-obj-get.command.ts | 4 +- .../store/segment/api-segment-add.command.ts | 8 +-- .../api-segment-get-children.command.ts | 4 +- .../store/segment/api-segment-get.command.ts | 4 +- .../segment/api-segment-quota-get.command.ts | 4 +- .../content-extension-login.command.ts | 68 +++++++++++++++++++ .../sync/outgoing/sync-note.command.ts | 2 +- .../sync/outgoing/sync-object.command.ts | 39 +++++------ .../sync/outgoing/sync-page-note.command.ts | 6 +- .../command/sync/outgoing/sync-pdf.command.ts | 6 +- .../command/sync/outgoing/sync-pin.command.ts | 12 ++-- .../sync/outgoing/sync-removed.command.ts | 4 +- .../sync/outgoing/sync-snapshot.command.ts | 10 +-- .../command/sync/sync-index.command.ts | 14 ++-- .../command/sync/sync-month.command.ts | 10 +-- .../sync/sync-server-incoming.command.ts | 4 +- .../command/sync/sync-server.command.ts | 1 + .../command/sync/sync-tx.helper.ts | 8 +-- src/service-worker/service-worker.ts | 4 ++ 35 files changed, 264 insertions(+), 116 deletions(-) create mode 100644 src/content-script/command/login/login-extension.command.ts create mode 100644 src/service-worker/command/api/api-auth-url.command.ts create mode 100644 src/service-worker/command/content/content-extension-login.command.ts diff --git a/.env.development b/.env.development index 6d05043..d5842cb 100644 --- a/.env.development +++ b/.env.development @@ -1,4 +1,4 @@ VERSION=1 -WEB_URL=http://127.0.0.1:5173 +WEB_URL=http://localhost:5173 IS_PRODUCTION=false OBJ_LIST_LIMIT=20 \ No newline at end of file diff --git a/src/common/environment.ts b/src/common/environment.ts index b0baa46..a739c90 100644 --- a/src/common/environment.ts +++ b/src/common/environment.ts @@ -65,10 +65,10 @@ export const environmentConfig: EnvironmentConfig = { skipCssImageSizeMB: 2, expertMode: false, history: { - pinComment: true, - pinDraw: true, - pageComment: true, - pageNote: true + pinComment: false, + pinDraw: false, + pageComment: false, + pageNote: false } }, objListLimit: parseInt(process.env.OBJ_LIST_LIMIT || '100000') diff --git a/src/common/model/bus.model.ts b/src/common/model/bus.model.ts index 601c589..468ad5e 100644 --- a/src/common/model/bus.model.ts +++ b/src/common/model/bus.model.ts @@ -50,6 +50,7 @@ export enum BusMessageType { POPUP_IS_PDF = 'popup.is.pdf', // Content script CONTENT_DOWNLOAD_DATA = 'content.download', + CONTENT_EXTENSION_LOGIN = 'content.extension.login', CONTENT_INVALIDATE = 'content.invalidate', CONTENT_PING_URL = 'content.ping.url', CONTENT_PIN_VISIBLE = 'content.pin.visible', diff --git a/src/common/model/obj/obj-server.dto.ts b/src/common/model/obj/obj-server.dto.ts index 531b38b..a633697 100644 --- a/src/common/model/obj/obj-server.dto.ts +++ b/src/common/model/obj/obj-server.dto.ts @@ -16,4 +16,5 @@ */ export interface ObjServerDto { id: number; + sub: string; } diff --git a/src/content-script/command/login/login-extension.command.ts b/src/content-script/command/login/login-extension.command.ts new file mode 100644 index 0000000..fb56f73 --- /dev/null +++ b/src/content-script/command/login/login-extension.command.ts @@ -0,0 +1,30 @@ +/* + * This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension). + * Copyright (c) 2023 Michal Szczepanski. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import { BrowserApi } from '@pinmenote/browser-api'; +import { BusMessageType } from '../../../common/model/bus.model'; +import { ICommand } from '../../../common/model/shared/common.dto'; +import { TokenStorageGetCommand } from '../../../common/command/server/token/token-storage-get.command'; + +export class LoginExtensionCommand implements ICommand> { + async execute(): Promise { + const token = localStorage.getItem('accessToken'); + const extensionToken = await new TokenStorageGetCommand().execute(); + // we are logged in on website but not on extension + if (!extensionToken && token) + await BrowserApi.sendRuntimeMessage({ type: BusMessageType.CONTENT_EXTENSION_LOGIN, data: JSON.parse(token) }); + } +} diff --git a/src/content-script/content-script.ts b/src/content-script/content-script.ts index 42df5a0..27b1096 100644 --- a/src/content-script/content-script.ts +++ b/src/content-script/content-script.ts @@ -34,6 +34,8 @@ import { RuntimePinGetHrefCommand } from './command/runtime/runtime-pin-get-href import { TinyDispatcher } from '@pinmenote/tiny-dispatcher'; import { UrlFactory } from '../common/factory/url.factory'; import { fnUid } from '../common/fn/fn-uid'; +import { environmentConfig } from '../common/environment'; +import { LoginExtensionCommand } from './command/login/login-extension.command'; class PinMeScript { private href: string; @@ -56,6 +58,8 @@ class PinMeScript { private handlePinSettings = async (event: string, key: string): Promise => { TinyDispatcher.getInstance().removeListener(event, key); + if (location.origin === environmentConfig.defaultServer) await new LoginExtensionCommand().execute(); + await ContentSettingsStore.initSettings(); await new RuntimePinGetHrefCommand().execute(); diff --git a/src/service-worker/command/api/api-auth-url.command.ts b/src/service-worker/command/api/api-auth-url.command.ts new file mode 100644 index 0000000..88ba982 --- /dev/null +++ b/src/service-worker/command/api/api-auth-url.command.ts @@ -0,0 +1,27 @@ +/* + * This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension). + * Copyright (c) 2023 Michal Szczepanski. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import { FetchService } from '@pinmenote/fetch-service'; +import { ICommand } from '../../../common/model/shared/common.dto'; +import { environmentConfig } from '../../../common/environment'; + +export class ApiAuthUrlCommand implements ICommand> { + async execute(): Promise { + const req = await FetchService.fetch<{ auth: string }>(`${environmentConfig.defaultServer}/api/server.json`, {}); + if (!req.ok) throw new Error('Invalid api url'); + return req.data.auth; + } +} diff --git a/src/service-worker/command/api/api-call.base.ts b/src/service-worker/command/api/api-call.base.ts index 4eed6f3..ee18844 100644 --- a/src/service-worker/command/api/api-call.base.ts +++ b/src/service-worker/command/api/api-call.base.ts @@ -18,7 +18,6 @@ import { AccessTokenDto, TokenDataDto } from '../../../common/model/shared/token import { FetchHeaders, RefreshTokenParams } from '@pinmenote/fetch-service'; import { TokenStorageGetCommand } from '../../../common/command/server/token/token-storage-get.command'; import { TokenStorageSetCommand } from '../../../common/command/server/token/token-storage-set.command'; -import { environmentConfig } from '../../../common/environment'; import { fnConsoleLog } from '../../../common/fn/fn-console'; import jwtDecode from 'jwt-decode'; @@ -26,10 +25,6 @@ export class ApiCallBase { protected token: AccessTokenDto | undefined; protected tokenData: TokenDataDto | undefined; - get apiUrl(): string { - return environmentConfig.defaultServer; - } - get storeUrl(): string | undefined { return this.tokenData?.data.store; } @@ -40,31 +35,29 @@ export class ApiCallBase { this.tokenData = jwtDecode(this.token.access_token); } - protected refreshParams(): RefreshTokenParams { + protected refreshParams(baseUrl: string): RefreshTokenParams { return { data: { refreshKey: 'message', refreshValue: 'jwt expired', method: 'PUT', - url: `${this.apiUrl}/api/v1/auth/refresh-token` + url: `${baseUrl}/api/v1/refresh-token` }, - successCallback: (res) => { - if (res.status === 200) { - const value: AccessTokenDto = JSON.parse(res.data); - new TokenStorageSetCommand(value) - .execute() - .then(() => { - /* IGNORE */ - }) - .catch(() => { - /* IGNORE */ - }); - return { - Authorization: `Bearer ${value.access_token}` - } as FetchHeaders; - } + successCallback: (res, headers) => { fnConsoleLog('refreshParams->successCallback', res); - return {}; + const value: AccessTokenDto = JSON.parse(res.data); + new TokenStorageSetCommand(value) + .execute() + .then(() => { + /* IGNORE */ + }) + .catch(() => { + /* IGNORE */ + }); + return { + ...headers, + Authorization: `Bearer ${value.access_token}` + } as FetchHeaders; }, errorCallback: (error) => { fnConsoleLog('refreshParams->errorCallback', error); diff --git a/src/service-worker/command/api/api-login.command.ts b/src/service-worker/command/api/api-login.command.ts index 2570d8f..8f4cc3b 100644 --- a/src/service-worker/command/api/api-login.command.ts +++ b/src/service-worker/command/api/api-login.command.ts @@ -20,6 +20,7 @@ import { ICommand, ServerErrorDto } from '../../../common/model/shared/common.dt import { ApiCallBase } from './api-call.base'; import { apiResponseError } from './api.model'; import { fnConsoleLog } from '../../../common/fn/fn-console'; +import { ApiAuthUrlCommand } from './api-auth-url.command'; export class ApiLoginCommand extends ApiCallBase @@ -31,7 +32,8 @@ export class ApiLoginCommand async execute(): Promise> { fnConsoleLog('ApiLoginCommand->execute'); - const url = `${this.apiUrl}/api/v1/auth/login`; + const baseUrl = await new ApiAuthUrlCommand().execute(); + const url = `${baseUrl}/api/v1/login`; try { return await FetchService.fetch(url, { method: 'POST', diff --git a/src/service-worker/command/api/api-logout.command.ts b/src/service-worker/command/api/api-logout.command.ts index 0b92074..e795e0e 100644 --- a/src/service-worker/command/api/api-logout.command.ts +++ b/src/service-worker/command/api/api-logout.command.ts @@ -19,6 +19,7 @@ import { FetchResponse, FetchService } from '@pinmenote/fetch-service'; import { ApiCallBase } from './api-call.base'; import { fnConsoleLog } from '../../../common/fn/fn-console'; import { ApiErrorCode } from '../../../common/model/shared/api.error-code'; +import { ApiAuthUrlCommand } from './api-auth-url.command'; export class ApiLogoutCommand extends ApiCallBase @@ -26,7 +27,8 @@ export class ApiLogoutCommand { async execute(): Promise> { await this.initTokenData(); - const url = `${this.apiUrl}/api/v1/auth/logout`; + const baseUrl = await new ApiAuthUrlCommand().execute(); + const url = `${baseUrl}/api/v1/logout`; fnConsoleLog('ApiLogoutCommand->execute', url); try { return await FetchService.fetch( @@ -35,7 +37,7 @@ export class ApiLogoutCommand method: 'POST', headers: this.getAuthHeaders() }, - this.refreshParams() + this.refreshParams(baseUrl) ); } catch (e) { fnConsoleLog('ERROR', e); diff --git a/src/service-worker/command/api/api-verify-2fa.command.ts b/src/service-worker/command/api/api-verify-2fa.command.ts index 696610e..cc57cca 100644 --- a/src/service-worker/command/api/api-verify-2fa.command.ts +++ b/src/service-worker/command/api/api-verify-2fa.command.ts @@ -20,6 +20,7 @@ import { ICommand, ServerErrorDto } from '../../../common/model/shared/common.dt import { ApiCallBase } from './api-call.base'; import { fnConsoleLog } from '../../../common/fn/fn-console'; import { ApiErrorCode } from '../../../common/model/shared/api.error-code'; +import { ApiAuthUrlCommand } from './api-auth-url.command'; export class ApiVerify2faCommand extends ApiCallBase @@ -31,7 +32,8 @@ export class ApiVerify2faCommand async execute(): Promise> { fnConsoleLog('ApiVerify2faCommand->execute'); - const url = `${this.apiUrl}/api/v1/auth/2fa/verify`; + const baseUrl = await new ApiAuthUrlCommand().execute(); + const url = `${baseUrl}/api/v1/2fa/verify`; try { return await FetchService.fetch(url, { method: 'POST', diff --git a/src/service-worker/command/api/store/api-store-begin.command.ts b/src/service-worker/command/api/store/api-store-begin.command.ts index 32b7cb1..94e85f8 100644 --- a/src/service-worker/command/api/store/api-store-begin.command.ts +++ b/src/service-worker/command/api/store/api-store-begin.command.ts @@ -21,6 +21,9 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { fnConsoleLog } from '../../../../common/fn/fn-console'; export class ApiStoreBeginCommand extends ApiCallBase implements ICommand> { + constructor(private authUrl: string) { + super(); + } async execute(): Promise { await this.initTokenData(); if (!this.storeUrl) return; @@ -28,7 +31,7 @@ export class ApiStoreBeginCommand extends ApiCallBase implements ICommand( `${this.storeUrl}/api/v1/tx/begin`, { headers: this.getAuthHeaders() }, - this.refreshParams() + this.refreshParams(this.authUrl) ); return resp.data; } catch (e) { diff --git a/src/service-worker/command/api/store/api-store-commit.command.ts b/src/service-worker/command/api/store/api-store-commit.command.ts index e871837..b434cd1 100644 --- a/src/service-worker/command/api/store/api-store-commit.command.ts +++ b/src/service-worker/command/api/store/api-store-commit.command.ts @@ -21,7 +21,7 @@ import { ICommand } from '../../../../common/model/shared/common.dto'; import { fnConsoleLog } from '../../../../common/fn/fn-console'; export class ApiStoreCommitCommand extends ApiCallBase implements ICommand> { - constructor(private tx: BeginTxResponse) { + constructor(private authUrl: string, private tx: BeginTxResponse) { super(); } async execute(): Promise { @@ -34,7 +34,7 @@ export class ApiStoreCommitCommand extends ApiCallBase implements ICommand> { - constructor(private obj: ObjDto, private hash: string, private tx: BeginTxResponse) { + constructor(private authUrl: string, private obj: ObjDto, private hash: string, private tx: BeginTxResponse) { super(); } async execute(): Promise { @@ -49,7 +50,7 @@ export class ApiObjAddCommand extends ApiCallBase implements ICommandresponse', resp); return resp.data; diff --git a/src/service-worker/command/api/store/obj/api-obj-get-by-hash.command.ts b/src/service-worker/command/api/store/obj/api-obj-get-by-hash.command.ts index e1d8e8f..3c227a2 100644 --- a/src/service-worker/command/api/store/obj/api-obj-get-by-hash.command.ts +++ b/src/service-worker/command/api/store/obj/api-obj-get-by-hash.command.ts @@ -17,26 +17,34 @@ import { ApiCallBase } from '../../api-call.base'; import { ICommand, ServerErrorDto } from '../../../../../common/model/shared/common.dto'; -import { ApiErrorCode } from '../../../../../common/model/shared/api.error-code'; import { FetchService } from '@pinmenote/fetch-service'; -import { BeginTxResponse, ObjSingleChange } from '../api-store.model'; +import { ObjSingleChange } from '../api-store.model'; +import { fnConsoleLog } from '../../../../../common/fn/fn-console'; -export class ApiObjGetByHashCommand extends ApiCallBase implements ICommand> { - constructor(private hash: string, private tx: BeginTxResponse) { +export interface ObjSingleChangeSub extends ObjSingleChange { + sub: string; +} + +export class ApiObjGetByHashCommand extends ApiCallBase implements ICommand> { + constructor(private authUrl: string, private hash: string) { super(); } - async execute(): Promise { + async execute(): Promise { await this.initTokenData(); - if (!this.storeUrl) return { code: ApiErrorCode.INTERNAL, message: 'ApiStoreObjGetByHashCommand' }; + if (!this.storeUrl) { + fnConsoleLog('ApiStoreObjGetByHashCommand', this.storeUrl); + throw new Error('PROBLEM !!!!!!!!!!!!!!!'); + } const resp = await FetchService.fetch( `${this.storeUrl}/api/v1/obj/hash/${this.hash}`, { headers: this.getAuthHeaders(), method: 'GET' }, - this.refreshParams() + this.refreshParams(this.authUrl) ); // fnConsoleLog('ApiStoreObjGetByHashCommand->response', resp); - return resp.data; + if (!resp.ok) throw new Error('PROBLEM !!!!!!!!!!!!!!!'); + return { ...resp.data, sub: this.tokenData?.sub } as ObjSingleChangeSub; } } diff --git a/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts b/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts index 4ebbeee..730ca9a 100644 --- a/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts +++ b/src/service-worker/command/api/store/obj/api-obj-get-changes.command.ts @@ -27,7 +27,7 @@ export class ApiObjGetChangesCommand extends ApiCallBase implements ICommand> { - constructor(private serverId: number) { + constructor(private authUrl: string, private serverId: number) { super(); } async execute(): Promise { @@ -37,7 +37,7 @@ export class ApiObjGetChangesCommand const resp = await FetchService.fetch( `${this.storeUrl}/api/v1/obj/changes?serverId=${this.serverId}`, { headers: this.getAuthHeaders() }, - this.refreshParams() + this.refreshParams(this.authUrl) ); if (resp.status === 200) return resp.data; fnConsoleLog(resp); diff --git a/src/service-worker/command/api/store/obj/api-obj-get.command.ts b/src/service-worker/command/api/store/obj/api-obj-get.command.ts index fe8bcf8..11a7f85 100644 --- a/src/service-worker/command/api/store/obj/api-obj-get.command.ts +++ b/src/service-worker/command/api/store/obj/api-obj-get.command.ts @@ -21,7 +21,7 @@ import { ICommand } from '../../../../../common/model/shared/common.dto'; import { fnConsoleLog } from '../../../../../common/fn/fn-console'; export class ApiObjGetChangesCommand extends ApiCallBase implements ICommand> { - constructor(private id: number) { + constructor(private authUrl: string, private id: number) { super(); } async execute(): Promise { @@ -31,7 +31,7 @@ export class ApiObjGetChangesCommand extends ApiCallBase implements ICommand( `${this.storeUrl}/api/v1/obj/${this.id}`, { headers: this.getAuthHeaders() }, - this.refreshParams() + this.refreshParams(this.authUrl) ); fnConsoleLog('ApiStoreChangesCommand->response', resp); return resp.data; diff --git a/src/service-worker/command/api/store/segment/api-segment-add.command.ts b/src/service-worker/command/api/store/segment/api-segment-add.command.ts index 968715a..475ffbd 100644 --- a/src/service-worker/command/api/store/segment/api-segment-add.command.ts +++ b/src/service-worker/command/api/store/segment/api-segment-add.command.ts @@ -30,13 +30,13 @@ export interface FileDataDto { } export class ApiSegmentAddCommand extends ApiCallBase implements ICommand> { - constructor(private tx: BeginTxResponse, private file: string, private data: FileDataDto) { + constructor(private authUrl: string, private tx: BeginTxResponse, private file: string, private data: FileDataDto) { super(); } async execute(): Promise { await this.initTokenData(); if (!this.storeUrl) return false; - // if (await this.hasSegment(this.storeUrl)) return true; + if (await this.hasSegment(this.storeUrl)) return true; return await this.addSegment(this.storeUrl); } @@ -52,7 +52,7 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommandresp', resp); return resp.status === 200; diff --git a/src/service-worker/command/api/store/segment/api-segment-get-children.command.ts b/src/service-worker/command/api/store/segment/api-segment-get-children.command.ts index 93e8663..9aaedbb 100644 --- a/src/service-worker/command/api/store/segment/api-segment-get-children.command.ts +++ b/src/service-worker/command/api/store/segment/api-segment-get-children.command.ts @@ -24,7 +24,7 @@ export class ApiSegmentGetChildrenCommand extends ApiCallBase implements ICommand> { - constructor(private hash: string) { + constructor(private authUrl: string, private hash: string) { super(); } async execute(): Promise { @@ -34,7 +34,7 @@ export class ApiSegmentGetChildrenCommand const resp = await FetchService.fetch( `${this.storeUrl}/api/v1/segment/children/${this.hash}`, { headers: this.getAuthHeaders() }, - this.refreshParams() + this.refreshParams(this.authUrl) ); return resp.data; } catch (e) { diff --git a/src/service-worker/command/api/store/segment/api-segment-get.command.ts b/src/service-worker/command/api/store/segment/api-segment-get.command.ts index b80068f..9cd8b0f 100644 --- a/src/service-worker/command/api/store/segment/api-segment-get.command.ts +++ b/src/service-worker/command/api/store/segment/api-segment-get.command.ts @@ -20,7 +20,7 @@ import { ICommand } from '../../../../../common/model/shared/common.dto'; import { fnConsoleLog } from '../../../../../common/fn/fn-console'; export class ApiSegmentGetCommand extends ApiCallBase implements ICommand> { - constructor(private hash: string, private mimeType?: string) { + constructor(private authUrl: string, private hash: string, private mimeType?: string) { super(); } async execute(): Promise { @@ -31,7 +31,7 @@ export class ApiSegmentGetCommand extends ApiCallBase implements ICommand( `${this.storeUrl}/api/v1/segment/${this.hash}${mimeType}`, { headers: this.getAuthHeaders(), type: 'BLOB' }, - this.refreshParams() + this.refreshParams(this.authUrl) ); return resp.data; } catch (e) { diff --git a/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts b/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts index 71d20b0..55ce38b 100644 --- a/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts +++ b/src/service-worker/command/api/store/segment/api-segment-quota-get.command.ts @@ -25,7 +25,7 @@ export class ApiSegmentQuotaGetCommand extends ApiCallBase implements ICommand> { - constructor() { + constructor(private authUrl: string) { super(); } async execute(): Promise { @@ -38,7 +38,7 @@ export class ApiSegmentQuotaGetCommand type: 'JSON', headers: this.getAuthHeaders(true) }, - this.refreshParams() + this.refreshParams(this.authUrl) ); return resp.data; } catch (e) { diff --git a/src/service-worker/command/content/content-extension-login.command.ts b/src/service-worker/command/content/content-extension-login.command.ts new file mode 100644 index 0000000..0d06a78 --- /dev/null +++ b/src/service-worker/command/content/content-extension-login.command.ts @@ -0,0 +1,68 @@ +/* + * This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension). + * Copyright (c) 2023 Michal Szczepanski. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +import { FetchService, RefreshTokenParams, FetchHeaders } from '@pinmenote/fetch-service'; +import { ICommand, ServerErrorDto } from '../../../common/model/shared/common.dto'; +import { AccessTokenDto } from '../../../common/model/shared/token.dto'; +import { TokenStorageSetCommand } from '../../../common/command/server/token/token-storage-set.command'; +import { fnConsoleLog } from '../../../common/fn/fn-console'; +import { ApiAuthUrlCommand } from '../api/api-auth-url.command'; + +export class ContentExtensionLoginCommand implements ICommand> { + constructor(private token: AccessTokenDto) {} + async execute(): Promise { + fnConsoleLog('ContentExtensionLoginCommand->execute'); + await new ApiAuthUrlCommand().execute(); + const baseUrl = await new ApiAuthUrlCommand().execute(); + const req = await FetchService.fetch( + `${baseUrl}/api/v1/login/new-device`, + { + method: 'PATCH', + headers: { + Authorization: `Bearer ${this.token.access_token}`, + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ source: 'EXTENSION' }) + }, + this.refreshParams(baseUrl) + ); + if (req.ok && 'access_token' in req.data) { + await new TokenStorageSetCommand(req.data).execute(); + } + } + + protected refreshParams(baseUrl: string): RefreshTokenParams { + return { + data: { + refreshKey: 'message', + refreshValue: 'jwt expired', + method: 'PUT', + url: `${baseUrl}/api/v1/refresh-token` + }, + successCallback: (res, headers) => { + const value: AccessTokenDto = JSON.parse(res.data); + fnConsoleLog('ContentExtensionLoginCommand->successCallback', res, 'value', value, 'headers', headers); + return { + ...headers, + Authorization: `Bearer ${value.access_token}` + } as FetchHeaders; + }, + errorCallback: (error) => { + fnConsoleLog('ContentExtensionLoginCommand->errorCallback', error); + } + }; + } +} diff --git a/src/service-worker/command/sync/outgoing/sync-note.command.ts b/src/service-worker/command/sync/outgoing/sync-note.command.ts index 8c3f926..2e022db 100644 --- a/src/service-worker/command/sync/outgoing/sync-note.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-note.command.ts @@ -23,7 +23,7 @@ import { BeginTxResponse } from '../../api/store/api-store.model'; import { SyncObjectStatus } from '../../../../common/model/sync.model'; export class SyncNoteCommand implements ICommand> { - constructor(private obj: ObjDto, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjDto, private tx: BeginTxResponse) {} // eslint-disable-next-line @typescript-eslint/require-await async execute(): Promise { fnConsoleLog('SyncNoteCommand'); diff --git a/src/service-worker/command/sync/outgoing/sync-object.command.ts b/src/service-worker/command/sync/outgoing/sync-object.command.ts index 6d3c57c..1188cf0 100644 --- a/src/service-worker/command/sync/outgoing/sync-object.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-object.command.ts @@ -14,25 +14,29 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import { BrowserStorage } from '@pinmenote/browser-api'; -import { ICommand, ServerErrorDto } from '../../../../common/model/shared/common.dto'; -import { ObjDto } from '../../../../common/model/obj/obj.dto'; -import { fnConsoleLog } from '../../../../common/fn/fn-console'; import { ApiObjAddCommand, ObjAddResponse } from '../../api/store/obj/api-obj-add.command'; -import { BeginTxResponse, ObjSingleChange } from '../../api/store/api-store.model'; +import { ApiObjGetByHashCommand, ObjSingleChangeSub } from '../../api/store/obj/api-obj-get-by-hash.command'; +import { ICommand, ServerErrorDto } from '../../../../common/model/shared/common.dto'; import { ApiErrorCode } from '../../../../common/model/shared/api.error-code'; -import { ApiObjGetByHashCommand } from '../../api/store/obj/api-obj-get-by-hash.command'; +import { BeginTxResponse } from '../../api/store/api-store.model'; +import { BrowserStorage } from '@pinmenote/browser-api'; +import { ObjDto } from '../../../../common/model/obj/obj.dto'; import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys'; -import { fnSleep } from '../../../../common/fn/fn-sleep'; +import { fnConsoleLog } from '../../../../common/fn/fn-console'; export class SyncObjectCommand implements ICommand> { - constructor(private obj: ObjDto, private hash: string, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjDto, private hash: string, private tx: BeginTxResponse) {} async execute(): Promise { if (this.obj.server?.id) return; - const resp: ObjAddResponse | ServerErrorDto = await new ApiObjAddCommand(this.obj, this.hash, this.tx).execute(); + const resp: ObjAddResponse | ServerErrorDto = await new ApiObjAddCommand( + this.authUrl, + this.obj, + this.hash, + this.tx + ).execute(); if ('serverId' in resp) { - return await this.saveServerId(resp.serverId); + return await this.saveServerId(resp.serverId, resp.sub); } else if ('code' in resp && resp.code === ApiErrorCode.SYNC_DUPLICATED_HASH) { return await this.setByHash(); } @@ -41,19 +45,12 @@ export class SyncObjectCommand implements ICommand> { } private async setByHash(): Promise { - const resp: ObjSingleChange | ServerErrorDto = await new ApiObjGetByHashCommand(this.hash, this.tx).execute(); - if ('serverId' in resp) { - await this.saveServerId(resp.serverId); - return; - } - fnConsoleLog('SyncObjectCommand->setByHash'); - throw new Error('PROBLEM !!!!!!!!!!!!!!!'); + const resp: ObjSingleChangeSub = await new ApiObjGetByHashCommand(this.authUrl, this.hash).execute(); + await this.saveServerId(resp.serverId, resp.sub); } - private async saveServerId(serverId: number): Promise { - this.obj.server = { id: serverId }; + private async saveServerId(serverId: number, sub: string): Promise { + this.obj.server = { id: serverId, sub }; await BrowserStorage.set(`${ObjectStoreKeys.OBJECT_ID}:${this.obj.id}`, this.obj); await BrowserStorage.set(`${ObjectStoreKeys.SERVER_ID}:${serverId}`, this.obj.id); - await fnSleep(500); - fnConsoleLog('SyncObjectCommand->saveServerId', serverId, 'obj->id', this.obj.id); } } diff --git a/src/service-worker/command/sync/outgoing/sync-page-note.command.ts b/src/service-worker/command/sync/outgoing/sync-page-note.command.ts index 1c9dff6..3b3a98d 100644 --- a/src/service-worker/command/sync/outgoing/sync-page-note.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-page-note.command.ts @@ -27,11 +27,11 @@ import { ApiSegmentAddCommand } from '../../api/store/segment/api-segment-add.co import { SyncCryptoFactory } from '../crypto/sync-crypto.factory'; export class SyncPageNoteCommand implements ICommand> { - constructor(private obj: ObjDto, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjDto, private tx: BeginTxResponse) {} async execute(): Promise { const data = this.obj.data; - await new SyncObjectCommand(this.obj, data.hash, this.tx).execute(); + await new SyncObjectCommand(this.authUrl, this.obj, data.hash, this.tx).execute(); await this.syncNote(data); @@ -40,7 +40,7 @@ export class SyncPageNoteCommand implements ICommand> private async syncNote(data: ObjPageNoteDto): Promise { const content = JSON.stringify(data); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPdfDataDto, hash: data.hash diff --git a/src/service-worker/command/sync/outgoing/sync-pdf.command.ts b/src/service-worker/command/sync/outgoing/sync-pdf.command.ts index 7e23a96..ce6a9b7 100644 --- a/src/service-worker/command/sync/outgoing/sync-pdf.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-pdf.command.ts @@ -26,7 +26,7 @@ import { ApiSegmentAddCommand } from '../../api/store/segment/api-segment-add.co import { SyncCryptoFactory } from '../crypto/sync-crypto.factory'; export class SyncPdfCommand implements ICommand> { - constructor(private obj: ObjDto, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjDto, private tx: BeginTxResponse) {} async execute(): Promise { const data = this.obj.data; await new SyncObjectCommand(this.obj, data.hash, this.tx).execute(); @@ -39,7 +39,7 @@ export class SyncPdfCommand implements ICommand> { private async syncData(data: ObjPdfDataDto, parent: string): Promise { const content = JSON.stringify(data); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPdfDataDto, hash: data.hash, @@ -50,7 +50,7 @@ export class SyncPdfCommand implements ICommand> { private async syncPdf(hash: string): Promise { const pdfData = await BrowserStorage.get(`${ObjectStoreKeys.PDF_DATA}:${hash}`); if (!pdfData) return; - await new ApiSegmentAddCommand(this.tx, pdfData, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, pdfData, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPdf, hash diff --git a/src/service-worker/command/sync/outgoing/sync-pin.command.ts b/src/service-worker/command/sync/outgoing/sync-pin.command.ts index be5bc50..d8baa33 100644 --- a/src/service-worker/command/sync/outgoing/sync-pin.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-pin.command.ts @@ -27,7 +27,7 @@ import { ObjVideoDataDto } from '../../../../common/model/obj/page-snapshot.dto' import { SyncCryptoFactory } from '../crypto/sync-crypto.factory'; export class SyncPinCommand implements ICommand> { - constructor(private obj: ObjDto, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjDto, private tx: BeginTxResponse) {} async execute(): Promise { const data = this.obj.data; await new SyncObjectCommand(this.obj, data.data.hash, this.tx).execute(); @@ -44,7 +44,7 @@ export class SyncPinCommand implements ICommand> { private syncPinVideo = async (parent: string, data?: ObjVideoDataDto) => { if (!data) return; const content = JSON.stringify(data); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjVideoDataDto, hash: data.hash, @@ -56,7 +56,7 @@ export class SyncPinCommand implements ICommand> { for (const draw of data) { // TODO SYNC DRAW LIKE COMMENTS const content = JSON.stringify(draw); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjDrawDto, hash: draw.hash, @@ -70,7 +70,7 @@ export class SyncPinCommand implements ICommand> { const comment = await new PinGetCommentCommand(hash).execute(); if (!comment) continue; const content = JSON.stringify(comment); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjCommentDto, hash: comment.hash, @@ -81,7 +81,7 @@ export class SyncPinCommand implements ICommand> { private syncPinData = async (data: ObjPinDataDto) => { const content = JSON.stringify(data); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPinDataDto, hash: data.hash @@ -90,7 +90,7 @@ export class SyncPinCommand implements ICommand> { private syncPinDescription = async (data: ObjPinDescription, parent: string) => { const content = JSON.stringify(data); - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.ObjPinDescription, hash: data.hash, diff --git a/src/service-worker/command/sync/outgoing/sync-removed.command.ts b/src/service-worker/command/sync/outgoing/sync-removed.command.ts index 355d6b5..28b1968 100644 --- a/src/service-worker/command/sync/outgoing/sync-removed.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-removed.command.ts @@ -14,14 +14,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -import { ObjDto, ObjRemovedDto } from '../../../../common/model/obj/obj.dto'; +import { ObjRemovedDto } from '../../../../common/model/obj/obj.dto'; import { ICommand } from '../../../../common/model/shared/common.dto'; import { SyncObjectStatus } from '../../../../common/model/sync.model'; import { fnConsoleLog } from '../../../../common/fn/fn-console'; import { BeginTxResponse } from '../../api/store/api-store.model'; export class SyncRemovedCommand implements ICommand> { - constructor(private obj: ObjDto, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjRemovedDto, private tx: BeginTxResponse) {} // eslint-disable-next-line @typescript-eslint/require-await async execute(): Promise { fnConsoleLog('SyncRemovedCommand', this.obj, this.tx); diff --git a/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts b/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts index b83c80c..eeef31b 100644 --- a/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts +++ b/src/service-worker/command/sync/outgoing/sync-snapshot.command.ts @@ -28,7 +28,7 @@ import { ApiSegmentAddCommand } from '../../api/store/segment/api-segment-add.co import { SyncCryptoFactory } from '../crypto/sync-crypto.factory'; export class SyncSnapshotCommand implements ICommand> { - constructor(private obj: ObjDto, private tx: BeginTxResponse) {} + constructor(private authUrl: string, private obj: ObjDto, private tx: BeginTxResponse) {} async execute(): Promise { const page = this.obj.data; const snapshot = page.snapshot; @@ -54,7 +54,7 @@ export class SyncSnapshotCommand implements ICommand> if (!segment) return; const content = this.getSegmentContent(segment); if (!content) return; - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: SyncHashType.PageSnapshotFirstHash, hash: segment.hash, @@ -65,14 +65,14 @@ export class SyncSnapshotCommand implements ICommand> private async syncSnapshot(snapshot: PageSnapshotDto, parent: string): Promise { // snapshot->info - await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.info), { + await new ApiSegmentAddCommand(this.authUrl, this.tx, JSON.stringify(snapshot.info), { key: await SyncCryptoFactory.newKey(), type: SyncHashType.PageSnapshotInfoDto, hash: snapshot.info.hash, parent }).execute(); // snapshot->data - await new ApiSegmentAddCommand(this.tx, JSON.stringify(snapshot.data), { + await new ApiSegmentAddCommand(this.authUrl, this.tx, JSON.stringify(snapshot.data), { key: await SyncCryptoFactory.newKey(), type: SyncHashType.PageSnapshotDataDto, hash: snapshot.data.hash, @@ -90,7 +90,7 @@ export class SyncSnapshotCommand implements ICommand> const content = this.getSegmentContent(segment); if (!content) return; - await new ApiSegmentAddCommand(this.tx, content, { + await new ApiSegmentAddCommand(this.authUrl, this.tx, content, { key: await SyncCryptoFactory.newKey(), type: this.convertSegmentTypeSyncHashType(segment.type), hash, diff --git a/src/service-worker/command/sync/sync-index.command.ts b/src/service-worker/command/sync/sync-index.command.ts index b45bf35..dbb6321 100644 --- a/src/service-worker/command/sync/sync-index.command.ts +++ b/src/service-worker/command/sync/sync-index.command.ts @@ -32,7 +32,7 @@ import { fnConsoleLog } from '../../../common/fn/fn-console'; import { BeginTxResponse } from '../api/store/api-store.model'; export class SyncIndexCommand implements ICommand> { - constructor(private tx: BeginTxResponse, private id: number) {} + constructor(private authUrl: string, private tx: BeginTxResponse, private id: number) {} async execute(): Promise { const obj = await new ObjGetCommand(this.id).execute(); @@ -46,22 +46,22 @@ export class SyncIndexCommand implements ICommand> { switch (obj.type) { case ObjTypeDto.PageSnapshot: case ObjTypeDto.PageElementSnapshot: { - return await new SyncSnapshotCommand(obj as ObjDto, this.tx).execute(); + return await new SyncSnapshotCommand(this.authUrl, obj as ObjDto, this.tx).execute(); } case ObjTypeDto.PageElementPin: { - return await new SyncPinCommand(obj as ObjDto, this.tx).execute(); + return await new SyncPinCommand(this.authUrl, obj as ObjDto, this.tx).execute(); } case ObjTypeDto.Pdf: { - return await new SyncPdfCommand(obj as ObjDto, this.tx).execute(); + return await new SyncPdfCommand(this.authUrl, obj as ObjDto, this.tx).execute(); } case ObjTypeDto.Note: { - return await new SyncNoteCommand(obj as ObjDto, this.tx).execute(); + return await new SyncNoteCommand(this.authUrl, obj as ObjDto, this.tx).execute(); } case ObjTypeDto.PageNote: { - return await new SyncPageNoteCommand(obj as ObjDto, this.tx).execute(); + return await new SyncPageNoteCommand(this.authUrl, obj as ObjDto, this.tx).execute(); } case ObjTypeDto.Removed: { - return await new SyncRemovedCommand(obj as ObjDto, this.tx).execute(); + return await new SyncRemovedCommand(this.authUrl, obj as any as ObjRemovedDto, this.tx).execute(); } default: { fnConsoleLog('SyncObjectCommand->PROBLEM', obj, 'index', this.id); diff --git a/src/service-worker/command/sync/sync-month.command.ts b/src/service-worker/command/sync/sync-month.command.ts index 41dae84..8fcf0fd 100644 --- a/src/service-worker/command/sync/sync-month.command.ts +++ b/src/service-worker/command/sync/sync-month.command.ts @@ -23,6 +23,7 @@ import { fnConsoleLog } from '../../../common/fn/fn-console'; import { ObjDateIndex } from '../../../common/command/obj/index/obj-update-index-add.command'; import { SyncSetProgressCommand } from './progress/sync-set-progress.command'; import { BrowserStorage } from '@pinmenote/browser-api'; +import { ApiAuthUrlCommand } from '../api/api-auth-url.command'; export class SyncMonthCommand implements ICommand> { constructor(private progress: SyncProgress, private yearMonth: string) {} @@ -51,16 +52,17 @@ export class SyncMonthCommand implements ICommand> { } async syncIndex(indexList: ObjDateIndex[], start: number): Promise { - const begin = await SyncTxHelper.begin(); + const authUrl = await new ApiAuthUrlCommand().execute(); + const begin = await SyncTxHelper.begin(authUrl); if (!begin) return SyncObjectStatus.TX_LOCKED; let i = start; let status = SyncObjectStatus.OK; for (i; i < indexList.length; i++) { - status = await new SyncIndexCommand(begin, indexList[i].id).execute(); + status = await new SyncIndexCommand(authUrl, begin, indexList[i].id).execute(); switch (status) { case SyncObjectStatus.SERVER_ERROR: { fnConsoleLog('SERVER_ERROR !!!!!!!!!!!!!!!!!!!'); - await SyncTxHelper.commit(); + await SyncTxHelper.commit(authUrl); await this.updateProgress(indexList[i].id, indexList[i].dt); return status; } @@ -94,7 +96,7 @@ export class SyncMonthCommand implements ICommand> { // all conditions (not current year/month, not last id, object exists) are met if (resetMonth) await this.updateProgress(-1, lastIndex.dt); - await SyncTxHelper.commit(); + await SyncTxHelper.commit(authUrl); return SyncObjectStatus.OK; } diff --git a/src/service-worker/command/sync/sync-server-incoming.command.ts b/src/service-worker/command/sync/sync-server-incoming.command.ts index 30110af..af3ada6 100644 --- a/src/service-worker/command/sync/sync-server-incoming.command.ts +++ b/src/service-worker/command/sync/sync-server-incoming.command.ts @@ -21,6 +21,7 @@ import { SyncObjIncomingCommand } from './incoming/sync-obj-incoming.command'; import { SyncSetProgressCommand } from './progress/sync-set-progress.command'; import { SyncProgress } from '../../../common/model/sync.model'; import { SwSyncStore } from '../../sw-sync.store'; +import { ApiAuthUrlCommand } from '../api/api-auth-url.command'; export class SyncServerIncomingCommand implements ICommand> { constructor(private progress: SyncProgress) {} @@ -28,7 +29,8 @@ export class SyncServerIncomingCommand implements ICommand> { if (SwSyncStore.isInSync) return; SwSyncStore.isInSync = true; try { - const changesResp = await new ApiObjGetChangesCommand(this.progress.serverId).execute(); + const authUrl = await new ApiAuthUrlCommand().execute(); + const changesResp = await new ApiObjGetChangesCommand(authUrl, this.progress.serverId).execute(); fnConsoleLog('SyncServerIncomingCommand->START', changesResp); if ('code' in changesResp) return; for (let i = 0; i < changesResp.data.length; i++) { diff --git a/src/service-worker/command/sync/sync-server.command.ts b/src/service-worker/command/sync/sync-server.command.ts index 0c2e8b6..5177dd6 100644 --- a/src/service-worker/command/sync/sync-server.command.ts +++ b/src/service-worker/command/sync/sync-server.command.ts @@ -21,6 +21,7 @@ import { fnConsoleLog } from '../../../common/fn/fn-console'; import { SyncResetProgressCommand } from './progress/sync-reset-progress.command'; import { SyncServerIncomingCommand } from './sync-server-incoming.command'; import { SwSyncStore } from '../../sw-sync.store'; +import { SyncServerOutgoingCommand } from './sync-server-outgoing.command'; export class SyncServerCommand implements ICommand> { async execute(): Promise { diff --git a/src/service-worker/command/sync/sync-tx.helper.ts b/src/service-worker/command/sync/sync-tx.helper.ts index 7ffbe13..b91ec79 100644 --- a/src/service-worker/command/sync/sync-tx.helper.ts +++ b/src/service-worker/command/sync/sync-tx.helper.ts @@ -28,10 +28,10 @@ import { TokenDataDto } from '../../../common/model/shared/token.dto'; const SYNC_DELAY = 10_000; export class SyncTxHelper { - static async begin(): Promise { + static async begin(authUrl: string): Promise { const tx = await BrowserStorage.get(ObjectStoreKeys.SYNC_TX); if (tx) return tx; - const txResponse = await new ApiStoreBeginCommand().execute(); + const txResponse = await new ApiStoreBeginCommand(authUrl).execute(); if (txResponse?.locked) { const token = await new TokenStorageGetCommand().execute(); if (!token) return undefined; @@ -53,11 +53,11 @@ export class SyncTxHelper { return txResponse; } - static async commit(): Promise { + static async commit(authUrl: string): Promise { const tx = await BrowserStorage.get(ObjectStoreKeys.SYNC_TX); if (!tx) return; fnConsoleLog('SyncServerCommand->commit', tx); - await new ApiStoreCommitCommand(tx).execute(); + await new ApiStoreCommitCommand(authUrl, tx).execute(); await BrowserStorage.remove(ObjectStoreKeys.SYNC_TX); } diff --git a/src/service-worker/service-worker.ts b/src/service-worker/service-worker.ts index f795b6b..ac6a457 100644 --- a/src/service-worker/service-worker.ts +++ b/src/service-worker/service-worker.ts @@ -40,6 +40,7 @@ import { fnConsoleLog } from '../common/fn/fn-console'; import { SyncManualOutgoingCommand } from './command/sync/manual/sync-manual-outgoing.command'; import { SyncServerIncomingCommand } from './command/sync/sync-server-incoming.command'; import { SyncGetProgressCommand } from './command/sync/progress/sync-get-progress.command'; +import { ContentExtensionLoginCommand } from './command/content/content-extension-login.command'; const handleMessage = async ( msg: BusMessage, @@ -54,6 +55,9 @@ const handleMessage = async ( if (runtime.id !== BrowserApi.runtime.id) return; switch (msg.type) { + case BusMessageType.CONTENT_EXTENSION_LOGIN: + await new ContentExtensionLoginCommand(msg.data).execute(); + break; case BusMessageType.CONTENT_DOWNLOAD_DATA: await new ContentDownloadDataCommand(msg.data).execute(); break;