UNPKG

react-native-nitro-totp

Version:

React Native module for TOTP (Time-based One-Time Password) and HOTP (HMAC-based One-Time Password) authentication.

90 lines (89 loc) 3.24 kB
import React, { useEffect } from 'react'; import { StyleSheet, View, Text, TextInput, Button } from 'react-native'; import { defaultOptions, formatOTP, formatSecretKey, isSecretKeyValid, NitroSecret, NitroTotp, parseSecretKey, SupportedAlgorithm, } from 'react-native-nitro-totp'; import { useTimer } from 'react-timer-hook'; import dayjs from 'dayjs'; export default function App() { const [secretKey, setSecretKey] = React.useState(''); const [otp, setOTP] = React.useState(''); const [isValid, setIsValid] = React.useState(false); const [authURL, setAuthURL] = React.useState(''); const { seconds, restart } = useTimer({ autoStart: true, expiryTimestamp: dayjs().add(30, 'seconds').toDate(), onExpire: () => onGenerateNewOTP(), }); const onGenerateNewOTP = () => { if (!secretKey) { return; } const secret = parseSecretKey(secretKey); const generatedOTP = NitroTotp.generate(secret); const valid = NitroTotp.validate(secret, generatedOTP); setOTP(formatOTP(generatedOTP)); setIsValid(valid); restart(dayjs().add(30, 'seconds').toDate()); }; const onPressGenerateSecretKey = () => { const secret = NitroSecret.generate(); setSecretKey(formatSecretKey(secret)); onGenerateNewOTP(); }; const onChangeSecretKey = (text) => { if (isSecretKeyValid(text)) { setSecretKey(text); } }; useEffect(() => { if (!secretKey) { return; } const secret = parseSecretKey(secretKey); const generatedAuthURL = NitroTotp.generateAuthURL({ secret, issuer: 'NitroTotp', label: 'NitroTotp', period: defaultOptions.period, digits: defaultOptions.digits, issuerInLabel: false, algorithm: SupportedAlgorithm.SHA1, }); setAuthURL(generatedAuthURL); }, [secretKey]); useEffect(() => { // generate secret key const secret = 'JRAQ465DVY4J4AP6CIFQ'; setSecretKey(formatSecretKey(secret)); onGenerateNewOTP(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return (React.createElement(View, { style: styles.container }, React.createElement(TextInput, { placeholder: "ABCD-ABCD-ABCD-ABCD-ABCD", value: secretKey, onChangeText: onChangeSecretKey, style: styles.input }), React.createElement(Text, null, "OTP: ", otp), React.createElement(Text, null, "Expire in: ", seconds), React.createElement(Text, null, "Is Valid: ", `${isValid}`), React.createElement(Text, { selectable: true }, authURL), React.createElement(Button, { title: "Generate Secret Key", onPress: onPressGenerateSecretKey }))); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', padding: 20, }, input: { height: 50, width: '100%', borderColor: 'gray', borderWidth: 1, padding: 10, }, });