forked from jsnbuchanan/crowd-funder-for-time-pwa
add encryption for the two SQL columns, replace basic DB utils, add USE_DEXIE_DB flag, and start adding SQL everywhere
This commit is contained in:
@@ -273,7 +273,7 @@ export async function decryptMessage(encryptedJson: string, password: string) {
|
||||
}
|
||||
|
||||
// Test function to verify encryption/decryption
|
||||
export async function testEncryptionDecryption() {
|
||||
export async function testMessageEncryptionDecryption() {
|
||||
try {
|
||||
const testMessage = "Hello, this is a test message! 🚀";
|
||||
const testPassword = "myTestPassword123";
|
||||
@@ -299,9 +299,102 @@ export async function testEncryptionDecryption() {
|
||||
logger.log("\nTesting with wrong password...");
|
||||
try {
|
||||
await decryptMessage(encrypted, "wrongPassword");
|
||||
logger.log("Should not reach here");
|
||||
logger.log("Incorrectly decrypted with wrong password ❌");
|
||||
} catch (error) {
|
||||
logger.log("Correctly failed with wrong password ✅");
|
||||
logger.log("Correctly failed to decrypt with wrong password ✅");
|
||||
}
|
||||
|
||||
return success;
|
||||
} catch (error) {
|
||||
logger.error("Test failed with error:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Simple encryption/decryption using Node's crypto
|
||||
export async function simpleEncrypt(text: string, secret: string): Promise<string> {
|
||||
const iv = crypto.getRandomValues(new Uint8Array(16));
|
||||
|
||||
// Derive a 256-bit key from the secret using SHA-256
|
||||
const keyData = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(secret));
|
||||
const key = await crypto.subtle.importKey(
|
||||
'raw',
|
||||
keyData,
|
||||
{ name: 'AES-GCM' },
|
||||
false,
|
||||
['encrypt']
|
||||
);
|
||||
|
||||
const encrypted = await crypto.subtle.encrypt(
|
||||
{ name: 'AES-GCM', iv },
|
||||
key,
|
||||
new TextEncoder().encode(text)
|
||||
);
|
||||
|
||||
// Combine IV and encrypted data
|
||||
const result = new Uint8Array(iv.length + encrypted.byteLength);
|
||||
result.set(iv);
|
||||
result.set(new Uint8Array(encrypted), iv.length);
|
||||
|
||||
return btoa(String.fromCharCode(...result));
|
||||
}
|
||||
|
||||
export async function simpleDecrypt(encryptedText: string, secret: string): Promise<string> {
|
||||
const data = Uint8Array.from(atob(encryptedText), c => c.charCodeAt(0));
|
||||
|
||||
// Extract IV and encrypted data
|
||||
const iv = data.slice(0, 16);
|
||||
const encrypted = data.slice(16);
|
||||
|
||||
// Derive the same 256-bit key from the secret using SHA-256
|
||||
const keyData = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(secret));
|
||||
const key = await crypto.subtle.importKey(
|
||||
'raw',
|
||||
keyData,
|
||||
{ name: 'AES-GCM' },
|
||||
false,
|
||||
['decrypt']
|
||||
);
|
||||
|
||||
const decrypted = await crypto.subtle.decrypt(
|
||||
{ name: 'AES-GCM', iv },
|
||||
key,
|
||||
encrypted
|
||||
);
|
||||
|
||||
return new TextDecoder().decode(decrypted);
|
||||
}
|
||||
|
||||
// Test function for simple encryption/decryption
|
||||
export async function testSimpleEncryptionDecryption() {
|
||||
try {
|
||||
const testMessage = "Hello, this is a test message! 🚀";
|
||||
const testSecret = "myTestSecret123";
|
||||
|
||||
logger.log("Original message:", testMessage);
|
||||
|
||||
// Test encryption
|
||||
logger.log("Encrypting...");
|
||||
const encrypted = await simpleEncrypt(testMessage, testSecret);
|
||||
logger.log("Encrypted result:", encrypted);
|
||||
|
||||
// Test decryption
|
||||
logger.log("Decrypting...");
|
||||
const decrypted = await simpleDecrypt(encrypted, testSecret);
|
||||
logger.log("Decrypted result:", decrypted);
|
||||
|
||||
// Verify
|
||||
const success = testMessage === decrypted;
|
||||
logger.log("Test " + (success ? "PASSED ✅" : "FAILED ❌"));
|
||||
logger.log("Messages match:", success);
|
||||
|
||||
// Test with wrong secret
|
||||
logger.log("\nTesting with wrong secret...");
|
||||
try {
|
||||
await simpleDecrypt(encrypted, "wrongSecret");
|
||||
logger.log("Incorrectly decrypted with wrong secret ❌");
|
||||
} catch (error) {
|
||||
logger.log("Correctly failed to decrypt with wrong secret ✅");
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Buffer } from "buffer";
|
||||
import * as R from "ramda";
|
||||
import { useClipboard } from "@vueuse/core";
|
||||
|
||||
import { DEFAULT_PUSH_SERVER, NotificationIface } from "../constants/app";
|
||||
import { DEFAULT_PUSH_SERVER, NotificationIface, USE_DEXIE_DB } from "../constants/app";
|
||||
import {
|
||||
accountsDBPromise,
|
||||
retrieveSettingsForActiveAccount,
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from "../db/index";
|
||||
import { Account } from "../db/tables/accounts";
|
||||
import { Contact } from "../db/tables/contacts";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import { DEFAULT_PASSKEY_EXPIRATION_MINUTES } from "../db/tables/settings";
|
||||
import { deriveAddress, generateSeed, newIdentifier } from "../libs/crypto";
|
||||
import * as serverUtil from "../libs/endorserServer";
|
||||
@@ -541,16 +542,6 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
|
||||
|
||||
// one of the few times we use accountsDBPromise directly; try to avoid more usage
|
||||
try {
|
||||
const accountsDB = await accountsDBPromise;
|
||||
await accountsDB.accounts.add({
|
||||
dateCreated: new Date().toISOString(),
|
||||
derivationPath: derivationPath,
|
||||
did: newId.did,
|
||||
identity: identity,
|
||||
mnemonic: mnemonic,
|
||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||
});
|
||||
|
||||
// add to the new sql db
|
||||
const platformService = PlatformServiceFactory.getInstance();
|
||||
await platformService.dbExec(
|
||||
@@ -565,15 +556,31 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
|
||||
newId.keys[0].publicKeyHex,
|
||||
],
|
||||
);
|
||||
await databaseUtil.updateDefaultSettings({ activeDid: newId.did });
|
||||
|
||||
await updateDefaultSettings({ activeDid: newId.did });
|
||||
if (USE_DEXIE_DB) {
|
||||
const accountsDB = await accountsDBPromise;
|
||||
await accountsDB.accounts.add({
|
||||
dateCreated: new Date().toISOString(),
|
||||
derivationPath: derivationPath,
|
||||
did: newId.did,
|
||||
identity: identity,
|
||||
mnemonic: mnemonic,
|
||||
publicKeyHex: newId.keys[0].publicKeyHex,
|
||||
});
|
||||
|
||||
await updateDefaultSettings({ activeDid: newId.did });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("Failed to update default settings:", error);
|
||||
throw new Error(
|
||||
"Failed to set default settings. Please try again or restart the app.",
|
||||
);
|
||||
}
|
||||
await updateAccountSettings(newId.did, { isRegistered: false });
|
||||
await databaseUtil.updateAccountSettings(newId.did, { isRegistered: false });
|
||||
if (USE_DEXIE_DB) {
|
||||
await updateAccountSettings(newId.did, { isRegistered: false });
|
||||
}
|
||||
return newId.did;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user