@chem-po/firebase-native 0.0.51 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/adapter/auth.js +12 -5
- package/lib/commonjs/adapter/auth.js.map +1 -1
- package/lib/commonjs/adapter/db.js.map +1 -1
- package/lib/commonjs/adapter/index.js.map +1 -1
- package/lib/commonjs/adapter/storage.js.map +1 -1
- package/lib/commonjs/auth/functions.js.map +1 -1
- package/lib/commonjs/auth/index.js.map +1 -1
- package/lib/commonjs/components/AuthenticatorVerify.js +4 -2
- package/lib/commonjs/components/AuthenticatorVerify.js.map +1 -1
- package/lib/commonjs/components/FirebaseSignIn.js.map +1 -1
- package/lib/commonjs/components/PhoneVerify.js.map +1 -1
- package/lib/commonjs/components/TwoFactorAuthModal.js +3 -1
- package/lib/commonjs/components/TwoFactorAuthModal.js.map +1 -1
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/FirebaseContext.js.map +1 -1
- package/lib/commonjs/contexts/index.js.map +1 -1
- package/lib/commonjs/db/index.js.map +1 -1
- package/lib/commonjs/db/utils.js.map +1 -1
- package/lib/commonjs/hooks/backend.js.map +1 -1
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useAuthenticatorVerify.js +19 -13
- package/lib/commonjs/hooks/useAuthenticatorVerify.js.map +1 -1
- package/lib/commonjs/hooks/usePhoneVerify.js +1 -1
- package/lib/commonjs/hooks/usePhoneVerify.js.map +1 -1
- package/lib/commonjs/icons/Apple.js.map +1 -1
- package/lib/commonjs/icons/Google.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/storage/index.js.map +1 -1
- package/lib/commonjs/storage/utils.js.map +1 -1
- package/lib/commonjs/types/adapter.js.map +1 -1
- package/lib/commonjs/types/auth.js.map +1 -1
- package/lib/commonjs/types/db.js.map +1 -1
- package/lib/commonjs/types/functions.js.map +1 -1
- package/lib/commonjs/types/index.js.map +1 -1
- package/lib/commonjs/types/storage.js.map +1 -1
- package/lib/commonjs/utils/validation.js.map +1 -1
- package/lib/module/adapter/auth.js +13 -6
- package/lib/module/adapter/auth.js.map +1 -1
- package/lib/module/adapter/db.js.map +1 -1
- package/lib/module/adapter/index.js.map +1 -1
- package/lib/module/adapter/storage.js.map +1 -1
- package/lib/module/auth/functions.js.map +1 -1
- package/lib/module/auth/index.js.map +1 -1
- package/lib/module/components/AuthenticatorVerify.js +4 -2
- package/lib/module/components/AuthenticatorVerify.js.map +1 -1
- package/lib/module/components/FirebaseSignIn.js.map +1 -1
- package/lib/module/components/PhoneVerify.js.map +1 -1
- package/lib/module/components/TwoFactorAuthModal.js +3 -1
- package/lib/module/components/TwoFactorAuthModal.js.map +1 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/FirebaseContext.js.map +1 -1
- package/lib/module/contexts/index.js.map +1 -1
- package/lib/module/db/index.js.map +1 -1
- package/lib/module/db/utils.js.map +1 -1
- package/lib/module/hooks/backend.js.map +1 -1
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useAuthenticatorVerify.js +20 -14
- package/lib/module/hooks/useAuthenticatorVerify.js.map +1 -1
- package/lib/module/hooks/usePhoneVerify.js +1 -1
- package/lib/module/hooks/usePhoneVerify.js.map +1 -1
- package/lib/module/icons/Apple.js.map +1 -1
- package/lib/module/icons/Google.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/storage/index.js.map +1 -1
- package/lib/module/storage/utils.js.map +1 -1
- package/lib/module/types/adapter.js.map +1 -1
- package/lib/module/types/auth.js.map +1 -1
- package/lib/module/types/db.js.map +1 -1
- package/lib/module/types/functions.js.map +1 -1
- package/lib/module/types/index.js.map +1 -1
- package/lib/module/types/storage.js.map +1 -1
- package/lib/module/utils/validation.js.map +1 -1
- package/lib/typescript/adapter/auth.d.ts.map +1 -1
- package/lib/typescript/components/AuthenticatorVerify.d.ts +4 -1
- package/lib/typescript/components/AuthenticatorVerify.d.ts.map +1 -1
- package/lib/typescript/hooks/useAuthenticatorVerify.d.ts +2 -1
- package/lib/typescript/hooks/useAuthenticatorVerify.d.ts.map +1 -1
- package/package.json +6 -21
- package/src/adapter/auth.ts +0 -556
- package/src/adapter/db.ts +0 -146
- package/src/adapter/index.ts +0 -32
- package/src/adapter/storage.ts +0 -58
- package/src/auth/functions.ts +0 -7
- package/src/auth/index.ts +0 -1
- package/src/components/AuthenticatorVerify.tsx +0 -75
- package/src/components/FirebaseSignIn.tsx +0 -234
- package/src/components/PhoneVerify.tsx +0 -115
- package/src/components/TwoFactorAuthModal.tsx +0 -198
- package/src/components/index.ts +0 -2
- package/src/contexts/FirebaseContext.tsx +0 -50
- package/src/contexts/index.ts +0 -1
- package/src/db/index.ts +0 -1
- package/src/db/utils.ts +0 -142
- package/src/hooks/backend.ts +0 -4
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useAuthenticatorVerify.ts +0 -45
- package/src/hooks/usePhoneVerify.ts +0 -87
- package/src/icons/Apple.tsx +0 -12
- package/src/icons/Google.tsx +0 -24
- package/src/index.ts +0 -9
- package/src/storage/index.ts +0 -1
- package/src/storage/utils.ts +0 -29
- package/src/types/adapter.ts +0 -13
- package/src/types/auth.ts +0 -13
- package/src/types/db.ts +0 -10
- package/src/types/functions.ts +0 -3
- package/src/types/index.ts +0 -29
- package/src/types/storage.ts +0 -3
- package/src/utils/validation.ts +0 -92
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { EnrollmentFactor, PhoneEnrollmentFactor } from '@chem-po/core'
|
|
2
|
-
import { useAuth, useBackgroundColor, useBorderColor, useIconColor } from '@chem-po/react'
|
|
3
|
-
import { Txt, useFont } from '@chem-po/react-native'
|
|
4
|
-
import { Ionicons } from '@expo/vector-icons'
|
|
5
|
-
import React, { useState } from 'react'
|
|
6
|
-
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native'
|
|
7
|
-
import { Modal, Portal } from 'react-native-paper'
|
|
8
|
-
import { useBackend } from '../hooks/backend'
|
|
9
|
-
import { AuthenticatorVerify } from './AuthenticatorVerify'
|
|
10
|
-
import { PhoneVerify } from './PhoneVerify'
|
|
11
|
-
|
|
12
|
-
const FactorView = ({
|
|
13
|
-
factor,
|
|
14
|
-
buttonBackgroundColor,
|
|
15
|
-
iconColor,
|
|
16
|
-
borderColor,
|
|
17
|
-
onPress,
|
|
18
|
-
}: {
|
|
19
|
-
factor: EnrollmentFactor
|
|
20
|
-
buttonBackgroundColor: string
|
|
21
|
-
iconColor: string
|
|
22
|
-
borderColor: string
|
|
23
|
-
onPress: () => void
|
|
24
|
-
}) => {
|
|
25
|
-
return (
|
|
26
|
-
<TouchableOpacity
|
|
27
|
-
style={[
|
|
28
|
-
styles.factorButton,
|
|
29
|
-
{
|
|
30
|
-
backgroundColor: buttonBackgroundColor,
|
|
31
|
-
borderColor,
|
|
32
|
-
},
|
|
33
|
-
]}
|
|
34
|
-
onPress={onPress}
|
|
35
|
-
>
|
|
36
|
-
<View style={styles.factorContent}>
|
|
37
|
-
<Ionicons
|
|
38
|
-
name={factor.type === 'phone' ? 'phone-portrait' : 'qr-code'}
|
|
39
|
-
size={20}
|
|
40
|
-
color={iconColor}
|
|
41
|
-
/>
|
|
42
|
-
<Txt style={styles.factorHeaderText}>
|
|
43
|
-
{factor.type === 'phone' ? `Phone: ${factor.phoneNumber}` : 'Authenticator App'}
|
|
44
|
-
</Txt>
|
|
45
|
-
{factor.displayName ? (
|
|
46
|
-
<Txt style={styles.factorDetailsText}>{factor.displayName}</Txt>
|
|
47
|
-
) : null}
|
|
48
|
-
</View>
|
|
49
|
-
</TouchableOpacity>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const TwoFactorSelect = ({
|
|
54
|
-
factors,
|
|
55
|
-
onSelect,
|
|
56
|
-
}: {
|
|
57
|
-
factors: EnrollmentFactor[]
|
|
58
|
-
onSelect: (factor: EnrollmentFactor) => void
|
|
59
|
-
}) => {
|
|
60
|
-
const buttonBackgroundColor = useBackgroundColor(100)
|
|
61
|
-
const borderColor = useBorderColor()
|
|
62
|
-
const iconColor = useIconColor()
|
|
63
|
-
const textFont = useFont('body', 'md')
|
|
64
|
-
return (
|
|
65
|
-
<View style={styles.selectContainer}>
|
|
66
|
-
<Txt style={[styles.selectTitle, textFont]}>Select an option to verify with:</Txt>
|
|
67
|
-
<View style={styles.factorsList}>
|
|
68
|
-
{factors.map((factor) => (
|
|
69
|
-
<FactorView
|
|
70
|
-
key={`${factor.type}-${factor.enrollmentTime}`}
|
|
71
|
-
factor={factor}
|
|
72
|
-
buttonBackgroundColor={buttonBackgroundColor}
|
|
73
|
-
onPress={() => onSelect(factor)}
|
|
74
|
-
iconColor={iconColor}
|
|
75
|
-
borderColor={borderColor}
|
|
76
|
-
/>
|
|
77
|
-
))}
|
|
78
|
-
</View>
|
|
79
|
-
</View>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const TwoFactorVerify = ({ factorInfo }: { factorInfo: EnrollmentFactor }) =>
|
|
84
|
-
factorInfo.type === 'phone' ? (
|
|
85
|
-
<PhoneVerify factor={factorInfo as PhoneEnrollmentFactor} />
|
|
86
|
-
) : (
|
|
87
|
-
<AuthenticatorVerify />
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
const TwoFactorContent = () => {
|
|
91
|
-
const [selectedEnrollmentFactor, setSelectedEnrollmentFactor] =
|
|
92
|
-
useState<EnrollmentFactor | null>(null)
|
|
93
|
-
const enrolledFactors = useAuth((s) => s.enrollmentFactors)
|
|
94
|
-
|
|
95
|
-
if (selectedEnrollmentFactor)
|
|
96
|
-
return <TwoFactorVerify factorInfo={selectedEnrollmentFactor} />
|
|
97
|
-
if (!enrolledFactors) return null
|
|
98
|
-
if (enrolledFactors.enrollmentFactors.length === 0) return null
|
|
99
|
-
// if (enrolledFactors.enrollmentFactors.length === 1) return <TwoFactorVerify factorInfo={enrolledFactors.enrollmentFactors[0]} />
|
|
100
|
-
return (
|
|
101
|
-
<TwoFactorSelect
|
|
102
|
-
factors={enrolledFactors.enrollmentFactors}
|
|
103
|
-
onSelect={setSelectedEnrollmentFactor}
|
|
104
|
-
/>
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export const TwoFactorAuthModal = () => {
|
|
109
|
-
const { auth } = useBackend()
|
|
110
|
-
const backgroundColor = useBackgroundColor(150)
|
|
111
|
-
const twoFactorVerification = useAuth(s => s.multiFactorVerification)
|
|
112
|
-
const enrollmentFactors = useAuth(s => s.enrollmentFactors)
|
|
113
|
-
if (!twoFactorVerification && !enrollmentFactors) return null
|
|
114
|
-
|
|
115
|
-
return (
|
|
116
|
-
<Portal>
|
|
117
|
-
<Modal
|
|
118
|
-
visible={true}
|
|
119
|
-
onDismiss={() => {
|
|
120
|
-
auth.logout()
|
|
121
|
-
}}
|
|
122
|
-
style={styles.modal}
|
|
123
|
-
>
|
|
124
|
-
<View style={[styles.modalContent, { backgroundColor }]}>
|
|
125
|
-
<ScrollView contentContainerStyle={styles.scrollContent}>
|
|
126
|
-
<TwoFactorContent />
|
|
127
|
-
</ScrollView>
|
|
128
|
-
</View>
|
|
129
|
-
</Modal>
|
|
130
|
-
</Portal>
|
|
131
|
-
)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const testFactor: EnrollmentFactor = {
|
|
135
|
-
uid: 'test',
|
|
136
|
-
type: 'phone',
|
|
137
|
-
phoneNumber: '1234567890',
|
|
138
|
-
displayName: 'Test Phone',
|
|
139
|
-
enrollmentTime: '2021-01-01',
|
|
140
|
-
}
|
|
141
|
-
export const TestTwoFactorVerifyModal = () => {
|
|
142
|
-
const backgroundColor = useBackgroundColor(150)
|
|
143
|
-
return (
|
|
144
|
-
<Portal>
|
|
145
|
-
<Modal visible={true} onDismiss={() => {}} style={styles.modal}>
|
|
146
|
-
<View style={[styles.modalContent, { backgroundColor }]}>
|
|
147
|
-
<ScrollView contentContainerStyle={styles.scrollContent}>
|
|
148
|
-
<TwoFactorVerify factorInfo={testFactor} />
|
|
149
|
-
</ScrollView>
|
|
150
|
-
</View>
|
|
151
|
-
</Modal>
|
|
152
|
-
</Portal>
|
|
153
|
-
)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const styles = StyleSheet.create({
|
|
157
|
-
modal: {
|
|
158
|
-
margin: 0,
|
|
159
|
-
},
|
|
160
|
-
modalContent: {
|
|
161
|
-
margin: 20,
|
|
162
|
-
borderRadius: 12,
|
|
163
|
-
position: 'relative',
|
|
164
|
-
maxHeight: '80%',
|
|
165
|
-
},
|
|
166
|
-
scrollContent: {
|
|
167
|
-
padding: 16,
|
|
168
|
-
},
|
|
169
|
-
selectContainer: {
|
|
170
|
-
width: '100%',
|
|
171
|
-
},
|
|
172
|
-
selectTitle: {
|
|
173
|
-
fontSize: 16,
|
|
174
|
-
marginBottom: 8,
|
|
175
|
-
paddingHorizontal: 4,
|
|
176
|
-
},
|
|
177
|
-
factorsList: {
|
|
178
|
-
gap: 8,
|
|
179
|
-
},
|
|
180
|
-
factorContent: {
|
|
181
|
-
flexDirection: 'row',
|
|
182
|
-
alignItems: 'center',
|
|
183
|
-
gap: 8,
|
|
184
|
-
},
|
|
185
|
-
factorButton: {
|
|
186
|
-
padding: 16,
|
|
187
|
-
borderRadius: 8,
|
|
188
|
-
borderWidth: 1,
|
|
189
|
-
},
|
|
190
|
-
factorHeaderText: {
|
|
191
|
-
fontSize: 16,
|
|
192
|
-
fontWeight: 'bold',
|
|
193
|
-
opacity: 0.8,
|
|
194
|
-
},
|
|
195
|
-
factorDetailsText: {
|
|
196
|
-
fontSize: 16,
|
|
197
|
-
},
|
|
198
|
-
})
|
package/src/components/index.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext, useMemo } from 'react'
|
|
2
|
-
import type {
|
|
3
|
-
FirebaseApp,
|
|
4
|
-
FirebaseAuth,
|
|
5
|
-
FirebaseContextValue,
|
|
6
|
-
FirebaseFirestore,
|
|
7
|
-
FirebaseFunctions,
|
|
8
|
-
FirebaseStorage,
|
|
9
|
-
} from '../types'
|
|
10
|
-
|
|
11
|
-
const FirebaseContext = createContext<FirebaseContextValue | null>(null)
|
|
12
|
-
|
|
13
|
-
export interface FirebaseProviderProps {
|
|
14
|
-
children: React.ReactNode
|
|
15
|
-
app: FirebaseApp
|
|
16
|
-
firestore: FirebaseFirestore | null
|
|
17
|
-
storage: FirebaseStorage | null
|
|
18
|
-
functions: FirebaseFunctions | null
|
|
19
|
-
auth: FirebaseAuth | null
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function FirebaseProvider({
|
|
23
|
-
children,
|
|
24
|
-
app,
|
|
25
|
-
firestore,
|
|
26
|
-
storage,
|
|
27
|
-
functions,
|
|
28
|
-
auth,
|
|
29
|
-
}: FirebaseProviderProps) {
|
|
30
|
-
const value: FirebaseContextValue = useMemo(
|
|
31
|
-
() => ({
|
|
32
|
-
app,
|
|
33
|
-
auth,
|
|
34
|
-
firestore,
|
|
35
|
-
storage,
|
|
36
|
-
functions,
|
|
37
|
-
}),
|
|
38
|
-
[app, auth, firestore, storage, functions],
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
return <FirebaseContext.Provider value={value}>{children}</FirebaseContext.Provider>
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function useFirebase() {
|
|
45
|
-
const context = useContext(FirebaseContext)
|
|
46
|
-
if (!context) {
|
|
47
|
-
throw new Error('useFirebase must be used within a FirebaseProvider')
|
|
48
|
-
}
|
|
49
|
-
return context
|
|
50
|
-
}
|
package/src/contexts/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './FirebaseContext'
|
package/src/db/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './utils'
|
package/src/db/utils.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { AnyObject, BaseQuery, isInequalityOperator, stringTransforms } from '@chem-po/core'
|
|
2
|
-
import {
|
|
3
|
-
collection,
|
|
4
|
-
collectionGroup,
|
|
5
|
-
limit as limitTo,
|
|
6
|
-
orderBy,
|
|
7
|
-
query,
|
|
8
|
-
startAfter,
|
|
9
|
-
where,
|
|
10
|
-
} from '@react-native-firebase/firestore'
|
|
11
|
-
import { Firestore, FirestoreBaseQuery, FirestoreCursor, FirestoreQuery } from '../types/db'
|
|
12
|
-
|
|
13
|
-
export const toFirestoreQuery = <T extends AnyObject>(
|
|
14
|
-
db: Firestore,
|
|
15
|
-
baseQuery: FirestoreBaseQuery<T>,
|
|
16
|
-
): FirestoreQuery<T> => {
|
|
17
|
-
const {
|
|
18
|
-
collection: collectionPath,
|
|
19
|
-
filters,
|
|
20
|
-
limit,
|
|
21
|
-
search,
|
|
22
|
-
sort,
|
|
23
|
-
isCollectionGroup,
|
|
24
|
-
cursor: startAfterDoc,
|
|
25
|
-
} = baseQuery
|
|
26
|
-
|
|
27
|
-
let q: FirestoreQuery<T> = (
|
|
28
|
-
isCollectionGroup ? collectionGroup(db, collectionPath) : collection(db, collectionPath)
|
|
29
|
-
) as FirestoreQuery<T>
|
|
30
|
-
|
|
31
|
-
if (filters) {
|
|
32
|
-
filters.forEach(({ key, operator, value }) => {
|
|
33
|
-
q = query(q, where(key, operator, value))
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (sort) {
|
|
38
|
-
q = query(q, orderBy(sort.key, sort.direction))
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (startAfterDoc) {
|
|
42
|
-
q = query(q, startAfter(startAfterDoc))
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (search?.paths?.length && search.query) {
|
|
46
|
-
const trimmed = (search.query || '').trim()
|
|
47
|
-
if (trimmed) {
|
|
48
|
-
q = query(
|
|
49
|
-
q,
|
|
50
|
-
where(search.paths[0].prop, '>=', trimmed),
|
|
51
|
-
where(search.paths[0].prop, '<=', `${trimmed}\uf8ff`),
|
|
52
|
-
)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return limit ? query(q, limitTo(limit)) : q
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const toCursorQuery = <T extends AnyObject>(
|
|
60
|
-
db: Firestore,
|
|
61
|
-
baseQuery: FirestoreBaseQuery<T>,
|
|
62
|
-
cursor: FirestoreCursor | null,
|
|
63
|
-
): FirestoreQuery<T> => {
|
|
64
|
-
const { collection: collectionPath, filters, sort, isCollectionGroup, search, limit } = baseQuery
|
|
65
|
-
|
|
66
|
-
let q: FirestoreQuery<T> = (
|
|
67
|
-
isCollectionGroup ? collectionGroup(db, collectionPath) : collection(db, collectionPath)
|
|
68
|
-
) as FirestoreQuery<T>
|
|
69
|
-
|
|
70
|
-
if (filters) {
|
|
71
|
-
filters.forEach(({ key, operator, value }) => {
|
|
72
|
-
q = query(q, where(key, operator, value))
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (sort) {
|
|
77
|
-
q = query(q, orderBy(sort.key, sort.direction))
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (search?.paths?.length && search.query) {
|
|
81
|
-
const trimmed = (search.query || '').trim()
|
|
82
|
-
if (trimmed) {
|
|
83
|
-
q = query(
|
|
84
|
-
q,
|
|
85
|
-
where(search.paths[0].prop, '>=', trimmed),
|
|
86
|
-
where(search.paths[0].prop, '<=', `${trimmed}\uf8ff`),
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (cursor) {
|
|
92
|
-
q = query(q, startAfter(cursor))
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return limit ? query(q, limitTo(limit), limitTo(1)) : q
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export const toFirestoreQueries = <T extends AnyObject>(
|
|
99
|
-
db: Firestore,
|
|
100
|
-
baseQuery: BaseQuery<T>,
|
|
101
|
-
cursors: Array<FirestoreCursor | null> | null,
|
|
102
|
-
): Array<FirestoreQuery<T>> => {
|
|
103
|
-
const { collection: collectionPath, filters, limit, search, sort, isCollectionGroup } = baseQuery
|
|
104
|
-
|
|
105
|
-
let q: FirestoreQuery<T> = (
|
|
106
|
-
isCollectionGroup ? collectionGroup(db, collectionPath) : collection(db, collectionPath)
|
|
107
|
-
) as FirestoreQuery<T>
|
|
108
|
-
if (filters) {
|
|
109
|
-
let filterSortKey: string | null = null
|
|
110
|
-
filters.forEach(({ key, operator, value }) => {
|
|
111
|
-
q = query(q, where(key, operator, value))
|
|
112
|
-
if (!filterSortKey && isInequalityOperator(operator) && sort?.key !== key) {
|
|
113
|
-
filterSortKey = key
|
|
114
|
-
q = query(q, orderBy(key, 'asc'))
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (sort) {
|
|
120
|
-
q = query(q, orderBy(sort.key, sort.direction))
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (cursors?.length) {
|
|
124
|
-
q = query(q, startAfter(cursors[cursors.length - 1]))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const queries =
|
|
128
|
-
search?.paths?.length && search.query
|
|
129
|
-
? search.paths.map(path => {
|
|
130
|
-
let trimmed = (search.query ?? '').trim()
|
|
131
|
-
if (!trimmed) return q
|
|
132
|
-
if (path.transform) trimmed = stringTransforms[path.transform](trimmed)
|
|
133
|
-
return query(
|
|
134
|
-
q,
|
|
135
|
-
where(path.prop, '>=', trimmed),
|
|
136
|
-
where(path.prop, '<=', `${trimmed}\uf8ff`),
|
|
137
|
-
)
|
|
138
|
-
})
|
|
139
|
-
: [q]
|
|
140
|
-
|
|
141
|
-
return queries.map(q0 => (limit ? query(q0, limitTo(limit)) : q0))
|
|
142
|
-
}
|
package/src/hooks/backend.ts
DELETED
package/src/hooks/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './backend'
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { useAuth } from '@chem-po/react'
|
|
2
|
-
import { FirebaseAuthTypes } from '@react-native-firebase/auth'
|
|
3
|
-
import { useCallback, useState } from 'react'
|
|
4
|
-
import { useBackend } from './backend'
|
|
5
|
-
|
|
6
|
-
export const useAuthenticatorVerify = () => {
|
|
7
|
-
const [code, setCode] = useState('')
|
|
8
|
-
const [verifying, setVerifying] = useState(false)
|
|
9
|
-
const [error, setError] = useState('')
|
|
10
|
-
const twoFactorVerification = useAuth(s => s.multiFactorVerification)
|
|
11
|
-
const { auth } = useBackend()
|
|
12
|
-
// const { showSuccess, showError, showInfo } = useToast()
|
|
13
|
-
|
|
14
|
-
const handleVerify = useCallback(async () => {
|
|
15
|
-
const verify = auth.verifyMultiFactor
|
|
16
|
-
if (!verify) {
|
|
17
|
-
setError('Error - Two factor verification is not supported')
|
|
18
|
-
return
|
|
19
|
-
}
|
|
20
|
-
if (!code) return
|
|
21
|
-
if (!twoFactorVerification) {
|
|
22
|
-
setError('Error - No session found')
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
const resolver = twoFactorVerification.resolver as FirebaseAuthTypes.MultiFactorResolver
|
|
26
|
-
if (!resolver) {
|
|
27
|
-
setError('Error - No session found')
|
|
28
|
-
return
|
|
29
|
-
}
|
|
30
|
-
setVerifying(true)
|
|
31
|
-
try {
|
|
32
|
-
await verify(twoFactorVerification, code)
|
|
33
|
-
} catch (error) {
|
|
34
|
-
setError(error instanceof Error ? error.message : 'An unknown error occurred')
|
|
35
|
-
}
|
|
36
|
-
}, [code, auth, twoFactorVerification])
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
code,
|
|
40
|
-
setCode,
|
|
41
|
-
verifying,
|
|
42
|
-
error,
|
|
43
|
-
handleVerify,
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { PhoneEnrollmentFactor } from '@chem-po/core'
|
|
2
|
-
import { useAuth, useToast } from '@chem-po/react'
|
|
3
|
-
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
4
|
-
import { useBackend } from './backend'
|
|
5
|
-
|
|
6
|
-
export const usePhoneVerify = (factor: PhoneEnrollmentFactor, automaticallySendSmsCode: boolean) => {
|
|
7
|
-
const [code, setCode] = useState('')
|
|
8
|
-
const [sendingCode, setSendingCode] = useState(false)
|
|
9
|
-
const [verifying, setVerifying] = useState(false)
|
|
10
|
-
const [error, setError] = useState('')
|
|
11
|
-
|
|
12
|
-
const { auth } = useBackend()
|
|
13
|
-
const {multiFactorVerification: twoFactorVerification, enrollmentFactors} = useAuth()
|
|
14
|
-
|
|
15
|
-
// const [{ automaticallySendSmsCode }, setCookie] = useCookies(['automaticallySendSmsCode'])
|
|
16
|
-
|
|
17
|
-
const initSendCode = useRef(!!automaticallySendSmsCode)
|
|
18
|
-
|
|
19
|
-
const { showSuccess, showError } = useToast()
|
|
20
|
-
|
|
21
|
-
const sendCode = useCallback(async () => {
|
|
22
|
-
if (!enrollmentFactors) {
|
|
23
|
-
showError('Error - No session found')
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
setSendingCode(true)
|
|
27
|
-
return auth.sendMultiFactorCode(factor, enrollmentFactors.multiFactorResolver)
|
|
28
|
-
.then(() => {
|
|
29
|
-
setSendingCode(false)
|
|
30
|
-
})
|
|
31
|
-
.catch((e) => {
|
|
32
|
-
setSendingCode(false)
|
|
33
|
-
setError(e.message || 'An error occurred')
|
|
34
|
-
})
|
|
35
|
-
}, [auth, factor, twoFactorVerification, showError])
|
|
36
|
-
|
|
37
|
-
const initSendCodeFunc = useRef(sendCode)
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (initSendCode.current) {
|
|
40
|
-
initSendCodeFunc.current()
|
|
41
|
-
}
|
|
42
|
-
}, [])
|
|
43
|
-
|
|
44
|
-
const handleVerify = useCallback(async () => {
|
|
45
|
-
setVerifying(true)
|
|
46
|
-
setError('')
|
|
47
|
-
if (!twoFactorVerification) {
|
|
48
|
-
showError('Error - No session found')
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
const resolver = twoFactorVerification.resolver
|
|
52
|
-
if (!resolver) {
|
|
53
|
-
showError('Error - No resolver found')
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
const verificationId = twoFactorVerification.verificationId
|
|
57
|
-
if (!verificationId) {
|
|
58
|
-
showError('Error - No verification ID found')
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
const verify = auth.verifyMultiFactor
|
|
62
|
-
if (!verify) {
|
|
63
|
-
showError('Error - Two factor verification is not supported')
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
return verify(twoFactorVerification, code)
|
|
67
|
-
.then(() => {
|
|
68
|
-
setVerifying(false)
|
|
69
|
-
setCode('')
|
|
70
|
-
showSuccess('Verification successful')
|
|
71
|
-
})
|
|
72
|
-
.catch(e => {
|
|
73
|
-
setVerifying(false)
|
|
74
|
-
setError(e.message || 'An error occurred')
|
|
75
|
-
})
|
|
76
|
-
}, [code, auth, showSuccess, showError])
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
code,
|
|
80
|
-
setCode,
|
|
81
|
-
sendCode,
|
|
82
|
-
verifying,
|
|
83
|
-
sendingCode,
|
|
84
|
-
error,
|
|
85
|
-
handleVerify,
|
|
86
|
-
}
|
|
87
|
-
}
|
package/src/icons/Apple.tsx
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import Svg, { Path, SvgProps } from 'react-native-svg'
|
|
3
|
-
|
|
4
|
-
const SvgApple = (props: SvgProps) => {
|
|
5
|
-
return (
|
|
6
|
-
<Svg width={24} height={24} viewBox="0 0 814 1000" {...props}>
|
|
7
|
-
<Path d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z" />
|
|
8
|
-
</Svg>
|
|
9
|
-
)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default SvgApple
|
package/src/icons/Google.tsx
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import Svg, { Path, SvgProps } from 'react-native-svg'
|
|
3
|
-
|
|
4
|
-
const SvgGoogle = (props: SvgProps) => (
|
|
5
|
-
<Svg width={24} height={24} viewBox="0 0 24 24" {...props}>
|
|
6
|
-
<Path
|
|
7
|
-
fill="#4285F4"
|
|
8
|
-
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
|
9
|
-
/>
|
|
10
|
-
<Path
|
|
11
|
-
fill="#34A853"
|
|
12
|
-
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
|
13
|
-
/>
|
|
14
|
-
<Path
|
|
15
|
-
fill="#FBBC05"
|
|
16
|
-
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
|
17
|
-
/>
|
|
18
|
-
<Path
|
|
19
|
-
fill="#EA4335"
|
|
20
|
-
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
|
21
|
-
/>
|
|
22
|
-
</Svg>
|
|
23
|
-
)
|
|
24
|
-
export default SvgGoogle
|
package/src/index.ts
DELETED
package/src/storage/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './utils'
|
package/src/storage/utils.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { FileValue, LocalFileValue, OnUploadProgress } from '@chem-po/core'
|
|
2
|
-
import { FirebaseStorageTypes, ref, uploadString } from '@react-native-firebase/storage'
|
|
3
|
-
|
|
4
|
-
export const uploadFileValue = async (
|
|
5
|
-
storage: FirebaseStorageTypes.Module,
|
|
6
|
-
path: string,
|
|
7
|
-
file: LocalFileValue | FileValue | null | undefined,
|
|
8
|
-
onUploadProgress: OnUploadProgress,
|
|
9
|
-
): Promise<FileValue | null> => {
|
|
10
|
-
if (!file) return null
|
|
11
|
-
const { dataUrl, type, filename } = file as LocalFileValue
|
|
12
|
-
if (!dataUrl) return file
|
|
13
|
-
|
|
14
|
-
const storageRef = ref(storage, path)
|
|
15
|
-
const uploadTask = uploadString(storageRef, dataUrl, 'data_url')
|
|
16
|
-
|
|
17
|
-
uploadTask.on('state_changed', snapshot => {
|
|
18
|
-
const percent = snapshot.bytesTransferred / snapshot.totalBytes
|
|
19
|
-
onUploadProgress({ total: snapshot.totalBytes, loaded: snapshot.bytesTransferred, percent })
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
uploadTask
|
|
24
|
-
.then(() => {
|
|
25
|
-
resolve({ storagePath: path, type, filename })
|
|
26
|
-
})
|
|
27
|
-
.catch(reject)
|
|
28
|
-
})
|
|
29
|
-
}
|
package/src/types/adapter.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { BackendAdapterInterface, BaseAuthProvider } from '@chem-po/core'
|
|
2
|
-
import { FirebaseStorageTypes } from '@react-native-firebase/storage'
|
|
3
|
-
import { EmailPasswordLogin, User } from './auth'
|
|
4
|
-
import { FirestoreCursor } from './db'
|
|
5
|
-
|
|
6
|
-
export type FirebaseBackendAdapter<AuthProvider extends BaseAuthProvider> = BackendAdapterInterface<
|
|
7
|
-
AuthProvider,
|
|
8
|
-
User,
|
|
9
|
-
EmailPasswordLogin,
|
|
10
|
-
FirestoreCursor,
|
|
11
|
-
Blob,
|
|
12
|
-
FirebaseStorageTypes.FullMetadata
|
|
13
|
-
>
|
package/src/types/auth.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { BaseUserRole } from '@chem-po/core'
|
|
2
|
-
import { getAuth } from '@react-native-firebase/auth'
|
|
3
|
-
|
|
4
|
-
export type Auth = ReturnType<typeof getAuth>
|
|
5
|
-
export interface User {
|
|
6
|
-
uid: string
|
|
7
|
-
role: BaseUserRole
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface EmailPasswordLogin {
|
|
11
|
-
email: string
|
|
12
|
-
password: string
|
|
13
|
-
}
|
package/src/types/db.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// import { AnyObject } from '@chem-po/core'
|
|
2
|
-
import { AnyObject, BaseQuery, OnItemsData } from '@chem-po/core'
|
|
3
|
-
import { FirebaseFirestoreTypes } from '@react-native-firebase/firestore'
|
|
4
|
-
|
|
5
|
-
export type Firestore = FirebaseFirestoreTypes.Module
|
|
6
|
-
export type FirestoreCursor = FirebaseFirestoreTypes.QueryDocumentSnapshot
|
|
7
|
-
export type FirestoreBaseQuery<T extends AnyObject> = BaseQuery<T, FirestoreCursor>
|
|
8
|
-
export type FirestoreQuery<T extends AnyObject> = FirebaseFirestoreTypes.Query<T>
|
|
9
|
-
// export type FirestoreQuery<T extends AnyObject> = BaseQuery<T, FirestoreCursor>
|
|
10
|
-
export type FirestoreOnItemsData<T extends AnyObject> = OnItemsData<T, FirestoreCursor>
|
package/src/types/functions.ts
DELETED