forked from acsant/react-native-recaptcha
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
105 lines (94 loc) · 3.57 KB
/
index.js
File metadata and controls
105 lines (94 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import React, { Component } from "react";
import MessageWebView from "./MessageWebView";
import PropTypes from "prop-types";
import { Platform, Linking } from "react-native";
import { invisibleRecaptcha, normalRecaptcha } from "./get-captcha";
const RECAPTCHA_SUB_STR = "https://www.google.com/recaptcha/api2/anchor?";
const RECAPTCHA_SUB_STR_FRAME = "https://www.google.com/recaptcha/api2/bframe";
export const type = Object.freeze({ "invisible": 1, "normal": 2 });
export default class ReCaptcha extends Component {
static propTypes = {
onMessage: PropTypes.func,
containerStyle: PropTypes.any,
siteKey: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
action: PropTypes.string,
onReady: PropTypes.func,
onExecute: PropTypes.func,
customWebRecaptcha: PropTypes.func,
reCaptchaType: PropTypes.oneOf(Object.values(type)).isRequired
};
static defaultProps = {
onReady: () => {
},
onExecute: () => {
},
action: "",
containerStyle: {
width: "100%",
height: "100%",
zIndex: -1,
position: "relative",
marginBottom: 20
},
reCaptchaType: type.invisible
};
getSource = () => {
const { action, config, onReady, recaptchaType, siteKey, url: baseUrl } = this.props;
let html = normalRecaptcha(config);
if (recaptchaType === type.invisible) {
html = invisibleRecaptcha(siteKey, action, onReady);
}
return { html, baseUrl };
};
onMessage = (message) => {
this.props.onExecute(message);
};
onNavigationStateChange = ({ canGoBack, loading, url: eventUrl }) => {
if (Platform.OS === "android") {
const { url } = this.props;
if (url !== eventUrl && eventUrl.indexOf(RECAPTCHA_SUB_STR) === -1 && !!canGoBack && !loading) {
Linking.canOpenURL(eventUrl).then(supported => {
if (!supported) {
console.log(`Can't handle url: ${url}`);
} else {
return Linking.openUrl(eventUrl);
}
});
}
if (!!canGoBack) {
this.webview.getWebViewHandle().goBack();
}
}
};
onShouldStartLoadWithRequest = ({ url: eventUrl }) => {
const { config, url } = this.props;
const hasCaptchaAnchor = eventUrl.indexOf(RECAPTCHA_SUB_STR) !== -1;
const hasCaptchaFrame = eventUrl.indexOf(RECAPTCHA_SUB_STR_FRAME) !== -1;
const hasFirebaseAuthDomain = (!!config && eventUrl.indexOf(config.authDomain) !== -1);
if (eventUrl === url || hasCaptchaAnchor || hasFirebaseAuthDomain || hasCaptchaFrame) {
return true;
} else {
Linking.canOpenURL(eventUrl).then(supported => {
if (!supported) {
console.log(`Can't handle url: ${url}`);
} else {
return Linking.openURL(eventUrl);
}
});
return false;
}
};
render() {
return <MessageWebView
ref={(ref) => this.webview = ref}
scalesPageToFit={true}
mixedContentMode={"always"}
containerStyle={this.props.containerStyle}
onMessage={this.onMessage}
source={this.getSource()}
onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest}
onNavigationStateChange={this.onNavigationStateChange}
/>;
}
}