sdk_client/src/services.ts
2024-03-29 20:08:46 +01:00

401 lines
15 KiB
TypeScript

import { createUserReturn, User } from '../dist/pkg/sdk_client';
import IndexedDB from './database'
import Processstore from './store/processstore';
class Services {
private static instance: Services;
private sdkClient: any;
private current_process: string | null = null;
// Private constructor to prevent direct instantiation from outside
private constructor() {}
// Method to access the singleton instance of Services
public static async getInstance(): Promise<Services> {
if (!Services.instance) {
Services.instance = new Services();
await Services.instance.init();
}
return Services.instance;
}
// The init method is now part of the instance, and should only be called once
private async init(): Promise<void> {
this.sdkClient = await import("../dist/pkg/sdk_client");
this.sdkClient.setup();
}
// public async getSpAddressDefaultClient(): Promise<string | null> {
// try {
// const indexedDB = await IndexedDB.getInstance();
// const db = indexedDB.getDb();
// const spClient = await indexedDB.getObject<string>(db, indexedDB.getStoreList().SpClient, "default");
// if (spClient) {
// return this.sdkClient.get_receiving_address(spClient);
// } else {
// console.error("SP client not found");
// return null;
// }
// } catch (error) {
// console.error("Failed to retrieve object or get sp address:", error);
// return null;
// }
// }
public async isNewUser(): Promise<boolean> {
let isNew = false;
try {
const indexedDB = await IndexedDB.getInstance();
const db = indexedDB.getDb();
let userListObject = await indexedDB.getAll<User>(db, indexedDB.getStoreList().AnkUser);
if (userListObject.length == 0) {
isNew = true;
}
} catch (error) {
console.error("Failed to retrieve isNewUser :", error);
}
return isNew;
}
public async displayCreateId(): Promise<void> {
Services.instance.injectHtml(Services.instance.get_html_create_id());
Services.instance.attachSubmitListener("form4nk", (event) => this.createId(event));
Services.instance.attachClickListener("displayrecover", Services.instance.displayRecover);
Services.instance.displayProcess(await Services.instance.getAllProcess());
}
public get_html_create_id(): string {
return this.sdkClient.inject_html_create_id();
}
public async createId(event: Event): Promise<void> {
event.preventDefault();
const passwordElement = document.getElementById("password") as HTMLInputElement;
const processElement = document.getElementById("selectProcess") as HTMLSelectElement;
if (!passwordElement || !processElement) {
console.error("One or more elements not found");
return;
}
const password = passwordElement.value;
this.current_process = processElement.value;
console.log("JS password: " + password + " process: " + this.current_process);
// To comment if test
// if (!Services.instance.isPasswordValid(password)) return;
let label = null;
let birthday = 50000;
const user: createUserReturn = this.sdkClient.create_user(password, label, birthday, this.current_process);
try {
const indexedDb = await IndexedDB.getInstance();
const db = indexedDb.getDb();
await indexedDb.writeObject(db, indexedDb.getStoreList().AnkUser, user.user, null);
// console.log("JS User added");
await indexedDb.writeObject(db, indexedDb.getStoreList().SpOutputs, user.output_list_vec, null);
} catch (error) {
console.error("Failed to write user object :", error);
}
await Services.instance.displayRevokeImage();
}
private async getImage(imageUrl:string): Promise<Uint8Array|null> {
let imageBytes = null;
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`);
}
const arrayBuffer = await response.arrayBuffer();
imageBytes = new Uint8Array(arrayBuffer);
console.log(imageBytes);
} catch (error) {
console.error("Failed to get image : "+imageUrl, error);
}
return imageBytes;
}
public async displayRecover(): Promise<void> {
Services.instance.injectHtml(Services.instance.get_html_recover());
Services.instance.attachSubmitListener("form4nk", Services.instance.recover);
Services.instance.attachClickListener("displaycreateid", Services.instance.displayCreateId);
Services.instance.attachClickListener("displayrevoke", Services.instance.displayRevoke);
Services.instance.attachClickListener("submitButtonRevoke", Services.instance.revoke);
Services.instance.displayProcess(await Services.instance.getAllUserProcess());
}
public get_html_recover(): string {
return this.sdkClient.inject_html_recover();
}
public async recover(event: Event) {
event.preventDefault();
console.log("JS recover submit ");
const passwordElement = document.getElementById("password") as HTMLInputElement;
const processElement = document.getElementById("selectProcess") as HTMLSelectElement;
if (!passwordElement || !processElement) {
console.error("One or more elements not found");
return;
}
const password = passwordElement.value;
const process = processElement.value;
console.log("JS password: " + password + " process: " + process);
// To comment if test
if (!Services.instance.isPasswordValid(password)) return;
// TODO
alert("Recover submit to do ...");
}
public async displayRevokeImage(): Promise<void> {
const html = Services.instance.get_html_revokeimage();
Services.instance.injectHtml(html);
Services.instance.attachSubmitListener("form4nk", Services.instance.revokeimage);
}
public get_html_revokeimage(): string {
return this.sdkClient.inject_html_revokeimage();
}
public async revokeimage(event: Event): Promise<void> {
event.preventDefault();
console.log("JS revokeimage submit ");
// TODO
alert("Revokeimage submit to do ..., next page Update an id ...");
await Services.instance.displayUpdateAnId();
}
public async displayRevoke(): Promise<void> {
const html = Services.instance.get_html_revoke();
Services.instance.injectHtml(html);
Services.instance.attachClickListener("displayrecover", Services.instance.displayRecover);
Services.instance.attachSubmitListener("form4nk", Services.instance.revoke);
}
public get_html_revoke(): string {
return this.sdkClient.inject_html_revoke();
}
public async revoke(event: Event): Promise<void> {
event.preventDefault();
console.log("JS revoke click ");
// TODO
alert("revoke click to do ...");
}
public async displayUpdateAnId() {
let body = "";
let style = "";
let script = "";
try {
const indexedDB = await IndexedDB.getInstance();
const db = indexedDB.getDb();
try {
let processObject = await indexedDB.getObject<Processstore>(db, indexedDB.getStoreList().AnkProcess, this.current_process!);
body = processObject.html;
style = processObject.style;
script = processObject.script;
} catch (error) {
console.log("JS Processstore not exist ");
}
} catch (error) {
console.error("Failed to retrieve user object :", error);
}
Services.instance.injectUpdateAnIdHtml(body, style, script);
Services.instance.attachSubmitListener("form4nk", Services.instance.updateAnId);
}
public injectUpdateAnIdHtml(bodyToInject: string, styleToInject: string, scriptToInject: string) {
console.log("JS html : "+bodyToInject);
const body = document.getElementsByTagName('body')[0];
if (!body) {
console.error("No body tag");
return;
}
body.innerHTML = styleToInject + bodyToInject;
const script = document.createElement("script");
script.innerHTML = scriptToInject;
document.body.appendChild(script);
script.onload = () => {
console.log('Script loaded successfuly');
};
script.onerror = () => {
console.log('Error loading script');
};
}
public async updateAnId(event: Event): Promise<void> {
event.preventDefault();
// TODO get values
const firstNameElement = 'firstName';
const lastNameElement = 'lastName';
const firstName = document.getElementById(firstNameElement) as HTMLInputElement;
const lastName = document.getElementById(lastNameElement) as HTMLInputElement;
console.log("JS updateAnId submit ");
// TODO
alert("updateAnId submit to do ... Name : "+firstName.value + " "+lastName.value);
// TODO Mock add user member to process
}
public displayProcess(processList: string[]): void {
console.log("JS processList : "+processList);
const selectProcess = document.getElementById("selectProcess");
if (selectProcess) {
processList.forEach((process) => {
let child = new Option(process, process);
if (!selectProcess.contains(child)) {
selectProcess.appendChild(child);
}
})
}
}
public async getAllUserProcess(): Promise<string[]> {
let userProcessList: string[] = [];
try {
const indexedDB = await IndexedDB.getInstance();
const db = indexedDB.getDb();
let processListObject = await indexedDB.getAll<Processstore>(db, indexedDB.getStoreList().AnkProcess);
processListObject.forEach(async (processObject) => {
const listMember = processObject.listMember;
const processName = processObject.process;
listMember.forEach(async (member) => {
if (member == "user1") {
userProcessList.push(processName);
console.log("JS UserProcess found");
}
})
})
} catch (error) {
console.log("JS Processstore not found");
}
return userProcessList;
}
public async getAllProcess(): Promise<string[]> {
// if indexedDB is empty, get list from wasm
let processList: string[] = [];
try {
const indexedDB = await IndexedDB.getInstance();
const db = indexedDB.getDb();
let processListObject = await indexedDB.getAll<Processstore>(db, indexedDB.getStoreList().AnkProcess);
processListObject.forEach(async (processObject) => {
const processName = processObject.process;
processList.push(processName);
console.log("JS Processstore found");
})
} catch (error) {
console.log("JS Processstore not found");
}
if (processList.length == 0) {
processList = await this.addProcessStore();
}
return processList;
}
public async addProcessStore(): Promise<string[]> {
const processList = this.sdkClient.get_process()
processList.forEach(async (process: string) => {
// TODO process mock
let processstore = new Processstore;
processstore.process = process;
const indexedDB = await IndexedDB.getInstance();
const db = indexedDB.getDb();
await indexedDB.writeObject(db, indexedDB.getStoreList().AnkProcess, processstore, process);
console.log("JS Processstore mock added");
})
return processList;
}
public attachClickListener(elementId: string, callback: (event: Event) => void): void {
const element = document.getElementById(elementId);
element?.removeEventListener("click", callback);
element?.addEventListener("click", callback);
}
public attachSubmitListener(elementId: string, callback: (event: Event) => void): void {
const element = document.getElementById(elementId);
element?.removeEventListener("submit", callback);
element?.addEventListener("submit", callback);
}
public injectHtml(html: string) {
console.log("JS html : "+html);
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
container.innerHTML = html;
}
// public async getCurrentProcess(): Promise<string> {
// let currentProcess = "";
// try {
// const indexedDB = await IndexedDB.getInstance();
// const db = indexedDB.getDb();
// currentProcess = await indexedDB.getObject<string>(db, indexedDB.getStoreList().AnkSession, Services.CURRENT_PROCESS);
// } catch (error) {
// console.error("Failed to retrieve currentprocess object :", error);
// }
// return currentProcess;
// }
public isPasswordValid(password: string) {
var alertElem = document.getElementById("passwordalert");
var success = true;
var strength = 0;
if (password.match(/[a-z]+/)) {
var strength = 0;
strength += 1;
}
if (password.match(/[A-Z]+/)) {
strength += 1;
}
if (password.match(/[0-9]+/)) {
strength += 1;
}
if (password.match(/[$@#&!]+/)) {
strength += 1;
}
if (alertElem !== null) {
// TODO Passer à 18
if (password.length < 4) {
alertElem.innerHTML = "Password size is < 4";
success = false;
} else {
if (password.length > 30) {
alertElem.innerHTML = "Password size is > 30";
success = false;
} else {
if (strength < 4) {
alertElem.innerHTML = "Password need [a-z] [A-Z] [0-9]+ [$@#&!]+";
success = false;
}
}
}
}
return success;
}
}
export default Services;