add data to image

This commit is contained in:
Sosthene00 2024-04-07 23:18:16 +02:00
parent 750bf69aa5
commit 9657be4959
6 changed files with 92 additions and 20 deletions

View File

@ -21,6 +21,7 @@ tsify = { git = "https://github.com/Sosthene00/tsify", branch = "next" }
aes-gcm = "0.10.3" aes-gcm = "0.10.3"
aes = "0.8.3" aes = "0.8.3"
shamir = { git = "https://github.com/Sosthene00/shamir", branch = "master" } shamir = { git = "https://github.com/Sosthene00/shamir", branch = "master" }
img-parts = "0.3.0"
[dev-dependencies] [dev-dependencies]
wasm-bindgen-test = "0.3" wasm-bindgen-test = "0.3"

View File

@ -23,6 +23,7 @@ use wasm_bindgen::prelude::*;
use sp_backend::spclient::{derive_keys_from_seed, OutputList, SpClient}; use sp_backend::spclient::{derive_keys_from_seed, OutputList, SpClient};
use sp_backend::spclient::{SpWallet, SpendKey}; use sp_backend::spclient::{SpWallet, SpendKey};
use crate::images;
use crate::network::{BitcoinNetworkMsg, BitcoinTopic}; use crate::network::{BitcoinNetworkMsg, BitcoinTopic};
use crate::silentpayments::check_transaction; use crate::silentpayments::check_transaction;
use crate::user::{lock_connected_users, User, UserWallets, CONNECTED_USERS}; use crate::user::{lock_connected_users, User, UserWallets, CONNECTED_USERS};
@ -173,6 +174,17 @@ pub fn create_user(
Ok(generate_user) Ok(generate_user)
} }
#[wasm_bindgen]
pub fn add_data_to_image(image: Vec<u8>, data: Vec<u8>, is_revoke: bool) -> ApiResult<Vec<u8>> {
let mut new_image: Vec<u8>;
if is_revoke {
new_image = images::BackUpImage::new_revoke(image, &data)?.to_inner();
} else {
new_image = images::BackUpImage::new_recover(image, &data)?.to_inner();
}
Ok(new_image)
}
#[derive(Tsify, Serialize, Deserialize)] #[derive(Tsify, Serialize, Deserialize)]
#[tsify(into_wasm_abi)] #[tsify(into_wasm_abi)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]

View File

@ -0,0 +1,38 @@
use anyhow::{Error, Result};
use img_parts::{jpeg::Jpeg, Bytes, ImageEXIF};
use serde::{Deserialize, Serialize};
use sp_backend::bitcoin::secp256k1::SecretKey;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackUpImage(Vec<u8>);
impl BackUpImage {
pub fn new_recover(image: Vec<u8>, data: &[u8]) -> Result<Self> {
// TODO: sanity check on data
let img = write_exif(image, data)?;
Ok(Self(img))
}
pub fn new_revoke(image: Vec<u8>, data: &[u8]) -> Result<Self> {
// TODO: sanity check on data
let img = write_exif(image, data)?;
Ok(Self(img))
}
pub fn to_inner(&self) -> Vec<u8> {
self.0.clone()
}
pub fn as_inner(&self) -> &[u8] {
&self.0
}
}
fn write_exif(image: Vec<u8>, data: &[u8]) -> Result<Vec<u8>> {
let mut jpeg = Jpeg::from_bytes(Bytes::from(image))?;
let data_bytes = Bytes::from(data.to_owned());
jpeg.set_exif(Some(data_bytes));
let output_image_bytes = jpeg.encoder().bytes();
let output_image = output_image_bytes.to_vec();
Ok(output_image)
}

View File

@ -6,6 +6,7 @@ use std::sync::{Mutex, MutexGuard};
mod Prd_list; mod Prd_list;
pub mod api; pub mod api;
mod crypto; mod crypto;
mod images;
mod network; mod network;
mod peers; mod peers;
mod process; mod process;

View File

@ -9,17 +9,17 @@ class Database {
// options: {}, // options: {},
// indices: [] // indices: []
// }, // },
SpOutputs: { // SpOutputs: {
name: "sp_outputs", // name: "sp_outputs",
options: {'autoIncrement': true}, // options: {'autoIncrement': true},
indices: [{ // indices: [{
name: 'by_wallet_fingerprint', // name: 'by_wallet_fingerprint',
keyPath: 'wallet_fingerprint', // keyPath: 'wallet_fingerprint',
options: { // options: {
'unique': false // 'unique': false
} // }
}] // }]
}, // },
AnkUser: { AnkUser: {
name: "user", name: "user",
options: {'keyPath': 'pre_id'}, options: {'keyPath': 'pre_id'},

View File

@ -89,7 +89,7 @@ class Services {
const password = passwordElement.value; const password = passwordElement.value;
this.current_process = processElement.value; this.current_process = processElement.value;
console.log("JS password: " + password + " process: " + this.current_process); // console.log("JS password: " + password + " process: " + this.current_process);
// To comment if test // To comment if test
// if (!Services.instance.isPasswordValid(password)) return; // if (!Services.instance.isPasswordValid(password)) return;
@ -101,10 +101,14 @@ class Services {
let createUserReturn: createUserReturn = services.sdkClient.create_user(password, label, birthday_main, birthday_signet, this.current_process); let createUserReturn: createUserReturn = services.sdkClient.create_user(password, label, birthday_main, birthday_signet, this.current_process);
let user = createUserReturn.user; let user = createUserReturn.user;
const outputs_list = createUserReturn.output_list_vec;
const shares = user.shares; const shares = user.shares;
// send the shares on the network
const revokeData = user.revoke_data; const revokeData = user.revoke_data;
if (!revokeData) {
console.error('Failed to get revoke data from wasm');
return;
}
user.shares = []; user.shares = [];
user.revoke_data = null; user.revoke_data = null;
@ -113,7 +117,6 @@ class Services {
const indexedDb = await IndexedDB.getInstance(); const indexedDb = await IndexedDB.getInstance();
const db = indexedDb.getDb(); const db = indexedDb.getDb();
await indexedDb.writeObject(db, indexedDb.getStoreList().AnkUser, user, null); await indexedDb.writeObject(db, indexedDb.getStoreList().AnkUser, user, null);
await indexedDb.writeObject(db, indexedDb.getStoreList().SpOutputs, outputs_list, null);
} catch (error) { } catch (error) {
console.error("Failed to write user object :", error); console.error("Failed to write user object :", error);
} }
@ -163,17 +166,16 @@ class Services {
alert("Recover submit to do ..."); alert("Recover submit to do ...");
} }
public async displayRevokeImage(): Promise<void> { public async displayRevokeImage(revokeData: Uint8Array): Promise<void> {
const services = await Services.getInstance(); const services = await Services.getInstance();
await services.injectHtml('REVOKE_IMAGE'); await services.injectHtml('REVOKE_IMAGE');
services.attachClickListener("displayupdateanid", services.displayUpdateAnId); services.attachClickListener("displayupdateanid", services.displayUpdateAnId);
let imageBytes = await services.getRecoverImage('assets/4nk_revoke.jpg'); let imageBytes = await services.getRecoverImage('assets/4nk_revoke.jpg');
if (imageBytes != null) { if (imageBytes != null) {
let blob = new Blob([imageBytes], {type: 'image/png'});
var elem = document.getElementById("revoke") as HTMLAnchorElement; var elem = document.getElementById("revoke") as HTMLAnchorElement;
if (elem != null) { if (elem != null) {
elem.href = URL.createObjectURL(blob); let imageWithData = services.sdkClient.add_data_to_image(imageBytes, revokeData, true);
} }
} }
} }
@ -299,6 +301,16 @@ class Services {
} }
} }
public async addProcess(process: Process): Promise<void> {
try {
const indexedDB = await IndexedDB.getInstance();
const db = indexedDB.getDb();
await indexedDB.writeObject(db, indexedDB.getStoreList().AnkProcess, process, null);
} catch (error) {
console.log('addProcess failed: ',error);
}
}
public async getAllProcess(): Promise<Process[]> { public async getAllProcess(): Promise<Process[]> {
try { try {
const indexedDB = await IndexedDB.getInstance(); const indexedDB = await IndexedDB.getInstance();
@ -369,7 +381,7 @@ class Services {
try { try {
const processStore = await indexedDB.getObject<Process>(db, indexedDB.getStoreList().AnkProcess, process.id); const processStore = await indexedDB.getObject<Process>(db, indexedDB.getStoreList().AnkProcess, process.id);
if (!processStore) { if (!processStore) {
console.error('Add process.id : '+process.id); console.error('Adding process.id : '+process.id);
await indexedDB.writeObject(db, indexedDB.getStoreList().AnkProcess, process, null); await indexedDB.writeObject(db, indexedDB.getStoreList().AnkProcess, process, null);
} }
} catch (error) { } catch (error) {
@ -391,7 +403,6 @@ class Services {
} }
public async injectHtml(processName: string) { public async injectHtml(processName: string) {
// console.log("JS html : "+html);
const container = document.getElementById('containerId'); const container = document.getElementById('containerId');
if (!container) { if (!container) {
@ -401,8 +412,17 @@ class Services {
const services = await Services.getInstance(); const services = await Services.getInstance();
await services.loadProcesses(); // do we have all processes in db?
const knownProcesses = await services.getAllProcess();
const processesFromNetwork: Process[] = services.sdkClient.get_processes();
const processToAdd = processesFromNetwork.filter(processFromNetwork => !knownProcesses.some(knownProcess => knownProcess.id === processFromNetwork.id));
processToAdd.forEach(async p => {
await services.addProcess(p);
})
// get the process we need
const process = await services.getProcessByName(processName); const process = await services.getProcessByName(processName);
if (process) { if (process) {
container.innerHTML = process.html; container.innerHTML = process.html;