401 lines
15 KiB
TypeScript
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;
|