feat: dynamic authentication url and authentication using website token
This commit is contained in:
parent
bc5414a27c
commit
06de9cbac9
|
@ -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
|
|
@ -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')
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -16,4 +16,5 @@
|
|||
*/
|
||||
export interface ObjServerDto {
|
||||
id: number;
|
||||
sub: string;
|
||||
}
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<Promise<void>> {
|
||||
async execute(): Promise<void> {
|
||||
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) });
|
||||
}
|
||||
}
|
|
@ -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<void> => {
|
||||
TinyDispatcher.getInstance().removeListener(event, key);
|
||||
|
||||
if (location.origin === environmentConfig.defaultServer) await new LoginExtensionCommand().execute();
|
||||
|
||||
await ContentSettingsStore.initSettings();
|
||||
|
||||
await new RuntimePinGetHrefCommand().execute();
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { FetchService } from '@pinmenote/fetch-service';
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { environmentConfig } from '../../../common/environment';
|
||||
|
||||
export class ApiAuthUrlCommand implements ICommand<Promise<string>> {
|
||||
async execute(): Promise<string> {
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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<TokenDataDto>(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);
|
||||
|
|
|
@ -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<FetchResponse<AccessTokenDto | ServerErrorDto>> {
|
||||
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<AccessTokenDto | ServerErrorDto>(url, {
|
||||
method: 'POST',
|
||||
|
|
|
@ -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<FetchResponse<BoolDto | ServerErrorDto>> {
|
||||
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<BoolDto>(
|
||||
|
@ -35,7 +37,7 @@ export class ApiLogoutCommand
|
|||
method: 'POST',
|
||||
headers: this.getAuthHeaders()
|
||||
},
|
||||
this.refreshParams()
|
||||
this.refreshParams(baseUrl)
|
||||
);
|
||||
} catch (e) {
|
||||
fnConsoleLog('ERROR', e);
|
||||
|
|
|
@ -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<FetchResponse<AccessTokenDto | ServerErrorDto>> {
|
||||
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<AccessTokenDto>(url, {
|
||||
method: 'POST',
|
||||
|
|
|
@ -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<Promise<BeginTxResponse | undefined>> {
|
||||
constructor(private authUrl: string) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<BeginTxResponse | undefined> {
|
||||
await this.initTokenData();
|
||||
if (!this.storeUrl) return;
|
||||
|
@ -28,7 +31,7 @@ export class ApiStoreBeginCommand extends ApiCallBase implements ICommand<Promis
|
|||
const resp = await FetchService.fetch<BeginTxResponse>(
|
||||
`${this.storeUrl}/api/v1/tx/begin`,
|
||||
{ headers: this.getAuthHeaders() },
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
return resp.data;
|
||||
} catch (e) {
|
||||
|
|
|
@ -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<Promise<boolean>> {
|
||||
constructor(private tx: BeginTxResponse) {
|
||||
constructor(private authUrl: string, private tx: BeginTxResponse) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<boolean> {
|
||||
|
@ -34,7 +34,7 @@ export class ApiStoreCommitCommand extends ApiCallBase implements ICommand<Promi
|
|||
type: 'TEXT',
|
||||
headers: this.getAuthHeaders()
|
||||
},
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
return resp.ok;
|
||||
} catch (e) {
|
||||
|
|
|
@ -29,10 +29,11 @@ export interface ObjAddRequest {
|
|||
|
||||
export interface ObjAddResponse {
|
||||
serverId: number;
|
||||
sub: string;
|
||||
}
|
||||
|
||||
export class ApiObjAddCommand extends ApiCallBase implements ICommand<Promise<ObjAddResponse | ServerErrorDto>> {
|
||||
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<ObjAddResponse | ServerErrorDto> {
|
||||
|
@ -49,7 +50,7 @@ export class ApiObjAddCommand extends ApiCallBase implements ICommand<Promise<Ob
|
|||
hash: this.hash
|
||||
})
|
||||
},
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
// fnConsoleLog('ApiStoreSyncInfoCommand->response', resp);
|
||||
return resp.data;
|
||||
|
|
|
@ -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<Promise<ObjSingleChange | ServerErrorDto>> {
|
||||
constructor(private hash: string, private tx: BeginTxResponse) {
|
||||
export interface ObjSingleChangeSub extends ObjSingleChange {
|
||||
sub: string;
|
||||
}
|
||||
|
||||
export class ApiObjGetByHashCommand extends ApiCallBase implements ICommand<Promise<ObjSingleChangeSub>> {
|
||||
constructor(private authUrl: string, private hash: string) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<ObjSingleChange | ServerErrorDto> {
|
||||
async execute(): Promise<ObjSingleChangeSub> {
|
||||
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<ObjSingleChange | ServerErrorDto>(
|
||||
`${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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export class ApiObjGetChangesCommand
|
|||
extends ApiCallBase
|
||||
implements ICommand<Promise<ObjChangesResponse | ServerErrorDto>>
|
||||
{
|
||||
constructor(private serverId: number) {
|
||||
constructor(private authUrl: string, private serverId: number) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<ObjChangesResponse | ServerErrorDto> {
|
||||
|
@ -37,7 +37,7 @@ export class ApiObjGetChangesCommand
|
|||
const resp = await FetchService.fetch<ObjChangesResponse | ServerErrorDto>(
|
||||
`${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);
|
||||
|
|
|
@ -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<Promise<ObjSingleChange | undefined>> {
|
||||
constructor(private id: number) {
|
||||
constructor(private authUrl: string, private id: number) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<ObjSingleChange | undefined> {
|
||||
|
@ -31,7 +31,7 @@ export class ApiObjGetChangesCommand extends ApiCallBase implements ICommand<Pro
|
|||
const resp = await FetchService.fetch<ObjSingleChange>(
|
||||
`${this.storeUrl}/api/v1/obj/${this.id}`,
|
||||
{ headers: this.getAuthHeaders() },
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
fnConsoleLog('ApiStoreChangesCommand->response', resp);
|
||||
return resp.data;
|
||||
|
|
|
@ -30,13 +30,13 @@ export interface FileDataDto {
|
|||
}
|
||||
|
||||
export class ApiSegmentAddCommand extends ApiCallBase implements ICommand<Promise<boolean>> {
|
||||
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<boolean> {
|
||||
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 ICommand<Promis
|
|||
...authHeaders
|
||||
}
|
||||
},
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
return resp.status === 200;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ export class ApiSegmentAddCommand extends ApiCallBase implements ICommand<Promis
|
|||
method: 'POST',
|
||||
body: formData
|
||||
},
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
// fnConsoleLog('ApiSegmentAddCommand->resp', resp);
|
||||
return resp.status === 200;
|
||||
|
|
|
@ -24,7 +24,7 @@ export class ApiSegmentGetChildrenCommand
|
|||
extends ApiCallBase
|
||||
implements ICommand<Promise<SegmentHashListResponse | undefined>>
|
||||
{
|
||||
constructor(private hash: string) {
|
||||
constructor(private authUrl: string, private hash: string) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<SegmentHashListResponse | undefined> {
|
||||
|
@ -34,7 +34,7 @@ export class ApiSegmentGetChildrenCommand
|
|||
const resp = await FetchService.fetch<SegmentHashListResponse>(
|
||||
`${this.storeUrl}/api/v1/segment/children/${this.hash}`,
|
||||
{ headers: this.getAuthHeaders() },
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
return resp.data;
|
||||
} catch (e) {
|
||||
|
|
|
@ -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<Promise<Blob | undefined>> {
|
||||
constructor(private hash: string, private mimeType?: string) {
|
||||
constructor(private authUrl: string, private hash: string, private mimeType?: string) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<Blob | undefined> {
|
||||
|
@ -31,7 +31,7 @@ export class ApiSegmentGetCommand extends ApiCallBase implements ICommand<Promis
|
|||
const resp = await FetchService.fetch<Blob>(
|
||||
`${this.storeUrl}/api/v1/segment/${this.hash}${mimeType}`,
|
||||
{ headers: this.getAuthHeaders(), type: 'BLOB' },
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
return resp.data;
|
||||
} catch (e) {
|
||||
|
|
|
@ -25,7 +25,7 @@ export class ApiSegmentQuotaGetCommand
|
|||
extends ApiCallBase
|
||||
implements ICommand<Promise<ServerQuotaResponse | ServerErrorDto>>
|
||||
{
|
||||
constructor() {
|
||||
constructor(private authUrl: string) {
|
||||
super();
|
||||
}
|
||||
async execute(): Promise<ServerQuotaResponse | ServerErrorDto> {
|
||||
|
@ -38,7 +38,7 @@ export class ApiSegmentQuotaGetCommand
|
|||
type: 'JSON',
|
||||
headers: this.getAuthHeaders(true)
|
||||
},
|
||||
this.refreshParams()
|
||||
this.refreshParams(this.authUrl)
|
||||
);
|
||||
return resp.data;
|
||||
} catch (e) {
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<Promise<void>> {
|
||||
constructor(private token: AccessTokenDto) {}
|
||||
async execute(): Promise<void> {
|
||||
fnConsoleLog('ContentExtensionLoginCommand->execute');
|
||||
await new ApiAuthUrlCommand().execute();
|
||||
const baseUrl = await new ApiAuthUrlCommand().execute();
|
||||
const req = await FetchService.fetch<AccessTokenDto | ServerErrorDto>(
|
||||
`${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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ import { BeginTxResponse } from '../../api/store/api-store.model';
|
|||
import { SyncObjectStatus } from '../../../../common/model/sync.model';
|
||||
|
||||
export class SyncNoteCommand implements ICommand<Promise<SyncObjectStatus>> {
|
||||
constructor(private obj: ObjDto<ObjNoteDto>, private tx: BeginTxResponse) {}
|
||||
constructor(private authUrl: string, private obj: ObjDto<ObjNoteDto>, private tx: BeginTxResponse) {}
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
fnConsoleLog('SyncNoteCommand');
|
||||
|
|
|
@ -14,25 +14,29 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<Promise<void>> {
|
||||
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<void> {
|
||||
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<Promise<void>> {
|
|||
}
|
||||
|
||||
private async setByHash(): Promise<void> {
|
||||
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<void> {
|
||||
this.obj.server = { id: serverId };
|
||||
private async saveServerId(serverId: number, sub: string): Promise<void> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Promise<SyncObjectStatus>> {
|
||||
constructor(private obj: ObjDto<ObjPageNoteDto>, private tx: BeginTxResponse) {}
|
||||
constructor(private authUrl: string, private obj: ObjDto<ObjPageNoteDto>, private tx: BeginTxResponse) {}
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
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<Promise<SyncObjectStatus>>
|
|||
|
||||
private async syncNote(data: ObjPageNoteDto): Promise<void> {
|
||||
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
|
||||
|
|
|
@ -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<Promise<SyncObjectStatus>> {
|
||||
constructor(private obj: ObjDto<ObjPdfDto>, private tx: BeginTxResponse) {}
|
||||
constructor(private authUrl: string, private obj: ObjDto<ObjPdfDto>, private tx: BeginTxResponse) {}
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
const data = this.obj.data;
|
||||
await new SyncObjectCommand(this.obj, data.hash, this.tx).execute();
|
||||
|
@ -39,7 +39,7 @@ export class SyncPdfCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||
|
||||
private async syncData(data: ObjPdfDataDto, parent: string): Promise<void> {
|
||||
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<Promise<SyncObjectStatus>> {
|
|||
private async syncPdf(hash: string): Promise<void> {
|
||||
const pdfData = await BrowserStorage.get<string | undefined>(`${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
|
||||
|
|
|
@ -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<Promise<SyncObjectStatus>> {
|
||||
constructor(private obj: ObjDto<ObjPinDto>, private tx: BeginTxResponse) {}
|
||||
constructor(private authUrl: string, private obj: ObjDto<ObjPinDto>, private tx: BeginTxResponse) {}
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
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<Promise<SyncObjectStatus>> {
|
|||
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<Promise<SyncObjectStatus>> {
|
|||
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<Promise<SyncObjectStatus>> {
|
|||
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<Promise<SyncObjectStatus>> {
|
|||
|
||||
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<Promise<SyncObjectStatus>> {
|
|||
|
||||
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,
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<Promise<SyncObjectStatus>> {
|
||||
constructor(private obj: ObjDto<ObjRemovedDto>, private tx: BeginTxResponse) {}
|
||||
constructor(private authUrl: string, private obj: ObjRemovedDto, private tx: BeginTxResponse) {}
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
fnConsoleLog('SyncRemovedCommand', this.obj, this.tx);
|
||||
|
|
|
@ -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<Promise<SyncObjectStatus>> {
|
||||
constructor(private obj: ObjDto<ObjPageDto>, private tx: BeginTxResponse) {}
|
||||
constructor(private authUrl: string, private obj: ObjDto<ObjPageDto>, private tx: BeginTxResponse) {}
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
const page = this.obj.data;
|
||||
const snapshot = page.snapshot;
|
||||
|
@ -54,7 +54,7 @@ export class SyncSnapshotCommand implements ICommand<Promise<SyncObjectStatus>>
|
|||
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<Promise<SyncObjectStatus>>
|
|||
|
||||
private async syncSnapshot(snapshot: PageSnapshotDto, parent: string): Promise<void> {
|
||||
// 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<Promise<SyncObjectStatus>>
|
|||
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,
|
||||
|
|
|
@ -32,7 +32,7 @@ import { fnConsoleLog } from '../../../common/fn/fn-console';
|
|||
import { BeginTxResponse } from '../api/store/api-store.model';
|
||||
|
||||
export class SyncIndexCommand implements ICommand<Promise<SyncObjectStatus>> {
|
||||
constructor(private tx: BeginTxResponse, private id: number) {}
|
||||
constructor(private authUrl: string, private tx: BeginTxResponse, private id: number) {}
|
||||
|
||||
async execute(): Promise<SyncObjectStatus> {
|
||||
const obj = await new ObjGetCommand(this.id).execute();
|
||||
|
@ -46,22 +46,22 @@ export class SyncIndexCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||
switch (obj.type) {
|
||||
case ObjTypeDto.PageSnapshot:
|
||||
case ObjTypeDto.PageElementSnapshot: {
|
||||
return await new SyncSnapshotCommand(obj as ObjDto<ObjPageDto>, this.tx).execute();
|
||||
return await new SyncSnapshotCommand(this.authUrl, obj as ObjDto<ObjPageDto>, this.tx).execute();
|
||||
}
|
||||
case ObjTypeDto.PageElementPin: {
|
||||
return await new SyncPinCommand(obj as ObjDto<ObjPinDto>, this.tx).execute();
|
||||
return await new SyncPinCommand(this.authUrl, obj as ObjDto<ObjPinDto>, this.tx).execute();
|
||||
}
|
||||
case ObjTypeDto.Pdf: {
|
||||
return await new SyncPdfCommand(obj as ObjDto<ObjPdfDto>, this.tx).execute();
|
||||
return await new SyncPdfCommand(this.authUrl, obj as ObjDto<ObjPdfDto>, this.tx).execute();
|
||||
}
|
||||
case ObjTypeDto.Note: {
|
||||
return await new SyncNoteCommand(obj as ObjDto<ObjNoteDto>, this.tx).execute();
|
||||
return await new SyncNoteCommand(this.authUrl, obj as ObjDto<ObjNoteDto>, this.tx).execute();
|
||||
}
|
||||
case ObjTypeDto.PageNote: {
|
||||
return await new SyncPageNoteCommand(obj as ObjDto<ObjPageNoteDto>, this.tx).execute();
|
||||
return await new SyncPageNoteCommand(this.authUrl, obj as ObjDto<ObjPageNoteDto>, this.tx).execute();
|
||||
}
|
||||
case ObjTypeDto.Removed: {
|
||||
return await new SyncRemovedCommand(obj as ObjDto<ObjRemovedDto>, 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);
|
||||
|
|
|
@ -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<Promise<SyncObjectStatus>> {
|
||||
constructor(private progress: SyncProgress, private yearMonth: string) {}
|
||||
|
@ -51,16 +52,17 @@ export class SyncMonthCommand implements ICommand<Promise<SyncObjectStatus>> {
|
|||
}
|
||||
|
||||
async syncIndex(indexList: ObjDateIndex[], start: number): Promise<SyncObjectStatus> {
|
||||
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<Promise<SyncObjectStatus>> {
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Promise<void>> {
|
||||
constructor(private progress: SyncProgress) {}
|
||||
|
@ -28,7 +29,8 @@ export class SyncServerIncomingCommand implements ICommand<Promise<void>> {
|
|||
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++) {
|
||||
|
|
|
@ -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<Promise<void>> {
|
||||
async execute(): Promise<void> {
|
||||
|
|
|
@ -28,10 +28,10 @@ import { TokenDataDto } from '../../../common/model/shared/token.dto';
|
|||
const SYNC_DELAY = 10_000;
|
||||
|
||||
export class SyncTxHelper {
|
||||
static async begin(): Promise<BeginTxResponse | undefined> {
|
||||
static async begin(authUrl: string): Promise<BeginTxResponse | undefined> {
|
||||
const tx = await BrowserStorage.get<BeginTxResponse | undefined>(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<void> {
|
||||
static async commit(authUrl: string): Promise<void> {
|
||||
const tx = await BrowserStorage.get<BeginTxResponse | undefined>(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<any>,
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue