diff --git a/lib/facts/links.js b/lib/facts/links.js index 551306eb7..8437ee383 100644 --- a/lib/facts/links.js +++ b/lib/facts/links.js @@ -1,63 +1,63 @@ // @flow /* Invite Links */ function inviteLinkURL(secret: string): string { return `https://comm.app/invite/${secret}`; } /* QR Code */ -function qrCodeLinkURL(aes256Param: string, ed25519Param: string): string { +function qrCodeLinkURL(aes256Param: Uint8Array, ed25519Param: string): string { const keys = { aes256: aes256Param, ed25519: ed25519Param, }; const keysString = encodeURIComponent(JSON.stringify(keys)); return `comm://qr-code/${keysString}`; } /* Deep Link Utils */ function parseInstallReferrerFromInviteLinkURL(referrer: string): ?string { const referrerRegex = /utm_source=(invite\/(\S+))$/; const match = referrerRegex.exec(referrer); return match?.[1]; } type ParsedInviteLinkData = { +type: 'invite-link', +data: { +secret: string }, }; type ParsedQRCodeData = { +type: 'qr-code', +data: { +keys: string }, }; export type ParsedDeepLinkData = ParsedInviteLinkData | ParsedQRCodeData | null; function parseDataFromDeepLink(url: string): ParsedDeepLinkData { const inviteLinkSecretRegex = /invite\/(\S+)$/; const qrCodeKeysRegex = /qr-code\/(\S+)$/; const inviteLinkSecretMatch = inviteLinkSecretRegex.exec(url); if (inviteLinkSecretMatch) { return { type: 'invite-link', data: { secret: inviteLinkSecretMatch[1] }, }; } const qrCodeKeysMatch = qrCodeKeysRegex.exec(url); if (qrCodeKeysMatch) { return { type: 'qr-code', data: { keys: qrCodeKeysMatch[1] }, }; } return null; } export { inviteLinkURL, qrCodeLinkURL, parseInstallReferrerFromInviteLinkURL, parseDataFromDeepLink, }; diff --git a/native/qr-code/qr-code-screen.react.js b/native/qr-code/qr-code-screen.react.js index 64a4ba37a..e4d7a1ca4 100644 --- a/native/qr-code/qr-code-screen.react.js +++ b/native/qr-code/qr-code-screen.react.js @@ -1,90 +1,107 @@ // @flow import * as React from 'react'; import { View, Text } from 'react-native'; import QRCode from 'react-native-qrcode-svg'; import { qrCodeLinkURL } from 'lib/facts/links.js'; import type { QRCodeSignInNavigationProp } from './qr-code-sign-in-navigator.react.js'; import type { NavigationRoute } from '../navigation/route-names.js'; import { useStyles } from '../themes/colors.js'; +import * as AES from '../utils/aes-crypto-module.js'; type QRCodeScreenProps = { +navigation: QRCodeSignInNavigationProp<'QRCodeScreen'>, +route: NavigationRoute<'QRCodeScreen'>, }; -const qrCodeValue = qrCodeLinkURL('random_aes256_key', 'device_ed25519_key'); +const defaultDeviceEd25519Key = 'device_ed25519_key'; // eslint-disable-next-line no-unused-vars function QRCodeScreen(props: QRCodeScreenProps): React.Node { + const [qrCodeValue, setQrCodeValue] = React.useState(); + + const generateQRCode = React.useCallback(async () => { + try { + const aes256Key: Uint8Array = await AES.generateKey(); + const url = qrCodeLinkURL(aes256Key, defaultDeviceEd25519Key); + setQrCodeValue(url); + } catch (err) { + console.error('Failed to generate QR Code:', err); + } + }, []); + + React.useEffect(() => { + generateQRCode(); + }, [generateQRCode]); + const styles = useStyles(unboundStyles); return ( Log in to Comm Open the Comm app on your phone and scan the QR code below How to find the scanner: Go to Profile Select Linked devices Click Add on the top right ); } const unboundStyles = { container: { flex: 1, alignItems: 'center', marginTop: 125, }, heading: { fontSize: 24, color: 'panelForegroundLabel', paddingBottom: 12, }, headingSubtext: { fontSize: 12, color: 'panelForegroundLabel', paddingBottom: 30, }, instructionsBox: { alignItems: 'center', width: 300, marginTop: 40, padding: 15, borderColor: 'panelForegroundLabel', borderWidth: 2, borderRadius: 8, }, instructionsTitle: { fontSize: 12, color: 'panelForegroundLabel', paddingBottom: 15, }, instructionsStep: { fontSize: 12, padding: 1, color: 'panelForegroundLabel', }, instructionsBold: { fontWeight: 'bold', }, }; export default QRCodeScreen; diff --git a/web/account/qr-code-login.react.js b/web/account/qr-code-login.react.js index 720c38b6c..9b5366ecb 100644 --- a/web/account/qr-code-login.react.js +++ b/web/account/qr-code-login.react.js @@ -1,36 +1,53 @@ // @flow import { QRCodeSVG } from 'qrcode.react'; import * as React from 'react'; import { qrCodeLinkURL } from 'lib/facts/links.js'; import css from './qr-code-login.css'; +import { generateKey } from '../media/aes-crypto-utils.js'; -const qrCodeValue = qrCodeLinkURL('random_aes256_key', 'device_ed25519_key'); +const defaultDeviceEd25519Key = 'device_ed25519_key'; function QrCodeLogin(): React.Node { + const [qrCodeValue, setQrCodeValue] = React.useState(); + + const generateQRCode = React.useCallback(async () => { + try { + const aes256Key: Uint8Array = await generateKey(); + const url = qrCodeLinkURL(aes256Key, defaultDeviceEd25519Key); + setQrCodeValue(url); + } catch (err) { + console.error('Failed to generate QR Code:', err); + } + }, []); + + React.useEffect(() => { + generateQRCode(); + }, [generateQRCode]); + return (
Log in to Comm
Open the Comm app on your phone and scan the QR code below
How to find the scanner:
Go to Profile
Select Linked devices
Click Add on the top right
); } export default QrCodeLogin;