import React from 'react'; // @ts-ignore const QrReader = React.lazy(() => import('@uides/react-qr-reader')); export interface QrCodeScannerProps { style?: React.CSSProperties; dataType?: 'url' | 'text'; legacyMode?: boolean; validate?: (...args) => boolean; onScan: (...args) => void; onError: (err: any, data: any) => void; onLoad?: (...args) => void; onImageLoad?: (...args) => void; delay?: number; facingMode?: 'user' | 'environment'; showViewFinder?: boolean; className?: string; children?: React.ReactNode; } /** * QRCodeScanner assumes that the data provided inside the QR code image, * are a HTTP link, thus it uses the `encodeURI` function to escape * all scanned data that will be forwarded to the `onScan` function * * When a QR code is scanned, before we run the `onScan` callback function, * we do the following: * * 1. Run a validator function provided in the props of QrCodeScanner component * that receives the *raw* scanned data and returns a boolean type. (eg. check * if it's a gov.gr subdomain, or that it matches the current domain) * 2. If the validator returns `true`, then construct a URL object from the data provided * and check if the protocol is `https` and the `origin` is the same as the origin of this page * 2. Automatically fallback to the `onError` callback function, if the validation or url check fail * 3. Finally, run `onScan` callback function with the scanned data encoded as a URI. * */ export const QrCodeScanner: React.FC = ({ children, validate, onScan, onError, dataType = 'url', legacyMode = false, ...props }) => { if (dataType === 'text') { console.warn( `Security Warning! The \`text\` dataType could be used to inject XSS code to your application database or user DOM. In order to be safe, you can: 1. Use a sanitizer function inside the \`onScan\` callback function that makes sure the data is not posing a threat to your app 2. Contact @digigov-ui for any further details and feature requests. 3. Read more about xss https://owasp.org/www-community/attacks/xss/ ` ); } const handleOnScan = (data) => { if (data) { if (dataType === 'url') { try { new URL(data); } catch { return onError( new Error( '@digigov-ui XSS Validation failed: qr code payload should follow the pattern `https://dilosi.services.gov.gr/show/:reference_code`' ), data ); } } // run a validator function provided by the application code if (validate && !validate(data)) { return onError( new Error('Custom QR Code payload validation failed'), data ); } // proceed with application defined callback function onScan(data); } }; return ( <> {children} ); }; export default QrCodeScanner;