Format code

This commit is contained in:
Nicola Benaglia 2025-05-13 06:15:26 +02:00
parent 035142504b
commit 452c3a0894
12 changed files with 502 additions and 449 deletions

View File

@ -1,5 +1,5 @@
import { useCallback, useContext, useEffect, useState } from 'react';
import Logo2 from '../assets/svgs/Logo2.svg';
import Logo2 from '../../assets/svgs/Logo2.svg';
import {
MyContext,
getArbitraryEndpointReact,

View File

@ -7,22 +7,25 @@ const keysToEncrypt = ['keyPair'];
async function initializeKeyAndIV() {
if (!inMemoryKey) {
inMemoryKey = await generateKey(); // Generates the key in memory
inMemoryKey = await generateKey(); // Generates the key in memory
}
}
async function generateKey(): Promise<CryptoKey> {
return await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
name: 'AES-GCM',
length: 256,
},
true,
["encrypt", "decrypt"]
['encrypt', 'decrypt']
);
}
async function encryptData(data: string, key: CryptoKey): Promise<{ iv: Uint8Array; encryptedData: ArrayBuffer }> {
async function encryptData(
data: string,
key: CryptoKey
): Promise<{ iv: Uint8Array; encryptedData: ArrayBuffer }> {
const encoder = new TextEncoder();
const encodedData = encoder.encode(data);
@ -31,8 +34,8 @@ async function encryptData(data: string, key: CryptoKey): Promise<{ iv: Uint8Arr
const encryptedData = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv
name: 'AES-GCM',
iv: iv,
},
key,
encodedData
@ -41,11 +44,15 @@ async function encryptData(data: string, key: CryptoKey): Promise<{ iv: Uint8Arr
return { iv, encryptedData };
}
async function decryptData(encryptedData: ArrayBuffer, key: CryptoKey, iv: Uint8Array): Promise<string> {
async function decryptData(
encryptedData: ArrayBuffer,
key: CryptoKey,
iv: Uint8Array
): Promise<string> {
const decryptedData = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv
name: 'AES-GCM',
iv: iv,
},
key,
encryptedData
@ -83,7 +90,10 @@ export const storeData = async (key: string, payload: any): Promise<string> => {
const { iv, encryptedData } = await encryptData(base64Data, inMemoryKey);
// Combine IV and encrypted data into a single Uint8Array
const combinedData = new Uint8Array([...iv, ...new Uint8Array(encryptedData)]);
const combinedData = new Uint8Array([
...iv,
...new Uint8Array(encryptedData),
]);
const encryptedBase64Data = btoa(String.fromCharCode(...combinedData));
await SecureStoragePlugin.set({ key, value: encryptedBase64Data });
} else {
@ -91,10 +101,9 @@ export const storeData = async (key: string, payload: any): Promise<string> => {
await SecureStoragePlugin.set({ key, value: base64Data });
}
return "Data saved successfully";
return 'Data saved successfully';
};
export const getData = async <T = any>(key: string): Promise<T | null> => {
await initializeKeyAndIV();
@ -105,13 +114,17 @@ export const getData = async <T = any>(key: string): Promise<T | null> => {
if (keysToEncrypt.includes(key) && inMemoryKey) {
// Decode the Base64-encoded encrypted data
const combinedData = atob(storedDataBase64.value)
.split("")
.split('')
.map((c) => c.charCodeAt(0));
const iv = new Uint8Array(combinedData.slice(0, 12)); // First 12 bytes are the IV
const encryptedData = new Uint8Array(combinedData.slice(12)).buffer;
const decryptedBase64Data = await decryptData(encryptedData, inMemoryKey, iv);
const decryptedBase64Data = await decryptData(
encryptedData,
inMemoryKey,
iv
);
return base64ToJson(decryptedBase64Data);
} else {
// Decode non-encrypted data
@ -121,21 +134,21 @@ export const getData = async <T = any>(key: string): Promise<T | null> => {
return null;
}
} catch (error) {
return null
return null;
}
};
// Remove keys from storage and log out
export async function removeKeysAndLogout(keys: string[], event: MessageEvent, request: any) {
export async function removeKeysAndLogout(
keys: string[],
event: MessageEvent,
request: any
) {
try {
for (const key of keys) {
try {
await SecureStoragePlugin.remove({ key });
await SecureStoragePlugin.remove({ key: `${key}_iv` }); // Remove associated IV
await SecureStoragePlugin.remove({ key: `${key}_iv` }); // Remove associated IV
} catch (error) {
console.warn(`Key not found: ${key}`);
}
@ -144,13 +157,13 @@ export async function removeKeysAndLogout(keys: string[], event: MessageEvent, r
event.source.postMessage(
{
requestId: request.requestId,
action: "logout",
action: 'logout',
payload: true,
type: "backgroundMessageResponse",
type: 'backgroundMessageResponse',
},
event.origin
);
} catch (error) {
console.error("Error removing keys:", error);
console.error('Error removing keys:', error);
}
}

View File

@ -1,31 +1,31 @@
export function decodeIfEncoded(input) {
try {
// Check if input is URI-encoded by encoding and decoding
const encoded = encodeURIComponent(decodeURIComponent(input));
if (encoded === input) {
// Input is URI-encoded, so decode it
return decodeURIComponent(input);
}
} catch (e) {
// decodeURIComponent throws an error if input is not encoded
console.error("Error decoding URI:", e);
try {
// Check if input is URI-encoded by encoding and decoding
const encoded = encodeURIComponent(decodeURIComponent(input));
if (encoded === input) {
// Input is URI-encoded, so decode it
return decodeURIComponent(input);
}
// Return input as-is if not URI-encoded
return input;
} catch (e) {
// decodeURIComponent throws an error if input is not encoded
console.error('Error decoding URI:', e);
}
export const isValidBase64 = (str: string): boolean => {
if (typeof str !== "string" || str.length % 4 !== 0) return false;
// Return input as-is if not URI-encoded
return input;
}
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
return base64Regex.test(str);
};
export const isValidBase64 = (str: string): boolean => {
if (typeof str !== 'string' || str.length % 4 !== 0) return false;
export const isValidBase64WithDecode = (str: string): boolean => {
try {
return isValidBase64(str) && Boolean(atob(str));
} catch {
return false;
}
};
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
return base64Regex.test(str);
};
export const isValidBase64WithDecode = (str: string): boolean => {
try {
return isValidBase64(str) && Boolean(atob(str));
} catch {
return false;
}
};

View File

@ -1,38 +1,59 @@
// @ts-nocheck
import Base58 from '../deps/Base58'
import ed2curve from '../deps/ed2curve'
import nacl from '../deps/nacl-fast'
import {Sha256} from 'asmcrypto.js'
import Base58 from '../deps/Base58';
import ed2curve from '../deps/ed2curve';
import nacl from '../deps/nacl-fast';
import { Sha256 } from 'asmcrypto.js';
export const decryptChatMessage = (
encryptedMessage,
privateKey,
recipientPublicKey,
lastReference
) => {
const test = encryptedMessage;
let _encryptedMessage = atob(encryptedMessage);
const binaryLength = _encryptedMessage.length;
const bytes = new Uint8Array(binaryLength);
export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => {
const test = encryptedMessage
let _encryptedMessage = atob(encryptedMessage)
const binaryLength = _encryptedMessage.length
const bytes = new Uint8Array(binaryLength)
for (let i = 0; i < binaryLength; i++) {
bytes[i] = _encryptedMessage.charCodeAt(i);
}
for (let i = 0; i < binaryLength; i++) {
bytes[i] = _encryptedMessage.charCodeAt(i)
}
const _base58RecipientPublicKey =
recipientPublicKey instanceof Uint8Array
? Base58.encode(recipientPublicKey)
: recipientPublicKey;
const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey);
const _lastReference =
lastReference instanceof Uint8Array
? lastReference
: Base58.decode(lastReference);
const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey
const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey)
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey);
const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey);
const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(
sharedSecret,
convertedPrivateKey,
convertedPublicKey
);
const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference)
const _chatEncryptionSeed = new Sha256()
.process(sharedSecret)
.finish().result;
const _decryptedMessage = nacl.secretbox.open(
bytes,
_lastReference.slice(0, 24),
_chatEncryptionSeed
);
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey)
const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
let decryptedMessage = '';
const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
const _decryptedMessage = nacl.secretbox.open(bytes, _lastReference.slice(0, 24), _chatEncryptionSeed)
_decryptedMessage === false
? decryptedMessage
: (decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage));
let decryptedMessage = ''
_decryptedMessage === false ? decryptedMessage : decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage)
return decryptedMessage
}
return decryptedMessage;
};

View File

@ -1,33 +1,38 @@
// @ts-nocheck
import { crypto } from '../constants/decryptWallet'
import Base58 from '../deps/Base58'
import {AES_CBC, HmacSha512} from 'asmcrypto.js'
import { doInitWorkers, kdf } from '../deps/kdf'
import { crypto } from '../constants/decryptWallet';
import Base58 from '../deps/Base58';
import { AES_CBC, HmacSha512 } from 'asmcrypto.js';
import { doInitWorkers, kdf } from '../deps/kdf';
export const decryptStoredWallet = async (password, wallet) => {
const threads = doInitWorkers(crypto.kdfThreads)
const encryptedSeedBytes = Base58.decode(wallet.encryptedSeed)
const iv = Base58.decode(wallet.iv)
const salt = Base58.decode(wallet.salt)
const threads = doInitWorkers(crypto.kdfThreads);
const encryptedSeedBytes = Base58.decode(wallet.encryptedSeed);
const iv = Base58.decode(wallet.iv);
const salt = Base58.decode(wallet.salt);
const key = await kdf(password, salt, threads)
const encryptionKey = key.slice(0, 32)
const macKey = key.slice(32, 63)
const mac = new HmacSha512(macKey).process(encryptedSeedBytes).finish().result
if (Base58.encode(mac) !== wallet.mac) {
throw new Error("Incorrect password")
}
const decryptedBytes = AES_CBC.decrypt(encryptedSeedBytes, encryptionKey, false, iv)
return decryptedBytes
}
const key = await kdf(password, salt, threads);
const encryptionKey = key.slice(0, 32);
const macKey = key.slice(32, 63);
const mac = new HmacSha512(macKey)
.process(encryptedSeedBytes)
.finish().result;
if (Base58.encode(mac) !== wallet.mac) {
throw new Error('Incorrect password');
}
const decryptedBytes = AES_CBC.decrypt(
encryptedSeedBytes,
encryptionKey,
false,
iv
);
return decryptedBytes;
};
export const decryptStoredWalletFromSeedPhrase = async (password) => {
const threads = doInitWorkers(crypto.kdfThreads)
const salt = new Uint8Array(void 0)
const threads = doInitWorkers(crypto.kdfThreads);
const salt = new Uint8Array(void 0);
const seed = await kdf(password, salt, threads)
return seed
}
const seed = await kdf(password, salt, threads);
return seed;
};

View File

@ -1,11 +1,12 @@
export const executeEvent = (eventName: string, data: any)=> {
const event = new CustomEvent(eventName, {detail: data})
document.dispatchEvent(event)
}
export const subscribeToEvent = (eventName: string, listener: any)=> {
document.addEventListener(eventName, listener)
}
export const executeEvent = (eventName: string, data: any) => {
const event = new CustomEvent(eventName, { detail: data });
document.dispatchEvent(event);
};
export const unsubscribeFromEvent = (eventName: string, listener: any)=> {
document.removeEventListener(eventName, listener)
}
export const subscribeToEvent = (eventName: string, listener: any) => {
document.addEventListener(eventName, listener);
};
export const unsubscribeFromEvent = (eventName: string, listener: any) => {
document.removeEventListener(eventName, listener);
};

View File

@ -1,34 +1,28 @@
import moment from "moment";
export const delay = (time: number) => new Promise((_, reject) =>
export const delay = (time: number) =>
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Request timed out')), time)
);
// const originalHtml = `<p>---------- Forwarded message ---------</p><p>From: Alex</p><p>Date: Mon, Jun 9 2014 9:32 PM</p><p>Subject: Batteries </p><p>To: Jessica</p><p><br></p><p><br></p>`;
// export function updateMessageDetails(newFrom: string, newDateMillis: number, newTo: string) {
// let htmlString = originalHtml
// // Use Moment.js to format the date from milliseconds
// const formattedDate = moment(newDateMillis).format('ddd, MMM D YYYY h:mm A');
// // Replace the From, Date, and To fields in the HTML string
// htmlString = htmlString.replace(/<p>From:.*?<\/p>/, `<p>From: ${newFrom}</p>`);
// htmlString = htmlString.replace(/<p>Date:.*?<\/p>/, `<p>Date: ${formattedDate}</p>`);
// htmlString = htmlString.replace(/<p>To:.*?<\/p>/, `<p>To: ${newTo}</p>`);
// return htmlString;
// }
);
const originalHtml = `<p>---------- Forwarded message ---------</p><p>From: Alex</p><p>Subject: Batteries </p><p>To: Jessica</p><p><br></p><p><br></p>`;
export function updateMessageDetails(
newFrom: string,
newSubject: string,
newTo: string
) {
let htmlString = originalHtml;
export function updateMessageDetails(newFrom: string, newSubject: string, newTo: string) {
let htmlString = originalHtml
htmlString = htmlString.replace(
/<p>From:.*?<\/p>/,
`<p>From: ${newFrom}</p>`
);
htmlString = htmlString.replace(/<p>From:.*?<\/p>/, `<p>From: ${newFrom}</p>`);
htmlString = htmlString.replace(/<p>Subject:.*?<\/p>/, `<p>Subject: ${newSubject}</p>`);
htmlString = htmlString.replace(/<p>To:.*?<\/p>/, `<p>To: ${newTo}</p>`);
htmlString = htmlString.replace(
/<p>Subject:.*?<\/p>/,
`<p>Subject: ${newSubject}</p>`
);
return htmlString;
htmlString = htmlString.replace(/<p>To:.*?<\/p>/, `<p>To: ${newTo}</p>`);
return htmlString;
}

View File

@ -1,90 +1,107 @@
import { openIndexedDB } from "../components/Apps/useQortalMessageListener";
import { fileToBase64 } from "./fileReading";
import { openIndexedDB } from '../components/Apps/useQortalMessageListener';
import { fileToBase64 } from './fileReading';
export async function handleGetFileFromIndexedDB(event) {
try {
const { fileId, requestId } = event.data;
const db = await openIndexedDB();
const transaction = db.transaction(["files"], "readonly");
const objectStore = transaction.objectStore("files");
try {
const { fileId, requestId } = event.data;
const db = await openIndexedDB();
const transaction = db.transaction(['files'], 'readonly');
const objectStore = transaction.objectStore('files');
const getRequest = objectStore.get(fileId);
const getRequest = objectStore.get(fileId);
getRequest.onsuccess = async function (event) {
if (getRequest.result) {
const file = getRequest.result.data;
getRequest.onsuccess = async function (event) {
if (getRequest.result) {
const file = getRequest.result.data;
try {
const base64String = await fileToBase64(file);
try {
const base64String = await fileToBase64(file);
// Create a new transaction to delete the file
const deleteTransaction = db.transaction(["files"], "readwrite");
const deleteObjectStore = deleteTransaction.objectStore("files");
const deleteRequest = deleteObjectStore.delete(fileId);
// Create a new transaction to delete the file
const deleteTransaction = db.transaction(['files'], 'readwrite');
const deleteObjectStore = deleteTransaction.objectStore('files');
const deleteRequest = deleteObjectStore.delete(fileId);
deleteRequest.onsuccess = function () {
try {
const targetOrigin = window.location.origin;
deleteRequest.onsuccess = function () {
try {
const targetOrigin = window.location.origin;
window.postMessage(
{ action: "getFileFromIndexedDBResponse", requestId, result: base64String },
targetOrigin
);
} catch (error) {
console.log('error', error)
}
};
window.postMessage(
{
action: 'getFileFromIndexedDBResponse',
requestId,
result: base64String,
},
targetOrigin
);
} catch (error) {
console.log('error', error);
}
};
deleteRequest.onerror = function () {
console.error(`Error deleting file with ID ${fileId} from IndexedDB`);
};
} catch (error) {
console.error("Error converting file to Base64:", error);
event.ports[0].postMessage({
result: null,
error: "Failed to convert file to Base64",
});
const targetOrigin = window.location.origin;
window.postMessage(
{ action: "getFileFromIndexedDBResponse", requestId, result: null,
error: "Failed to convert file to Base64"
},
targetOrigin
deleteRequest.onerror = function () {
console.error(
`Error deleting file with ID ${fileId} from IndexedDB`
);
}
} else {
console.error(`File with ID ${fileId} not found in IndexedDB`);
};
} catch (error) {
console.error('Error converting file to Base64:', error);
event.ports[0].postMessage({
result: null,
error: 'Failed to convert file to Base64',
});
const targetOrigin = window.location.origin;
window.postMessage(
{ action: "getFileFromIndexedDBResponse", requestId, result: null,
error: 'File not found in IndexedDB'
},
targetOrigin
{
action: 'getFileFromIndexedDBResponse',
requestId,
result: null,
error: 'Failed to convert file to Base64',
},
targetOrigin
);
}
};
} else {
console.error(`File with ID ${fileId} not found in IndexedDB`);
const targetOrigin = window.location.origin;
getRequest.onerror = function () {
console.error(`Error retrieving file with ID ${fileId} from IndexedDB`);
event.source.postMessage(
{ action: "getFileFromIndexedDBResponse", requestId, result: null,
error: 'Error retrieving file from IndexedDB'
},
event.origin
window.postMessage(
{
action: 'getFileFromIndexedDBResponse',
requestId,
result: null,
error: 'File not found in IndexedDB',
},
targetOrigin
);
};
} catch (error) {
const { requestId } = event.data;
console.error("Error opening IndexedDB:", error);
}
};
getRequest.onerror = function () {
console.error(`Error retrieving file with ID ${fileId} from IndexedDB`);
event.source.postMessage(
{ action: "getFileFromIndexedDBResponse", requestId, result: null,
error: 'Error opening IndexedDB'
},
{
action: 'getFileFromIndexedDBResponse',
requestId,
result: null,
error: 'Error retrieving file from IndexedDB',
},
event.origin
);
}
};
} catch (error) {
const { requestId } = event.data;
console.error('Error opening IndexedDB:', error);
event.source.postMessage(
{
action: 'getFileFromIndexedDBResponse',
requestId,
result: null,
error: 'Error opening IndexedDB',
},
event.origin
);
}
}

View File

@ -1,123 +1,125 @@
export const mimeToExtensionMap = {
// Documents
"application/pdf": ".pdf",
"application/msword": ".doc",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
"application/vnd.ms-excel": ".xls",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
"application/vnd.ms-powerpoint": ".ppt",
"application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
"application/vnd.oasis.opendocument.text": ".odt",
"application/vnd.oasis.opendocument.spreadsheet": ".ods",
"application/vnd.oasis.opendocument.presentation": ".odp",
"text/plain": ".txt",
"text/csv": ".csv",
"application/xhtml+xml": ".xhtml",
"application/xml": ".xml",
"application/rtf": ".rtf",
"application/vnd.apple.pages": ".pages",
"application/vnd.google-apps.document": ".gdoc",
"application/vnd.google-apps.spreadsheet": ".gsheet",
"application/vnd.google-apps.presentation": ".gslides",
// Documents
'application/pdf': '.pdf',
'application/msword': '.doc',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
'.docx',
'application/vnd.ms-excel': '.xls',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',
'application/vnd.ms-powerpoint': '.ppt',
'application/vnd.openxmlformats-officedocument.presentationml.presentation':
'.pptx',
'application/vnd.oasis.opendocument.text': '.odt',
'application/vnd.oasis.opendocument.spreadsheet': '.ods',
'application/vnd.oasis.opendocument.presentation': '.odp',
'text/plain': '.txt',
'text/csv': '.csv',
'application/xhtml+xml': '.xhtml',
'application/xml': '.xml',
'application/rtf': '.rtf',
'application/vnd.apple.pages': '.pages',
'application/vnd.google-apps.document': '.gdoc',
'application/vnd.google-apps.spreadsheet': '.gsheet',
'application/vnd.google-apps.presentation': '.gslides',
// Images
"image/jpeg": ".jpg",
"image/png": ".png",
"image/gif": ".gif",
"image/webp": ".webp",
"image/svg+xml": ".svg",
"image/tiff": ".tif",
"image/bmp": ".bmp",
"image/x-icon": ".ico",
"image/heic": ".heic",
"image/heif": ".heif",
"image/apng": ".apng",
"image/avif": ".avif",
// Images
'image/jpeg': '.jpg',
'image/png': '.png',
'image/gif': '.gif',
'image/webp': '.webp',
'image/svg+xml': '.svg',
'image/tiff': '.tif',
'image/bmp': '.bmp',
'image/x-icon': '.ico',
'image/heic': '.heic',
'image/heif': '.heif',
'image/apng': '.apng',
'image/avif': '.avif',
// Audio
"audio/mpeg": ".mp3",
"audio/ogg": ".ogg",
"audio/wav": ".wav",
"audio/webm": ".weba",
"audio/aac": ".aac",
"audio/flac": ".flac",
"audio/x-m4a": ".m4a",
"audio/x-ms-wma": ".wma",
"audio/midi": ".midi",
"audio/x-midi": ".mid",
// Audio
'audio/mpeg': '.mp3',
'audio/ogg': '.ogg',
'audio/wav': '.wav',
'audio/webm': '.weba',
'audio/aac': '.aac',
'audio/flac': '.flac',
'audio/x-m4a': '.m4a',
'audio/x-ms-wma': '.wma',
'audio/midi': '.midi',
'audio/x-midi': '.mid',
// Video
"video/mp4": ".mp4",
"video/webm": ".webm",
"video/ogg": ".ogv",
"video/x-msvideo": ".avi",
"video/quicktime": ".mov",
"video/x-ms-wmv": ".wmv",
"video/mpeg": ".mpeg",
"video/3gpp": ".3gp",
"video/3gpp2": ".3g2",
"video/x-matroska": ".mkv",
"video/x-flv": ".flv",
"video/x-ms-asf": ".asf",
// Video
'video/mp4': '.mp4',
'video/webm': '.webm',
'video/ogg': '.ogv',
'video/x-msvideo': '.avi',
'video/quicktime': '.mov',
'video/x-ms-wmv': '.wmv',
'video/mpeg': '.mpeg',
'video/3gpp': '.3gp',
'video/3gpp2': '.3g2',
'video/x-matroska': '.mkv',
'video/x-flv': '.flv',
'video/x-ms-asf': '.asf',
// Archives
"application/zip": ".zip",
"application/x-rar-compressed": ".rar",
"application/x-tar": ".tar",
"application/x-7z-compressed": ".7z",
"application/x-gzip": ".gz",
"application/x-bzip2": ".bz2",
"application/x-apple-diskimage": ".dmg",
"application/vnd.android.package-archive": ".apk",
"application/x-iso9660-image": ".iso",
// Archives
'application/zip': '.zip',
'application/x-rar-compressed': '.rar',
'application/x-tar': '.tar',
'application/x-7z-compressed': '.7z',
'application/x-gzip': '.gz',
'application/x-bzip2': '.bz2',
'application/x-apple-diskimage': '.dmg',
'application/vnd.android.package-archive': '.apk',
'application/x-iso9660-image': '.iso',
// Code Files
"text/javascript": ".js",
"text/css": ".css",
"text/html": ".html",
"application/json": ".json",
"text/xml": ".xml",
"application/x-sh": ".sh",
"application/x-csh": ".csh",
"text/x-python": ".py",
"text/x-java-source": ".java",
"application/java-archive": ".jar",
"application/vnd.microsoft.portable-executable": ".exe",
"application/x-msdownload": ".msi",
"text/x-c": ".c",
"text/x-c++": ".cpp",
"text/x-go": ".go",
"application/x-perl": ".pl",
"text/x-php": ".php",
"text/x-ruby": ".rb",
"text/x-sql": ".sql",
"application/x-httpd-php": ".php",
"application/x-python-code": ".pyc",
// Code Files
'text/javascript': '.js',
'text/css': '.css',
'text/html': '.html',
'application/json': '.json',
'text/xml': '.xml',
'application/x-sh': '.sh',
'application/x-csh': '.csh',
'text/x-python': '.py',
'text/x-java-source': '.java',
'application/java-archive': '.jar',
'application/vnd.microsoft.portable-executable': '.exe',
'application/x-msdownload': '.msi',
'text/x-c': '.c',
'text/x-c++': '.cpp',
'text/x-go': '.go',
'application/x-perl': '.pl',
'text/x-php': '.php',
'text/x-ruby': '.rb',
'text/x-sql': '.sql',
'application/x-httpd-php': '.php',
'application/x-python-code': '.pyc',
// ROM Files
"application/x-nintendo-nes-rom": ".nes",
"application/x-snes-rom": ".smc",
"application/x-gameboy-rom": ".gb",
"application/x-gameboy-advance-rom": ".gba",
"application/x-n64-rom": ".n64",
"application/x-sega-genesis-rom": ".gen",
"application/x-sega-master-system-rom": ".sms",
"application/x-psx-rom": ".iso", // PlayStation ROMs
"application/x-bios-rom": ".rom",
"application/x-flash-rom": ".bin",
"application/x-eeprom": ".eep",
"application/x-c64-rom": ".prg",
// ROM Files
'application/x-nintendo-nes-rom': '.nes',
'application/x-snes-rom': '.smc',
'application/x-gameboy-rom': '.gb',
'application/x-gameboy-advance-rom': '.gba',
'application/x-n64-rom': '.n64',
'application/x-sega-genesis-rom': '.gen',
'application/x-sega-master-system-rom': '.sms',
'application/x-psx-rom': '.iso', // PlayStation ROMs
'application/x-bios-rom': '.rom',
'application/x-flash-rom': '.bin',
'application/x-eeprom': '.eep',
'application/x-c64-rom': '.prg',
// Miscellaneous
"application/octet-stream": ".bin", // General binary files
"application/x-shockwave-flash": ".swf",
"application/x-silverlight-app": ".xap",
"application/x-ms-shortcut": ".lnk",
"application/vnd.ms-fontobject": ".eot",
"font/woff": ".woff",
"font/woff2": ".woff2",
"font/ttf": ".ttf",
"font/otf": ".otf",
"application/vnd.visio": ".vsd",
"application/vnd.ms-project": ".mpp",
// Miscellaneous
'application/octet-stream': '.bin', // General binary files
'application/x-shockwave-flash': '.swf',
'application/x-silverlight-app': '.xap',
'application/x-ms-shortcut': '.lnk',
'application/vnd.ms-fontobject': '.eot',
'font/woff': '.woff',
'font/woff2': '.woff2',
'font/ttf': '.ttf',
'font/otf': '.otf',
'application/vnd.visio': '.vsd',
'application/vnd.ms-project': '.mpp',
};

View File

@ -1,56 +1,57 @@
import moment from "moment"
import moment from 'moment';
export function formatTimestamp(timestamp: number): string {
const now = moment()
const timestampMoment = moment(timestamp)
const elapsedTime = now.diff(timestampMoment, 'minutes')
const now = moment();
const timestampMoment = moment(timestamp);
const elapsedTime = now.diff(timestampMoment, 'minutes');
if (elapsedTime < 1) {
return 'Just now'
} else if (elapsedTime < 60) {
return `${elapsedTime}m ago`
} else if (elapsedTime < 1440) {
return `${Math.floor(elapsedTime / 60)}h ago`
} else {
return timestampMoment.format('MMM D, YYYY')
}
if (elapsedTime < 1) {
return 'Just now';
} else if (elapsedTime < 60) {
return `${elapsedTime}m ago`;
} else if (elapsedTime < 1440) {
return `${Math.floor(elapsedTime / 60)}h ago`;
} else {
return timestampMoment.format('MMM D, YYYY');
}
export function formatTimestampForum(timestamp: number): string {
const now = moment();
const timestampMoment = moment(timestamp);
const elapsedTime = now.diff(timestampMoment, 'minutes');
if (elapsedTime < 1) {
return `Just now - ${timestampMoment.format('h:mm A')}`;
} else if (elapsedTime < 60) {
return `${elapsedTime}m ago - ${timestampMoment.format('h:mm A')}`;
} else if (elapsedTime < 1440) {
return `${Math.floor(elapsedTime / 60)}h ago - ${timestampMoment.format('h:mm A')}`;
} else {
return timestampMoment.format('MMM D, YYYY - h:mm A');
}
}
export const formatDate = (unixTimestamp: number): string => {
const date = moment(unixTimestamp, 'x').fromNow()
export function formatTimestampForum(timestamp: number): string {
const now = moment();
const timestampMoment = moment(timestamp);
const elapsedTime = now.diff(timestampMoment, 'minutes');
return date
if (elapsedTime < 1) {
return `Just now - ${timestampMoment.format('h:mm A')}`;
} else if (elapsedTime < 60) {
return `${elapsedTime}m ago - ${timestampMoment.format('h:mm A')}`;
} else if (elapsedTime < 1440) {
return `${Math.floor(elapsedTime / 60)}h ago - ${timestampMoment.format('h:mm A')}`;
} else {
return timestampMoment.format('MMM D, YYYY - h:mm A');
}
}
export function sortArrayByTimestampAndGroupName(array) {
return array.sort((a, b) => {
if (a.timestamp && b.timestamp) {
// Both have timestamp, sort by timestamp descending
return b.timestamp - a.timestamp;
} else if (a.timestamp) {
// Only `a` has timestamp, it comes first
return -1;
} else if (b.timestamp) {
// Only `b` has timestamp, it comes first
return 1;
} else {
// Neither has timestamp, sort alphabetically by groupName
return a.groupName.localeCompare(b.groupName);
}
});
}
export const formatDate = (unixTimestamp: number): string => {
const date = moment(unixTimestamp, 'x').fromNow();
return date;
};
export function sortArrayByTimestampAndGroupName(array) {
return array.sort((a, b) => {
if (a.timestamp && b.timestamp) {
// Both have timestamp, sort by timestamp descending
return b.timestamp - a.timestamp;
} else if (a.timestamp) {
// Only `a` has timestamp, it comes first
return -1;
} else if (b.timestamp) {
// Only `b` has timestamp, it comes first
return 1;
} else {
// Neither has timestamp, sort alphabetically by groupName
return a.groupName.localeCompare(b.groupName);
}
});
}

View File

@ -1,55 +1,55 @@
// @ts-nocheck
const utils = {
int32ToBytes (word) {
var byteArray = []
for (var b = 0; b < 32; b += 8) {
byteArray.push((word >>> (24 - b % 32)) & 0xFF)
}
return byteArray
},
stringtoUTF8Array (message) {
if (typeof message === 'string') {
var s = unescape(encodeURIComponent(message)) // UTF-8
message = new Uint8Array(s.length)
for (var i = 0; i < s.length; i++) {
message[i] = s.charCodeAt(i) & 0xff
}
}
return message
},
// ...buffers then buffers.foreach and append to buffer1
appendBuffer (buffer1, buffer2) {
buffer1 = new Uint8Array(buffer1)
buffer2 = new Uint8Array(buffer2)
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
tmp.set(buffer1, 0)
tmp.set(buffer2, buffer1.byteLength)
return tmp
},
int64ToBytes (int64) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]
for (var index = 0; index < byteArray.length; index++) {
var byte = int64 & 0xff
byteArray[byteArray.length - index - 1] = byte
int64 = (int64 - byte) / 256
}
return byteArray
},
equal (buf1, buf2) {
if (buf1.byteLength != buf2.byteLength) return false
var dv1 = new Uint8Array(buf1)
var dv2 = new Uint8Array(buf2)
for (var i = 0; i != buf1.byteLength; i++) {
if (dv1[i] != dv2[i]) return false
}
return true
int32ToBytes(word) {
var byteArray = [];
for (var b = 0; b < 32; b += 8) {
byteArray.push((word >>> (24 - (b % 32))) & 0xff);
}
}
return byteArray;
},
export default utils
stringtoUTF8Array(message) {
if (typeof message === 'string') {
var s = unescape(encodeURIComponent(message)); // UTF-8
message = new Uint8Array(s.length);
for (var i = 0; i < s.length; i++) {
message[i] = s.charCodeAt(i) & 0xff;
}
}
return message;
},
// ...buffers then buffers.foreach and append to buffer1
appendBuffer(buffer1, buffer2) {
buffer1 = new Uint8Array(buffer1);
buffer2 = new Uint8Array(buffer2);
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(buffer1, 0);
tmp.set(buffer2, buffer1.byteLength);
return tmp;
},
int64ToBytes(int64) {
// we want to represent the input as a 8-bytes array
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
for (var index = 0; index < byteArray.length; index++) {
var byte = int64 & 0xff;
byteArray[byteArray.length - index - 1] = byte;
int64 = (int64 - byte) / 256;
}
return byteArray;
},
equal(buf1, buf2) {
if (buf1.byteLength != buf2.byteLength) return false;
var dv1 = new Uint8Array(buf1);
var dv2 = new Uint8Array(buf2);
for (var i = 0; i != buf1.byteLength; i++) {
if (dv1[i] != dv2[i]) return false;
}
return true;
},
};
export default utils;

View File

@ -1,21 +1,20 @@
// @ts-nocheck
import Base58 from "../deps/Base58"
import Base58 from '../deps/Base58';
export const validateAddress = (address) => {
let isAddress = false
try {
const decodePubKey = Base58.decode(address)
let isAddress = false;
try {
const decodePubKey = Base58.decode(address);
if (!(decodePubKey instanceof Uint8Array && decodePubKey.length == 25)) {
isAddress = false
} else {
isAddress = true
}
if (!(decodePubKey instanceof Uint8Array && decodePubKey.length == 25)) {
isAddress = false;
} else {
isAddress = true;
}
} catch (error) {
console.log(error);
}
} catch (error) {
}
return isAddress
}
return isAddress;
};