diff --git a/package-lock.json b/package-lock.json index 2b1b8a9..aadb354 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "react-dom": "^16.14.0", "react-dropzone": "^11.3.2", "react-ga": "^3.3.0", + "react-google-recaptcha-v3": "^1.10.0", "react-notifications-component": "^3.1.0", "react-scripts": "^4.0.3", "reactstrap": "^8.9.0", @@ -18676,6 +18677,18 @@ "react": "^15.6.2 || ^16.0 || ^17" } }, + "node_modules/react-google-recaptcha-v3": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz", + "integrity": "sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==", + "dependencies": { + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "react": "^17.0 || ^18.0", + "react-dom": "^17.0 || ^18.0" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -38638,6 +38651,14 @@ "resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.3.0.tgz", "integrity": "sha512-o8RScHj6Lb8cwy3GMrVH6NJvL+y0zpJvKtc0+wmH7Bt23rszJmnqEQxRbyrqUzk9DTJIHoP42bfO5rswC9SWBQ==" }, + "react-google-recaptcha-v3": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz", + "integrity": "sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==", + "requires": { + "hoist-non-react-statics": "^3.3.2" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index 7487c87..39172fd 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "react-dom": "^16.14.0", "react-dropzone": "^11.3.2", "react-ga": "^3.3.0", + "react-google-recaptcha-v3": "^1.10.0", "react-notifications-component": "^3.1.0", "react-scripts": "^4.0.3", "reactstrap": "^8.9.0", diff --git a/src/ChecksumResolver.js b/src/ChecksumResolver.js index 58691cf..41c076b 100644 --- a/src/ChecksumResolver.js +++ b/src/ChecksumResolver.js @@ -1,313 +1,325 @@ -import React, { useState } from 'react'; -import { withStyles } from "@material-ui/core/styles"; -import Avatar from '@material-ui/core/Avatar'; -import Button from '@material-ui/core/Button'; -import CssBaseline from '@material-ui/core/CssBaseline'; -import TextField from '@material-ui/core/TextField'; +import React, { useState } from 'react' +import { withStyles } from '@material-ui/core/styles' +import Avatar from '@material-ui/core/Avatar' +import Button from '@material-ui/core/Button' +import CssBaseline from '@material-ui/core/CssBaseline' +import TextField from '@material-ui/core/TextField' -import Link from '@material-ui/core/Link'; -import Box from '@material-ui/core/Box'; -import LockOutlinedIcon from '@material-ui/icons/LockOutlined'; -import Typography from '@material-ui/core/Typography'; -import Container from '@material-ui/core/Container'; +import Link from '@material-ui/core/Link' +import Box from '@material-ui/core/Box' +import LockOutlinedIcon from '@material-ui/icons/LockOutlined' +import Typography from '@material-ui/core/Typography' +import Container from '@material-ui/core/Container' import Dropzone from 'react-dropzone' -import IconButton from '@material-ui/core/IconButton'; -import FileCopyOutlined from '@material-ui/icons/FileCopyOutlined'; -import PublishOutlined from '@material-ui/icons/PublishOutlined'; - -// import { useFilePicker } from 'react-sage' -// import { FilePicker } from 'react-file-picker' +import IconButton from '@material-ui/core/IconButton' +import FileCopyOutlined from '@material-ui/icons/FileCopyOutlined' +import PublishOutlined from '@material-ui/icons/PublishOutlined' import { FilePicker } from '../src/Components' - -import { CopyToClipboard } from 'react-copy-to-clipboard'; +import { CopyToClipboard } from 'react-copy-to-clipboard' import ControlledAccordions from './ControlledAccordions' -import OnlineConverter from "./OnlineConverter"; +import OnlineConverter from './OnlineConverter' import 'react-notifications-component/dist/theme.css' import ReactNotification from 'react-notifications-component' -import { store } from 'react-notifications-component'; -// import 'animate.css/animate.compat.css' +import { store } from 'react-notifications-component' import AaxHashAlgorithm from './Utils/AaxHashAlgorithm' +import { + GoogleReCaptchaProvider, + withGoogleReCaptcha, +} from 'react-google-recaptcha-v3' -const useStyles = theme => ({ - paper: { - marginTop: theme.spacing(8), - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }, - avatar: { - margin: theme.spacing(1), - backgroundColor: theme.palette.secondary.main, - }, - form: { - width: '100%', // Fix IE 11 issue. - marginTop: theme.spacing(1), - }, +const useStyles = (theme) => ({ + paper: { + marginTop: theme.spacing(8), + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + }, + avatar: { + margin: theme.spacing(1), + backgroundColor: theme.palette.secondary.main, + }, + form: { + width: '100%', // Fix IE 11 issue. + marginTop: theme.spacing(1), + }, - //Accordeon - heading: { - fontSize: theme.typography.pxToRem(15), - flexBasis: '33.33%', - flexShrink: 0, - }, - secondaryHeading: { - fontSize: theme.typography.pxToRem(15), - color: theme.palette.text.secondary, - }, -}); + //Accordeon + heading: { + fontSize: theme.typography.pxToRem(15), + flexBasis: '33.33%', + flexShrink: 0, + }, + secondaryHeading: { + fontSize: theme.typography.pxToRem(15), + color: theme.palette.text.secondary, + }, +}) class ChecksumResolver extends React.Component { - constructor(props) { - super(props); - this.state = { - checksum: "", - fileName: "input.aax" - } + constructor(props) { + super(props) + this.state = { + checksum: '', + fileName: 'input.aax', } + } - DarkerDisabledTextField = withStyles({ - root: { - marginRight: 8, - "& .MuiInputBase-root.Mui-disabled": { - color: "rgba(0, 0, 0, 0.6)" - } - } - })(TextField); + DarkerDisabledTextField = withStyles({ + root: { + marginRight: 8, + '& .MuiInputBase-root.Mui-disabled': { + color: 'rgba(0, 0, 0, 0.6)', + }, + }, + })(TextField) - Copyright = (function () { - return ( - - {'Copyright © '} - - audible-tools - {' '} - {new Date().getFullYear()} - {'. V 0.3'} - - ); + Copyright = function () { + return ( + + {'Copyright © '} + + audible-tools + {' '} + {new Date().getFullYear()} + {'. V 0.3'} + + ) + } + + setChecksum = (value) => { + if (value.length > 40) { + return + } + this.setState({ checksum: value }) + } + + isChecksumValid = () => { + const { checksum } = this.state + const regex = RegExp('[a-f0-9]{40}') + const testResults = regex.test(checksum) + + return testResults + } + + isInputInvalid = () => { + const { checksum } = this.state + if (!checksum || checksum === '') { + return false + } + return !this.isChecksumValid() + } + + addNotification = function (text, success = true) { + store.addNotification({ + message: text, + type: success ? 'success' : 'danger', + // type: "danger", + insert: 'bottom-left', + container: 'top-full', + animationIn: ['animate__animated', 'animate__fadeIn'], + animationOut: ['animate__animated', 'animate__fadeOut'], + dismiss: { + duration: 3000, + onScreen: false, + }, }) + } - setChecksum = (value) => { - if (value.length > 40) { - return; + requestActivationBytes = async () => { + const { checksum } = this.state + + const { executeRecaptcha } = (this.props) + .googleReCaptchaProps; + + if (!executeRecaptcha) { + console.log('Recaptcha has not been loaded'); + + return; + } + + const token = await executeRecaptcha('homepage'); + console.log(`XToken: ${token}`); + try { + let request = await fetch( + 'https://api.audible-converter.ml/api/v2/activation/' + checksum, + ) + let result = await request.json() + const { success, activationBytes } = result + + if (success !== true) { + this.setState({ activationBytes: 'UNKNOWN' }) + this.addNotification( + 'An error occured while resolving the activation bytes, please check your inputs', + false, + ) + return + } + + if (success === true) { + const calculatedChecksum = await AaxHashAlgorithm.CalculateChecksum( + activationBytes, + ) + if (calculatedChecksum == checksum) { + this.setState({ activationBytes: activationBytes }) + this.addNotification('Successfully resolved the activation bytes') + return } - this.setState({ checksum: value }) + + this.setState({ activationBytes: 'API ERROR' }) + this.addNotification( + 'An unexpected error occured while resolving the activation bytes, please try again', + false, + ) + } + } catch (error) { + this.setState({ activationBytes: error }) + this.addNotification( + 'An error occured while resolving the activation bytes, please check your inputs', + false, + ) } + } - isChecksumValid = () => { - const { checksum } = this.state; - const regex = RegExp('[a-f0-9]{40}'); - const testResults = regex.test(checksum); + buf2hex(buffer) { + // buffer is an ArrayBuffer + return Array.prototype.map + .call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2)) + .join('') + } - return testResults; - } + acceptFiles = async (files) => { + const file = files[0] + await this.acceptFile(file) + } - isInputInvalid = () => { - const { checksum } = this.state; - if (!checksum || checksum === '') { - return false; - } - return !this.isChecksumValid(); - }; + acceptFile = async (file) => { + // if (!file.name.toLowerCase().endsWith(".aax")) { + // alert('FileType not supported!'); + // return; + // } - addNotification = function (text, success = true) { - store.addNotification({ - message: text, - type: success ? "success" : "danger", - // type: "danger", - insert: "bottom-left", - container: "top-full", - animationIn: ["animate__animated", "animate__fadeIn"], - animationOut: ["animate__animated", "animate__fadeOut"], - dismiss: { - duration: 3000, - onScreen: false - } - }); - } + this.setState({ fileName: file.name, file: file }) + const slic = file.slice(653, 653 + 20) + const results = this.buf2hex(await slic.arrayBuffer()) + this.setChecksum(results) + this.requestActivationBytes() + } - requestActivationBytes = async () => { - const { checksum } = this.state; - try { - let request = await fetch("https://api.audible-converter.ml/api/v2/activation/" + checksum); - let result = await request.json(); - const { success, activationBytes } = result; + render() { + const { classes } = this.props + const { checksum, activationBytes, fileName, file } = this.state - if (success !== true) { - this.setState({ activationBytes: 'UNKNOWN' }); - this.addNotification("An error occured while resolving the activation bytes, please check your inputs", false); - return; - } + return ( + + +
+ + + + + AAX Checksum Resolver + - if (success === true) { - const calculatedChecksum = await AaxHashAlgorithm.CalculateChecksum(activationBytes); - if (calculatedChecksum == checksum) { - this.setState({ activationBytes: activationBytes }); - this.addNotification("Successfully resolved the activation bytes"); - return; - } - - this.setState({ activationBytes: "API ERROR" }); - this.addNotification("An unexpected error occured while resolving the activation bytes, please try again", false); +
+ { + console.log(acceptedFiles) + this.acceptFiles(acceptedFiles) + }} + > + {({ getRootProps, getInputProps }) => ( +
+
+ + this.setChecksum(x.target.value)} + onError={() => {}} + value={checksum} + InputProps={{ + readOnly: false, + endAdornment: ( + {}} + > + + + + + ), + }} + /> +
+
+ )} +
- } - } catch (error) { - this.setState({ activationBytes: error }); - this.addNotification("An error occured while resolving the activation bytes, please check your inputs", false); - } - } + - buf2hex(buffer) { // buffer is an ArrayBuffer - return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join(''); - } - - acceptFiles = async files => { - const file = files[0]; - await this.acceptFile(file); - } - - acceptFile = async file => { - // if (!file.name.toLowerCase().endsWith(".aax")) { - // alert('FileType not supported!'); - // return; - // } - - this.setState({ fileName: file.name, file:file }); - const slic = file.slice(653, 653 + 20); - const results = this.buf2hex(await slic.arrayBuffer()); - this.setChecksum(results) - this.requestActivationBytes(); - - } - - render() { - const { classes } = this.props; - const { checksum, activationBytes, fileName, file } = this.state; - - // const { files, onClick, errors, HiddenFileInput } = useFilePicker({ - // maxFileSize: 1000000, - // maxImageWidth: 1000, - // imageQuality: 0.92, - // resizeImage: true - // }); - - return ( - - - -
- - - - - AAX Checksum Resolver - - - - { - console.log(acceptedFiles); - this.acceptFiles(acceptedFiles); - }}> - {({ getRootProps, getInputProps }) => ( -
-
- - this.setChecksum(x.target.value)} - onError={()=>{}} - value={checksum} - InputProps={{ - readOnly: false, - endAdornment: ( - - - - - - ) - }} - - /> -
-
- )} -
- - - - - - - - - ) - }} - - /> - - -
- - - - - - - -
- ); - } + + + + + + ), + }} + /> + +
+ + + + +
+ ) + } } -export default withStyles(useStyles)(ChecksumResolver); +export default withGoogleReCaptcha(withStyles(useStyles)(ChecksumResolver)) diff --git a/src/index.js b/src/index.js index ea3e2d7..a8b3892 100644 --- a/src/index.js +++ b/src/index.js @@ -1,37 +1,47 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import * as serviceWorker from './serviceWorker'; -import ChecksumResolver from './ChecksumResolver'; +import React from 'react' +import ReactDOM from 'react-dom' +import './index.css' +import * as serviceWorker from './serviceWorker' +import ChecksumResolver from './ChecksumResolver' import ReactNotification from 'react-notifications-component' -import ForkMeOnGithub from 'fork-me-on-github'; +import ForkMeOnGithub from 'fork-me-on-github' +import ReactGA from 'react-ga' +import { + GoogleReCaptchaProvider, + GoogleReCaptcha, +} from 'react-google-recaptcha-v3' -import ReactGA from 'react-ga'; +fetch('https://api.audible-converter.ml/api/v2/WakeUpNeo').then((data) => + console.log('Woke up, im ready to serve :D'), +) -fetch("https://api.audible-converter.ml/api/v2/WakeUpNeo") - .then(data => console.log("Woke up, im ready to serve :D")) - -ReactGA.initialize('UA-174657678-1'); -ReactGA.pageview(window.location.pathname + window.location.search); +ReactGA.initialize('UA-174657678-1') +ReactGA.pageview(window.location.pathname + window.location.search) ReactDOM.render(
-
- - -
- - + + {/* { + console.log(`Token: ${a}`); + }} + /> */} +
+ +
+ + +
, - document.getElementById('root') -); + document.getElementById('root'), +) // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA -serviceWorker.unregister(); +serviceWorker.unregister()