Merge branche webapps dans dev
This commit is contained in:
parent
59bbfafbb7
commit
92c77c91e0
99
crates/sp_client/src/injecteurhtml.rs
Normal file
99
crates/sp_client/src/injecteurhtml.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn inject_html_create_id() -> String {
|
||||||
|
String::from("
|
||||||
|
<div class='card'>
|
||||||
|
<div class='side-by-side'>
|
||||||
|
<h3>Create an Id</h3>
|
||||||
|
<div><a href='#'>Processes</a></div>
|
||||||
|
</div>
|
||||||
|
<form id='form4nk' action='#'>
|
||||||
|
<label for='password'>Password :</label>
|
||||||
|
<input type='password' id='password' /><hr/>
|
||||||
|
<input type='hidden' id='currentpage' value='creatid' />
|
||||||
|
<select id='selectProcess' class='custom-select'></select><hr/>
|
||||||
|
<div class='side-by-side'>
|
||||||
|
<button type='submit' id='submitButton' class='bg-primary'>Create</button>
|
||||||
|
<div>
|
||||||
|
<a href='#' id='displayrecover'>Recover</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form><br/>
|
||||||
|
<div id='passwordalert' class='passwordalert'></div>
|
||||||
|
</div>
|
||||||
|
")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn inject_html_recover() -> String {
|
||||||
|
String::from("
|
||||||
|
<div class='card'>
|
||||||
|
<div class='side-by-side'>
|
||||||
|
<h3>Recover my Id</h3>
|
||||||
|
<div><a href='#'>Processes</a></div>
|
||||||
|
</div>
|
||||||
|
<form id='form4nk' action='#'>
|
||||||
|
<label for='password'>Password :</label>
|
||||||
|
<input type='password' id='password' />
|
||||||
|
<input type='hidden' id='currentpage' value='recover' />
|
||||||
|
<select id='selectProcess' class='custom-select'></select><hr/>
|
||||||
|
<div class='side-by-side'>
|
||||||
|
<button type='submit' id='submitButton' class='recover bg-primary'>Recover</button>
|
||||||
|
<div>
|
||||||
|
<a href='#' id='displaycreateid'>Create an Id</a>
|
||||||
|
</div>
|
||||||
|
</div><hr/>
|
||||||
|
<a href='#' id='displayrevoke' class='btn'>Revoke</a>
|
||||||
|
</form><br/>
|
||||||
|
<div id='passwordalert' class='passwordalert'></div>
|
||||||
|
</div>
|
||||||
|
")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn inject_html_revokeimage() -> String {
|
||||||
|
String::from("
|
||||||
|
<div class='card2'>
|
||||||
|
<form id='form4nk' action='#'>
|
||||||
|
<input type='hidden' id='currentpage' value='revokeimage' />
|
||||||
|
<button type='submit' id='submitButton'>
|
||||||
|
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'>
|
||||||
|
<path
|
||||||
|
d='M246.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 109.3V320c0 17.7 14.3 32 32 32s32-14.3 32-32V109.3l73.4 73.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-128-128zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 53 43 96 96 96H352c53 0 96-43 96-96V352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V352z'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div class='image-container'>
|
||||||
|
<label class='image-label bg-secondary'>Revoke image</label>
|
||||||
|
<img src='assets/revoke.jpeg' alt='' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn inject_html_revoke() -> String {
|
||||||
|
String::from("
|
||||||
|
<div class='card'>
|
||||||
|
<div class='side-by-side'>
|
||||||
|
<h3>Revoke an Id</h3>
|
||||||
|
<div>
|
||||||
|
<a href='#' id='displayrecover'>Recover</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form id='form4nk' action='#'>
|
||||||
|
<label for='password'>Password :</label>
|
||||||
|
<input type='password' id='password' />
|
||||||
|
<hr/>
|
||||||
|
<div class='image-container'>
|
||||||
|
<label class='image-label'>Revoke image</label>
|
||||||
|
<img src='assets/revoke.jpeg' alt='' />
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<button type='submit' id='submitButton' class='recover bg-primary'>Revoke</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
")
|
||||||
|
}
|
@ -1 +1,3 @@
|
|||||||
pub mod api;
|
pub mod api;
|
||||||
|
mod injecteurhtml;
|
||||||
|
mod process;
|
||||||
|
10
crates/sp_client/src/process.rs
Normal file
10
crates/sp_client/src/process.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn get_process() -> Vec<String> {
|
||||||
|
let mut data_process: Vec<String> = Vec::new();
|
||||||
|
data_process.push(String::from("process1"));
|
||||||
|
data_process.push(String::from("process2"));
|
||||||
|
data_process.push(String::from("process3"));
|
||||||
|
data_process
|
||||||
|
}
|
@ -13,6 +13,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
"html-webpack-plugin": "^5.6.0",
|
"html-webpack-plugin": "^5.6.0",
|
||||||
"ts-loader": "^9.5.1",
|
"ts-loader": "^9.5.1",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
|
BIN
src/assets/4nk_image.png
Normal file
BIN
src/assets/4nk_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
src/assets/revoke.jpeg
Normal file
BIN
src/assets/revoke.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 408 KiB |
@ -9,15 +9,15 @@ class Database {
|
|||||||
options: {}
|
options: {}
|
||||||
},
|
},
|
||||||
AnkUser: {
|
AnkUser: {
|
||||||
name: "4nkUser",
|
name: "user",
|
||||||
options: {}
|
options: {}
|
||||||
},
|
},
|
||||||
AnkSession: {
|
AnkSession: {
|
||||||
name: "4nkSession",
|
name: "session",
|
||||||
options: {}
|
options: {}
|
||||||
},
|
},
|
||||||
AnkProcess: {
|
AnkProcess: {
|
||||||
name: "4nkProcess",
|
name: "process",
|
||||||
options: {}
|
options: {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,16 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="author" content="4NK">
|
||||||
|
<meta name="description" content="4NK Web5 Platform">
|
||||||
|
<meta name="keywords" content="4NK web5 bitcoin blockchain decentralize dapps relay contract">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>4NK Client</title>
|
<link rel="stylesheet" href="style/4nk.css">
|
||||||
|
<title>4NK Application</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div id="containerId" class="container">
|
||||||
|
<!-- 4NK Web5 Solution -->
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
10
src/index.ts
10
src/index.ts
@ -4,10 +4,18 @@ import IndexedDB from './database'
|
|||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
try {
|
try {
|
||||||
const services = await Services.getInstance();
|
const services = await Services.getInstance();
|
||||||
const indexedDB = await IndexedDB.getInstance();
|
|
||||||
|
|
||||||
|
if ((await services.isNewUser())) {
|
||||||
|
services.displayCreateId();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
services.displayRecover()
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexedDB = await IndexedDB.getInstance();
|
||||||
const db = indexedDB.getDb();
|
const db = indexedDB.getDb();
|
||||||
await indexedDB.writeObject(db, indexedDB.getStoreList().SpClient, services.new_sp_client(), "default");
|
await indexedDB.writeObject(db, indexedDB.getStoreList().SpClient, services.new_sp_client(), "default");
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
365
src/services.ts
365
src/services.ts
@ -1,8 +1,11 @@
|
|||||||
import IndexedDB from './database'
|
import IndexedDB from './database'
|
||||||
|
import Processstore from './store/processstore';
|
||||||
|
import Userstore from './store/userstore';
|
||||||
|
|
||||||
class Services {
|
class Services {
|
||||||
private static instance: Services;
|
private static instance: Services;
|
||||||
private sdkClient: any;
|
private sdkClient: any;
|
||||||
|
private static CURRENT_PROCESS = "currentprocess";
|
||||||
|
|
||||||
// Private constructor to prevent direct instantiation from outside
|
// Private constructor to prevent direct instantiation from outside
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
@ -44,6 +47,368 @@ class Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async isNewUser(): Promise<boolean> {
|
||||||
|
let isNew = false;
|
||||||
|
try {
|
||||||
|
let listUserProcess = await Services.instance.getAllUserProces();
|
||||||
|
if (listUserProcess.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", Services.instance.createId);
|
||||||
|
Services.instance.attachClickListener("displayrecover", Services.instance.displayRecover);
|
||||||
|
Services.instance.displayProcess(await Services.instance.getAllProcesAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
const process = processElement.value;
|
||||||
|
console.log("JS password: " + password + " process: " + process);
|
||||||
|
// To comment if test
|
||||||
|
if (!Services.instance.isPasswordValid(password)) return;
|
||||||
|
|
||||||
|
// TODO get secretpart1 from User object
|
||||||
|
// const user = new this.sdkClient.User(password);
|
||||||
|
let secretpart1 = "LKHGKJJJ3H";
|
||||||
|
|
||||||
|
try {
|
||||||
|
let userstore = new Userstore;
|
||||||
|
userstore.secretpart1 = secretpart1;
|
||||||
|
userstore.process = process;
|
||||||
|
const indexedDb = await IndexedDB.getInstance();
|
||||||
|
const db = indexedDb.getDb();
|
||||||
|
|
||||||
|
await indexedDb.writeObject(db, indexedDb.getStoreList().AnkUser, userstore, process);
|
||||||
|
console.log("JS Userstore added");
|
||||||
|
|
||||||
|
await indexedDb.writeObject(db, indexedDb.getStoreList().AnkSession, process, Services.CURRENT_PROCESS);
|
||||||
|
console.log("JS Sessionstore added currentprocess");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to write userstore object :", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Services.instance.displayRevokeImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
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.getAllUserProces());
|
||||||
|
}
|
||||||
|
|
||||||
|
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 currentProcess = await this.getCurrentProcess();
|
||||||
|
|
||||||
|
let body = "";
|
||||||
|
let style = "";
|
||||||
|
let script = "";
|
||||||
|
let inputName = "";
|
||||||
|
try {
|
||||||
|
const indexedDB = await IndexedDB.getInstance();
|
||||||
|
const db = indexedDB.getDb();
|
||||||
|
try {
|
||||||
|
let processObject = await indexedDB.getObject<Processstore>(db, indexedDB.getStoreList().AnkProcess, currentProcess);
|
||||||
|
body = processObject.html;
|
||||||
|
style = processObject.style;
|
||||||
|
script = processObject.script;
|
||||||
|
inputName = processObject.inputName;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("JS Processstore not exist ");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to retrieve userstore object :", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Services.instance.injectUpdateAnIdHtml(body, style, script, inputName);
|
||||||
|
Services.instance.attachSubmitListener("form4nk", Services.instance.updateAnId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public injectUpdateAnIdHtml(bodyToInject: string, styleToInject: string, scriptToInject: string, inputName: 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 getAllUserProces(): Promise<string[]> {
|
||||||
|
let userProcessList: string[] = [];
|
||||||
|
try {
|
||||||
|
const indexedDB = await IndexedDB.getInstance();
|
||||||
|
const db = indexedDB.getDb();
|
||||||
|
let userListObject = await indexedDB.getAll<Userstore>(db, indexedDB.getStoreList().AnkUser);
|
||||||
|
userListObject.forEach(async (userObject) => {
|
||||||
|
const processName = userObject.process;
|
||||||
|
userProcessList.push(processName);
|
||||||
|
console.log("JS Userstore found");
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log("JS Userstore not found");
|
||||||
|
}
|
||||||
|
return userProcessList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getAllProcesAvailable(): Promise<string[]> {
|
||||||
|
let userProcessList = await Services.instance.getAllUserProces();
|
||||||
|
let processList = await Services.instance.getAllProces();
|
||||||
|
let availableProcessList = processList.filter(x => !userProcessList.includes(x));
|
||||||
|
return availableProcessList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getAllProces(): 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getSecretPart1(process: string): Promise<string> {
|
||||||
|
let secretpart1 = "";
|
||||||
|
try {
|
||||||
|
const indexedDB = await IndexedDB.getInstance();
|
||||||
|
const db = indexedDB.getDb();
|
||||||
|
try {
|
||||||
|
let userObject = await indexedDB.getObject<Userstore>(db, indexedDB.getStoreList().AnkUser, process);
|
||||||
|
secretpart1 = userObject.secretpart1;
|
||||||
|
console.log("JS Userstore exist secretpart1 : "+secretpart1);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("JS Userstore not exist ");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to retrieve userstore object :", error);
|
||||||
|
}
|
||||||
|
console.log("JS secretpart1 : "+secretpart1);
|
||||||
|
|
||||||
|
return secretpart1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
export default Services;
|
||||||
|
237
src/store/processstore.ts
Normal file
237
src/store/processstore.ts
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
class Processstore {
|
||||||
|
process: string;
|
||||||
|
html: string;
|
||||||
|
style: string;
|
||||||
|
script: string;
|
||||||
|
inputName: string;
|
||||||
|
createDate: Date;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.process = "";
|
||||||
|
this.html = getMockHtml();
|
||||||
|
this.style = getMockStyle();
|
||||||
|
this.script = getMockScript();
|
||||||
|
this.script = getMockScript();
|
||||||
|
this.inputName = getMockinputName();
|
||||||
|
this.createDate = new Date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Processstore;
|
||||||
|
|
||||||
|
function getMockHtml(): string {
|
||||||
|
let html: string = `
|
||||||
|
<body>
|
||||||
|
<div class='container'>
|
||||||
|
<div>
|
||||||
|
<h3>Update an Id</h3>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<form id='form4nk' action='#'>
|
||||||
|
<label for='firstName'>First Name:</label>
|
||||||
|
<input type='text' id='firstName' name='firstName' required />
|
||||||
|
|
||||||
|
<label for='lastName'>Last Name:</label>
|
||||||
|
<input type='text' id='lastName' name='lastName' required />
|
||||||
|
|
||||||
|
<label for='Birthday'>Birthday:</label>
|
||||||
|
<input type='date' id='Birthday' name='birthday' />
|
||||||
|
|
||||||
|
<label for='file'>File:</label>
|
||||||
|
<input type='file' id='fileInput' name='file' />
|
||||||
|
|
||||||
|
<label>Third parties:</label>
|
||||||
|
<div id='sp-address-block'>
|
||||||
|
<div class='side-by-side'>
|
||||||
|
<input
|
||||||
|
type='text'
|
||||||
|
name='sp-address'
|
||||||
|
id='sp-address'
|
||||||
|
placeholder='sp address'
|
||||||
|
form='no-form'
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
class='circle-btn bg-secondary'
|
||||||
|
id='add-sp-address-btn'
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='div-text-area'>
|
||||||
|
<textarea
|
||||||
|
name='bio'
|
||||||
|
id=''
|
||||||
|
cols='30'
|
||||||
|
rows='10'
|
||||||
|
placeholder='Bio'
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
<button type='submit' class='bg-primary'>Update</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMockStyle(): string {
|
||||||
|
let style: string = `
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: left;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(1fr, 2fr);
|
||||||
|
gap: 10px;
|
||||||
|
max-width: 400px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-primary {
|
||||||
|
background-color: #1a61ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-primary:hover {
|
||||||
|
background-color: #457be8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-secondary {
|
||||||
|
background-color: #2b81ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-secondary:hover {
|
||||||
|
background-color: #5f9bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
text-align: left;
|
||||||
|
padding-right: 10px;
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
grid-column: span 2;
|
||||||
|
display: inline-block;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 17px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-text-area {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-by-side {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.circle-btn {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 0px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileInput {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
padding-left: 0px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
</style>`;
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMockScript(): string {
|
||||||
|
let script: string = `
|
||||||
|
var addSpAddressBtn = document.getElementById('add-sp-address-btn');
|
||||||
|
var removeSpAddressBtn = document.querySelectorAll('.minus-sp-address-btn');
|
||||||
|
|
||||||
|
addSpAddressBtn.addEventListener('click', function (event) {
|
||||||
|
addDynamicField(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
function addDynamicField(element) {
|
||||||
|
var addSpAddressBlock = document.getElementById('sp-address-block');
|
||||||
|
var spAddress = addSpAddressBlock.querySelector('#sp-address').value;
|
||||||
|
addSpAddressBlock.querySelector('#sp-address').value = '';
|
||||||
|
spAddress = spAddress.trim();
|
||||||
|
if (spAddress != '') {
|
||||||
|
var sideBySideDiv = document.createElement('div');
|
||||||
|
sideBySideDiv.className = 'side-by-side';
|
||||||
|
|
||||||
|
var inputElement = document.createElement('input');
|
||||||
|
inputElement.type = 'text';
|
||||||
|
inputElement.name = 'spAddresses[]';
|
||||||
|
inputElement.setAttribute('form', 'no-form');
|
||||||
|
inputElement.value = spAddress;
|
||||||
|
inputElement.disabled = true;
|
||||||
|
|
||||||
|
var buttonElement = document.createElement('button');
|
||||||
|
buttonElement.type = 'button';
|
||||||
|
buttonElement.className =
|
||||||
|
'circle-btn bg-secondary minus-sp-address-btn';
|
||||||
|
buttonElement.innerHTML = '-';
|
||||||
|
|
||||||
|
buttonElement.addEventListener('click', function (event) {
|
||||||
|
removeDynamicField(this.parentElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
sideBySideDiv.appendChild(inputElement);
|
||||||
|
sideBySideDiv.appendChild(buttonElement);
|
||||||
|
|
||||||
|
addSpAddressBlock.appendChild(sideBySideDiv);
|
||||||
|
}
|
||||||
|
function removeDynamicField(element) {
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMockinputName(): string {
|
||||||
|
return "firstName";
|
||||||
|
}
|
15
src/store/userstore.ts
Normal file
15
src/store/userstore.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class Userstore {
|
||||||
|
process: string;
|
||||||
|
secretpart1: string;
|
||||||
|
password: string;
|
||||||
|
createDate: Date;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.process = "";
|
||||||
|
this.secretpart1 = "";
|
||||||
|
this.password = "";
|
||||||
|
this.createDate = new Date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Userstore;
|
162
src/style/4nk.css
Normal file
162
src/style/4nk.css
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: left;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
/* flex-wrap: wrap; */
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #ddd;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
input, select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 8px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 17px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
.side-by-side {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.side-by-side>* {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
button.recover {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 17px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button.recover:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
a.btn {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #4caf50;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 17px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.btn:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #78a6de;
|
||||||
|
}
|
||||||
|
.bg-secondary {
|
||||||
|
background-color: #2b81ed;
|
||||||
|
}
|
||||||
|
.bg-primary {
|
||||||
|
background-color: #1A61ED;
|
||||||
|
}
|
||||||
|
.bg-primary:hover {
|
||||||
|
background-color: #457be8;
|
||||||
|
}
|
||||||
|
.card2 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.card2 button {
|
||||||
|
max-width: 50px;
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.card2 svg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
fill: #333;
|
||||||
|
}
|
||||||
|
.image-label {
|
||||||
|
display: block;
|
||||||
|
color: #fff;
|
||||||
|
padding: 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.image-container {
|
||||||
|
width: 400px;
|
||||||
|
height: 300px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.image-container img {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center center;
|
||||||
|
}
|
||||||
|
.passwordalert {
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
@ -32,6 +33,12 @@ module.exports = {
|
|||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: 'src/index.html'
|
template: 'src/index.html'
|
||||||
}),
|
}),
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
|
{ from: 'src/assets', to: './assets' },
|
||||||
|
{ from: 'src/style', to: './style' }
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
devServer: {
|
devServer: {
|
||||||
static: './dist',
|
static: './dist',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user