From f5c5ad41fa41a89cc3f3618267fb45f2b44510b7 Mon Sep 17 00:00:00 2001 From: First-Terraner Date: Thu, 7 Dec 2023 15:22:59 +0100 Subject: [PATCH] check if incoming token is from default token --- assets/translations/de.json | 2 +- src/context/FocusClaim.tsx | 8 ++++++-- src/screens/Dashboard.tsx | 6 ++++-- src/screens/Payment/Receive/nostrDM/Token.tsx | 16 +++++++-------- src/screens/QRScan/index.tsx | 15 +++++++------- src/screens/Settings/General/index.tsx | 20 +++++++++---------- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/assets/translations/de.json b/assets/translations/de.json index 75d4a02f..3dbc91f1 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -232,7 +232,7 @@ "backupQ": "Wie funktioniert es?", "backupHint": "Der aktuelle Sicherungsprozess stellt eine rudimentäre Umsetzung dar. Er erstellt ein Cashu-Token aus allen Mints und zugehörige Beweise, das nach neuen Transaktionen ungültig wird. Um den Token auf einem neuen Gerät wiederherzustellen, folgen Sie dem vertrauten Beanspruchungsprozess, und der alte Kontostand wird ungültig. Vermeiden Sie es, es auf dem aktuellen Kontostand einzulösen, um Fehler vorzubeugen. Es sei darauf hingewiesen, dass wir aktiv an der Entwicklung einer Sicherungslösung mit Passphrase arbeiten, um die Sicherheit und Bequemlichkeit zu verbessern.", "singleBackupHint": "Hinweis: Sie können auch eine Sicherung für eine einzelne Mint erstellen unter 'Optionen' > 'Mint Management' > 'Mint auswählen' > 'Guthabensicherung'.", - "noDefaultHint": "Du musst eine Standard-Mint einrichten, um einen automatischen Tausch durchzuführen." + "noDefaultHint": "Sie müssen eine Standard-Mint einrichten, um einen automatischen Tausch durchzuführen." }, "error": { "checkSpendableErr": "Fehler beim Überprüfen, ob der Token ausgegeben werden kann", diff --git a/src/context/FocusClaim.tsx b/src/context/FocusClaim.tsx index e39a6dd7..d8a0eeec 100644 --- a/src/context/FocusClaim.tsx +++ b/src/context/FocusClaim.tsx @@ -4,7 +4,8 @@ import { l } from '@log' import type { ITokenInfo } from '@model' import { store } from '@store' import { STORE_KEYS } from '@store/consts' -import { getStrFromClipboard, hasTrustedMint, isCashuToken, sleep } from '@util' +import { getDefaultMint } from '@store/mintStore' +import { getStrFromClipboard, hasTrustedMint, isCashuToken, isStr, sleep } from '@util' import { isTokenSpendable } from '@wallet' import { getTokenInfo } from '@wallet/proofs' import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react' @@ -32,9 +33,12 @@ const useFocusClaim = () => { const info = getTokenInfo(cleanedClipboard) if (!info) { return false } // check if mint is a trusted one + const defaultM = await getDefaultMint() const userMints = await getMintsUrls() // do not claim from clipboard when app comes to the foreground if mint from token is not trusted - if (!hasTrustedMint(userMints, info.mints)) { return false } + if (!hasTrustedMint(userMints, info.mints)|| (isStr(defaultM) && !info.mints.includes(defaultM))) { + return false + } // check if token is spendable try { const isSpendable = await isTokenSpendable(cleanedClipboard) diff --git a/src/screens/Dashboard.tsx b/src/screens/Dashboard.tsx index d20e9689..ebf46ab4 100644 --- a/src/screens/Dashboard.tsx +++ b/src/screens/Dashboard.tsx @@ -25,7 +25,7 @@ import { NS } from '@src/i18n' import { store } from '@store' import { STORE_KEYS } from '@store/consts' import { addToHistory } from '@store/latestHistoryEntries' -import { saveDefaultOnInit } from '@store/mintStore' +import { getDefaultMint, saveDefaultOnInit } from '@store/mintStore' import { highlight as hi, mainColors } from '@styles' import { extractStrFromURL, getStrFromClipboard, hasTrustedMint, isCashuToken, isErr, isLnInvoice, isStr } from '@util' import { claimToken, getMintsForPayment } from '@wallet' @@ -128,9 +128,10 @@ export default function Dashboard({ navigation, route }: TDashboardPageProps) { } // save token info in state setTokenInfo(tokenInfo) + const defaultM = await getDefaultMint() // check if user wants to trust the token mint const userMints = await getMintsUrls() - if (!hasTrustedMint(userMints, tokenInfo.mints)) { + if (!hasTrustedMint(userMints, tokenInfo.mints) || (isStr(defaultM) && !tokenInfo.mints.includes(defaultM))) { closeOptsModal() // ask user for permission if token mint is not in his mint list const t = setTimeout(() => { @@ -180,6 +181,7 @@ export default function Dashboard({ navigation, route }: TDashboardPageProps) { if (token.length) { return } startLoading() const clipboard = await getStrFromClipboard() + l({ clipboard }) if (!clipboard?.length || !isCashuToken(clipboard)) { openPromptAutoClose({ msg: t('invalidOrSpent') }) closeOptsModal() diff --git a/src/screens/Payment/Receive/nostrDM/Token.tsx b/src/screens/Payment/Receive/nostrDM/Token.tsx index 9cd59770..0dcc346a 100644 --- a/src/screens/Payment/Receive/nostrDM/Token.tsx +++ b/src/screens/Payment/Receive/nostrDM/Token.tsx @@ -8,15 +8,16 @@ import { addMint } from '@db' import { l } from '@log' import type { ITokenInfo } from '@model' import type { IContact, INostrDm } from '@model/nostr' +import { getNostrUsername, truncateStr } from '@nostr/util' import { useNostrContext } from '@src/context/Nostr' import { usePromptContext } from '@src/context/Prompt' import { useThemeContext } from '@src/context/Theme' import { NS } from '@src/i18n' -import { getNostrUsername, truncateStr } from '@src/nostr/util' import { addToHistory } from '@store/latestHistoryEntries' +import { getDefaultMint } from '@store/mintStore' import { updateNostrRedeemed } from '@store/nostrDms' import { highlight as hi, mainColors } from '@styles' -import { formatMintUrl, formatSatStr } from '@util' +import { formatMintUrl, formatSatStr, isStr } from '@util' import { claimToken } from '@wallet' import { getTokenInfo } from '@wallet/proofs' import { useEffect, useState } from 'react' @@ -56,11 +57,11 @@ export default function Token({ sender, token, id, dms, setDms, mints }: ITokenP const handleRedeem = async () => { if (!info) { return } startLoading() - // check for unknown mint - if (!mints.includes(info.mints[0] || '')) { + const defaultM = await getDefaultMint() + // check if user wants to trust the token mint + if (!mints.includes(info.mints[0] || '') || (isStr(defaultM) && !info.mints.includes(defaultM))) { // show trust modal - setTrustModal(true) - return + return setTrustModal(true) } await receiveToken() } @@ -85,8 +86,7 @@ export default function Token({ sender, token, id, dms, setDms, mints }: ITokenP if (!success) { openPromptAutoClose({ msg: t('invalidOrSpent') }) await handleStoreRedeemed() - stopLoading() - return + return stopLoading() } // add as history entry (receive ecash from nostr) await addToHistory({ diff --git a/src/screens/QRScan/index.tsx b/src/screens/QRScan/index.tsx index 9802e4dd..b71f387f 100644 --- a/src/screens/QRScan/index.tsx +++ b/src/screens/QRScan/index.tsx @@ -11,8 +11,9 @@ import { useIsFocused } from '@react-navigation/core' import { usePromptContext } from '@src/context/Prompt' import { useThemeContext } from '@src/context/Theme' import { NS } from '@src/i18n' +import { getDefaultMint } from '@store/mintStore' import { globals, mainColors } from '@styles' -import { decodeLnInvoice, extractStrFromURL, hasTrustedMint, isCashuToken, isNull, isUrl } from '@util' +import { decodeLnInvoice, extractStrFromURL, hasTrustedMint, isCashuToken, isNull, isStr, isUrl } from '@util' import { getTokenInfo } from '@wallet/proofs' import { BarCodeScanner, PermissionStatus } from 'expo-barcode-scanner' import { Camera, FlashMode } from 'expo-camera' @@ -48,17 +49,16 @@ export default function QRScanPage({ navigation, route }: TQRScanPageProps) { const handleCashuToken = async (data: string) => { const info = getTokenInfo(data) if (!info) { - openPromptAutoClose({ msg: t('invalidOrSpent') }) - return + return openPromptAutoClose({ msg: t('invalidOrSpent') }) } // save token info in state setTokenInfo(info) // check if user wants to trust the token mint + const defaultM = await getDefaultMint() const userMints = await getMintsUrls() - if (!hasTrustedMint(userMints, info.mints)) { + if (!hasTrustedMint(userMints, info.mints) || (isStr(defaultM) && !info.mints.includes(defaultM))) { // ask user for permission if token mint is not in his mint list - setTrustModal(true) - return + return setTrustModal(true) } navigation.navigate('qr processing', { tokenInfo: info, token: data }) } @@ -70,8 +70,7 @@ export default function QRScanPage({ navigation, route }: TQRScanPageProps) { openPromptAutoClose({ msg: t('invalidToken') }) stopLoading() // close modal - setTrustModal(false) - return + return setTrustModal(false) } for (const mint of tokenInfo.mints) { // eslint-disable-next-line no-await-in-loop diff --git a/src/screens/Settings/General/index.tsx b/src/screens/Settings/General/index.tsx index 305ec78d..444a4bd1 100644 --- a/src/screens/Settings/General/index.tsx +++ b/src/screens/Settings/General/index.tsx @@ -26,9 +26,9 @@ export default function GeneralSettings({ navigation, route }: TGeneralSettingsP } - onPress={() => navigation.navigate('Security settings')} + txt={t('display', { ns: NS.topNav })} + icon={} + onPress={() => navigation.navigate('Display settings')} hasSeparator hasChevron /> @@ -39,6 +39,13 @@ export default function GeneralSettings({ navigation, route }: TGeneralSettingsP hasSeparator hasChevron /> + } + onPress={() => navigation.navigate('Security settings')} + hasSeparator + hasChevron + /> {nostr.nutPub.length > 0 && } - } - onPress={() => navigation.navigate('Display settings')} - hasSeparator - hasChevron - /> }