@oxyhq/services 26.0.0 → 26.0.1
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/README.md +2 -2
- package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +127 -21
- package/expo-module.config.json +1 -4
- package/lib/commonjs/index.js +49 -18
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/notifications/deviceNotifications.js +0 -63
- package/lib/commonjs/notifications/deviceNotifications.js.map +1 -1
- package/lib/commonjs/ui/boot/runProviderColdBoot.js +64 -20
- package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +4 -4
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +1 -13
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAuthChooser.js +8 -9
- package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +7 -8
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +30 -25
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/primitives.js +9 -9
- package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +2 -2
- package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +2 -2
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +1 -3
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/logo/LogoText.js +4 -4
- package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
- package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +2 -2
- package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
- package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +2 -2
- package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/components/styles/shadow.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +46 -32
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/commitSessionFlow.js +43 -3
- package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +2 -15
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/context/useOxyAccountGraph.js +4 -3
- package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/mutationFactory.js +5 -5
- package/lib/commonjs/ui/hooks/mutations/mutationFactory.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +11 -11
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/useServicesMutations.js +9 -9
- package/lib/commonjs/ui/hooks/mutations/useServicesMutations.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js +2 -3
- package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/userCache.js +17 -17
- package/lib/commonjs/ui/hooks/queries/userCache.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAssets.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAsyncAction.js +7 -7
- package/lib/commonjs/ui/hooks/useAsyncAction.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAuth.js +2 -4
- package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAvatarPicker.js +5 -5
- package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
- package/lib/commonjs/ui/hooks/useOnlineStatus.js +2 -3
- package/lib/commonjs/ui/hooks/useOnlineStatus.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +2 -0
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSettingToggle.js +4 -4
- package/lib/commonjs/ui/hooks/useSettingToggle.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSurfaceHeader.js +11 -68
- package/lib/commonjs/ui/hooks/useSurfaceHeader.js.map +1 -1
- package/lib/commonjs/ui/oauth/browserAuthTransport.js +64 -66
- package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -1
- package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +48 -0
- package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +1 -0
- package/lib/commonjs/ui/oauth/oauthPopup.js +0 -47
- package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountMembersScreen.js +10 -10
- package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +19 -41
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js +4 -4
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js +9 -9
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AvatarCropScreen.js +3 -3
- package/lib/commonjs/ui/screens/AvatarCropScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +7 -6
- package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +4 -4
- package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/CreateAccountScreen.js +13 -35
- package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +5 -5
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileScreen.js +3 -2
- package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FAQScreen.js +2 -2
- package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +89 -90
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +20 -20
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FollowersListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FollowingListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HelpSupportScreen.js +7 -7
- package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HistoryViewScreen.js +34 -9
- package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -3
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +3 -3
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js +15 -15
- package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +19 -19
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +15 -15
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +7 -17
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +2 -2
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserListScreen.js +7 -13
- package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +6 -5
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +4 -1
- package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +24 -34
- package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +4 -3
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/session/index.js +0 -7
- package/lib/commonjs/ui/session/index.js.map +1 -1
- package/lib/commonjs/ui/utils/crossOriginRestore.js +140 -0
- package/lib/commonjs/ui/utils/crossOriginRestore.js.map +1 -0
- package/lib/commonjs/ui/utils/fileManagement.js +24 -24
- package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
- package/lib/commonjs/ui/utils/oauthReturn.js +30 -19
- package/lib/commonjs/ui/utils/oauthReturn.js.map +1 -1
- package/lib/commonjs/ui/utils/userUtils.js +28 -27
- package/lib/commonjs/ui/utils/userUtils.js.map +1 -1
- package/lib/module/index.js +8 -20
- package/lib/module/index.js.map +1 -1
- package/lib/module/notifications/deviceNotifications.js +0 -62
- package/lib/module/notifications/deviceNotifications.js.map +1 -1
- package/lib/module/ui/boot/runProviderColdBoot.js +65 -21
- package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +1 -1
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/OxyAccountDialogScreen.js +1 -13
- package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/module/ui/components/OxyAuthChooser.js +4 -5
- package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +6 -7
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/ProfileButton.js +2 -2
- package/lib/module/ui/components/ProfileButton.js.map +1 -1
- package/lib/module/ui/components/authChooser/AccountsMenuView.js +8 -3
- package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/module/ui/components/authChooser/primitives.js +1 -1
- package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/module/ui/components/authChooser/useUsernameAvailability.js +1 -1
- package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +1 -1
- package/lib/module/ui/components/fileManagement/UploadPreview.js +1 -1
- package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +1 -3
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/logo/LogoText.js +4 -4
- package/lib/module/ui/components/logo/LogoText.js.map +1 -1
- package/lib/module/ui/components/payment/PaymentDetailsStep.js +1 -1
- package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
- package/lib/module/ui/components/payment/PaymentSummaryStep.js +2 -2
- package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
- package/lib/module/ui/components/styles/shadow.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +49 -35
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/commitSessionFlow.js +42 -3
- package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +2 -15
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/context/useOxyAccountGraph.js +4 -3
- package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/module/ui/hooks/mutations/mutationFactory.js +1 -1
- package/lib/module/ui/hooks/mutations/mutationFactory.js.map +1 -1
- package/lib/module/ui/hooks/mutations/useAccountMutations.js +1 -1
- package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/module/ui/hooks/mutations/useServicesMutations.js +1 -1
- package/lib/module/ui/hooks/mutations/useServicesMutations.js.map +1 -1
- package/lib/module/ui/hooks/queries/usePaymentQueries.js +2 -3
- package/lib/module/ui/hooks/queries/usePaymentQueries.js.map +1 -1
- package/lib/module/ui/hooks/queries/userCache.js +17 -17
- package/lib/module/ui/hooks/queries/userCache.js.map +1 -1
- package/lib/module/ui/hooks/useAssets.js.map +1 -1
- package/lib/module/ui/hooks/useAsyncAction.js +1 -1
- package/lib/module/ui/hooks/useAsyncAction.js.map +1 -1
- package/lib/module/ui/hooks/useAuth.js +2 -4
- package/lib/module/ui/hooks/useAuth.js.map +1 -1
- package/lib/module/ui/hooks/useAvatarPicker.js +1 -1
- package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
- package/lib/module/ui/hooks/useOnlineStatus.js +2 -3
- package/lib/module/ui/hooks/useOnlineStatus.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +2 -0
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/hooks/useSettingToggle.js +1 -1
- package/lib/module/ui/hooks/useSettingToggle.js.map +1 -1
- package/lib/module/ui/hooks/useSurfaceHeader.js +11 -68
- package/lib/module/ui/hooks/useSurfaceHeader.js.map +1 -1
- package/lib/module/ui/oauth/browserAuthTransport.js +64 -66
- package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -1
- package/lib/module/ui/oauth/legacyRedirectLanes.js +44 -0
- package/lib/module/ui/oauth/legacyRedirectLanes.js.map +1 -0
- package/lib/module/ui/oauth/oauthPopup.js +1 -48
- package/lib/module/ui/oauth/oauthPopup.js.map +1 -1
- package/lib/module/ui/screens/AccountMembersScreen.js +1 -1
- package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +15 -37
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/screens/AvatarCropScreen.js +1 -1
- package/lib/module/ui/screens/AvatarCropScreen.js.map +1 -1
- package/lib/module/ui/screens/ChangeAvatarScreen.js +5 -4
- package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -1
- package/lib/module/ui/screens/ConnectedAppsScreen.js +2 -2
- package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -1
- package/lib/module/ui/screens/CreateAccountScreen.js +12 -34
- package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileFieldScreen.js +4 -4
- package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileScreen.js +4 -3
- package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/FAQScreen.js +1 -1
- package/lib/module/ui/screens/FAQScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +91 -94
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/FollowersListScreen.js.map +1 -1
- package/lib/module/ui/screens/FollowingListScreen.js.map +1 -1
- package/lib/module/ui/screens/HelpSupportScreen.js +1 -1
- package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
- package/lib/module/ui/screens/HistoryViewScreen.js +30 -5
- package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/LegalDocumentsScreen.js +1 -1
- package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
- package/lib/module/ui/screens/ManageAccountScreen.js +3 -3
- package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +4 -4
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +11 -11
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +8 -18
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js +1 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/module/ui/screens/UserListScreen.js +8 -14
- package/lib/module/ui/screens/UserListScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +6 -5
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +4 -1
- package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +5 -15
- package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +5 -4
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/module/ui/session/index.js +0 -1
- package/lib/module/ui/session/index.js.map +1 -1
- package/lib/module/ui/utils/crossOriginRestore.js +131 -0
- package/lib/module/ui/utils/crossOriginRestore.js.map +1 -0
- package/lib/module/ui/utils/fileManagement.js +25 -25
- package/lib/module/ui/utils/fileManagement.js.map +1 -1
- package/lib/module/ui/utils/oauthReturn.js +30 -20
- package/lib/module/ui/utils/oauthReturn.js.map +1 -1
- package/lib/module/ui/utils/userUtils.js +28 -27
- package/lib/module/ui/utils/userUtils.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts +0 -51
- package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts +30 -11
- package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +0 -7
- package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts +1 -2
- package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/payment/types.d.ts +6 -6
- package/lib/typescript/commonjs/ui/components/payment/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +40 -0
- package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +2 -11
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +7 -26
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +1 -0
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/paymentTypes.d.ts +2 -3
- package/lib/typescript/commonjs/ui/hooks/queries/paymentTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/usePaymentQueries.d.ts +2 -3
- package/lib/typescript/commonjs/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts +2 -2
- package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts +1 -1
- package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useAsyncAction.d.ts +2 -2
- package/lib/typescript/commonjs/ui/hooks/useAsyncAction.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts +2 -4
- package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useOnlineStatus.d.ts +2 -3
- package/lib/typescript/commonjs/ui/hooks/useOnlineStatus.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts +2 -7
- package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +40 -0
- package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +0 -6
- package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts +2 -2
- package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FollowersListScreen.d.ts +0 -3
- package/lib/typescript/commonjs/ui/screens/FollowersListScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FollowingListScreen.d.ts +0 -3
- package/lib/typescript/commonjs/ui/screens/FollowingListScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts +0 -7
- package/lib/typescript/commonjs/ui/screens/UserListScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/index.d.ts +0 -1
- package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +19 -27
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts +43 -0
- package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +5 -5
- package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts +12 -15
- package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/userUtils.d.ts +14 -7
- package/lib/typescript/commonjs/ui/utils/userUtils.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/notifications/deviceNotifications.d.ts +0 -51
- package/lib/typescript/module/notifications/deviceNotifications.d.ts.map +1 -1
- package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts +30 -11
- package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +0 -7
- package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxySignInButton.d.ts +1 -2
- package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +1 -1
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts +1 -1
- package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/types.d.ts +6 -6
- package/lib/typescript/module/ui/components/payment/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +40 -0
- package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +2 -11
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +7 -26
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +1 -0
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/paymentTypes.d.ts +2 -3
- package/lib/typescript/module/ui/hooks/queries/paymentTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts +2 -3
- package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/userCache.d.ts +2 -2
- package/lib/typescript/module/ui/hooks/queries/userCache.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAssets.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useAssets.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAsyncAction.d.ts +2 -2
- package/lib/typescript/module/ui/hooks/useAsyncAction.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAuth.d.ts +2 -4
- package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useOnlineStatus.d.ts +2 -3
- package/lib/typescript/module/ui/hooks/useOnlineStatus.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts +2 -7
- package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
- package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -1
- package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +40 -0
- package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
- package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +0 -6
- package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts +2 -2
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts +0 -3
- package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts +0 -3
- package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/UserListScreen.d.ts +0 -7
- package/lib/typescript/module/ui/screens/UserListScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/index.d.ts +0 -1
- package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +19 -27
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts +43 -0
- package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts.map +1 -0
- package/lib/typescript/module/ui/utils/fileManagement.d.ts +5 -5
- package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/oauthReturn.d.ts +12 -15
- package/lib/typescript/module/ui/utils/oauthReturn.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/userUtils.d.ts +14 -7
- package/lib/typescript/module/ui/utils/userUtils.d.ts.map +1 -1
- package/package.json +10 -22
- package/src/index.ts +16 -18
- package/src/notifications/deviceNotifications.ts +0 -82
- package/src/ui/boot/__tests__/coldBootWebAuthMode.test.ts +281 -0
- package/src/ui/boot/runProviderColdBoot.ts +101 -24
- package/src/ui/components/FollowButton.tsx +1 -1
- package/src/ui/components/OxyAccountDialogScreen.tsx +1 -13
- package/src/ui/components/OxyAuthChooser.tsx +4 -14
- package/src/ui/components/OxyProvider.tsx +7 -8
- package/src/ui/components/OxySignInButton.tsx +1 -2
- package/src/ui/components/ProfileButton.tsx +2 -5
- package/src/ui/components/authChooser/AccountsMenuView.tsx +10 -5
- package/src/ui/components/authChooser/primitives.tsx +1 -1
- package/src/ui/components/authChooser/useUsernameAvailability.ts +1 -1
- package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
- package/src/ui/components/internal/PinInput.tsx +0 -1
- package/src/ui/components/logo/LogoText.tsx +4 -4
- package/src/ui/components/payment/PaymentDetailsStep.tsx +1 -1
- package/src/ui/components/payment/PaymentSummaryStep.tsx +2 -2
- package/src/ui/components/payment/types.ts +24 -24
- package/src/ui/components/styles/shadow.tsx +2 -2
- package/src/ui/context/OxyContext.tsx +46 -35
- package/src/ui/context/__tests__/commitSessionFlow.test.ts +89 -13
- package/src/ui/context/commitSessionFlow.ts +61 -3
- package/src/ui/context/hooks/useAuthOperations.ts +1 -26
- package/src/ui/context/oxyContextTypes.ts +7 -26
- package/src/ui/context/useOxyAccountGraph.ts +4 -4
- package/src/ui/hooks/mutations/mutationFactory.ts +1 -1
- package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
- package/src/ui/hooks/mutations/useServicesMutations.ts +1 -1
- package/src/ui/hooks/queries/paymentTypes.ts +2 -3
- package/src/ui/hooks/queries/usePaymentQueries.ts +2 -3
- package/src/ui/hooks/queries/userCache.ts +148 -169
- package/src/ui/hooks/useAssets.ts +1 -1
- package/src/ui/hooks/useAsyncAction.ts +3 -3
- package/src/ui/hooks/useAuth.ts +2 -4
- package/src/ui/hooks/useAvatarPicker.ts +1 -1
- package/src/ui/hooks/useOnlineStatus.ts +2 -3
- package/src/ui/hooks/useSessionManagement.ts +2 -0
- package/src/ui/hooks/useSettingToggle.ts +1 -1
- package/src/ui/hooks/useSurfaceHeader.ts +15 -90
- package/src/ui/oauth/__tests__/oauthPopup.test.ts +0 -26
- package/src/ui/oauth/browserAuthTransport.ts +49 -55
- package/src/ui/oauth/legacyRedirectLanes.ts +43 -0
- package/src/ui/oauth/oauthPopup.ts +3 -61
- package/src/ui/screens/AccountMembersScreen.tsx +1 -1
- package/src/ui/screens/AccountSettingsScreen.tsx +17 -45
- package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
- package/src/ui/screens/AppInfoScreen.tsx +1 -1
- package/src/ui/screens/AvatarCropScreen.tsx +1 -1
- package/src/ui/screens/ChangeAvatarScreen.tsx +4 -7
- package/src/ui/screens/ConnectedAppsScreen.tsx +2 -2
- package/src/ui/screens/CreateAccountScreen.tsx +13 -43
- package/src/ui/screens/EditProfileFieldScreen.tsx +4 -4
- package/src/ui/screens/EditProfileScreen.tsx +3 -6
- package/src/ui/screens/FAQScreen.tsx +1 -1
- package/src/ui/screens/FeedbackScreen.tsx +575 -741
- package/src/ui/screens/FileManagementScreen.tsx +1 -1
- package/src/ui/screens/FollowersListScreen.tsx +0 -3
- package/src/ui/screens/FollowingListScreen.tsx +0 -3
- package/src/ui/screens/HelpSupportScreen.tsx +1 -1
- package/src/ui/screens/HistoryViewScreen.tsx +20 -5
- package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
- package/src/ui/screens/LegalDocumentsScreen.tsx +1 -1
- package/src/ui/screens/ManageAccountScreen.tsx +2 -9
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +4 -4
- package/src/ui/screens/PrivacySettingsScreen.tsx +12 -15
- package/src/ui/screens/ProfileScreen.tsx +6 -24
- package/src/ui/screens/SavesCollectionsScreen.tsx +1 -1
- package/src/ui/screens/UserListScreen.tsx +8 -18
- package/src/ui/screens/WelcomeNewUserScreen.tsx +6 -6
- package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +1 -1
- package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +5 -14
- package/src/ui/screens/trust/TrustCenterScreen.tsx +2 -2
- package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +5 -6
- package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
- package/src/ui/screens/trust/TrustRulesScreen.tsx +1 -1
- package/src/ui/screens/trust/trustTier.ts +1 -1
- package/src/ui/session/index.ts +0 -1
- package/src/ui/types/navigation.ts +19 -27
- package/src/ui/utils/__tests__/crossOriginRestore.test.ts +143 -0
- package/src/ui/utils/crossOriginRestore.ts +169 -0
- package/src/ui/utils/fileManagement.ts +92 -108
- package/src/ui/utils/oauthReturn.ts +33 -23
- package/src/ui/utils/userUtils.ts +32 -27
- package/android/src/main/java/so/oxy/session/OxyBackgroundSession.kt +0 -184
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionApi.kt +0 -162
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionModule.kt +0 -116
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionStore.kt +0 -179
- package/android/src/main/java/so/oxy/session/OxyBackgroundToken.kt +0 -61
- package/android/src/main/java/so/oxy/storage/OxyEncryptedPrefs.kt +0 -241
- package/lib/commonjs/ui/session/backgroundSession.js +0 -258
- package/lib/commonjs/ui/session/backgroundSession.js.map +0 -1
- package/lib/commonjs/ui/session/useBackgroundSessionSync.js +0 -81
- package/lib/commonjs/ui/session/useBackgroundSessionSync.js.map +0 -1
- package/lib/commonjs/ui/utils/netConnectivity.js +0 -28
- package/lib/commonjs/ui/utils/netConnectivity.js.map +0 -1
- package/lib/module/ui/session/backgroundSession.js +0 -252
- package/lib/module/ui/session/backgroundSession.js.map +0 -1
- package/lib/module/ui/session/useBackgroundSessionSync.js +0 -76
- package/lib/module/ui/session/useBackgroundSessionSync.js.map +0 -1
- package/lib/module/ui/utils/netConnectivity.js +0 -23
- package/lib/module/ui/utils/netConnectivity.js.map +0 -1
- package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts +0 -42
- package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts +0 -23
- package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/utils/netConnectivity.d.ts +0 -17
- package/lib/typescript/commonjs/ui/utils/netConnectivity.d.ts.map +0 -1
- package/lib/typescript/module/ui/session/backgroundSession.d.ts +0 -42
- package/lib/typescript/module/ui/session/backgroundSession.d.ts.map +0 -1
- package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts +0 -23
- package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts.map +0 -1
- package/lib/typescript/module/ui/utils/netConnectivity.d.ts +0 -17
- package/lib/typescript/module/ui/utils/netConnectivity.d.ts.map +0 -1
- package/lib/typescript/types/expo-image-picker.d.ts +0 -35
- package/src/types/expo-image-picker.d.ts +0 -35
- package/src/ui/boot/__tests__/coldBootNoIdpRedirect.test.ts +0 -215
- package/src/ui/session/__tests__/backgroundSession.test.ts +0 -392
- package/src/ui/session/backgroundSession.ts +0 -313
- package/src/ui/session/useBackgroundSessionSync.ts +0 -92
- package/src/ui/utils/netConnectivity.ts +0 -27
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
clearOAuthHandshake,
|
|
4
4
|
consumeOAuthReturnPath,
|
|
5
5
|
logger,
|
|
6
|
-
|
|
6
|
+
normalizeOAuthRedirectUri,
|
|
7
7
|
readOAuthHandshake,
|
|
8
8
|
} from '@oxyhq/core';
|
|
9
9
|
import { completeOAuthCode } from '../oauth/completeOAuthCode';
|
|
@@ -14,21 +14,12 @@ import { isWebBrowser } from './isWebBrowser';
|
|
|
14
14
|
* When the RP lands with `?code=` after signing in at auth.oxy.so, exchange the
|
|
15
15
|
* code for a device-first session before cold boot runs.
|
|
16
16
|
*
|
|
17
|
-
* This is the REDIRECT transport's return leg.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* the URL, recovering the handshake `sessionStorage` carried across the
|
|
24
|
-
* navigation, and cleaning both up afterwards — and delegates state validation,
|
|
25
|
-
* the PKCE exchange, and the session commit to `completeOAuthCode`, the same
|
|
26
|
-
* function the popup transport runs.
|
|
27
|
-
*
|
|
28
|
-
* It is also the SINGLE cleanup path for an OAuth `error` landing on the URL:
|
|
29
|
-
* any `?error=…` (including an `error=login_required` left over from the
|
|
30
|
-
* now-deleted silent restore) is stripped along with `state` /
|
|
31
|
-
* `error_description`, and the stale PKCE handshake is cleared.
|
|
17
|
+
* This is the REDIRECT transport's return leg. It owns only what is specific to
|
|
18
|
+
* a full-page round trip — reading the code off the URL, recovering the
|
|
19
|
+
* handshake `sessionStorage` carried across the navigation, and cleaning both up
|
|
20
|
+
* afterwards — and delegates state validation, the PKCE exchange, and the
|
|
21
|
+
* session commit to `completeOAuthCode`, the same function the popup transport
|
|
22
|
+
* runs.
|
|
32
23
|
*/
|
|
33
24
|
export async function tryCompleteOAuthReturn(opts: {
|
|
34
25
|
oxyServices: OxyServices;
|
|
@@ -58,18 +49,13 @@ export async function tryCompleteOAuthReturn(opts: {
|
|
|
58
49
|
return false;
|
|
59
50
|
}
|
|
60
51
|
|
|
61
|
-
const handshake = readOAuthHandshake();
|
|
62
|
-
const redirectUri = canonicalizeOAuthRedirectUri(
|
|
63
|
-
handshake?.redirectUri ?? opts.authRedirectUri ?? location.origin,
|
|
64
|
-
);
|
|
65
|
-
|
|
66
52
|
const result = await completeOAuthCode({
|
|
67
53
|
oxyServices: opts.oxyServices,
|
|
68
54
|
clientId,
|
|
69
55
|
code,
|
|
70
56
|
returnedState: params.get('state'),
|
|
71
|
-
handshake,
|
|
72
|
-
redirectUri,
|
|
57
|
+
handshake: readOAuthHandshake(),
|
|
58
|
+
redirectUri: normalizeOAuthRedirectUri(opts.authRedirectUri ?? location.origin),
|
|
73
59
|
commitSession: opts.commitSession,
|
|
74
60
|
// Strip the params before the commit so a stale `?code=` cannot re-enter the
|
|
75
61
|
// exchange loop, and read the return path FIRST — clearOAuthHandshake drops
|
|
@@ -134,5 +120,29 @@ function stripOAuthParamsFromUrl(): void {
|
|
|
134
120
|
url.searchParams.delete('state');
|
|
135
121
|
url.searchParams.delete('error');
|
|
136
122
|
url.searchParams.delete('error_description');
|
|
123
|
+
url.searchParams.delete('hub_sync');
|
|
124
|
+
replaceUrlAfterOAuthReturn(`${url.pathname}${url.search}${url.hash}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* When auth.oxy.so hub-sync redeem fails, the IdP redirects back with
|
|
129
|
+
* `?hub_sync=failed`. Strip the param and log so cold boot can continue
|
|
130
|
+
* without leaving a stale query string.
|
|
131
|
+
*/
|
|
132
|
+
export function consumeHubSyncFailure(): boolean {
|
|
133
|
+
if (!isWebBrowser()) return false;
|
|
134
|
+
const location = (globalThis as { location?: Location }).location;
|
|
135
|
+
if (!location) return false;
|
|
136
|
+
|
|
137
|
+
const params = new URLSearchParams(location.search);
|
|
138
|
+
if (params.get('hub_sync') !== 'failed') return false;
|
|
139
|
+
|
|
140
|
+
logger.warn('Hub sync failed — IdP device session may be out of sync', {
|
|
141
|
+
component: 'hubSync',
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const url = new URL(location.href);
|
|
145
|
+
url.searchParams.delete('hub_sync');
|
|
137
146
|
replaceUrlAfterOAuthReturn(`${url.pathname}${url.search}${url.hash}`);
|
|
147
|
+
return true;
|
|
138
148
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* User display name and date formatting utilities.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `
|
|
4
|
+
* The display-name helpers are thin wrappers around the canonical
|
|
5
|
+
* `getAccountDisplayName` in `@oxyhq/core`, which handles all the edge cases
|
|
6
|
+
* (missing username, missing name, fallback to truncated `publicKey`, i18n).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getAccountDisplayName as coreGetAccountDisplayName,
|
|
11
|
+
type DisplayNameUserShape,
|
|
12
|
+
} from '@oxyhq/core';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Formats a date string to a readable format (e.g., "Feb 21, 2025")
|
|
@@ -28,42 +31,44 @@ export const formatDate = (dateString: string | undefined | null | Date): string
|
|
|
28
31
|
}
|
|
29
32
|
};
|
|
30
33
|
|
|
31
|
-
function readDisplayName(user: DisplayNameUserShape | null | undefined): string {
|
|
32
|
-
const name = user?.name;
|
|
33
|
-
if (!name || typeof name !== 'object') return '';
|
|
34
|
-
return typeof name.displayName === 'string' ? name.displayName.trim() : '';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
34
|
/**
|
|
38
35
|
* Gets a display name from user data.
|
|
39
36
|
*
|
|
40
|
-
* Prefers
|
|
37
|
+
* Prefers full name → composed first+last → username → `Account 0x12345678…`
|
|
38
|
+
* (derived from publicKey) → translated "Unnamed".
|
|
39
|
+
*
|
|
40
|
+
* @param user - User-like object with optional name/username/publicKey
|
|
41
|
+
* @param locale - Optional locale for the final fallback label
|
|
41
42
|
*/
|
|
42
43
|
export const getDisplayName = (
|
|
43
44
|
user: DisplayNameUserShape | null | undefined,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (displayName) return displayName;
|
|
47
|
-
return getNormalizedUserHandle(user) ?? '';
|
|
48
|
-
};
|
|
45
|
+
locale?: string,
|
|
46
|
+
): string => coreGetAccountDisplayName(user, locale);
|
|
49
47
|
|
|
50
48
|
/**
|
|
51
|
-
* Gets a short display name (first
|
|
49
|
+
* Gets a short display name (first name or username).
|
|
50
|
+
*
|
|
51
|
+
* Used for compact UI (e.g. greetings). Falls back to the full display name
|
|
52
|
+
* helper, which also handles publicKey-only accounts.
|
|
52
53
|
*/
|
|
53
54
|
export const getShortDisplayName = (
|
|
54
55
|
user: DisplayNameUserShape | null | undefined,
|
|
56
|
+
locale?: string,
|
|
55
57
|
): string => {
|
|
56
|
-
|
|
57
|
-
if (displayName) {
|
|
58
|
-
const firstToken = displayName.split(/\s+/).find(Boolean);
|
|
59
|
-
if (firstToken) return firstToken;
|
|
60
|
-
}
|
|
58
|
+
if (!user) return coreGetAccountDisplayName(user, locale);
|
|
61
59
|
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
const
|
|
65
|
-
|
|
60
|
+
const name = user.name;
|
|
61
|
+
if (name && typeof name === 'object') {
|
|
62
|
+
const first = typeof name.first === 'string' ? name.first.trim() : '';
|
|
63
|
+
if (first) return first;
|
|
64
|
+
const full = typeof name.full === 'string' ? name.full.trim() : '';
|
|
65
|
+
if (full) return full.split(' ')[0];
|
|
66
|
+
} else if (typeof name === 'string' && name.trim()) {
|
|
67
|
+
return name.trim().split(' ')[0];
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
if (typeof user.username === 'string' && user.username.trim()) return user.username.trim();
|
|
71
|
+
|
|
72
|
+
// Defer to the canonical helper for publicKey/unnamed fallbacks.
|
|
73
|
+
return coreGetAccountDisplayName(user, locale);
|
|
69
74
|
};
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
package so.oxy.session
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.util.Log
|
|
5
|
-
import java.util.concurrent.TimeUnit
|
|
6
|
-
import kotlinx.coroutines.sync.Mutex
|
|
7
|
-
import kotlinx.coroutines.sync.withLock
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* How native background code — a WorkManager worker refreshing a home-screen
|
|
11
|
-
* widget, a sync job — authenticates when there is no JS runtime in the process.
|
|
12
|
-
*
|
|
13
|
-
* ## What this is
|
|
14
|
-
*
|
|
15
|
-
* The app, while running, provisions a background credential and hands it to this
|
|
16
|
-
* store (see `OxyBackgroundSessionModule`). Background code then exchanges it for
|
|
17
|
-
* a short access token whenever it needs one. That is the whole surface:
|
|
18
|
-
*
|
|
19
|
-
* ```kotlin
|
|
20
|
-
* when (val token = OxyBackgroundSession.accessToken(applicationContext)) {
|
|
21
|
-
* is OxyBackgroundToken.Available -> fetch(token.baseUrl, token.accessToken, token.accountId)
|
|
22
|
-
* is OxyBackgroundToken.SignedOut -> renderSignedOut() // final; Result.success()
|
|
23
|
-
* is OxyBackgroundToken.Transient -> Result.retry() // keep last content
|
|
24
|
-
* is OxyBackgroundToken.Malformed -> Result.failure() // wire contract moved
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* ## What it deliberately cannot do
|
|
29
|
-
*
|
|
30
|
-
* It cannot create a session. Only the app, holding a bearer, can provision a
|
|
31
|
-
* credential — so background code can EXTEND a session the user established
|
|
32
|
-
* in-app but can never bootstrap one from nothing.
|
|
33
|
-
*
|
|
34
|
-
* It cannot damage the app's session. It never reads or writes the device
|
|
35
|
-
* credential, and the credential it does use is not rotated by anyone, so a
|
|
36
|
-
* worker killed mid-mint loses nothing. That property is the reason this exists
|
|
37
|
-
* as a separate credential instead of background code simply reading the device
|
|
38
|
-
* secret.
|
|
39
|
-
*
|
|
40
|
-
* It does not narrow authority. The minted token is a FULL user access token:
|
|
41
|
-
* access tokens carry no scopes today, so this yields exactly what the device
|
|
42
|
-
* credential yields while it is valid. The gains are isolation, a bounded
|
|
43
|
-
* lifetime and independent revocability — NOT "read-only". Do not read
|
|
44
|
-
* "background" as a permission boundary.
|
|
45
|
-
*
|
|
46
|
-
* ## Account correctness
|
|
47
|
-
*
|
|
48
|
-
* Every mint is re-authorized server-side against the live device session, so a
|
|
49
|
-
* stale record cannot resurrect a signed-out account. [OxyBackgroundToken.Available.accountId]
|
|
50
|
-
* is the server's answer, not a local guess — key cached content by it and drop
|
|
51
|
-
* content belonging to another account.
|
|
52
|
-
*/
|
|
53
|
-
object OxyBackgroundSession {
|
|
54
|
-
private const val TAG = "OxyBackgroundSession"
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Refuse to reuse a cached token this close to expiry, so it cannot die midway
|
|
58
|
-
* through the request it was fetched for.
|
|
59
|
-
*/
|
|
60
|
-
private val TOKEN_REUSE_FLOOR_MS = TimeUnit.SECONDS.toMillis(60)
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Serializes mints within a process so several widgets refreshing together make
|
|
64
|
-
* ONE network call and share its result, instead of one call each — which would
|
|
65
|
-
* also burn the server's per-device rate limit. Waiters re-check the cache after
|
|
66
|
-
* acquiring, so only the first actually mints.
|
|
67
|
-
*/
|
|
68
|
-
private val mintMutex = Mutex()
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* A usable access token for the account this device's app last provisioned, or
|
|
72
|
-
* the reason there is not one. Never throws.
|
|
73
|
-
*/
|
|
74
|
-
suspend fun accessToken(context: Context): OxyBackgroundToken {
|
|
75
|
-
val appContext = context.applicationContext
|
|
76
|
-
val credential = readCredential(appContext) ?: return OxyBackgroundToken.SignedOut
|
|
77
|
-
|
|
78
|
-
cachedToken(appContext, credential)?.let { return it }
|
|
79
|
-
|
|
80
|
-
return mintMutex.withLock {
|
|
81
|
-
// Another caller may have minted while this one waited for the lock.
|
|
82
|
-
cachedToken(appContext, credential)?.let { return@withLock it }
|
|
83
|
-
mintLocked(appContext, credential)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The account a background caller is currently provisioned for, without a
|
|
89
|
-
* network call — for keying cached content, or deciding whether cached content
|
|
90
|
-
* belongs to the current account at all. Null when there is no credential.
|
|
91
|
-
*/
|
|
92
|
-
fun activeAccountId(context: Context): String? =
|
|
93
|
-
runCatching { OxyBackgroundSessionStore.readAccountId(context.applicationContext) }
|
|
94
|
-
.getOrNull()
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Whether a credential is present, so a widget can draw its signed-out state
|
|
98
|
-
* without attempting a fetch. A `true` here is not a promise that the next mint
|
|
99
|
-
* succeeds — the server is still the authority.
|
|
100
|
-
*/
|
|
101
|
-
fun hasCredential(context: Context): Boolean = activeAccountId(context) != null
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Read the credential, degrading to null on a storage failure.
|
|
105
|
-
*
|
|
106
|
-
* The keystore can be transiently unavailable (direct-boot, a device being
|
|
107
|
-
* upgraded), and [so.oxy.storage.OxyEncryptedPrefs] can legitimately hand back
|
|
108
|
-
* an emptied file after healing an unreadable keyset. Both mean "no credential
|
|
109
|
-
* right now" rather than a crash in a background worker.
|
|
110
|
-
*/
|
|
111
|
-
private fun readCredential(appContext: Context): OxyBackgroundSessionStore.Credential? =
|
|
112
|
-
runCatching { OxyBackgroundSessionStore.readCredential(appContext) }
|
|
113
|
-
.onFailure { Log.w(TAG, "background credential store unreadable", it) }
|
|
114
|
-
.getOrNull()
|
|
115
|
-
|
|
116
|
-
private fun cachedToken(
|
|
117
|
-
appContext: Context,
|
|
118
|
-
credential: OxyBackgroundSessionStore.Credential,
|
|
119
|
-
): OxyBackgroundToken.Available? {
|
|
120
|
-
val cached = runCatching {
|
|
121
|
-
OxyBackgroundSessionStore.readToken(appContext, credential.accountId, TOKEN_REUSE_FLOOR_MS)
|
|
122
|
-
}.getOrNull() ?: return null
|
|
123
|
-
return OxyBackgroundToken.Available(
|
|
124
|
-
accessToken = cached.accessToken,
|
|
125
|
-
expiresAt = cached.expiresAt,
|
|
126
|
-
accountId = cached.accountId,
|
|
127
|
-
baseUrl = credential.baseUrl,
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Mint and map the outcome. Called with [mintMutex] held.
|
|
133
|
-
*
|
|
134
|
-
* Only [OxyBackgroundSessionApi.MintOutcome.Revoked] — an explicit server
|
|
135
|
-
* verdict — clears the record. Transient and malformed outcomes KEEP it, so a
|
|
136
|
-
* deploy window or a contract change can never sign a user out of their
|
|
137
|
-
* widgets.
|
|
138
|
-
*/
|
|
139
|
-
private suspend fun mintLocked(
|
|
140
|
-
appContext: Context,
|
|
141
|
-
credential: OxyBackgroundSessionStore.Credential,
|
|
142
|
-
): OxyBackgroundToken =
|
|
143
|
-
when (val outcome = OxyBackgroundSessionApi.mint(credential)) {
|
|
144
|
-
is OxyBackgroundSessionApi.MintOutcome.Minted -> {
|
|
145
|
-
runCatching {
|
|
146
|
-
OxyBackgroundSessionStore.writeToken(
|
|
147
|
-
appContext,
|
|
148
|
-
OxyBackgroundSessionStore.CachedToken(
|
|
149
|
-
accessToken = outcome.accessToken,
|
|
150
|
-
expiresAt = outcome.expiresAt,
|
|
151
|
-
accountId = outcome.accountId,
|
|
152
|
-
),
|
|
153
|
-
)
|
|
154
|
-
}.onFailure {
|
|
155
|
-
// Caching is an optimization; a failure to store costs one extra mint
|
|
156
|
-
// next time and must not fail the token the caller is waiting for.
|
|
157
|
-
Log.w(TAG, "could not cache the minted background token", it)
|
|
158
|
-
}
|
|
159
|
-
OxyBackgroundToken.Available(
|
|
160
|
-
accessToken = outcome.accessToken,
|
|
161
|
-
expiresAt = outcome.expiresAt,
|
|
162
|
-
accountId = outcome.accountId,
|
|
163
|
-
baseUrl = credential.baseUrl,
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
OxyBackgroundSessionApi.MintOutcome.Revoked -> {
|
|
168
|
-
Log.i(TAG, "background credential was revoked by the server; clearing it")
|
|
169
|
-
runCatching { OxyBackgroundSessionStore.clear(appContext) }
|
|
170
|
-
.onFailure { Log.w(TAG, "could not clear the revoked background credential", it) }
|
|
171
|
-
OxyBackgroundToken.SignedOut
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
is OxyBackgroundSessionApi.MintOutcome.Transient -> {
|
|
175
|
-
Log.w(TAG, "background token mint failed transiently; keeping the credential", outcome.cause)
|
|
176
|
-
OxyBackgroundToken.Transient(outcome.cause)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
is OxyBackgroundSessionApi.MintOutcome.Malformed -> {
|
|
180
|
-
Log.e(TAG, "background token response could not be read; keeping the credential", outcome.cause)
|
|
181
|
-
OxyBackgroundToken.Malformed(outcome.cause)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
package so.oxy.session
|
|
2
|
-
|
|
3
|
-
import kotlinx.coroutines.Dispatchers
|
|
4
|
-
import kotlinx.coroutines.withContext
|
|
5
|
-
import org.json.JSONException
|
|
6
|
-
import org.json.JSONObject
|
|
7
|
-
import java.io.IOException
|
|
8
|
-
import java.net.HttpURLConnection
|
|
9
|
-
import java.net.URL
|
|
10
|
-
import java.text.ParseException
|
|
11
|
-
import java.text.SimpleDateFormat
|
|
12
|
-
import java.util.Locale
|
|
13
|
-
import java.util.TimeZone
|
|
14
|
-
import java.util.concurrent.TimeUnit
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* The one network call background code makes: `POST /session/device/background-token`.
|
|
18
|
-
*
|
|
19
|
-
* Bearer-less and cookie-less — possession of the provisioned secret IS the
|
|
20
|
-
* proof. Unlike `POST /session/device/token` this NEVER rotates: the presented
|
|
21
|
-
* secret stays valid until it expires or is revoked, which is what makes it safe
|
|
22
|
-
* to call from a process the OS may kill at any moment.
|
|
23
|
-
*
|
|
24
|
-
* `HttpURLConnection` rather than an HTTP client library, for the same reason
|
|
25
|
-
* Mention's widget uses it: this is one small POST, and adding an HTTP stack to
|
|
26
|
-
* every consuming app's release APK would cost more than it saves.
|
|
27
|
-
*/
|
|
28
|
-
internal object OxyBackgroundSessionApi {
|
|
29
|
-
private val CONNECT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10).toInt()
|
|
30
|
-
private val READ_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(15).toInt()
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* The two server verdicts that PROVE the credential is finished, and the only
|
|
34
|
-
* two that may delete it.
|
|
35
|
-
*
|
|
36
|
-
* This mirrors `@oxyhq/core`'s `refresh.ts` rule deliberately, and for the same
|
|
37
|
-
* hard-won reason: ANY other 401 — a proxy or middleware 401, an ALB answering
|
|
38
|
-
* for a starting instance, an HTML error page during a deploy — is NOT proof
|
|
39
|
-
* that a credential is bad. Treating an ambiguous 401 as revocation is what
|
|
40
|
-
* logged users out ecosystem-wide once already. Here the blast radius is
|
|
41
|
-
* smaller (a widget going blank rather than a session dying) but the rule is
|
|
42
|
-
* the same, so the failure mode reads identically to anyone debugging it.
|
|
43
|
-
*
|
|
44
|
-
* These strings are wire contract with oxy-api, not log text.
|
|
45
|
-
*/
|
|
46
|
-
private const val ERROR_CREDENTIAL_INVALID = "background_credential_invalid"
|
|
47
|
-
private const val ERROR_ACCOUNT_NOT_ON_DEVICE = "account_not_on_device"
|
|
48
|
-
|
|
49
|
-
internal sealed interface MintOutcome {
|
|
50
|
-
data class Minted(val accessToken: String, val expiresAt: Long, val accountId: String) : MintOutcome
|
|
51
|
-
/** An explicit server verdict: this credential is finished. Delete it. */
|
|
52
|
-
data object Revoked : MintOutcome
|
|
53
|
-
data class Transient(val cause: Exception) : MintOutcome
|
|
54
|
-
data class Malformed(val cause: Exception) : MintOutcome
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
suspend fun mint(credential: OxyBackgroundSessionStore.Credential): MintOutcome =
|
|
58
|
-
withContext(Dispatchers.IO) {
|
|
59
|
-
val endpoint = "${credential.baseUrl.trimEnd('/')}/session/device/background-token"
|
|
60
|
-
val body = JSONObject()
|
|
61
|
-
.put("deviceId", credential.deviceId)
|
|
62
|
-
.put("secret", credential.secret)
|
|
63
|
-
.toString()
|
|
64
|
-
|
|
65
|
-
val connection: HttpURLConnection = try {
|
|
66
|
-
(URL(endpoint).openConnection() as HttpURLConnection).apply {
|
|
67
|
-
requestMethod = "POST"
|
|
68
|
-
connectTimeout = CONNECT_TIMEOUT_MS
|
|
69
|
-
readTimeout = READ_TIMEOUT_MS
|
|
70
|
-
doOutput = true
|
|
71
|
-
// No Authorization header and no cookies, by design.
|
|
72
|
-
setRequestProperty("Content-Type", "application/json")
|
|
73
|
-
setRequestProperty("Accept", "application/json")
|
|
74
|
-
}
|
|
75
|
-
} catch (cause: IOException) {
|
|
76
|
-
return@withContext MintOutcome.Transient(cause)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
connection.outputStream.use { it.write(body.toByteArray(Charsets.UTF_8)) }
|
|
81
|
-
val status = connection.responseCode
|
|
82
|
-
if (status != HttpURLConnection.HTTP_OK) {
|
|
83
|
-
return@withContext classifyFailure(status, readErrorBody(connection))
|
|
84
|
-
}
|
|
85
|
-
val payload = connection.inputStream.bufferedReader().use { it.readText() }
|
|
86
|
-
parseMintResponse(payload)
|
|
87
|
-
} catch (cause: IOException) {
|
|
88
|
-
// Connect/read failure, DNS, TLS, a dropped socket mid-body.
|
|
89
|
-
MintOutcome.Transient(cause)
|
|
90
|
-
} finally {
|
|
91
|
-
connection.disconnect()
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Read the error body, tolerating its absence — `errorStream` is null for some
|
|
97
|
-
* statuses, and a failure to read the explanation of a failure must not become
|
|
98
|
-
* a different failure.
|
|
99
|
-
*/
|
|
100
|
-
private fun readErrorBody(connection: HttpURLConnection): String =
|
|
101
|
-
try {
|
|
102
|
-
connection.errorStream?.bufferedReader()?.use { it.readText() } ?: ""
|
|
103
|
-
} catch (cause: IOException) {
|
|
104
|
-
""
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* A non-200 becomes [MintOutcome.Revoked] ONLY on an explicit verdict; every
|
|
109
|
-
* other status and every unrecognised 401 is [MintOutcome.Transient] so the
|
|
110
|
-
* credential is kept. Substring matching on the raw body (rather than parsing
|
|
111
|
-
* it) is deliberate: it is what core does, and it survives the body being an
|
|
112
|
-
* error page rather than the JSON envelope.
|
|
113
|
-
*/
|
|
114
|
-
private fun classifyFailure(status: Int, body: String): MintOutcome {
|
|
115
|
-
if (status == HttpURLConnection.HTTP_UNAUTHORIZED &&
|
|
116
|
-
(body.contains(ERROR_CREDENTIAL_INVALID) || body.contains(ERROR_ACCOUNT_NOT_ON_DEVICE))
|
|
117
|
-
) {
|
|
118
|
-
return MintOutcome.Revoked
|
|
119
|
-
}
|
|
120
|
-
return MintOutcome.Transient(IOException("POST /session/device/background-token responded $status"))
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private fun parseMintResponse(payload: String): MintOutcome =
|
|
124
|
-
try {
|
|
125
|
-
val data = JSONObject(payload).getJSONObject("data")
|
|
126
|
-
val accessToken = data.getString("accessToken")
|
|
127
|
-
val accountId = data.getString("accountId")
|
|
128
|
-
val expiresAt = parseIsoInstant(data.getString("expiresAt"))
|
|
129
|
-
if (accessToken.isEmpty() || accountId.isEmpty()) {
|
|
130
|
-
MintOutcome.Malformed(JSONException("background-token response had an empty accessToken or accountId"))
|
|
131
|
-
} else {
|
|
132
|
-
MintOutcome.Minted(accessToken, expiresAt, accountId)
|
|
133
|
-
}
|
|
134
|
-
} catch (cause: JSONException) {
|
|
135
|
-
MintOutcome.Malformed(cause)
|
|
136
|
-
} catch (cause: ParseException) {
|
|
137
|
-
MintOutcome.Malformed(cause)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Parse the server's `expiresAt` into epoch millis.
|
|
142
|
-
*
|
|
143
|
-
* The shape is fixed rather than guessed: oxy-api emits it with JavaScript's
|
|
144
|
-
* `Date.toISOString()`, which is specified to produce exactly
|
|
145
|
-
* `yyyy-MM-ddTHH:mm:ss.sssZ`. `SimpleDateFormat` (rather than `java.time`)
|
|
146
|
-
* because `Instant.parse` needs API 26 or core-library desugaring, and this
|
|
147
|
-
* module must compile for every consuming app's minSdk without imposing a
|
|
148
|
-
* build-config requirement on them.
|
|
149
|
-
*
|
|
150
|
-
* Anything else throws [ParseException], which the caller classifies as
|
|
151
|
-
* `Malformed` — never a silent fallback to a made-up expiry, which would either
|
|
152
|
-
* throw away a valid token or keep using a dead one.
|
|
153
|
-
*/
|
|
154
|
-
private fun parseIsoInstant(value: String): Long {
|
|
155
|
-
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.US).apply {
|
|
156
|
-
timeZone = TimeZone.getTimeZone("UTC")
|
|
157
|
-
isLenient = false
|
|
158
|
-
}
|
|
159
|
-
val parsed = format.parse(value) ?: throw ParseException("unparseable expiresAt: $value", 0)
|
|
160
|
-
return parsed.time
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
package so.oxy.session
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import expo.modules.kotlin.exception.Exceptions
|
|
5
|
-
import expo.modules.kotlin.modules.Module
|
|
6
|
-
import expo.modules.kotlin.modules.ModuleDefinition
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* JS side of the background session credential.
|
|
10
|
-
*
|
|
11
|
-
* JS is the only writer of the credential and native background code is the only
|
|
12
|
-
* consumer, so this bridge is deliberately one-way: put, clear, and a read of the
|
|
13
|
-
* account id (which JS needs to notice that the stored credential belongs to a
|
|
14
|
-
* different account than the one now signed in). There is no `get` — JS has no
|
|
15
|
-
* use for the secret it just wrote, and not exposing it keeps the secret's only
|
|
16
|
-
* reader native.
|
|
17
|
-
*
|
|
18
|
-
* Every function is a no-op-or-null on failure rather than throwing: the app must
|
|
19
|
-
* work identically whether or not background credentials are available, and a
|
|
20
|
-
* keystore hiccup must never break sign-in.
|
|
21
|
-
*/
|
|
22
|
-
class OxyBackgroundSessionModule : Module() {
|
|
23
|
-
private val context: Context
|
|
24
|
-
get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
|
|
25
|
-
|
|
26
|
-
override fun definition() = ModuleDefinition {
|
|
27
|
-
Name("OxyBackgroundSession")
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Store (replacing) the credential. Rejects an incomplete or already-expired
|
|
31
|
-
* one rather than persisting something no mint could ever use.
|
|
32
|
-
*
|
|
33
|
-
* ## Five scalars, not a `Record`, and that is not a style choice
|
|
34
|
-
*
|
|
35
|
-
* This took a `Record` and it did not work on a device: every call was rejected
|
|
36
|
-
* with `The 1st argument cannot be cast to type CredentialInput (received class
|
|
37
|
-
* ReadableNativeMap)`, preceded by `Introspectable data is missing for class
|
|
38
|
-
* CredentialInput. Falling back to reflection-based conversion`. The fallback
|
|
39
|
-
* then failed too, so nothing was ever stored — the provision succeeded, the
|
|
40
|
-
* server issued a credential, and the widget stayed signed out forever with only
|
|
41
|
-
* a warning in the log to show for it.
|
|
42
|
-
*
|
|
43
|
-
* The reason is where this package's Kotlin lives: it ships as SOURCE that each
|
|
44
|
-
* consuming app compiles, so the annotation processing that generates a `Record`'s
|
|
45
|
-
* introspection metadata does not necessarily run in the consumer's build. The
|
|
46
|
-
* sibling module in this same library, `OxyIdentityModule`, has always passed
|
|
47
|
-
* plain scalars (`putShared(privateKey, publicKey)`) and has always worked — so
|
|
48
|
-
* scalars are the proven shape here and `CredentialInput` was the only `Record`
|
|
49
|
-
* in the package, i.e. the one untested path.
|
|
50
|
-
*
|
|
51
|
-
* Do not "tidy" these five parameters back into a `Record` without first proving
|
|
52
|
-
* on a real device that a `Record` converts at all in a consumer build. The
|
|
53
|
-
* failure is silent from JS's side: it surfaces as a widget that never signs in.
|
|
54
|
-
*
|
|
55
|
-
* `expiresAt` is epoch MILLIS as a `Double`, already parsed from the server's
|
|
56
|
-
* ISO-8601 string on the JS side — JS has a `Date`, so there is no reason to hand
|
|
57
|
-
* native a string to re-parse. `Double` because that is what a JS number crosses
|
|
58
|
-
* the bridge as; a `Long` parameter would fail to convert for the same family of
|
|
59
|
-
* reason this comment exists.
|
|
60
|
-
*/
|
|
61
|
-
AsyncFunction("put") { baseUrl: String,
|
|
62
|
-
deviceId: String,
|
|
63
|
-
secret: String,
|
|
64
|
-
accountId: String,
|
|
65
|
-
expiresAtMs: Double ->
|
|
66
|
-
val expiresAt = expiresAtMs.toLong()
|
|
67
|
-
if (
|
|
68
|
-
baseUrl.isEmpty() ||
|
|
69
|
-
deviceId.isEmpty() ||
|
|
70
|
-
secret.isEmpty() ||
|
|
71
|
-
accountId.isEmpty() ||
|
|
72
|
-
expiresAt <= System.currentTimeMillis()
|
|
73
|
-
) {
|
|
74
|
-
return@AsyncFunction false
|
|
75
|
-
}
|
|
76
|
-
runCatching {
|
|
77
|
-
OxyBackgroundSessionStore.writeCredential(
|
|
78
|
-
context,
|
|
79
|
-
OxyBackgroundSessionStore.Credential(
|
|
80
|
-
baseUrl = baseUrl,
|
|
81
|
-
deviceId = deviceId,
|
|
82
|
-
secret = secret,
|
|
83
|
-
accountId = accountId,
|
|
84
|
-
expiresAt = expiresAt,
|
|
85
|
-
),
|
|
86
|
-
)
|
|
87
|
-
}.isSuccess
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Drop the credential and any cached token. Called on sign-out and BEFORE an
|
|
92
|
-
* account switch, so the window in which background code could serve the
|
|
93
|
-
* previous account's data is as short as a local write.
|
|
94
|
-
*/
|
|
95
|
-
AsyncFunction("clear") {
|
|
96
|
-
runCatching { OxyBackgroundSessionStore.clear(context) }.isSuccess
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* What is currently stored — the account it belongs to and when it expires
|
|
101
|
-
* (epoch millis) — or null when there is no usable credential.
|
|
102
|
-
*
|
|
103
|
-
* This is what lets JS decide whether to provision at all: a credential for
|
|
104
|
-
* the signed-in account with plenty of life left needs no network call. It
|
|
105
|
-
* deliberately does NOT return the secret; native is its only reader.
|
|
106
|
-
*/
|
|
107
|
-
AsyncFunction("peek") {
|
|
108
|
-
val stored = runCatching { OxyBackgroundSessionStore.readCredential(context) }.getOrNull()
|
|
109
|
-
?: return@AsyncFunction null
|
|
110
|
-
mapOf(
|
|
111
|
-
"accountId" to stored.accountId,
|
|
112
|
-
"expiresAt" to stored.expiresAt.toDouble(),
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|