interface cleanup

This commit is contained in:
balzack 2024-08-26 15:27:45 -07:00
parent aa71c4da6c
commit 8847448ab7
16 changed files with 123 additions and 20 deletions

View File

@ -95,7 +95,7 @@ jest.mock('../src/ring', () => {
test('allocates session correctly', async () => {
let status: string = '';
const sdk = new DatabagSDK(null);
const sdk = new DatabagSDK();
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; });

View File

@ -19,12 +19,33 @@ export interface WebStore {
}
export interface Crypto {
}
export interface Logging {
error(m: any): void;
warn(m: any): void;
info(m: any): void;
// 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 }
}
export interface Session {

View File

@ -1,15 +1,19 @@
import type { Bot, Logging } from './api';
import type { Bot } from './api';
import type { Asset } from './types';
import type { Crypto } from './crypto';
import type { Logging } from './logging';
export class BotModule implements Bot {
private log: Logging;
private crypto: Crypto | null;
private node: string;
private secure: boolean;
private token: string;
constructor(log: Logging, node: string, secure: boolean, token: string) {
constructor(log: Logging, crypto: Crypto | null, node: string, secure: boolean, token: string) {
this.log = log;
this.crypto = crypto;
this.node = node;
this.secure = secure;
this.token = token;

29
app/sdk/src/crypto.ts Normal file
View File

@ -0,0 +1,29 @@
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 }
}

View File

@ -1,6 +1,7 @@
import { EventEmitter } from 'eventemitter3';
import type { Identity, Contact, Content, Focus, Logging } from './api';
import type { Identity, Contact, Content, Focus } from './api';
import type { Topic, Asset, Repeater } from './types';
import type { Logging } from './logging';
import { Store } from './store';
export class FocusModule implements Focus {

View File

@ -1,5 +1,6 @@
import { EventEmitter } from 'eventemitter3';
import type { Identity, Logging } from './api';
import type { Identity } from './api';
import type { Logging } from './logging';
import type { Profile } from './types';
import { Store } from './store';
import { getProfile } from './net/getProfile';

View File

@ -1,7 +1,7 @@
import { SessionModule } from './session';
import { NodeModule } from './node';
import { BotModule } from './bot';
import { ConsoleLogging } from './logging';
import { type Logging, ConsoleLogging } from './logging';
import { type Store, OfflineStore, OnlineStore, NoStore } from './store';
import { setLogin } from './net/setLogin';
import { clearLogin } from './net/clearLogin';
@ -10,9 +10,10 @@ 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, Crypto, Logging } from './api';
import type { Session, Node, Bot, SqlStore, WebStore } from './api';
import type { SessionParams } from './types';
import type { Login } from './entities';
import type { Crypto } from './crypto';
export * from './api';
export * from './types';
@ -23,9 +24,9 @@ export class DatabagSDK {
private crypto: Crypto | null;
private store: Store;
constructor(crypto: Crypto | null, log?: Logging) {
this.crypto = crypto;
constructor(crypto?: Crypto, log?: Logging) {
this.store = new NoStore();
this.crypto = crypto ? crypto : null;
this.log = log ? log : new ConsoleLogging();
this.log.info("databag sdk");
}
@ -98,6 +99,6 @@ export class DatabagSDK {
}
public async automate(node: string, secure: boolean, token: string): Promise<Bot> {
return new BotModule(this.log, node, secure, token);
return new BotModule(this.log, this.crypto, node, secure, token);
}
}

View File

@ -1,4 +1,8 @@
import { Logging } from './api';
export interface Logging {
error(m: any): void;
warn(m: any): void;
info(m: any): void;
}
export class ConsoleLogging implements Logging {
public error(m: any): void {

View File

@ -0,0 +1,12 @@
import axios from 'redaxios';
import { ProfileEntity } from '../entities';
export async function getProfile(node: string, secure: boolean, token: string): Promise<ProfileEntity> {
const endpoint = `http${secure ? 's' : ''}://${node}/profile?agent=${token}`;
const response = await axios.get(endpoint);
if (response.status >= 400 && response.status < 600) {
throw new Error('getProfile failed');
}
return response.data;
}

View File

@ -0,0 +1,4 @@
export function getProfileImageUrl(node: string, secure: boolean, token: string, revision: number) {
return `http${secure ? 's' : ''}://${node}/profile/image?agent=${token}&revision=${revision}`;
}

View File

@ -0,0 +1,11 @@
import axios from 'redaxios';
export async function setProfileData(node: string, secure: boolean, token: string, name: string, location: string, description: string): Promise<void> {
const data = { name: name, location: location, description: description };
const endpoint = `http${secure ? 's' : ''}://${node}/profile/data?agent=${token}`;
const response = await axios.put(endpoint, data);
if (response.status >= 400 && response.status < 600) {
throw new Error('setProfileData failed');
}
}

View File

@ -0,0 +1,10 @@
import axios from 'redaxios';
export async function setProfileImage(node: string, secure: boolean, token: string, image: string) {
const endpoint = `http${secure ? 's' : ''}://${node}/profile/image?agent=${token}`;
const response = await axios.put(endpoint, image);
if (response.status >= 400 && response.status < 600) {
throw new Error('setProfileImage failed');
}
}

View File

@ -1,5 +1,6 @@
import type { Node, Logging } from './api';
import type { Node } from './api';
import type { NodeAccount, NodeConfig } from './types';
import type { Logging } from './logging';
export class NodeModule implements Node {

View File

@ -12,10 +12,12 @@ import { RingModule } from './ring';
import { Connection } from './connection';
import type { Session, Account, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus, Crypto, Logging } from './api';
import type { Session, Account, Identity, Contact, Ring, Alias, Attribute, Content, Stream, Focus } from './api';
import { Revision } from './entities';
import { Call } from './types';
import { Store } from './store';
import type { Logging } from './logging';
import type { Crypto } from './crypto';
export class SessionModule implements Session {

View File

@ -1,5 +1,6 @@
import { WebStore, SqlStore, Logging } from './api';
import { WebStore, SqlStore } from './api';
import { Login, ProfileEntity, defaultProfileEntity } from './entities';
import type { Logging } from './logging';
export interface Store {
init(): Promise<Login | null>;

View File

@ -1,7 +1,8 @@
import { EventEmitter } from 'eventemitter3';
import type { Contact, Content, Stream, Logging } from './api';
import type { Contact, Content, Stream } from './api';
import type { Channel } from './types';
import { Store } from './store';
import { Logging } from './logging';
export class StreamModule implements Stream {