this repo has no description
1import React from 'react'
2import { Text, View, StyleSheet, Button, Alert, TextInput } from 'react-native'
3import {
4 digest,
5 getRandomValues,
6 createJwt,
7 generateJwk,
8 ReactNativeOAuthClient,
9} from 'expo-atproto-auth'
10import { OAuthSession } from '@atproto/oauth-client'
11import { Agent } from '@atproto/api'
12import type { ReactNativeKey } from 'expo-atproto-auth'
13import * as Browser from 'expo-web-browser'
14
15const client = new ReactNativeOAuthClient({
16 clientMetadata: {
17 client_id: 'https://hailey.at/oauth-client-metadata.json',
18 client_name: 'React Native OAuth Client Demo',
19 client_uri: 'https://hailey.at',
20 redirect_uris: ['at.hailey:/auth/callback'],
21 scope: 'atproto transition:generic',
22 token_endpoint_auth_method: 'none',
23 response_types: ['code'],
24 grant_types: ['authorization_code', 'refresh_token'],
25 application_type: 'native',
26 dpop_bound_access_tokens: true,
27 },
28 handleResolver: 'https://bsky.social',
29})
30
31export default function App() {
32 const [values, setValues] = React.useState<Uint8Array>()
33 const [sha, setSha] = React.useState<Uint8Array>()
34 const [jwt, setJwt] = React.useState<string>()
35 const [privateJwk, setPrivateJwk] = React.useState<
36 ReactNativeKey | undefined
37 >()
38 const [session, setSession] = React.useState<OAuthSession>()
39 const [input, setInput] = React.useState<string>()
40 const [agent, setAgent] = React.useState<Agent>()
41
42 return (
43 <View style={styles.container}>
44 <Text>Current Account: {session ? session.did : 'No Account'}</Text>
45 <Text>Values: {values}</Text>
46 <Button
47 title="Generate Random Values"
48 onPress={() => {
49 const newValues = getRandomValues(400)
50 setValues(newValues)
51 }}
52 />
53 <Text>SHA: {sha}</Text>
54 <Button
55 title="SHA from values"
56 onPress={() => {
57 if (!values) {
58 return
59 }
60 let newSha: Uint8Array | undefined
61 try {
62 newSha = digest(values, 'sha256')
63 } catch (e: any) {
64 Alert.alert('Error', e.toString())
65 return
66 }
67 setSha(newSha)
68 }}
69 />
70 <Text>JWT: {jwt}</Text>
71 <Button
72 title="Create JWT"
73 onPress={() => {
74 if (!privateJwk) {
75 return
76 }
77
78 let newJwt: string | undefined
79 try {
80 newJwt = createJwt('', '', privateJwk)
81 } catch (e: any) {
82 Alert.alert('Error', e.toString())
83 return
84 }
85 setJwt(newJwt)
86 }}
87 />
88 <Text>Priv Key: {privateJwk?.kid}</Text>
89 <Button
90 title="Create JWK"
91 onPress={() => {
92 let newJwk: ReactNativeKey | undefined
93 try {
94 newJwk = generateJwk('ES256')
95 } catch (e: any) {
96 Alert.alert('Error', e.toString())
97 return
98 }
99 setPrivateJwk(newJwk)
100 }}
101 />
102
103 <TextInput
104 onChangeText={(t) => setInput(t)}
105 style={{ height: 40, width: 300, borderWidth: 1, padding: 5 }}
106 placeholder="Input"
107 autoCorrect={false}
108 />
109 <Button
110 title="Open Sign In"
111 onPress={async () => {
112 let url: URL
113 try {
114 url = await client.authorize(input ?? '')
115 } catch (e: any) {
116 Alert.alert('Error', e.toString())
117 return
118 }
119 const res = await Browser.openAuthSessionAsync(
120 url.toString(),
121 'at.hailey://auth/callback'
122 )
123
124 if (res.type === 'success') {
125 const resUrl = new URL(res.url)
126 try {
127 const params = new URLSearchParams(resUrl.hash.substring(1))
128 const callbackRes = await client.callback(params)
129 setSession(callbackRes.session)
130
131 const newAgent = new Agent(callbackRes.session)
132 setAgent(newAgent)
133 } catch (e: any) {
134 Alert.alert('Error', e.toString())
135 }
136 } else {
137 Alert.alert('Error', `Received non-success status: ${res.type}`)
138 }
139 }}
140 />
141
142 <Button
143 title="Restore from DID"
144 onPress={async () => {
145 try {
146 const restoreRes = await client.restore(input ?? '')
147 setSession(restoreRes)
148
149 const newAgent = new Agent(restoreRes)
150 setAgent(newAgent)
151 } catch (e: any) {
152 Alert.alert('Error', e.toString())
153 }
154 }}
155 />
156
157 <Button
158 title="Get Profile"
159 onPress={async () => {
160 try {
161 const res = await agent?.getProfile({
162 actor: session?.did ?? '',
163 })
164 Alert.alert(
165 'Profile',
166 `Display Name: ${res?.data.displayName}, Bio: ${res?.data.description}`
167 )
168 } catch (e: any) {
169 Alert.alert('Error', e.toString())
170 }
171 }}
172 disabled={!agent}
173 />
174
175 <Button
176 title="Create Post"
177 onPress={async () => {
178 try {
179 await agent?.post({
180 text: 'Test post from Expo Atproto Auth example',
181 })
182 } catch (e: any) {
183 Alert.alert('Error', e.toString())
184 }
185 }}
186 disabled={!agent}
187 />
188 </View>
189 )
190}
191
192const styles = StyleSheet.create({
193 container: {
194 flex: 1,
195 alignItems: 'center',
196 justifyContent: 'center',
197 },
198})