mirror of
https://github.com/balzack/databag.git
synced 2025-04-24 02:25:26 +00:00
renamed account interface
This commit is contained in:
parent
5de105ed89
commit
5c3b491f82
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Alias, Account } from '../src/api';
|
||||
import type { Alias } from '../src/api';
|
||||
import type { Group } from '../src/types';
|
||||
|
||||
export class MockAliasModule implements Alias {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Attribute, Account } from '../src/api';
|
||||
import type { Attribute } from '../src/api';
|
||||
import type { Article } from '../src/types';
|
||||
|
||||
export class MockAttributeModule implements Attribute {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Content, Account } from '../src/api';
|
||||
import type { Content } from '../src/api';
|
||||
import type { Channel, Topic, Asset, Tag, Repeater } from '../src/types';
|
||||
|
||||
export class MockContentModule implements Content {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { type Account } from '../src/api';
|
||||
import type { AccountStatus } from '../src/types';
|
||||
import { type Settings } from '../src/api';
|
||||
import type { Config } from '../src/types';
|
||||
|
||||
export class MockAccountModule implements Account {
|
||||
export class MockSettingsModule implements Settings {
|
||||
|
||||
public revision: number;
|
||||
private emitter: EventEmitter;
|
||||
@ -12,11 +12,11 @@ export class MockAccountModule implements Account {
|
||||
this.emitter = new EventEmitter();
|
||||
}
|
||||
|
||||
public addStatusListener(ev: (status: AccountStatus) => void): void {
|
||||
public addStatusListener(ev: (status: Config) => void): void {
|
||||
this.emitter.on('status', ev);
|
||||
}
|
||||
|
||||
public removeStatusListener(ev: (status: AccountStatus) => void): void {
|
||||
public removeStatusListener(ev: (status: Config) => void): void {
|
||||
this.emitter.off('status', ev);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { DatabagSDK } from '../src/index';
|
||||
import { type SessionParams } from '../src/types';
|
||||
|
||||
import { MockConnection } from '../__mocks__/connection';
|
||||
import { MockAccountModule } from '../__mocks__/account';
|
||||
import { MockSettingsModule } from '../__mocks__/settings';
|
||||
import { MockIdentityModule } from '../__mocks__/identity';
|
||||
import { MockAliasModule } from '../__mocks__/alias';
|
||||
import { MockContentModule } from '../__mocks__/content';
|
||||
@ -29,11 +29,11 @@ jest.mock('../src/connection', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const mockAccount = new MockAccountModule();
|
||||
jest.mock('../src/account', () => {
|
||||
const mockSettings = new MockSettingsModule();
|
||||
jest.mock('../src/settings', () => {
|
||||
return {
|
||||
AccountModule: jest.fn().mockImplementation(() => {
|
||||
return mockAccount;
|
||||
SettingsModule: jest.fn().mockImplementation(() => {
|
||||
return mockSettings;
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -99,14 +99,14 @@ test('allocates session correctly', async () => {
|
||||
const params: SessionParams = { topicBatch: 0, tagBatch: 0, channelTypes: [], pushType: '', deviceToken: '', notifications: [], deviceId: '', version: '', appName: '' };
|
||||
const session = await sdk.login('handle', 'password', 'jest.test', true, null, params);
|
||||
session.addStatusListener((ev: string) => { status = ev; });
|
||||
const account = session.getAccount();
|
||||
account.enableNotifications();
|
||||
const settings = session.getSettings();
|
||||
settings.enableNotifications();
|
||||
mockConnection.emitStatus('connected');
|
||||
mockConnection.emitRevision({ account: 3, profile: 3, article: 3, group: 3, channel: 3, card: 3});
|
||||
mockConnection.emitRing({ cardId: '', callId: 'test', calleeToken: '', ice: []});
|
||||
await waitFor(() => (status === 'connected'));
|
||||
await waitFor(() => (mockRing.call?.callId === 'test'));
|
||||
await waitFor(() => (mockAccount.revision == 3));
|
||||
await waitFor(() => (mockSettings.revision == 3));
|
||||
await waitFor(() => (mockIdentity.revision == 3));
|
||||
await waitFor(() => (mockContent.revision == 3));
|
||||
await waitFor(() => (mockContact.revision == 3));
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { AccountModule } from '../src/account';
|
||||
import { SettingsModule } from '../src/settings';
|
||||
import { NoStore } from '../src/store';
|
||||
import { Crypto } from '../src/crypto';
|
||||
import { ConsoleLogging } from '../src/logging';
|
||||
import { defaultAccountEntity } from '../src/entities';
|
||||
import { AccountStatus } from '../src/types';
|
||||
import { defaultConfigEntity } from '../src/entities';
|
||||
import { Config } from '../src/types';
|
||||
import { waitFor } from '../__mocks__/waitFor';
|
||||
import axios from 'redaxios';
|
||||
|
||||
const testStatus = JSON.parse(JSON.stringify(defaultAccountEntity));
|
||||
const testStatus = JSON.parse(JSON.stringify(defaultConfigEntity));
|
||||
|
||||
jest.mock('redaxios', () => {
|
||||
return {
|
||||
@ -76,29 +76,29 @@ class TestStore extends NoStore {
|
||||
}
|
||||
|
||||
test('allocates session correctly', async () => {
|
||||
let status: AccountStatus | null = null;
|
||||
let status: Config | null = null;
|
||||
const log = new ConsoleLogging();
|
||||
const store = new TestStore();
|
||||
const crypto = new TestCrypto();
|
||||
const account = new AccountModule(log, store, crypto, 'test_guid', 'test_token', 'test_url', false);
|
||||
account.addStatusListener((ev: AccountStatus) => { status = ev });
|
||||
account.setRevision(5);
|
||||
const settings = new SettingsModule(log, store, crypto, 'test_guid', 'test_token', 'test_url', false);
|
||||
settings.addStatusListener((ev: Config) => { status = ev });
|
||||
settings.setRevision(5);
|
||||
await waitFor(() => (status?.storageUsed == 2));
|
||||
account.enableRegistry();
|
||||
account.setRevision(6);
|
||||
settings.enableRegistry();
|
||||
settings.setRevision(6);
|
||||
await waitFor(() => Boolean(status?.searchable));
|
||||
account.disableRegistry();
|
||||
account.setRevision(7);
|
||||
settings.disableRegistry();
|
||||
settings.setRevision(7);
|
||||
await waitFor(() => !Boolean(status?.searchable));
|
||||
|
||||
account.enableNotifications();
|
||||
account.setRevision(8);
|
||||
settings.enableNotifications();
|
||||
settings.setRevision(8);
|
||||
await waitFor(() => Boolean(status?.pushEnabled));
|
||||
account.disableNotifications();
|
||||
account.setRevision(9);
|
||||
settings.disableNotifications();
|
||||
settings.setRevision(9);
|
||||
await waitFor(() => !Boolean(status?.pushEnabled));
|
||||
|
||||
account.setSeal('password');
|
||||
account.setRevision(10);
|
||||
settings.setSeal('password');
|
||||
settings.setRevision(10);
|
||||
await waitFor(() => Boolean(status?.sealSet));
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Alias, Account, Logging } from './api';
|
||||
import type { Alias, Settings, Logging } from './api';
|
||||
import type { Group } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
@ -10,16 +10,16 @@ export class AliasModule implements Alias {
|
||||
private token: string;
|
||||
private node: string;
|
||||
private secure: boolean;
|
||||
private account: Account;
|
||||
private settings: Settings;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, account: Account, store: Store, guid: string, token: string, node: string, secure: boolean) {
|
||||
constructor(log: Logging, settings: Settings, store: Store, guid: string, token: string, node: string, secure: boolean) {
|
||||
this.guid = guid;
|
||||
this.token = token;
|
||||
this.node = node;
|
||||
this.secure = secure;
|
||||
this.log = log;
|
||||
this.account = account;
|
||||
this.settings = settings;
|
||||
this.emitter = new EventEmitter();
|
||||
}
|
||||
|
||||
|
@ -4,54 +4,10 @@
|
||||
// formaize delete vs block remote channel
|
||||
// articles share by cards now
|
||||
|
||||
import type { Channel, Topic, Asset, Tag, Article, Group, Card, Profile, Call, AccountStatus, NodeConfig, NodeAccount, Repeater } from './types';
|
||||
|
||||
export interface SqlStore {
|
||||
set(stmt: string, params?: (string | number | null)[]): Promise<void>;
|
||||
get(stmt: string, params?: (string | number | null)[]): Promise<any[]>;
|
||||
}
|
||||
|
||||
export interface WebStore {
|
||||
getValue(key: string): Promise<string>;
|
||||
setValue(key: string, value: string): Promise<void>;
|
||||
clearValue(key: string): Promise<void>;
|
||||
clearAll(): Promise<void>;
|
||||
}
|
||||
|
||||
export interface Crypto {
|
||||
|
||||
// generate salt for pbk function
|
||||
pkdkfSalt(): { saltHex: string };
|
||||
|
||||
// generate aes key with pbkdf2
|
||||
pbkdfKey(saltHex: string, password: string): { aesKeyHex: string };
|
||||
|
||||
// generate random aes key
|
||||
aesKey(): { aesKeyHex: string };
|
||||
|
||||
// generate iv to use to aes function
|
||||
aesIv(): { ivHex: string };
|
||||
|
||||
// encrypt data with aes key and iv
|
||||
aesEncrypt(data: string, ivHex: string, aesKeyHex: string): { encryptedDataB64: string };
|
||||
|
||||
// decrypt data with aes key and iv
|
||||
aesDecrypt(encryptedDataB64: string, ivHex: string, aesKeyHex: string): { data: string };
|
||||
|
||||
// generate rsa key
|
||||
rsaKey(): { publicKeyB64: string, privateKeyB64: string };
|
||||
|
||||
// encrypt data with public rsa key
|
||||
rsaEncrypt(data: string, publicKeyB64: string): { encryptedDataB64: string }
|
||||
|
||||
// decrypt data with private rsa key
|
||||
rsaDecrypt(encryptedDataB64: string, privateKeyB64: string): { data: string }
|
||||
}
|
||||
import type { Channel, Topic, Asset, Tag, Article, Group, Card, Profile, Call, Config, NodeConfig, NodeAccount, Repeater } from './types';
|
||||
|
||||
export interface Session {
|
||||
close(): Promise<{ node: string, secure: boolean, token: string }>;
|
||||
|
||||
getAccount(): Account;
|
||||
getSettings(): Settings;
|
||||
getIdentity(): Identity;
|
||||
getContact(): Contact;
|
||||
getAlias(): Alias;
|
||||
@ -63,8 +19,6 @@ export interface Session {
|
||||
addFocus(cardId: string | null, channelId: string): Focus;
|
||||
removeFocus(focus: Focus): void;
|
||||
|
||||
resync(): void;
|
||||
|
||||
addStatusListener(ev: (status: string) => void): void;
|
||||
removeStatusListener(ev: (status: string) => void): void;
|
||||
}
|
||||
@ -82,7 +36,7 @@ export interface Ring {
|
||||
decline(callId: string): void;
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
export interface Settings {
|
||||
setLogin(username: string, password: string): Promise<void>;
|
||||
enableNotifications(): Promise<void>;
|
||||
disableNotifications(): Promise<void>;
|
||||
@ -96,8 +50,8 @@ export interface Account {
|
||||
unlockSeal(password: string): Promise<void>;
|
||||
forgetSeal(): Promise<void>;
|
||||
|
||||
addStatusListener(ev: (status: AccountStatus) => void): void;
|
||||
removeStatusListener(ev: (status: AccountStatus) => void): void;
|
||||
addStatusListener(ev: (config: Config) => void): void;
|
||||
removeStatusListener(ev: (config: Config) => void): void;
|
||||
}
|
||||
|
||||
export interface Identity {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Attribute, Account, Logging } from './api';
|
||||
import type { Attribute, Settings, Logging } from './api';
|
||||
import type { Article } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
@ -10,16 +10,16 @@ export class AttributeModule implements Attribute {
|
||||
private token: string;
|
||||
private node: string;
|
||||
private secure: boolean;
|
||||
private account: Account;
|
||||
private settings: Settings;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, account: Account, store: Store, guid: string, token: string, node: string, secure: boolean) {
|
||||
constructor(log: Logging, settings: Settings, store: Store, guid: string, token: string, node: string, secure: boolean) {
|
||||
this.guid = guid;
|
||||
this.token = token;
|
||||
this.node = node;
|
||||
this.secure = secure;
|
||||
this.log = log;
|
||||
this.account = account;
|
||||
this.settings = settings;
|
||||
this.emitter = new EventEmitter();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Content, Account, Logging } from './api';
|
||||
import type { Content, Settings, Logging } from './api';
|
||||
import type { Channel, Topic, Asset, Tag, Repeater } from './types';
|
||||
import { Store } from './store';
|
||||
|
||||
@ -10,16 +10,16 @@ export class ContentModule implements Content {
|
||||
private token: string;
|
||||
private node: string;
|
||||
private secure: boolean;
|
||||
private account: Account;
|
||||
private settings: Settings;
|
||||
private emitter: EventEmitter;
|
||||
|
||||
constructor(log: Logging, account: Account, store: Store, guid: string, token: string, node: string, secure: boolean) {
|
||||
constructor(log: Logging, settings: Settings, store: Store, guid: string, token: string, node: string, secure: boolean) {
|
||||
this.guid = guid;
|
||||
this.token = token;
|
||||
this.node = node;
|
||||
this.secure = secure;
|
||||
this.log = log;
|
||||
this.account = account;
|
||||
this.settings = settings;
|
||||
this.emitter = new EventEmitter();
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ export type SealEntity = {
|
||||
publicKey: string,
|
||||
}
|
||||
|
||||
export type AccountEntity = {
|
||||
export type ConfigEntity = {
|
||||
disabled: boolean,
|
||||
storageUsed: number,
|
||||
storageAvailable: number,
|
||||
@ -164,7 +164,7 @@ export type AccountEntity = {
|
||||
webPushKey: string,
|
||||
}
|
||||
|
||||
export const defaultAccountEntity = {
|
||||
export const defaultConfigEntity = {
|
||||
disabled: false,
|
||||
storageUsed: 0,
|
||||
storageAvailable: 0,
|
||||
|
@ -10,13 +10,16 @@ import { addAccount } from './net/addAccount';
|
||||
import { setAdmin } from './net/setAdmin';
|
||||
import { getAvailable } from './net/getAvailable';
|
||||
import { getUsername } from './net/getUsername';
|
||||
import type { Session, Node, Bot, SqlStore, WebStore } from './api';
|
||||
import type { Session, Node, Bot } from './api';
|
||||
import type { SessionParams } from './types';
|
||||
import type { Login } from './entities';
|
||||
import type { Crypto } from './crypto';
|
||||
import type { WebStore, SqlStore } from './store';
|
||||
|
||||
export * from './api';
|
||||
export * from './types';
|
||||
export { WebStore, SqlStore } from './store';
|
||||
export { Crypto } from './crypto';
|
||||
|
||||
export class DatabagSDK {
|
||||
|
||||
@ -77,7 +80,8 @@ export class DatabagSDK {
|
||||
}
|
||||
|
||||
public async logout(session: Session, all: boolean): Promise<void> {
|
||||
const params = await session.close();
|
||||
const sessionModule = session as SessionModule;
|
||||
const params = await sessionModule.close();
|
||||
try {
|
||||
const { node, secure, token } = params;
|
||||
await clearLogin(node, secure, token, all);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import axios from 'redaxios';
|
||||
import { AccountEntity } from '../entities';
|
||||
import { ConfigEntity } from '../entities';
|
||||
|
||||
export async function getAccountStatus(node: string, secure: boolean, token: string): Promise<AccountEntity> {
|
||||
export async function getAccountStatus(node: string, secure: boolean, token: string): Promise<ConfigEntity> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${node}/account/status?agent=${token}`;
|
||||
const response = await axios.get(endpoint);
|
||||
if (response.status >= 400 && response.status < 600) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
|
||||
import { AccountModule } from './account';
|
||||
import { SettingsModule } from './settings';
|
||||
import { IdentityModule } from './identity';
|
||||
import { ContactModule } from './contact';
|
||||
import { AliasModule } from './alias';
|
||||
@ -12,7 +12,7 @@ import { RingModule } from './ring';
|
||||
|
||||
import { Connection } from './connection';
|
||||
|
||||
import type { Session, Account, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus } from './api';
|
||||
import type { Session, Settings, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus } from './api';
|
||||
import { Revision } from './entities';
|
||||
import { Call } from './types';
|
||||
import { Store } from './store';
|
||||
@ -30,9 +30,8 @@ export class SessionModule implements Session {
|
||||
private node: string;
|
||||
private secure: boolean;
|
||||
private loginTimestamp: number;
|
||||
private syncRevision: Revision | null;
|
||||
private status: string;
|
||||
private account: AccountModule;
|
||||
private settings: SettingsModule;
|
||||
private identity: IdentityModule;
|
||||
private contact: ContactModule;
|
||||
private alias: AliasModule;
|
||||
@ -54,16 +53,15 @@ export class SessionModule implements Session {
|
||||
this.node = node;
|
||||
this.secure = secure;
|
||||
this.loginTimestamp = loginTimestamp;
|
||||
this.syncRevision = null;
|
||||
this.status = 'connecting'
|
||||
this.emitter = new EventEmitter();
|
||||
|
||||
this.identity = new IdentityModule(log, this.store, guid, token, node, secure);
|
||||
this.account = new AccountModule(log, this.store, this.crypto, guid, token, node, secure);
|
||||
this.settings = new SettingsModule(log, this.store, this.crypto, guid, token, node, secure);
|
||||
this.contact = new ContactModule(log, this.store, guid, token, node, secure);
|
||||
this.alias = new AliasModule(log, this.account, this.store, guid, token, node, secure);
|
||||
this.attribute = new AttributeModule(log, this.account, this.store, guid, token, node, secure);
|
||||
this.content = new ContentModule(log, this.account, this.store, guid, token, node, secure);
|
||||
this.alias = new AliasModule(log, this.settings, this.store, guid, token, node, secure);
|
||||
this.attribute = new AttributeModule(log, this.settings, this.store, guid, token, node, secure);
|
||||
this.content = new ContentModule(log, this.settings, this.store, guid, token, node, secure);
|
||||
this.stream = new StreamModule(log, this.contact, this.content, this.store, guid);
|
||||
this.ring = new RingModule(log);
|
||||
this.connection = new Connection(log, token, node, secure);
|
||||
@ -74,23 +72,12 @@ export class SessionModule implements Session {
|
||||
}
|
||||
|
||||
const onRevision = async (ev: Revision) => {
|
||||
try {
|
||||
await this.identity.setRevision(ev.profile);
|
||||
await this.account.setRevision(ev.account);
|
||||
await this.contact.setRevision(ev.card);
|
||||
await this.attribute.setRevision(ev.article);
|
||||
await this.alias.setRevision(ev.group);
|
||||
await this.content.setRevision(ev.channel);
|
||||
if (this.syncRevision) {
|
||||
this.syncRevision = null
|
||||
this.emitter.emit('status', this.getStatus());
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
this.log.warn(err);
|
||||
this.syncRevision = ev;
|
||||
this.emitter.emit('status', this.getStatus());
|
||||
}
|
||||
await this.identity.setRevision(ev.profile);
|
||||
await this.settings.setRevision(ev.account);
|
||||
await this.contact.setRevision(ev.card);
|
||||
await this.attribute.setRevision(ev.article);
|
||||
await this.alias.setRevision(ev.group);
|
||||
await this.content.setRevision(ev.channel);
|
||||
}
|
||||
|
||||
const onRing = (ev: Call) => {
|
||||
@ -111,45 +98,24 @@ export class SessionModule implements Session {
|
||||
}
|
||||
|
||||
private getStatus(): string {
|
||||
if (this.status === 'connected' && this.syncRevision) {
|
||||
return 'offsync';
|
||||
}
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public async resync() {
|
||||
if (this.syncRevision) {
|
||||
try {
|
||||
await this.identity.setRevision(this.syncRevision.profile);
|
||||
await this.account.setRevision(this.syncRevision.account);
|
||||
await this.contact.setRevision(this.syncRevision.card);
|
||||
await this.attribute.setRevision(this.syncRevision.article);
|
||||
await this.alias.setRevision(this.syncRevision.group);
|
||||
await this.content.setRevision(this.syncRevision.channel);
|
||||
this.syncRevision = null
|
||||
this.emitter.emit('status', this.getStatus());
|
||||
}
|
||||
catch(err) {
|
||||
this.log.warn(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async close(): Promise<{ node: string, secure: boolean, token: string }> {
|
||||
await this.content.close();
|
||||
await this.attribute.close();
|
||||
await this.alias.close();
|
||||
await this.contact.close();
|
||||
await this.identity.close();
|
||||
await this.account.close();
|
||||
await this.settings.close();
|
||||
await this.stream.close();
|
||||
this.connection.close();
|
||||
const { node, secure, token } = this;
|
||||
return { node: node, secure: secure, token: token };
|
||||
}
|
||||
|
||||
public getAccount(): Account {
|
||||
return this.account;
|
||||
public getSettings(): Settings {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
public getIdentity(): Identity {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import type { Account } from './api';
|
||||
import type { AccountStatus } from './types';
|
||||
import type { Settings } from './api';
|
||||
import type { Config } from './types';
|
||||
import { Store } from './store';
|
||||
import { Crypto } from './crypto';
|
||||
import { Logging } from './logging';
|
||||
import { defaultAccountEntity, AccountEntity } from './entities';
|
||||
import { defaultConfigEntity, ConfigEntity } from './entities';
|
||||
import { getAccountStatus } from './net/getAccountStatus';
|
||||
import { addAccountMFAuth } from './net/addAccountMFAuth';
|
||||
import { setAccountMFAuth } from './net/setAccountMFAuth';
|
||||
@ -18,7 +18,7 @@ import { clearAccountSeal } from './net/clearAccountSeal';
|
||||
const CLOSE_POLL_MS = 100;
|
||||
const RETRY_POLL_MS = 2000;
|
||||
|
||||
export class AccountModule implements Account {
|
||||
export class SettingsModule implements Settings {
|
||||
|
||||
private emitter: EventEmitter;
|
||||
private guid: string;
|
||||
@ -32,7 +32,7 @@ export class AccountModule implements Account {
|
||||
private closing: boolean;
|
||||
private revision: number;
|
||||
private nextRevision: number | null;
|
||||
private entity: AccountEntity;
|
||||
private entity: ConfigEntity;
|
||||
private sealKey: { privateKey: string, publicKey: string } | null;
|
||||
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, guid: string, token: string, node: string, secure: boolean) {
|
||||
@ -46,7 +46,7 @@ export class AccountModule implements Account {
|
||||
this.sealKey = null;
|
||||
this.secure = secure;
|
||||
this.revision = 0;
|
||||
this.entity = defaultAccountEntity;
|
||||
this.entity = defaultConfigEntity;
|
||||
this.syncing = true;
|
||||
this.closing = false;
|
||||
this.nextRevision = null;
|
||||
@ -54,8 +54,8 @@ export class AccountModule implements Account {
|
||||
}
|
||||
|
||||
private async init() {
|
||||
this.revision = await this.store.getAccountRevision(this.guid);
|
||||
this.entity = await this.store.getAccountData(this.guid);
|
||||
this.revision = await this.store.getSettingsRevision(this.guid);
|
||||
this.entity = await this.store.getSettingsData(this.guid);
|
||||
this.sealKey = await this.store.getSeal(this.guid);
|
||||
this.syncing = false;
|
||||
await this.sync();
|
||||
@ -73,8 +73,8 @@ export class AccountModule implements Account {
|
||||
try {
|
||||
const { guid, node, secure, token } = this;
|
||||
const status = await getAccountStatus(node, secure, token);
|
||||
await this.store.setAccountData(guid, status);
|
||||
await this.store.setAccountRevision(guid, nextRev);
|
||||
await this.store.setSettingsData(guid, status);
|
||||
await this.store.setSettingsRevision(guid, nextRev);
|
||||
this.entity = status;
|
||||
this.emitter.emit('status', this.getStatus());
|
||||
this.revision = nextRev;
|
||||
@ -101,12 +101,12 @@ export class AccountModule implements Account {
|
||||
return { storageUsed, storageAvailable, forwardingAddress, searchable, allowUnsealed, pushEnabled, sealable, sealSet, sealUnlocked, enableIce, multiFactorAuth, webPushKey };
|
||||
}
|
||||
|
||||
public addStatusListener(ev: (status: AccountStatus) => void): void {
|
||||
public addStatusListener(ev: (status: Config) => void): void {
|
||||
this.emitter.on('status', ev);
|
||||
this.emitter.emit('status', this.getStatus());
|
||||
}
|
||||
|
||||
public removeStatusListener(ev: (status: AccountStatus) => void): void {
|
||||
public removeStatusListener(ev: (status: Config) => void): void {
|
||||
this.emitter.off('status', ev);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { WebStore, SqlStore } from './api';
|
||||
import { Login, ProfileEntity, defaultProfileEntity, AccountEntity, defaultAccountEntity } from './entities';
|
||||
import { Login, ProfileEntity, defaultProfileEntity, ConfigEntity, defaultConfigEntity } from './entities';
|
||||
import type { Logging } from './logging';
|
||||
|
||||
export interface Store {
|
||||
@ -15,10 +14,22 @@ export interface Store {
|
||||
getProfileData(guid: string): Promise<ProfileEntity>;
|
||||
setProfileData(guid: string, data: ProfileEntity): Promise<void>;
|
||||
|
||||
getAccountRevision(guid: string): Promise<number>;
|
||||
setAccountRevision(guid: string, revision: number): Promise<void>;
|
||||
getAccountData(guid: string): Promise<AccountEntity>;
|
||||
setAccountData(guid: string, data: AccountEntity): Promise<void>;
|
||||
getSettingsRevision(guid: string): Promise<number>;
|
||||
setSettingsRevision(guid: string, revision: number): Promise<void>;
|
||||
getSettingsData(guid: string): Promise<ConfigEntity>;
|
||||
setSettingsData(guid: string, data: ConfigEntity): Promise<void>;
|
||||
}
|
||||
|
||||
export interface SqlStore {
|
||||
set(stmt: string, params?: (string | number | null)[]): Promise<void>;
|
||||
get(stmt: string, params?: (string | number | null)[]): Promise<any[]>;
|
||||
}
|
||||
|
||||
export interface WebStore {
|
||||
getValue(key: string): Promise<string>;
|
||||
setValue(key: string, value: string): Promise<void>;
|
||||
clearValue(key: string): Promise<void>;
|
||||
clearAll(): Promise<void>;
|
||||
}
|
||||
|
||||
export class OfflineStore implements Store {
|
||||
@ -102,19 +113,19 @@ export class OfflineStore implements Store {
|
||||
await this.setAppValue(guid, 'profile_data', JSON.stringify(data));
|
||||
}
|
||||
|
||||
public async getAccountRevision(guid: string): Promise<number> {
|
||||
public async getSettingsRevision(guid: string): Promise<number> {
|
||||
return await this.getAppValue(guid, 'account_revision', 0) as number;
|
||||
}
|
||||
|
||||
public async setAccountRevision(guid: string, revision: number): Promise<void> {
|
||||
public async setSettingsRevision(guid: string, revision: number): Promise<void> {
|
||||
await this.setAppValue(guid, 'account_revision', revision.toString());
|
||||
}
|
||||
|
||||
public async getAccountData(guid: string): Promise<AccountEntity> {
|
||||
return await this.getAppValue(guid, 'account_data', defaultAccountEntity) as AccountEntity;
|
||||
public async getSettingsData(guid: string): Promise<ConfigEntity> {
|
||||
return await this.getAppValue(guid, 'account_data', defaultConfigEntity) as ConfigEntity;
|
||||
}
|
||||
|
||||
public async setAccountData(guid: string, data: AccountEntity): Promise<void> {
|
||||
public async setSettingsData(guid: string, data: ConfigEntity): Promise<void> {
|
||||
await this.setAppValue(guid, 'account_data', JSON.stringify(data));
|
||||
}
|
||||
|
||||
@ -184,18 +195,18 @@ export class OnlineStore implements Store {
|
||||
public async setProfileData(guid: string, data: ProfileEntity): Promise<void> {
|
||||
}
|
||||
|
||||
public async getAccountRevision(guid: string): Promise<number> {
|
||||
public async getSettingsRevision(guid: string): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async setAccountRevision(guid: string, revision: number): Promise<void> {
|
||||
public async setSettingsRevision(guid: string, revision: number): Promise<void> {
|
||||
}
|
||||
|
||||
public async getAccountData(guid: string): Promise<AccountEntity> {
|
||||
return defaultAccountEntity;
|
||||
public async getSettingsData(guid: string): Promise<ConfigEntity> {
|
||||
return defaultConfigEntity;
|
||||
}
|
||||
|
||||
public async setAccountData(guid: string, data: AccountEntity): Promise<void> {
|
||||
public async setSettingsData(guid: string, data: ConfigEntity): Promise<void> {
|
||||
}
|
||||
|
||||
}
|
||||
@ -238,18 +249,18 @@ export class NoStore implements Store {
|
||||
public async setProfileData(guid: string, data: ProfileEntity): Promise<void> {
|
||||
}
|
||||
|
||||
public async getAccountRevision(guid: string): Promise<number> {
|
||||
public async getSettingsRevision(guid: string): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async setAccountRevision(guid: string, revision: number): Promise<void> {
|
||||
public async setSettingsRevision(guid: string, revision: number): Promise<void> {
|
||||
}
|
||||
|
||||
public async getAccountData(guid: string): Promise<AccountEntity> {
|
||||
return defaultAccountEntity;
|
||||
public async getSettingsData(guid: string): Promise<ConfigEntity> {
|
||||
return defaultConfigEntity;
|
||||
}
|
||||
|
||||
public async setAccountData(guid: string, data: AccountEntity): Promise<void> {
|
||||
public async setSettingsData(guid: string, data: ConfigEntity): Promise<void> {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ export type Repeater = {
|
||||
server: string,
|
||||
}
|
||||
|
||||
export type AccountStatus = {
|
||||
export type Config = {
|
||||
disabled: boolean,
|
||||
storageUsed: number,
|
||||
storageAvailable: number,
|
||||
|
Loading…
x
Reference in New Issue
Block a user