Repository navigation
feat(expo-native-components): add single-token client sync bridge #9957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
+881
−24
Open
Changes from all commits
Commits
Show all changes
86 commits
Select commit
Hold shift + click to select a range
eedabc7
feat(clerk-js,shared): add experimental trusted device resources
mikepitre 06409ce
feat(expo-biometrics): add biometric credential native module
mikepitre 193f277
chore(expo-biometrics): point iOS storage comment at the clerk-ios co…
mikepitre 8ae86de
fix(expo-biometrics): report missing secure key storage
mikepitre b04b97d
feat(expo-biometrics): add Android support
mikepitre 406e03d
fix(expo-biometrics): report missing secure key storage on Android
mikepitre b3fe64c
feat(expo): move biometric credentials to @clerk/expo-biometrics
mikepitre cffd179
fix(expo): keep API error codes on biometric credential errors
mikepitre 8bc206c
fix(expo): treat missing secure key storage as unavailable
mikepitre 76e4e5b
chore(expo): port biometrics to main and fix test typing
mikepitre 3d8a2eb
chore(expo-biometrics): raise the clerk.browser.js size limit and cla…
mikepitre 507c4fb
refactor(expo-native): move native SDK code from @clerk/expo into pac…
mikepitre c488efa
feat(expo-native): scaffold @clerk/expo-native package
mikepitre a0c461c
feat(expo): re-export native components from @clerk/expo-native and d…
mikepitre 99a6290
chore(expo-native): wire the package into CI, the native fixture, and…
mikepitre b6bc9c2
fix(expo): clarify config plugin warnings for @clerk/expo-native options
mikepitre 872e66b
refactor(expo-native): drop the dependency on @clerk/expo
mikepitre 007540a
chore(expo): leave biometric credentials out of the native split chan…
mikepitre a7f449e
refactor(expo-native-components): rename @clerk/expo-native to @clerk…
mikepitre e1a16c3
fix(expo): point biometric reverification at @clerk/expo-native-compo…
mikepitre b58926b
feat(expo-native): add single-token client sync bridge
mikepitre 252dc62
refactor(expo-native-components): rename @clerk/expo-native references
mikepitre 7ef069b
docs(expo-biometrics): describe the package as the install for useBio…
mikepitre fa996d4
feat(expo): run biometric reverification in JS
mikepitre ab01e9d
chore(expo): correct useBiometricCredentials requirements and raise t…
mikepitre 0c71b3d
Merge branch 'mike/expo-biometrics-package' of github.com:clerkinc/ja…
mikepitre 3bcc2f3
Merge branch 'mike/expo-native-package' of github.com:clerkinc/javasc…
mikepitre 6a7b7fb
chore(expo-biometrics): point storage comments at clerk-android's con…
mikepitre 0d8e5b0
fix(expo-biometrics): serialize Android record saves and deletes
mikepitre a662774
Merge branch 'main' into mike/expo-biometrics-package
wobsoriano 628192a
Merge branch 'mike/expo-biometrics-package' of github.com:clerkinc/ja…
mikepitre 690bef2
chore(expo): drop the Android re-enrollment note now that clerk-andro…
mikepitre 119ba4e
chore(expo-biometrics): exclude native tests from the published package
wobsoriano adecbb5
refactor(expo,expo-biometrics): remove unreachable compatibility shims
wobsoriano 413705c
refactor(expo): dedupe local credential cleanup in sign-in and reverify
wobsoriano 32f6c80
test(expo): drop native sync mocks the biometric hook no longer uses
wobsoriano f854344
chore(clerk-js): raise the clerk.legacy.browser.js size limit
wobsoriano c720537
chore(repo): simplify biometric credential changesets
wobsoriano d9f99e6
fix(expo): keep biometric credential error codes consistent
wobsoriano f253936
docs(expo): describe the @clerk/expo-biometrics requirement on useBio…
wobsoriano 4714f8e
test(e2e): add a biometric availability smoke flow
wobsoriano 4fe93d7
refactor(clerk-js): align native settings parsing with sibling resources
wobsoriano 89da67e
Merge branch 'main' into mike/expo-biometrics-package
wobsoriano 6ec83d4
fix(expo,expo-biometrics): check biometric challenges before promptin…
mikepitre 4ba69f8
feat(expo): export useBiometricCredentials from @clerk/expo/biometrics
wobsoriano b609ad1
fix(expo-biometrics): settle Android sign() when the prompt cannot show
swolfand af58d9f
Merge branch 'main' into mike/expo-biometrics-package
mikepitre d7094a9
ci(repo): copy expo-biometrics Android tests into the packed fixture …
mikepitre d82987a
Merge branch 'main' into mike/expo-biometrics-package
mikepitre b078daa
Merge commit 'd82987a040' into mike/expo-native-package
mikepitre fc5c343
Merge main before the #9989 squash into mike/expo-native-package
mikepitre f2aed86
Merge main into mike/expo-native-package
mikepitre 7d58a73
chore(expo): note that Android enrollments need the native SDK to mig…
mikepitre 061f265
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre b9138eb
fix(repo): use the @clerk/expo-native-components plugin in the native…
mikepitre 919d59c
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre e6d2f6f
Merge branch 'main' into mike/expo-native-package
mikepitre cb9e44e
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre f58ba94
Merge branch 'main' into mike/expo-native-package
mikepitre 472f686
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre 3b1a370
Merge branch 'main' into mike/expo-native-package
mikepitre ade2a17
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre 7dc90d2
Merge branch 'main' into mike/expo-native-package
mikepitre 607a8c3
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre affd28d
Merge branch 'main' into mike/expo-native-package
mikepitre a9dfdfe
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre 689340d
Merge branch 'main' into mike/expo-native-package
mikepitre d1b873e
Merge branch 'mike/expo-native-package' into mike/expo-native-sync-br…
mikepitre 6df3111
Merge branch 'main' into mike/expo-native-package
wobsoriano 55c8eae
refactor(expo,expo-native-components): keep useAuthViewState in @cler…
wobsoriano 792aecc
chore(expo,expo-native-components): describe the native components sp…
wobsoriano 8b767b2
chore(expo,expo-native-components): trim the native components changeset
wobsoriano c708f9c
Merge remote-tracking branch 'origin/main' into mike/expo-native-package
wobsoriano 12061bb
Merge branch 'main' into mike/expo-native-package
wobsoriano 094939a
Merge branch 'main' into mike/expo-native-package
wobsoriano 15c5c3d
feat(expo): export native components from @clerk/expo/native-components
wobsoriano 569545f
docs(expo-native-components): trim the README and point to the docs
wobsoriano d592ca1
chore(repo,expo): track @clerk/expo-native-components in break-check …
wobsoriano 245af6a
Merge #9955's final branch head into mike/expo-native-sync-bridge
mikepitre 1c70b92
Merge main before the #9955 squash into mike/expo-native-sync-bridge
mikepitre 2da954c
Merge main into mike/expo-native-sync-bridge
mikepitre d67a86f
Merge branch 'main' into mike/expo-native-sync-bridge
mikepitre 5133f51
chore(expo-native-components): pin clerk-ios to 1.6.1 instead of the …
mikepitre b079ca8
Merge branch 'main' into mike/expo-native-sync-bridge
mikepitre 57336ab
chore(expo-native-components): bump clerk-android to 1.2.0 for setDev…
mikepitre e451e40
chore(expo-native-components): bump clerk-android to 1.2.1
mikepitre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@clerk/expo-native-components': minor | ||
| --- | ||
|
|
||
| Add native module support for the upcoming single-token client sync between `@clerk/expo` and the Clerk iOS and Android SDKs. The native SDK's stored device token becomes the one token both runtimes use, and each side is notified to reload its own client when the other changes it. Existing sync behavior is unchanged until `@clerk/expo` adopts it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
...xpo-native-components/android/src/main/java/expo/modules/clerk/ClerkClientInvalidation.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| package expo.modules.clerk | ||
|
|
||
| import com.clerk.api.network.model.client.Client | ||
|
|
||
| /** The native client state that JS must refetch its own client for when it changes. */ | ||
| internal data class ClerkClientFingerprint( | ||
| val clientId: String?, | ||
| val lastActiveSessionId: String?, | ||
| val sessions: List<SessionState>, | ||
| val activeUserId: String?, | ||
| val activeUserUpdatedAt: Long?, | ||
| val deviceToken: String? | ||
| ) { | ||
| data class SessionState(val id: String, val status: String) | ||
|
|
||
| companion object { | ||
| fun from(client: Client?, deviceToken: String?): ClerkClientFingerprint { | ||
| val activeUser = client?.sessions?.firstOrNull { it.id == client.lastActiveSessionId }?.user | ||
| return ClerkClientFingerprint( | ||
| clientId = client?.id, | ||
| lastActiveSessionId = client?.lastActiveSessionId, | ||
| sessions = client?.sessions?.map { SessionState(it.id, it.status.name) }.orEmpty(), | ||
| activeUserId = activeUser?.id, | ||
| activeUserUpdatedAt = activeUser?.updatedAt, | ||
| deviceToken = deviceToken | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Emits one payload-free invalidation per main-loop turn in which the fingerprint moved away from | ||
| * the last state JS was told about. Not thread-safe: call it from the main thread only. | ||
| */ | ||
| internal class ClerkClientInvalidationTracker( | ||
| private val schedule: (() -> Unit) -> Unit, | ||
| private val emit: () -> Unit | ||
| ) { | ||
| private var baseline: ClerkClientFingerprint? = null | ||
| private var latest: ClerkClientFingerprint? = null | ||
| private var isFlushScheduled = false | ||
|
|
||
| /** Sets the state JS already knows about without emitting. */ | ||
| fun reset(fingerprint: ClerkClientFingerprint?) { | ||
| baseline = fingerprint | ||
| latest = fingerprint | ||
| } | ||
|
|
||
| fun observe(fingerprint: ClerkClientFingerprint) { | ||
| if (baseline == null) return | ||
| latest = fingerprint | ||
| if (fingerprint == baseline || isFlushScheduled) return | ||
| isFlushScheduled = true | ||
| schedule(::flush) | ||
| } | ||
|
|
||
| /** A token JS wrote itself is not news to JS, so it must not echo back as an invalidation. */ | ||
| fun acknowledgeDeviceToken(token: String?, current: ClerkClientFingerprint) { | ||
| baseline = baseline?.copy(deviceToken = token) | ||
| observe(current) | ||
| } | ||
|
|
||
| private fun flush() { | ||
| isFlushScheduled = false | ||
| val current = latest ?: return | ||
| if (current == baseline) return | ||
| baseline = current | ||
| emit() | ||
| } | ||
| } | ||
|
|
||
| internal data class ClerkDeviceTokenBridgeError(val code: String, val message: String) | ||
|
|
||
| internal fun clerkSetDeviceTokenBridgeError(throwable: Throwable): ClerkDeviceTokenBridgeError = when (throwable) { | ||
| is IllegalArgumentException -> ClerkDeviceTokenBridgeError( | ||
| "E_INVALID_DEVICE_TOKEN", | ||
| throwable.message ?: "Device token must not be blank" | ||
| ) | ||
| is IllegalStateException -> ClerkDeviceTokenBridgeError( | ||
| "E_NOT_CONFIGURED", | ||
| throwable.message ?: "Clerk must be configured with configureNative before syncing client state." | ||
| ) | ||
| else -> ClerkDeviceTokenBridgeError( | ||
| "E_SET_DEVICE_TOKEN_FAILED", | ||
| throwable.message ?: "Unable to set the device token" | ||
| ) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.