Skip to content

Commit cca45a7

Browse files
committed
first commit
1 parent 94122b1 commit cca45a7

File tree

65 files changed

+10714
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+10714
-0
lines changed

.gitignore

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
project.xcworkspace
24+
25+
# Android/IntelliJ
26+
#
27+
build/
28+
.idea
29+
.gradle
30+
local.properties
31+
*.iml
32+
*.hprof
33+
34+
# node.js
35+
#
36+
node_modules/
37+
npm-debug.log
38+
yarn-error.log
39+
40+
# BUCK
41+
buck-out/
42+
\.buckd/
43+
*.keystore
44+
45+
# fastlane
46+
#
47+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48+
# screenshots whenever they are needed.
49+
# For more information about the recommended setup visit:
50+
# https://docs.fastlane.tools/best-practices/source-control/
51+
52+
*/fastlane/report.xml
53+
*/fastlane/Preview.html
54+
55+
# Bundle artifact
56+
*.jsbundle
57+
58+
# Test artifact
59+
artifacts/
60+
61+
# coverage
62+
coverage/
63+
64+
# CocoaPods
65+
/ios/Pods/
66+
/ios/Pods-bak/
67+
68+
# local yarn settings
69+
.yarn/
70+
.yarnrc
71+
72+
.env*

App.js

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import React, {
2+
forwardRef,
3+
useRef,
4+
useState,
5+
useEffect,
6+
useImperativeHandle,
7+
} from "react";
8+
import {
9+
SafeAreaView,
10+
View,
11+
Text,
12+
TextInput,
13+
ScrollView,
14+
TouchableOpacity,
15+
Alert,
16+
} from "react-native";
17+
import WebView from "react-native-webview";
18+
19+
const OpenpgpWebView = forwardRef(({ publicKey, message, onDone }, ref) => {
20+
const webViewRef = useRef(null);
21+
22+
useImperativeHandle(ref, () => ({
23+
encrypt: encrypt,
24+
}));
25+
26+
function encrypt(publicKey, message) {
27+
if (webViewRef?.current != null && publicKey != null && message != null) {
28+
const jscode = `(async () => {
29+
const publicKey = '${publicKey}';
30+
const _message = '${message}';
31+
try {
32+
const message = await openpgp.createMessage({
33+
text: _message,
34+
});
35+
const decodedPublicKey = await openpgp.readKey({
36+
armoredKey: atob(publicKey),
37+
});
38+
const encrypted = await openpgp.encrypt({
39+
message,
40+
encryptionKeys: decodedPublicKey,
41+
});
42+
window.ReactNativeWebView.postMessage(btoa(encrypted));
43+
} catch (ex) {
44+
window.ReactNativeWebView.postMessage('error');
45+
alert(ex);
46+
}
47+
})();
48+
true;`;
49+
console.log("injecting script...");
50+
try {
51+
webViewRef.current.injectJavaScript(jscode);
52+
} catch (ex) {
53+
Alert.alert(ex);
54+
}
55+
}
56+
}
57+
58+
return (
59+
<View
60+
pointerEvents="none"
61+
style={{ position: "absolute", zIndex: -100, opacity: 0 }}
62+
>
63+
<WebView
64+
style={{ opacity: 0.99 }}
65+
incognito={true}
66+
ref={(ref) => (webViewRef.current = ref)}
67+
onMessage={(event) => {
68+
onDone && onDone(event.nativeEvent.data);
69+
}}
70+
javaScriptEnabled
71+
startInLoadingState
72+
allowUniversalAccessFromFileURLs={true}
73+
source={{
74+
html: `<html><body><script src="https://unpkg.com/[email protected]/dist/openpgp.min.js"></script><div>hello word</div></body></html>`,
75+
}}
76+
/>
77+
</View>
78+
);
79+
});
80+
81+
const App = () => {
82+
// public key must without spaces, linebreaks or other invalid characters
83+
const publicKey = `LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tClZlcnNpb246IEJDUEcgdjEuNTQKCm1RRU5CRjE1Rm5NQkNBQzhhTStXWEpjcUhSeW5KUWlSTm03eExoN1Q3cmxpZkYvVnpncW01eDdGWnYvNGhXNWoKQTRibktaOFpZT0swNzVlbFljRGpUL2M1bDdMT25YRllBell3eENkc21nbm1HLzMzcXJPV08rUmxBbVREODZSWQowYWFZVWNIRkxUc0ttK29GNkpJMVB4NGd5c0xndlNlSUFCSEJvTlErU2N4dXgzM2VTZUlBMGg3L3dURFgzOU15CnM2YURmbWgvVWpnb0hhRDM5SjhDWUJpNVMyRGVzbjVLK2tjM0NkOUU1SVhGcjVhNG9mWmpWcGJJL092MGxOclkKZXQydDAzVHdEdGJ2VUtYUkxxejg5d1BvdEtGdldlTHZrOXlUZ3Jmd3BsSSs5ZEJCeUFqNHVVQUswNlBUUFJtTgpVWWUxNGQ4eFVOeWJpN1k5bGpSbU80blBIOWh3bTJ4SVZuU0JBQkVCQUFHMEJrTnBjbU5zWllrQkhBUVFBUWtBCkJnVUNYWGtXY3dBS0NSREpQWEtSZEw4TmRDc29CLzlid3pabnEwT0pNKzEvbnREYmhDcnZOaGJoQUhvd3RNclgKMmhqRmVhTy82ZHp2RXJpL25wVml5SzVsVjdMa0lkQi8ybS9sTEx0Nm9KZWdpeXoreXZlZ0pwTGQ0UmRvUC9CSgp0bHBBNjVwbFQyQys4UENoNkJRSCtIMVVZOE92TTFXT0p2VzBjU09xNzdzS3p1RFo4dGQ0OUVnTkpGdzlmb0dnClhYa1I0VHppSzdGTTZXQnlnYmdCNjVrQzZCVHJGNjRtY21xWHFrTHMyUVY5SEtTWmpHOTNxMGJHaUo0RStLbjYKam91dFhlVGc1YWZVL3VwN0g1TWxXM25mU3MyWHRLbFZ5MDdOQ1JYeCtwZUFzUEhpdmFGc3VDK3JUbTIwYVhWTwp5WUhJcmdsKzFNSktaWVNzRVRYMm8xaGkrWXVVeWRJMThuZmMzMGVSYVhyRVF5VzFWZ0w3Cj1CbXVaCi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0=`;
84+
const [message, setMessage] = useState("");
85+
const [btnDisabled, setBtnDisabled] = useState(!message);
86+
const [result, setResult] = useState(null);
87+
const openpgpRef = useRef(null);
88+
89+
useEffect(() => {
90+
setBtnDisabled(!message);
91+
}, [message]);
92+
93+
function handleBtnPress() {
94+
if (openpgpRef?.current) {
95+
setResult(null);
96+
openpgpRef.current.encrypt(publicKey, message);
97+
}
98+
}
99+
100+
function handleEncryptedDone(encryptedMessage) {
101+
setResult(encryptedMessage);
102+
}
103+
104+
return (
105+
<SafeAreaView style={{ flex: 1 }}>
106+
<OpenpgpWebView
107+
ref={(ref) => (openpgpRef.current = ref)}
108+
onDone={handleEncryptedDone}
109+
/>
110+
<ScrollView keyboardShouldPersistTaps="handled">
111+
<Text
112+
style={{
113+
fontSize: 22,
114+
paddingHorizontal: 40,
115+
marginTop: 40,
116+
color: "#222",
117+
}}
118+
>
119+
This is an simple example of running
120+
<Text style={{ color: "blue" }}>{` openpgpjs `}</Text>
121+
in React Native through
122+
<Text style={{ color: "red" }}>{` react-native-webview`}</Text>.
123+
</Text>
124+
125+
<TextInput
126+
placeholder="message to encrypt"
127+
numberOfLines={1}
128+
style={{
129+
marginHorizontal: 40,
130+
height: 40,
131+
fontSize: 20,
132+
color: "#222",
133+
borderBottomColor: "rgba(0,0,0,0.5)",
134+
borderBottomWidth: 0.5,
135+
}}
136+
onChangeText={(value) => setMessage(value)}
137+
value={message}
138+
/>
139+
140+
<TouchableOpacity
141+
onPress={handleBtnPress}
142+
disabled={btnDisabled}
143+
style={{
144+
width: 120,
145+
height: 48,
146+
borderRadius: 24,
147+
backgroundColor: btnDisabled ? "#ddd" : "red",
148+
justifyContent: "center",
149+
alignItems: "center",
150+
marginTop: 20,
151+
alignSelf: "center",
152+
}}
153+
>
154+
<Text style={{ fontSize: 16, color: "#fff" }}>Encrypt</Text>
155+
</TouchableOpacity>
156+
157+
<Text style={{ paddingHorizontal: 40, marginTop: 20 }}>{result}</Text>
158+
</ScrollView>
159+
</SafeAreaView>
160+
);
161+
};
162+
163+
export default App;

Gemfile

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
source 'https://rubygems.org'
2+
3+
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4+
ruby '2.7.4'
5+
6+
gem 'cocoapods', '~> 1.11', '>= 1.11.2'

Gemfile.lock

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
CFPropertyList (3.0.5)
5+
rexml
6+
activesupport (6.1.5.1)
7+
concurrent-ruby (~> 1.0, >= 1.0.2)
8+
i18n (>= 1.6, < 2)
9+
minitest (>= 5.1)
10+
tzinfo (~> 2.0)
11+
zeitwerk (~> 2.3)
12+
addressable (2.8.0)
13+
public_suffix (>= 2.0.2, < 5.0)
14+
algoliasearch (1.27.5)
15+
httpclient (~> 2.8, >= 2.8.3)
16+
json (>= 1.5.1)
17+
atomos (0.1.3)
18+
claide (1.1.0)
19+
cocoapods (1.11.3)
20+
addressable (~> 2.8)
21+
claide (>= 1.0.2, < 2.0)
22+
cocoapods-core (= 1.11.3)
23+
cocoapods-deintegrate (>= 1.0.3, < 2.0)
24+
cocoapods-downloader (>= 1.4.0, < 2.0)
25+
cocoapods-plugins (>= 1.0.0, < 2.0)
26+
cocoapods-search (>= 1.0.0, < 2.0)
27+
cocoapods-trunk (>= 1.4.0, < 2.0)
28+
cocoapods-try (>= 1.1.0, < 2.0)
29+
colored2 (~> 3.1)
30+
escape (~> 0.0.4)
31+
fourflusher (>= 2.3.0, < 3.0)
32+
gh_inspector (~> 1.0)
33+
molinillo (~> 0.8.0)
34+
nap (~> 1.0)
35+
ruby-macho (>= 1.0, < 3.0)
36+
xcodeproj (>= 1.21.0, < 2.0)
37+
cocoapods-core (1.11.3)
38+
activesupport (>= 5.0, < 7)
39+
addressable (~> 2.8)
40+
algoliasearch (~> 1.0)
41+
concurrent-ruby (~> 1.1)
42+
fuzzy_match (~> 2.0.4)
43+
nap (~> 1.0)
44+
netrc (~> 0.11)
45+
public_suffix (~> 4.0)
46+
typhoeus (~> 1.0)
47+
cocoapods-deintegrate (1.0.5)
48+
cocoapods-downloader (1.6.3)
49+
cocoapods-plugins (1.0.0)
50+
nap
51+
cocoapods-search (1.0.1)
52+
cocoapods-trunk (1.6.0)
53+
nap (>= 0.8, < 2.0)
54+
netrc (~> 0.11)
55+
cocoapods-try (1.2.0)
56+
colored2 (3.1.2)
57+
concurrent-ruby (1.1.10)
58+
escape (0.0.4)
59+
ethon (0.15.0)
60+
ffi (>= 1.15.0)
61+
ffi (1.15.5)
62+
fourflusher (2.3.1)
63+
fuzzy_match (2.0.4)
64+
gh_inspector (1.1.3)
65+
httpclient (2.8.3)
66+
i18n (1.10.0)
67+
concurrent-ruby (~> 1.0)
68+
json (2.6.1)
69+
minitest (5.15.0)
70+
molinillo (0.8.0)
71+
nanaimo (0.3.0)
72+
nap (1.1.0)
73+
netrc (0.11.0)
74+
public_suffix (4.0.7)
75+
rexml (3.2.5)
76+
ruby-macho (2.5.1)
77+
typhoeus (1.4.0)
78+
ethon (>= 0.9.0)
79+
tzinfo (2.0.4)
80+
concurrent-ruby (~> 1.0)
81+
xcodeproj (1.21.0)
82+
CFPropertyList (>= 2.3.3, < 4.0)
83+
atomos (~> 0.1.3)
84+
claide (>= 1.0.2, < 2.0)
85+
colored2 (~> 3.1)
86+
nanaimo (~> 0.3.0)
87+
rexml (~> 3.2.4)
88+
zeitwerk (2.5.4)
89+
90+
PLATFORMS
91+
ruby
92+
93+
DEPENDENCIES
94+
cocoapods (~> 1.11, >= 1.11.2)
95+
96+
RUBY VERSION
97+
ruby 2.7.4p191
98+
99+
BUNDLED WITH
100+
2.2.27

__tests__/App-test.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* @format
3+
*/
4+
5+
import 'react-native';
6+
import React from 'react';
7+
import App from '../App';
8+
9+
// Note: test renderer must be required after react-native.
10+
import renderer from 'react-test-renderer';
11+
12+
it('renders correctly', () => {
13+
renderer.create(<App />);
14+
});

0 commit comments

Comments
 (0)