PluginProbe
CryptX / 4.2.0
CryptX v4.2.0
4.2.0 4.1.1 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9 2.0 2.1 2.2 2.3 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 All 92 releases
cryptx / src / components / Preview.js

Preview.js in CryptX 4.2.0, at src/components/Preview.js

154 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Shows what the current settings actually produce.
3 *
4 * The markup is rendered on the server through the same three filters the
5 * front end uses, so this is the real result rather than a reconstruction.
6 * Both halves matter: what a visitor sees, and what is left in the source for
7 * a spam bot to find. The second half is the whole point of the plugin and was
8 * previously invisible.
9 */
10
11 import { useEffect, useRef, useState } from '@wordpress/element';
12 import apiFetch from '@wordpress/api-fetch';
13 import { __ } from '@wordpress/i18n';
14 import { Card, CardBody, CardHeader, Spinner } from '@wordpress/components';
15
16 /**
17 * Waits until the user stops changing things before asking the server.
18 */
19 const DEBOUNCE_MS = 400;
20
21 /**
22 * What the server found in the markup, and how worried to be about it.
23 *
24 * The middle case is the one worth having: an address written as HTML entities
25 * is invisible to a search of the raw source and perfectly visible to anything
26 * that decodes entities first. Reporting that as "protected" would be a
27 * comforting lie, and this box exists to prevent exactly that.
28 */
29 const VERDICTS = {
30 none: {
31 tone: 'good',
32 text: () =>
33 __( 'No readable address is left in the source.', 'cryptx' ),
34 },
35 encoded: {
36 tone: 'warning',
37 text: () =>
38 __(
39 'The address is in the source as HTML entities. That defeats a simple scanner, but any spam bot that decodes entities will read it.',
40 'cryptx'
41 ),
42 },
43 plain: {
44 tone: 'bad',
45 text: () =>
46 __(
47 'An address is still plainly readable in the source with these settings.',
48 'cryptx'
49 ),
50 },
51 };
52
53 export default function Preview( { values } ) {
54 const [ preview, setPreview ] = useState( null );
55 const [ isLoading, setLoading ] = useState( false );
56 const [ error, setError ] = useState( null );
57 const requestId = useRef( 0 );
58
59 useEffect( () => {
60 const handle = setTimeout( () => {
61 const id = ++requestId.current;
62 setLoading( true );
63
64 apiFetch( {
65 path: '/cryptx/v1/preview',
66 method: 'POST',
67 data: { values },
68 } )
69 .then( ( response ) => {
70 // A slower earlier request must not overwrite a newer
71 // answer, or the preview shows the wrong settings.
72 if ( id === requestId.current ) {
73 setPreview( response );
74 setError( null );
75 }
76 } )
77 .catch( ( caught ) => {
78 if ( id === requestId.current ) {
79 setError(
80 caught?.message ||
81 __(
82 'The preview could not be generated.',
83 'cryptx'
84 )
85 );
86 }
87 } )
88 .finally( () => {
89 if ( id === requestId.current ) {
90 setLoading( false );
91 }
92 } );
93 }, DEBOUNCE_MS );
94
95 return () => clearTimeout( handle );
96 }, [ values ] );
97
98 return (
99 <Card className="cryptx-preview">
100 <CardHeader>
101 <h2 className="cryptx-section__title">
102 { __( 'Preview', 'cryptx' ) }
103 </h2>
104 { isLoading && <Spinner /> }
105 </CardHeader>
106 <CardBody>
107 { error && <p className="cryptx-preview__error">{ error }</p> }
108
109 { preview && (
110 <>
111 <div className="cryptx-preview__block">
112 <h3>{ __( 'What visitors see', 'cryptx' ) }</h3>
113 { /* The markup comes from our own filters, applied
114 to a fixed sample address. */ }
115 <div
116 className="cryptx-preview__rendered"
117 dangerouslySetInnerHTML={ {
118 __html: preview.markup,
119 } }
120 />
121 </div>
122
123 <div className="cryptx-preview__block">
124 <h3>
125 { __(
126 'What a spam bot finds in the source',
127 'cryptx'
128 ) }
129 </h3>
130 <pre className="cryptx-preview__source">
131 <code>{ preview.markup }</code>
132 </pre>
133 </div>
134
135 <p
136 className={
137 'cryptx-preview__verdict is-' +
138 (
139 VERDICTS[ preview.exposure ] ||
140 VERDICTS.none
141 ).tone
142 }
143 >
144 { (
145 VERDICTS[ preview.exposure ] || VERDICTS.none
146 ).text() }
147 </p>
148 </>
149 ) }
150 </CardBody>
151 </Card>
152 );
153 }
154