Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Commit

Permalink
Switch to a much better QR code scanning library
Browse files Browse the repository at this point in the history
@nop33 let's double check that the new CSP rules are safe. They should be.
  • Loading branch information
mvaivre committed Nov 3, 2023
1 parent e16b2c5 commit 8402dd8
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 55 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Official Alephium Wallet" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; worker-src 'self' blob:" />

This comment has been minimized.

Copy link
@nop33

nop33 Nov 6, 2023

Member

@mvaivre from what I read online, using blob: is not safe.

Other people seem to be complaining as well:

<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
Expand Down
44 changes: 32 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
"dependencies": {
"electron-context-menu": "^3.1.2",
"electron-is-dev": "^2.0.0",
"electron-updater": "^5.3.0",
"html5-qrcode": "^2.3.8"
"electron-updater": "^5.3.0"
},
"devDependencies": {
"@alephium/sdk": "0.7.5",
Expand Down Expand Up @@ -91,6 +90,7 @@
"nanoid": "^4.0.0",
"posthog-js": "^1.52.0",
"prettier": "^2.7.1",
"qr-scanner": "^1.4.2",
"qrloop": "^1.4.1",
"react": "^18.2.0",
"react-apexcharts": "^1.4.0",
Expand Down
51 changes: 15 additions & 36 deletions src/components/QRScanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
import { Html5Qrcode } from 'html5-qrcode'
import Scanner from 'qr-scanner'
import React, { useEffect, useRef, useState } from 'react'
import styled from 'styled-components'

import Select, { SelectOption } from '@/components/Inputs/Select'

interface QRScannerProps {
onScanSuccess: (decodedText: string, decodedResult: any) => void
onScanFailure: (error: any) => void
onScanSuccess: (result: Scanner.ScanResult) => void
}

const QRScanner: React.FC<QRScannerProps> = ({ onScanSuccess, onScanFailure = () => null }) => {
const scannerId = 'qrScannerElement'
const QRScanner: React.FC<QRScannerProps> = ({ onScanSuccess }) => {
const videoRef = useRef(null)
const qrCodeScannerRef = useRef<Scanner | null>(null)
const [deviceOptions, setDeviceOptions] = useState<SelectOption<string>[]>([])
const [selectedDeviceId, setSelectedDeviceId] = useState<string>('')
const html5QrCodeRef = useRef<Html5Qrcode | null>(null)
const previousSelectedDeviceId = useRef<string | null>(null)

useEffect(() => {
Expand All @@ -46,46 +45,26 @@ const QRScanner: React.FC<QRScannerProps> = ({ onScanSuccess, onScanFailure = ()
}, [])

useEffect(() => {
if (!selectedDeviceId) return
if (!selectedDeviceId || !videoRef.current) return

html5QrCodeRef.current = new Html5Qrcode(scannerId)
qrCodeScannerRef.current = new Scanner(videoRef.current, onScanSuccess, { highlightScanRegion: true })

const html5QrCode = html5QrCodeRef.current
const qrCodeScanner = qrCodeScannerRef.current

previousSelectedDeviceId.current = selectedDeviceId

const startScanner = () => {
html5QrCode
.start(
selectedDeviceId,
{
fps: 10,
qrbox: { width: 300, height: 300 }
},
onScanSuccess,
onScanFailure
)
.catch((error) => {
onScanFailure(error)
})
}

if (!html5QrCode.isScanning) {
startScanner()
}
qrCodeScanner.setCamera(selectedDeviceId)
qrCodeScanner.setInversionMode('both')
qrCodeScanner.start()

return () => {
if (html5QrCode.isScanning) {
html5QrCode.stop().catch((error) => {
console.error('Error stopping the QR scanner', error)
})
}
qrCodeScanner.stop()
}
}, [selectedDeviceId, onScanSuccess, onScanFailure])
}, [selectedDeviceId, onScanSuccess])

return (
<ScannerContainer>
<Scanner id={scannerId} />
<ScannerVideo ref={videoRef} />
<Select
id="cameraSelect"
label="Camera"
Expand All @@ -105,7 +84,7 @@ const ScannerContainer = styled.div`
flex-direction: column;
`

const Scanner = styled.div`
const ScannerVideo = styled.video`
flex: 1;
min-height: 400px;
background-color: ${({ theme }) => theme.bg.secondary};
Expand Down
11 changes: 7 additions & 4 deletions src/modals/SendModals/AddressInputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { isAddressValid } from '@alephium/sdk'
import { motion } from 'framer-motion'
import { AlbumIcon, ContactIcon, ScanLineIcon } from 'lucide-react'
import Scanner from 'qr-scanner'
import { useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled, { useTheme } from 'styled-components'
Expand Down Expand Up @@ -101,10 +103,11 @@ const AddressInputs = ({
moveFocusOnPreviousModal()
}

const handleQRCodeScan = (addressHash: string) => {
console.log('SUCCESSSS')
const handleQRCodeScan = (scanResult: Scanner.ScanResult) => {
if (!isAddressValid(scanResult.data)) return // TODO: SHOW SNACKBAR

if (onToAddressChange) {
onToAddressChange(addressHash)
onToAddressChange(scanResult.data)
setIsScanningModalOpen(false)
}
}
Expand Down Expand Up @@ -209,7 +212,7 @@ const AddressInputs = ({
)}
{isScanningModalOpen && onToAddressChange && (
<CenteredModal onClose={() => setIsScanningModalOpen(false)} title={t('QR code scanner')}>
<QRScanner onScanSuccess={handleQRCodeScan} onScanFailure={() => console.log('FAILL')} />
<QRScanner onScanSuccess={handleQRCodeScan} />
</CenteredModal>
)}
</ModalPortal>
Expand Down

0 comments on commit 8402dd8

Please sign in to comment.