import * as CryptoJS from "crypto-js" ; import { EncryptedShipCredentials , PopupPreference , PermissionsGraph } from "./types" ; interface Storage { ships ? : EncryptedShipCredentials [ ] ; password ? : string ; popup ? : PopupPreference ; permissions ? : PermissionsGraph ; } export async function validate ( password ) { const res = await getStorage ( "password" ) ; const string = decrypt ( res . password , password ) ; if ( string === "urbit_visor" ) return true ; else return false ; } export const getStorage = ( key ) : Promise < Storage > => new Promise ( ( res , rej ) => chrome . storage . local . get ( key , ( result ) => { if ( chrome . runtime . lastError ) rej ( undefined ) ; res ( result ) ; } ) ) ; export const setStorage = ( item ) : Promise < any > => new Promise ( ( res , rej ) => chrome . storage . local . set ( item , ( ) => { if ( chrome . runtime . lastError ) rej ( chrome . runtime . lastError ) ; res ( true ) ; } ) ) ; export async function storeCredentials ( ship , url , code , pw ) { const encryptedCredentials = encryptCreds ( ship , url , code , pw ) ; return saveShip ( encryptedCredentials ) ; } ; export function savePassword ( password ) { const encryptedString = encrypt ( "urbit_visor" , password ) ; return setStorage ( { password : encryptedString } ) ; } export function resetApp ( ) { return new Promise ( ( resolve , reject ) => { chrome . storage . local . clear ( ( ) => { if ( chrome . runtime . lastError ) reject ( undefined ) ; resolve ( "ok" ) ; } ) ; } ) ; } export function setPopupPreference ( preference ) { return setStorage ( { popup : preference } ) ; } export async function initStorage ( password ) { await setPopupPreference ( "modal" ) ; return savePassword ( password ) ; } export async function removeShip ( ship ) { const res = await getStorage ( "ships" ) ; const new_ships = res [ "ships" ] . filter ( ( el ) => el . shipName !== ship . shipName ) ; return setStorage ( { ships : new_ships } ) ; } async function saveShip ( ship ) { const res = await getStorage ( "ships" ) ; if ( res [ "ships" ] ?. length ) { const ships = res [ "ships" ] ; const filteredShips = ships . filter ( sp => sp . shipName !== ship . shipName ) ; const new_ships = [ ... filteredShips , ship ] ; await setStorage ( { ships : new_ships } ) ; return ship ; } else { const new_ships = [ ship ] ; await setStorage ( { ships : new_ships } ) ; return ship ; } } export async function getShips ( ) { return new Promise ( ( resolve , reject ) => { chrome . storage . local . get ( "ships" , ( res ) => { if ( res [ "ships" ] && res [ "ships" ] . length ) { resolve ( res ) ; } else { reject ( "data not set" ) ; } } ) ; } ) ; } ; export async function getPreference ( ) { return new Promise ( ( resolve , reject ) => { chrome . storage . local . get ( "popup" , ( res ) => { if ( res [ "popup" ] ) { resolve ( res . popup ) ; } else { reject ( "data not set" ) ; } } ) ; } ) ; } ; export async function reEncryptAll ( oldPassword , newPassword ) { const ships = await getShips ( ) ; for ( const ship of ships . ships ) { const newShip = reEncrypt ( ship , oldPassword , newPassword ) ; saveShip ( newShip ) ; } } export function encryptCreds ( ship , url , code , pw ) { const encryptedURL = encrypt ( url , pw ) . toString ( ) ; const encryptedCode = encrypt ( code , pw ) . toString ( ) ; return { shipName : ship , encryptedShipURL : encryptedURL , encryptedShipCode : encryptedCode , } ; } function reEncrypt ( ship , oldPassword , newPassword ) { return { shipName : ship . shipName , encryptedShipURL : encrypt ( decrypt ( ship . encryptedShipURL , oldPassword ) , newPassword ) , encryptedShipCode : encrypt ( decrypt ( ship . encryptedShipCode , oldPassword ) , newPassword ) , } ; } ; export function encrypt ( target , password ) { return CryptoJS . AES . encrypt ( target , password ) . toString ( ) ; } ; export function decrypt ( target , password ) { if ( password === "" ) return "" ; const decrypted = CryptoJS . AES . decrypt ( target , password ) ; try { return decrypted . toString ( CryptoJS . enc . Utf8 ) ; } catch { return "" ; } } ;