@oxyhq/services 22.12.4 → 22.13.0
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 +16 -46
- package/lib/commonjs/index.js +18 -12
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/boot/runProviderColdBoot.js +51 -9
- package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/commonjs/ui/client.js +0 -13
- package/lib/commonjs/ui/client.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +27 -4
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAuthChooser.js +72 -1123
- package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/commonjs/ui/components/OxyConsentScreen.js +50 -12
- package/lib/commonjs/ui/components/OxyConsentScreen.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +4 -4
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js +74 -40
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +527 -0
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +90 -0
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/SignInRequestView.js +144 -0
- package/lib/commonjs/ui/components/authChooser/SignInRequestView.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/SignUpView.js +188 -0
- package/lib/commonjs/ui/components/authChooser/SignUpView.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js +63 -0
- package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/primitives.js +169 -0
- package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/requestSurfaces.js +149 -0
- package/lib/commonjs/ui/components/authChooser/requestSurfaces.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/signInProgress.js +54 -0
- package/lib/commonjs/ui/components/authChooser/signInProgress.js.map +1 -0
- package/lib/commonjs/ui/components/{oxyAuthChooserStyles.js → authChooser/styles.js} +19 -1
- package/lib/commonjs/ui/components/authChooser/styles.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/types.js +59 -0
- package/lib/commonjs/ui/components/authChooser/types.js.map +1 -0
- package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +50 -0
- package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +1 -0
- package/lib/commonjs/ui/context/OxyContext.js +205 -30
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/commitSessionFlow.js +46 -0
- package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +15 -2
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/context/useOxyAccountGraph.js +13 -5
- package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +6 -1
- package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +1 -1
- package/lib/commonjs/ui/index.js +0 -13
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/oauth/browserAuthTransport.js +170 -0
- package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -0
- package/lib/commonjs/ui/oauth/completeOAuthCode.js +78 -0
- package/lib/commonjs/ui/oauth/completeOAuthCode.js.map +1 -0
- package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +48 -0
- package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +1 -0
- package/lib/commonjs/ui/oauth/oauthHandshake.js +53 -0
- package/lib/commonjs/ui/oauth/oauthHandshake.js.map +1 -0
- package/lib/commonjs/ui/oauth/oauthPopup.js +276 -0
- package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -0
- package/lib/commonjs/ui/oauth/oauthPopupMessages.js +141 -0
- package/lib/commonjs/ui/oauth/oauthPopupMessages.js.map +1 -0
- package/lib/commonjs/ui/oauth/types.js +2 -0
- package/lib/commonjs/ui/oauth/types.js.map +1 -0
- package/lib/commonjs/ui/server.js +2 -5
- package/lib/commonjs/ui/server.js.map +1 -1
- package/lib/commonjs/ui/session/authStore.js +6 -75
- package/lib/commonjs/ui/session/authStore.js.map +1 -1
- package/lib/commonjs/ui/session/createSessionClient.js +11 -3
- package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
- package/lib/commonjs/ui/session/identityBinding.js +95 -0
- package/lib/commonjs/ui/session/identityBinding.js.map +1 -0
- package/lib/commonjs/ui/session/index.js +13 -0
- package/lib/commonjs/ui/session/index.js.map +1 -1
- package/lib/commonjs/ui/session/nativeSecureStorage.js +90 -0
- package/lib/commonjs/ui/session/nativeSecureStorage.js.map +1 -0
- package/lib/commonjs/ui/session/tokenTransport.js +11 -1
- package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
- package/lib/commonjs/ui/utils/crossOriginRestore.js +5 -4
- package/lib/commonjs/ui/utils/crossOriginRestore.js.map +1 -1
- package/lib/commonjs/ui/utils/deliveryPlatform.js +58 -0
- package/lib/commonjs/ui/utils/deliveryPlatform.js.map +1 -0
- package/lib/commonjs/ui/utils/oauthReturn.js +72 -46
- package/lib/commonjs/ui/utils/oauthReturn.js.map +1 -1
- package/lib/module/index.js +9 -4
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/boot/runProviderColdBoot.js +51 -9
- package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/module/ui/client.js +0 -1
- package/lib/module/ui/client.js.map +1 -1
- package/lib/module/ui/components/OxyAccountDialogScreen.js +27 -4
- package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/module/ui/components/OxyAuthChooser.js +76 -1128
- package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/module/ui/components/OxyConsentScreen.js +50 -12
- package/lib/module/ui/components/OxyConsentScreen.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +4 -4
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js +76 -42
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/authChooser/AccountsMenuView.js +523 -0
- package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -0
- package/lib/module/ui/components/authChooser/SignInEntryView.js +85 -0
- package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -0
- package/lib/module/ui/components/authChooser/SignInRequestView.js +139 -0
- package/lib/module/ui/components/authChooser/SignInRequestView.js.map +1 -0
- package/lib/module/ui/components/authChooser/SignUpView.js +184 -0
- package/lib/module/ui/components/authChooser/SignUpView.js.map +1 -0
- package/lib/module/ui/components/authChooser/TroubleDisclosure.js +59 -0
- package/lib/module/ui/components/authChooser/TroubleDisclosure.js.map +1 -0
- package/lib/module/ui/components/authChooser/primitives.js +163 -0
- package/lib/module/ui/components/authChooser/primitives.js.map +1 -0
- package/lib/module/ui/components/authChooser/requestSurfaces.js +139 -0
- package/lib/module/ui/components/authChooser/requestSurfaces.js.map +1 -0
- package/lib/module/ui/components/authChooser/signInProgress.js +50 -0
- package/lib/module/ui/components/authChooser/signInProgress.js.map +1 -0
- package/lib/module/ui/components/{oxyAuthChooserStyles.js → authChooser/styles.js} +19 -1
- package/lib/module/ui/components/authChooser/styles.js.map +1 -0
- package/lib/module/ui/components/authChooser/types.js +55 -0
- package/lib/module/ui/components/authChooser/types.js.map +1 -0
- package/lib/module/ui/components/authChooser/useUsernameAvailability.js +46 -0
- package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +1 -0
- package/lib/module/ui/context/OxyContext.js +208 -33
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/commitSessionFlow.js +45 -0
- package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +15 -2
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/context/useOxyAccountGraph.js +13 -5
- package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/module/ui/hooks/useSwitchableAccounts.js +6 -1
- package/lib/module/ui/hooks/useSwitchableAccounts.js.map +1 -1
- package/lib/module/ui/index.js +0 -1
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/oauth/browserAuthTransport.js +167 -0
- package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -0
- package/lib/module/ui/oauth/completeOAuthCode.js +75 -0
- package/lib/module/ui/oauth/completeOAuthCode.js.map +1 -0
- package/lib/module/ui/oauth/legacyRedirectLanes.js +44 -0
- package/lib/module/ui/oauth/legacyRedirectLanes.js.map +1 -0
- package/lib/module/ui/oauth/oauthHandshake.js +50 -0
- package/lib/module/ui/oauth/oauthHandshake.js.map +1 -0
- package/lib/module/ui/oauth/oauthPopup.js +268 -0
- package/lib/module/ui/oauth/oauthPopup.js.map +1 -0
- package/lib/module/ui/oauth/oauthPopupMessages.js +135 -0
- package/lib/module/ui/oauth/oauthPopupMessages.js.map +1 -0
- package/lib/module/ui/oauth/types.js +2 -0
- package/lib/module/ui/oauth/types.js.map +1 -0
- package/lib/module/ui/server.js +0 -2
- package/lib/module/ui/server.js.map +1 -1
- package/lib/module/ui/session/authStore.js +5 -75
- package/lib/module/ui/session/authStore.js.map +1 -1
- package/lib/module/ui/session/createSessionClient.js +11 -3
- package/lib/module/ui/session/createSessionClient.js.map +1 -1
- package/lib/module/ui/session/identityBinding.js +89 -0
- package/lib/module/ui/session/identityBinding.js.map +1 -0
- package/lib/module/ui/session/index.js +5 -2
- package/lib/module/ui/session/index.js.map +1 -1
- package/lib/module/ui/session/nativeSecureStorage.js +88 -0
- package/lib/module/ui/session/nativeSecureStorage.js.map +1 -0
- package/lib/module/ui/session/tokenTransport.js +11 -1
- package/lib/module/ui/session/tokenTransport.js.map +1 -1
- package/lib/module/ui/utils/crossOriginRestore.js +6 -5
- package/lib/module/ui/utils/crossOriginRestore.js.map +1 -1
- package/lib/module/ui/utils/deliveryPlatform.js +55 -0
- package/lib/module/ui/utils/deliveryPlatform.js.map +1 -0
- package/lib/module/ui/utils/oauthReturn.js +73 -47
- package/lib/module/ui/utils/oauthReturn.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +4 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts +34 -2
- package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/client.d.ts +0 -1
- package/lib/typescript/commonjs/ui/client.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 +21 -29
- package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyConsentScreen.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 +17 -12
- package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +38 -0
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +32 -0
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts +34 -0
- package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts +34 -0
- package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts +43 -0
- package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +55 -0
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts +54 -0
- package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts +26 -0
- package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts.map +1 -0
- package/lib/typescript/{module/ui/components/oxyAuthChooserStyles.d.ts → commonjs/ui/components/authChooser/styles.d.ts} +19 -1
- package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +85 -0
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts +16 -0
- package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts.map +1 -0
- 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 +11 -2
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +44 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +7 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts +0 -1
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts +56 -0
- package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/oauth/completeOAuthCode.d.ts +49 -0
- package/lib/typescript/commonjs/ui/oauth/completeOAuthCode.d.ts.map +1 -0
- 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/oauthHandshake.d.ts +50 -0
- package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +83 -0
- package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/oauth/oauthPopupMessages.d.ts +67 -0
- package/lib/typescript/commonjs/ui/oauth/oauthPopupMessages.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/oauth/types.d.ts +176 -0
- package/lib/typescript/commonjs/ui/oauth/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/server.d.ts +0 -2
- package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/authStore.d.ts +3 -7
- package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +8 -1
- package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/identityBinding.d.ts +66 -0
- package/lib/typescript/commonjs/ui/session/identityBinding.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/session/index.d.ts +6 -2
- package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/nativeSecureStorage.d.ts +25 -0
- package/lib/typescript/commonjs/ui/session/nativeSecureStorage.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +8 -1
- package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +44 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/deliveryPlatform.d.ts +33 -0
- package/lib/typescript/commonjs/ui/utils/deliveryPlatform.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts +30 -16
- package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +4 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts +34 -2
- package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/module/ui/client.d.ts +0 -1
- package/lib/typescript/module/ui/client.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 +21 -29
- package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyConsentScreen.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 +17 -12
- package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +38 -0
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +32 -0
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts +34 -0
- package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts +34 -0
- package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts +43 -0
- package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +55 -0
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts +54 -0
- package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts +26 -0
- package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts.map +1 -0
- package/lib/typescript/{commonjs/ui/components/oxyAuthChooserStyles.d.ts → module/ui/components/authChooser/styles.d.ts} +19 -1
- package/lib/typescript/module/ui/components/authChooser/styles.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/types.d.ts +85 -0
- package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts +16 -0
- package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts.map +1 -0
- 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 +11 -2
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +44 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +7 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
- package/lib/typescript/module/ui/index.d.ts +0 -1
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts +56 -0
- package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -0
- package/lib/typescript/module/ui/oauth/completeOAuthCode.d.ts +49 -0
- package/lib/typescript/module/ui/oauth/completeOAuthCode.d.ts.map +1 -0
- 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/oauthHandshake.d.ts +50 -0
- package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts.map +1 -0
- package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +83 -0
- package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -0
- package/lib/typescript/module/ui/oauth/oauthPopupMessages.d.ts +67 -0
- package/lib/typescript/module/ui/oauth/oauthPopupMessages.d.ts.map +1 -0
- package/lib/typescript/module/ui/oauth/types.d.ts +176 -0
- package/lib/typescript/module/ui/oauth/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/server.d.ts +0 -2
- package/lib/typescript/module/ui/server.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/authStore.d.ts +3 -7
- package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/createSessionClient.d.ts +8 -1
- package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/identityBinding.d.ts +66 -0
- package/lib/typescript/module/ui/session/identityBinding.d.ts.map +1 -0
- package/lib/typescript/module/ui/session/index.d.ts +6 -2
- package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/nativeSecureStorage.d.ts +25 -0
- package/lib/typescript/module/ui/session/nativeSecureStorage.d.ts.map +1 -0
- package/lib/typescript/module/ui/session/tokenTransport.d.ts +8 -1
- package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +44 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/deliveryPlatform.d.ts +33 -0
- package/lib/typescript/module/ui/utils/deliveryPlatform.d.ts.map +1 -0
- package/lib/typescript/module/ui/utils/oauthReturn.d.ts +30 -16
- package/lib/typescript/module/ui/utils/oauthReturn.d.ts.map +1 -1
- package/package.json +6 -8
- package/src/index.ts +19 -5
- package/src/ui/boot/__tests__/coldBootWebAuthMode.test.ts +281 -0
- package/src/ui/boot/runProviderColdBoot.ts +83 -13
- package/src/ui/client.ts +0 -1
- package/src/ui/components/OxyAccountDialogScreen.tsx +33 -4
- package/src/ui/components/OxyAuthChooser.tsx +100 -1230
- package/src/ui/components/OxyConsentScreen.tsx +56 -13
- package/src/ui/components/OxyProvider.tsx +4 -4
- package/src/ui/components/OxySignInButton.tsx +119 -78
- package/src/ui/components/__tests__/OxyConsentScreen.test.tsx +27 -0
- package/src/ui/components/authChooser/AccountsMenuView.tsx +569 -0
- package/src/ui/components/authChooser/SignInEntryView.tsx +115 -0
- package/src/ui/components/authChooser/SignInRequestView.tsx +163 -0
- package/src/ui/components/authChooser/SignUpView.tsx +174 -0
- package/src/ui/components/authChooser/TroubleDisclosure.tsx +81 -0
- package/src/ui/components/authChooser/primitives.tsx +144 -0
- package/src/ui/components/authChooser/requestSurfaces.tsx +116 -0
- package/src/ui/components/authChooser/signInProgress.ts +54 -0
- package/src/ui/components/{oxyAuthChooserStyles.ts → authChooser/styles.ts} +18 -0
- package/src/ui/components/authChooser/types.ts +101 -0
- package/src/ui/components/authChooser/useUsernameAvailability.ts +60 -0
- package/src/ui/context/OxyContext.tsx +226 -24
- package/src/ui/context/__tests__/commitSessionFlow.test.ts +102 -0
- package/src/ui/context/commitSessionFlow.ts +64 -0
- package/src/ui/context/hooks/useAuthOperations.ts +26 -1
- package/src/ui/context/oxyContextTypes.ts +45 -1
- package/src/ui/context/useOxyAccountGraph.ts +19 -5
- package/src/ui/hooks/useSwitchableAccounts.ts +12 -1
- package/src/ui/index.ts +0 -1
- package/src/ui/oauth/__tests__/browserAuthTransport.test.ts +335 -0
- package/src/ui/oauth/__tests__/completeOAuthCode.test.ts +142 -0
- package/src/ui/oauth/__tests__/oauthPopup.test.ts +352 -0
- package/src/ui/oauth/__tests__/oauthPopupMessages.test.ts +189 -0
- package/src/ui/oauth/__tests__/sharedCompletionPath.test.ts +174 -0
- package/src/ui/oauth/browserAuthTransport.ts +193 -0
- package/src/ui/oauth/completeOAuthCode.ts +93 -0
- package/src/ui/oauth/legacyRedirectLanes.ts +43 -0
- package/src/ui/oauth/oauthHandshake.ts +74 -0
- package/src/ui/oauth/oauthPopup.ts +277 -0
- package/src/ui/oauth/oauthPopupMessages.ts +136 -0
- package/src/ui/oauth/types.ts +150 -0
- package/src/ui/server.ts +0 -2
- package/src/ui/session/__tests__/createSessionClient.test.ts +26 -0
- package/src/ui/session/__tests__/tokenTransport.test.ts +34 -0
- package/src/ui/session/authStore.ts +5 -89
- package/src/ui/session/createSessionClient.ts +15 -2
- package/src/ui/session/identityBinding.ts +116 -0
- package/src/ui/session/index.ts +6 -2
- package/src/ui/session/nativeSecureStorage.ts +98 -0
- package/src/ui/session/tokenTransport.ts +14 -1
- package/src/ui/types/navigation.ts +44 -1
- package/src/ui/utils/__tests__/crossOriginRestore.test.ts +17 -0
- package/src/ui/utils/crossOriginRestore.ts +9 -13
- package/src/ui/utils/deliveryPlatform.ts +65 -0
- package/src/ui/utils/oauthReturn.ts +79 -65
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
- package/lib/commonjs/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
- package/lib/commonjs/ui/components/FontLoader.js +0 -35
- package/lib/commonjs/ui/components/FontLoader.js.map +0 -1
- package/lib/commonjs/ui/components/FontLoader.native.js +0 -88
- package/lib/commonjs/ui/components/FontLoader.native.js.map +0 -1
- package/lib/commonjs/ui/components/oxyAuthChooserStyles.js.map +0 -1
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
- package/lib/module/assets/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
- package/lib/module/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
- package/lib/module/ui/components/FontLoader.js +0 -29
- package/lib/module/ui/components/FontLoader.js.map +0 -1
- package/lib/module/ui/components/FontLoader.native.js +0 -83
- package/lib/module/ui/components/FontLoader.native.js.map +0 -1
- package/lib/module/ui/components/oxyAuthChooserStyles.js.map +0 -1
- package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +0 -24
- package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts +0 -13
- package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/FontLoader.d.ts +0 -24
- package/lib/typescript/module/ui/components/FontLoader.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/FontLoader.native.d.ts +0 -13
- package/lib/typescript/module/ui/components/FontLoader.native.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts.map +0 -1
- package/src/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
- package/src/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
- package/src/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
- package/src/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
- package/src/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
- package/src/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
- package/src/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
- package/src/ui/components/FontLoader.native.tsx +0 -88
- package/src/ui/components/FontLoader.tsx +0 -27
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The RP half of an OAuth authorize request: a fresh CSRF `state` + PKCE pair,
|
|
5
|
+
* and the authorize URL built from them.
|
|
6
|
+
*
|
|
7
|
+
* Both web transports start here, and the ONLY difference between them is one
|
|
8
|
+
* parameter: `popup` asks the IdP for `response_mode=web_message` so the result
|
|
9
|
+
* comes back to `window.opener` instead of navigating the RP's tab. Everything
|
|
10
|
+
* else — `S256` PKCE, exact registered `redirect_uri`, random `state` — is
|
|
11
|
+
* identical, which is what lets both lanes converge on one completion path.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { buildOAuthAuthorizeUrl, generateOAuthState, generatePkcePair } from '@oxyhq/core';
|
|
15
|
+
|
|
16
|
+
/** Inputs for {@link prepareAuthorizeRequest}. */
|
|
17
|
+
|
|
18
|
+
/** A ready-to-use authorize request plus the secrets that finish it. */
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Generate a fresh handshake and build the authorize URL around it.
|
|
22
|
+
*
|
|
23
|
+
* The verifier is returned to the caller and never stored here: the popup
|
|
24
|
+
* transport keeps it in memory for the lifetime of the attempt, and the
|
|
25
|
+
* redirect transport persists it through `persistOAuthHandshake` because a
|
|
26
|
+
* full-page navigation destroys the running document.
|
|
27
|
+
*/
|
|
28
|
+
export async function prepareAuthorizeRequest(params) {
|
|
29
|
+
const [pkce, state] = await Promise.all([generatePkcePair(), generateOAuthState()]);
|
|
30
|
+
const authorizeUrl = buildOAuthAuthorizeUrl({
|
|
31
|
+
authorizeBaseUrl: params.authorizeBaseUrl,
|
|
32
|
+
clientId: params.clientId,
|
|
33
|
+
redirectUri: params.redirectUri,
|
|
34
|
+
scope: params.scope,
|
|
35
|
+
state,
|
|
36
|
+
codeChallenge: pkce.codeChallenge,
|
|
37
|
+
...(params.responseMode ? {
|
|
38
|
+
responseMode: params.responseMode
|
|
39
|
+
} : {})
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
authorizeUrl,
|
|
43
|
+
authorizeOrigin: new URL(authorizeUrl).origin,
|
|
44
|
+
handshake: {
|
|
45
|
+
state,
|
|
46
|
+
codeVerifier: pkce.codeVerifier
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=oauthHandshake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["buildOAuthAuthorizeUrl","generateOAuthState","generatePkcePair","prepareAuthorizeRequest","params","pkce","state","Promise","all","authorizeUrl","authorizeBaseUrl","clientId","redirectUri","scope","codeChallenge","responseMode","authorizeOrigin","URL","origin","handshake","codeVerifier"],"sourceRoot":"../../../../src","sources":["ui/oauth/oauthHandshake.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,sBAAsB,EAAEC,kBAAkB,EAAEC,gBAAgB,QAAQ,aAAa;;AAG1F;;AAkBA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeC,uBAAuBA,CAC3CC,MAAqC,EACF;EACnC,MAAM,CAACC,IAAI,EAAEC,KAAK,CAAC,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CAACN,gBAAgB,CAAC,CAAC,EAAED,kBAAkB,CAAC,CAAC,CAAC,CAAC;EAEnF,MAAMQ,YAAY,GAAGT,sBAAsB,CAAC;IAC1CU,gBAAgB,EAAEN,MAAM,CAACM,gBAAgB;IACzCC,QAAQ,EAAEP,MAAM,CAACO,QAAQ;IACzBC,WAAW,EAAER,MAAM,CAACQ,WAAW;IAC/BC,KAAK,EAAET,MAAM,CAACS,KAAK;IACnBP,KAAK;IACLQ,aAAa,EAAET,IAAI,CAACS,aAAa;IACjC,IAAIV,MAAM,CAACW,YAAY,GAAG;MAAEA,YAAY,EAAEX,MAAM,CAACW;IAAa,CAAC,GAAG,CAAC,CAAC;EACtE,CAAC,CAAC;EAEF,OAAO;IACLN,YAAY;IACZO,eAAe,EAAE,IAAIC,GAAG,CAACR,YAAY,CAAC,CAACS,MAAM;IAC7CC,SAAS,EAAE;MAAEb,KAAK;MAAEc,YAAY,EAAEf,IAAI,CAACe;IAAa;EACtD,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Popup lifecycle for the web OAuth transport.
|
|
5
|
+
*
|
|
6
|
+
* Owns the window itself — opening it, navigating it, watching it, and tearing
|
|
7
|
+
* every listener and timer down — and nothing else: message validation lives in
|
|
8
|
+
* `oauthPopupMessages.ts`, and the code exchange in `completeOAuthCode.ts`.
|
|
9
|
+
*
|
|
10
|
+
* Three browser realities shape this module:
|
|
11
|
+
*
|
|
12
|
+
* - **Gesture attribution.** `window.open` only succeeds while the user's click
|
|
13
|
+
* is still being handled. Anything awaited first (resolving the application,
|
|
14
|
+
* generating PKCE) loses it and the popup is silently blocked. So the window
|
|
15
|
+
* is opened EMPTY up front and navigated once the authorize URL exists —
|
|
16
|
+
* the same shape as `passkeyHubPopup.ts`.
|
|
17
|
+
* - **No close event.** A cross-origin popup fires nothing when the user
|
|
18
|
+
* dismisses it; polling `closed` is the only mechanism (as in core's
|
|
19
|
+
* `AccountDialogController.watchPopup`).
|
|
20
|
+
* - **No cross-origin reads.** The popup's URL, title, and document are all
|
|
21
|
+
* opaque. The authorization result arrives ONLY as a `postMessage`.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { canonicalizeOAuthRedirectUri, logger } from '@oxyhq/core';
|
|
25
|
+
import { readOAuthPopupMessage } from "./oauthPopupMessages.js";
|
|
26
|
+
/**
|
|
27
|
+
* Window name for the sign-in popup. Naming the target means a second press
|
|
28
|
+
* REUSES the same window instead of stacking a new one behind the first.
|
|
29
|
+
*/
|
|
30
|
+
export const OXY_OAUTH_POPUP_WINDOW_NAME = 'oxy-oauth';
|
|
31
|
+
|
|
32
|
+
/** Chrome-free window roughly sized for the IdP's sign-in / QR surface. */
|
|
33
|
+
const POPUP_FEATURES = 'popup=yes,width=460,height=700,menubar=no,toolbar=no,location=no,status=no';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* How long a popup sign-in may stay unanswered (ms).
|
|
37
|
+
*
|
|
38
|
+
* Generous on purpose: the IdP surface can involve scanning a QR and approving
|
|
39
|
+
* on a phone, so this tracks the authorize handle's own ~5-minute lifetime
|
|
40
|
+
* rather than a UI-scale timeout. It is a backstop against a wedged popup, not
|
|
41
|
+
* a pace-setter — a user who gives up closes the window and gets the faster
|
|
42
|
+
* `closed` outcome.
|
|
43
|
+
*/
|
|
44
|
+
export const DEFAULT_OAUTH_POPUP_TIMEOUT_MS = 300_000;
|
|
45
|
+
|
|
46
|
+
/** How often the popup's `closed` flag is sampled (ms). */
|
|
47
|
+
const CLOSE_POLL_INTERVAL_MS = 1000;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Grace period (ms) after `closed` flips before reporting cancellation.
|
|
51
|
+
*
|
|
52
|
+
* The IdP posts its result and THEN closes itself. Both land as separate tasks,
|
|
53
|
+
* so a poll tick that happens to fall between them would otherwise turn a
|
|
54
|
+
* successful sign-in into a "user cancelled". One short grace window lets the
|
|
55
|
+
* already-queued message win.
|
|
56
|
+
*/
|
|
57
|
+
const CLOSE_GRACE_MS = 400;
|
|
58
|
+
|
|
59
|
+
/** The `message` half of the DOM host, absent on native and during SSR. */
|
|
60
|
+
|
|
61
|
+
/** The `open` half of the DOM host, absent on native and during SSR. */
|
|
62
|
+
|
|
63
|
+
function messageEventHost() {
|
|
64
|
+
const win = globalThis.window;
|
|
65
|
+
if (!win || typeof win.addEventListener !== 'function' || typeof win.removeEventListener !== 'function') {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return win;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Open a new, EMPTY sign-in popup.
|
|
73
|
+
*
|
|
74
|
+
* MUST be called SYNCHRONOUSLY from a user-gesture handler, before any `await`.
|
|
75
|
+
* Returns `null` when the browser blocked it, when `window.open` threw, and on
|
|
76
|
+
* hosts with no DOM (native / SSR) — never throws, because "no popup" is an
|
|
77
|
+
* ordinary outcome the caller answers by falling back to a redirect.
|
|
78
|
+
*/
|
|
79
|
+
export function openOAuthPopup() {
|
|
80
|
+
const win = globalThis.window;
|
|
81
|
+
if (!win || typeof win.open !== 'function') return null;
|
|
82
|
+
try {
|
|
83
|
+
return win.open('', OXY_OAUTH_POPUP_WINDOW_NAME, POPUP_FEATURES) ?? null;
|
|
84
|
+
} catch (error) {
|
|
85
|
+
logger.warn('Could not open the OAuth sign-in popup', {
|
|
86
|
+
component: 'oauthPopup'
|
|
87
|
+
}, error);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Point an already-open popup at the authorize URL. Returns `false` when the
|
|
94
|
+
* assignment threw (a window closed between opening and navigating), so the
|
|
95
|
+
* caller can fall back to a redirect instead of waiting on a dead window.
|
|
96
|
+
*/
|
|
97
|
+
export function navigateOAuthPopup(popup, url) {
|
|
98
|
+
try {
|
|
99
|
+
popup.location.href = url;
|
|
100
|
+
return true;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
logger.warn('Could not navigate the OAuth sign-in popup', {
|
|
103
|
+
component: 'oauthPopup'
|
|
104
|
+
}, error);
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Close the popup if it is still open. Idempotent, null-safe, never throws. */
|
|
110
|
+
export function closeOAuthPopup(popup) {
|
|
111
|
+
if (!popup || popup.closed) return;
|
|
112
|
+
try {
|
|
113
|
+
popup.close();
|
|
114
|
+
} catch (error) {
|
|
115
|
+
logger.debug('OAuth popup close failed', {
|
|
116
|
+
component: 'oauthPopup'
|
|
117
|
+
}, error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* When the IdP falls back to a top-level redirect inside the popup (no usable
|
|
123
|
+
* `window.opener`), a same-origin `redirect_uri` is readable from the opener.
|
|
124
|
+
* Cross-origin redirects remain opaque and are not handled here.
|
|
125
|
+
*/
|
|
126
|
+
function readSameOriginRedirectOutcome(popup, redirectUri, expectedState) {
|
|
127
|
+
try {
|
|
128
|
+
const href = popup.location.href;
|
|
129
|
+
if (!href) return null;
|
|
130
|
+
const popupUrl = new URL(href);
|
|
131
|
+
const expected = new URL(canonicalizeOAuthRedirectUri(redirectUri));
|
|
132
|
+
if (popupUrl.origin !== expected.origin) return null;
|
|
133
|
+
if (popupUrl.pathname !== expected.pathname) return null;
|
|
134
|
+
const oauthError = popupUrl.searchParams.get('error');
|
|
135
|
+
if (oauthError) {
|
|
136
|
+
const errorDescription = popupUrl.searchParams.get('error_description') ?? undefined;
|
|
137
|
+
return {
|
|
138
|
+
kind: 'oauth-error',
|
|
139
|
+
error: oauthError,
|
|
140
|
+
...(errorDescription ? {
|
|
141
|
+
errorDescription
|
|
142
|
+
} : {})
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const code = popupUrl.searchParams.get('code');
|
|
146
|
+
if (!code) return null;
|
|
147
|
+
const state = popupUrl.searchParams.get('state');
|
|
148
|
+
if (!state || state !== expectedState) return {
|
|
149
|
+
kind: 'state-mismatch'
|
|
150
|
+
};
|
|
151
|
+
return {
|
|
152
|
+
kind: 'code',
|
|
153
|
+
code,
|
|
154
|
+
state
|
|
155
|
+
};
|
|
156
|
+
} catch {
|
|
157
|
+
// Cross-origin navigation — the popup URL is opaque to the opener.
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Inputs for {@link awaitOAuthPopupResult}. */
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Wait for the popup to deliver an authorization result.
|
|
166
|
+
*
|
|
167
|
+
* Settles EXACTLY once, with a typed outcome for every path — code, IdP error,
|
|
168
|
+
* state mismatch, user-closed, timeout — and removes its listener, its close
|
|
169
|
+
* poll, and both timers before resolving, whatever the outcome. Messages that
|
|
170
|
+
* arrive after settling reach nothing, so a duplicate delivery is inert.
|
|
171
|
+
*
|
|
172
|
+
* Never rejects: closing the window and running out of time are expected
|
|
173
|
+
* outcomes, not exceptions.
|
|
174
|
+
*/
|
|
175
|
+
export function awaitOAuthPopupResult(options) {
|
|
176
|
+
const {
|
|
177
|
+
popup,
|
|
178
|
+
expectedOrigin,
|
|
179
|
+
expectedState,
|
|
180
|
+
redirectUri,
|
|
181
|
+
timeoutMs = DEFAULT_OAUTH_POPUP_TIMEOUT_MS
|
|
182
|
+
} = options;
|
|
183
|
+
const host = messageEventHost();
|
|
184
|
+
if (!host) return Promise.resolve({
|
|
185
|
+
kind: 'unsupported'
|
|
186
|
+
});
|
|
187
|
+
return new Promise(resolve => {
|
|
188
|
+
let settled = false;
|
|
189
|
+
let timeoutTimer = null;
|
|
190
|
+
let closeGraceTimer = null;
|
|
191
|
+
let closePoll = null;
|
|
192
|
+
const onMessage = event => {
|
|
193
|
+
const verdict = readOAuthPopupMessage(event, {
|
|
194
|
+
expectedOrigin,
|
|
195
|
+
expectedState,
|
|
196
|
+
popup
|
|
197
|
+
});
|
|
198
|
+
switch (verdict.kind) {
|
|
199
|
+
case 'ignore':
|
|
200
|
+
return;
|
|
201
|
+
case 'code':
|
|
202
|
+
settle({
|
|
203
|
+
kind: 'code',
|
|
204
|
+
code: verdict.code,
|
|
205
|
+
state: verdict.state
|
|
206
|
+
});
|
|
207
|
+
return;
|
|
208
|
+
case 'oauth-error':
|
|
209
|
+
settle({
|
|
210
|
+
kind: 'oauth-error',
|
|
211
|
+
error: verdict.error,
|
|
212
|
+
...(verdict.errorDescription ? {
|
|
213
|
+
errorDescription: verdict.errorDescription
|
|
214
|
+
} : {})
|
|
215
|
+
});
|
|
216
|
+
return;
|
|
217
|
+
case 'state-mismatch':
|
|
218
|
+
settle({
|
|
219
|
+
kind: 'state-mismatch'
|
|
220
|
+
});
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
const cleanup = () => {
|
|
225
|
+
host.removeEventListener('message', onMessage);
|
|
226
|
+
if (timeoutTimer !== null) {
|
|
227
|
+
clearTimeout(timeoutTimer);
|
|
228
|
+
timeoutTimer = null;
|
|
229
|
+
}
|
|
230
|
+
if (closeGraceTimer !== null) {
|
|
231
|
+
clearTimeout(closeGraceTimer);
|
|
232
|
+
closeGraceTimer = null;
|
|
233
|
+
}
|
|
234
|
+
if (closePoll !== null) {
|
|
235
|
+
clearInterval(closePoll);
|
|
236
|
+
closePoll = null;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
function settle(outcome) {
|
|
240
|
+
if (settled) return;
|
|
241
|
+
settled = true;
|
|
242
|
+
cleanup();
|
|
243
|
+
resolve(outcome);
|
|
244
|
+
}
|
|
245
|
+
host.addEventListener('message', onMessage);
|
|
246
|
+
timeoutTimer = setTimeout(() => settle({
|
|
247
|
+
kind: 'timed-out'
|
|
248
|
+
}), timeoutMs);
|
|
249
|
+
closePoll = setInterval(() => {
|
|
250
|
+
const redirectOutcome = readSameOriginRedirectOutcome(popup, redirectUri, expectedState);
|
|
251
|
+
if (redirectOutcome) {
|
|
252
|
+
settle(redirectOutcome);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (!popup.closed) return;
|
|
256
|
+
// Stop sampling immediately: the window is gone and only the in-flight
|
|
257
|
+
// message (if any) can still change the outcome.
|
|
258
|
+
if (closePoll !== null) {
|
|
259
|
+
clearInterval(closePoll);
|
|
260
|
+
closePoll = null;
|
|
261
|
+
}
|
|
262
|
+
closeGraceTimer = setTimeout(() => settle({
|
|
263
|
+
kind: 'closed'
|
|
264
|
+
}), CLOSE_GRACE_MS);
|
|
265
|
+
}, CLOSE_POLL_INTERVAL_MS);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=oauthPopup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["canonicalizeOAuthRedirectUri","logger","readOAuthPopupMessage","OXY_OAUTH_POPUP_WINDOW_NAME","POPUP_FEATURES","DEFAULT_OAUTH_POPUP_TIMEOUT_MS","CLOSE_POLL_INTERVAL_MS","CLOSE_GRACE_MS","messageEventHost","win","globalThis","window","addEventListener","removeEventListener","openOAuthPopup","open","error","warn","component","navigateOAuthPopup","popup","url","location","href","closeOAuthPopup","closed","close","debug","readSameOriginRedirectOutcome","redirectUri","expectedState","popupUrl","URL","expected","origin","pathname","oauthError","searchParams","get","errorDescription","undefined","kind","code","state","awaitOAuthPopupResult","options","expectedOrigin","timeoutMs","host","Promise","resolve","settled","timeoutTimer","closeGraceTimer","closePoll","onMessage","event","verdict","settle","cleanup","clearTimeout","clearInterval","outcome","setTimeout","setInterval","redirectOutcome"],"sourceRoot":"../../../../src","sources":["ui/oauth/oauthPopup.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,4BAA4B,EAAEC,MAAM,QAAQ,aAAa;AAClE,SAASC,qBAAqB,QAAQ,yBAAsB;AAG5D;AACA;AACA;AACA;AACA,OAAO,MAAMC,2BAA2B,GAAG,WAAW;;AAEtD;AACA,MAAMC,cAAc,GAAG,4EAA4E;;AAEnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,8BAA8B,GAAG,OAAO;;AAErD;AACA,MAAMC,sBAAsB,GAAG,IAAI;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,cAAc,GAAG,GAAG;;AAE1B;;AAMA;;AAKA,SAASC,gBAAgBA,CAAA,EAA4B;EACnD,MAAMC,GAAG,GAAIC,UAAU,CAA4CC,MAAM;EACzE,IAAI,CAACF,GAAG,IAAI,OAAOA,GAAG,CAACG,gBAAgB,KAAK,UAAU,IAAI,OAAOH,GAAG,CAACI,mBAAmB,KAAK,UAAU,EAAE;IACvG,OAAO,IAAI;EACb;EACA,OAAOJ,GAAG;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASK,cAAcA,CAAA,EAA4B;EACxD,MAAML,GAAG,GAAIC,UAAU,CAAkCC,MAAM;EAC/D,IAAI,CAACF,GAAG,IAAI,OAAOA,GAAG,CAACM,IAAI,KAAK,UAAU,EAAE,OAAO,IAAI;EACvD,IAAI;IACF,OAAON,GAAG,CAACM,IAAI,CAAC,EAAE,EAAEZ,2BAA2B,EAAEC,cAAc,CAAC,IAAI,IAAI;EAC1E,CAAC,CAAC,OAAOY,KAAK,EAAE;IACdf,MAAM,CAACgB,IAAI,CAAC,wCAAwC,EAAE;MAAEC,SAAS,EAAE;IAAa,CAAC,EAAEF,KAAK,CAAC;IACzF,OAAO,IAAI;EACb;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,kBAAkBA,CAACC,KAAuB,EAAEC,GAAW,EAAW;EAChF,IAAI;IACFD,KAAK,CAACE,QAAQ,CAACC,IAAI,GAAGF,GAAG;IACzB,OAAO,IAAI;EACb,CAAC,CAAC,OAAOL,KAAK,EAAE;IACdf,MAAM,CAACgB,IAAI,CAAC,4CAA4C,EAAE;MAAEC,SAAS,EAAE;IAAa,CAAC,EAAEF,KAAK,CAAC;IAC7F,OAAO,KAAK;EACd;AACF;;AAEA;AACA,OAAO,SAASQ,eAAeA,CAACJ,KAA8B,EAAQ;EACpE,IAAI,CAACA,KAAK,IAAIA,KAAK,CAACK,MAAM,EAAE;EAC5B,IAAI;IACFL,KAAK,CAACM,KAAK,CAAC,CAAC;EACf,CAAC,CAAC,OAAOV,KAAK,EAAE;IACdf,MAAM,CAAC0B,KAAK,CAAC,0BAA0B,EAAE;MAAET,SAAS,EAAE;IAAa,CAAC,EAAEF,KAAK,CAAC;EAC9E;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,SAASY,6BAA6BA,CACpCR,KAAuB,EACvBS,WAAmB,EACnBC,aAAqB,EACK;EAC1B,IAAI;IACF,MAAMP,IAAI,GAAGH,KAAK,CAACE,QAAQ,CAACC,IAAI;IAChC,IAAI,CAACA,IAAI,EAAE,OAAO,IAAI;IAEtB,MAAMQ,QAAQ,GAAG,IAAIC,GAAG,CAACT,IAAI,CAAC;IAC9B,MAAMU,QAAQ,GAAG,IAAID,GAAG,CAAChC,4BAA4B,CAAC6B,WAAW,CAAC,CAAC;IACnE,IAAIE,QAAQ,CAACG,MAAM,KAAKD,QAAQ,CAACC,MAAM,EAAE,OAAO,IAAI;IACpD,IAAIH,QAAQ,CAACI,QAAQ,KAAKF,QAAQ,CAACE,QAAQ,EAAE,OAAO,IAAI;IAExD,MAAMC,UAAU,GAAGL,QAAQ,CAACM,YAAY,CAACC,GAAG,CAAC,OAAO,CAAC;IACrD,IAAIF,UAAU,EAAE;MACd,MAAMG,gBAAgB,GAAGR,QAAQ,CAACM,YAAY,CAACC,GAAG,CAAC,mBAAmB,CAAC,IAAIE,SAAS;MACpF,OAAO;QACLC,IAAI,EAAE,aAAa;QACnBzB,KAAK,EAAEoB,UAAU;QACjB,IAAIG,gBAAgB,GAAG;UAAEA;QAAiB,CAAC,GAAG,CAAC,CAAC;MAClD,CAAC;IACH;IAEA,MAAMG,IAAI,GAAGX,QAAQ,CAACM,YAAY,CAACC,GAAG,CAAC,MAAM,CAAC;IAC9C,IAAI,CAACI,IAAI,EAAE,OAAO,IAAI;IAEtB,MAAMC,KAAK,GAAGZ,QAAQ,CAACM,YAAY,CAACC,GAAG,CAAC,OAAO,CAAC;IAChD,IAAI,CAACK,KAAK,IAAIA,KAAK,KAAKb,aAAa,EAAE,OAAO;MAAEW,IAAI,EAAE;IAAiB,CAAC;IACxE,OAAO;MAAEA,IAAI,EAAE,MAAM;MAAEC,IAAI;MAAEC;IAAM,CAAC;EACtC,CAAC,CAAC,MAAM;IACN;IACA,OAAO,IAAI;EACb;AACF;;AAEA;;AAkBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CACnCC,OAA+B,EACH;EAC5B,MAAM;IACJzB,KAAK;IACL0B,cAAc;IACdhB,aAAa;IACbD,WAAW;IACXkB,SAAS,GAAG1C;EACd,CAAC,GAAGwC,OAAO;EAEX,MAAMG,IAAI,GAAGxC,gBAAgB,CAAC,CAAC;EAC/B,IAAI,CAACwC,IAAI,EAAE,OAAOC,OAAO,CAACC,OAAO,CAAC;IAAET,IAAI,EAAE;EAAc,CAAC,CAAC;EAE1D,OAAO,IAAIQ,OAAO,CAAqBC,OAAO,IAAK;IACjD,IAAIC,OAAO,GAAG,KAAK;IACnB,IAAIC,YAAkD,GAAG,IAAI;IAC7D,IAAIC,eAAqD,GAAG,IAAI;IAChE,IAAIC,SAAgD,GAAG,IAAI;IAE3D,MAAMC,SAAS,GAAIC,KAAmB,IAAW;MAC/C,MAAMC,OAAO,GAAGvD,qBAAqB,CAACsD,KAAK,EAAE;QAAEV,cAAc;QAAEhB,aAAa;QAAEV;MAAM,CAAC,CAAC;MACtF,QAAQqC,OAAO,CAAChB,IAAI;QAClB,KAAK,QAAQ;UACX;QACF,KAAK,MAAM;UACTiB,MAAM,CAAC;YAAEjB,IAAI,EAAE,MAAM;YAAEC,IAAI,EAAEe,OAAO,CAACf,IAAI;YAAEC,KAAK,EAAEc,OAAO,CAACd;UAAM,CAAC,CAAC;UAClE;QACF,KAAK,aAAa;UAChBe,MAAM,CAAC;YACLjB,IAAI,EAAE,aAAa;YACnBzB,KAAK,EAAEyC,OAAO,CAACzC,KAAK;YACpB,IAAIyC,OAAO,CAAClB,gBAAgB,GAAG;cAAEA,gBAAgB,EAAEkB,OAAO,CAAClB;YAAiB,CAAC,GAAG,CAAC,CAAC;UACpF,CAAC,CAAC;UACF;QACF,KAAK,gBAAgB;UACnBmB,MAAM,CAAC;YAAEjB,IAAI,EAAE;UAAiB,CAAC,CAAC;UAClC;MACJ;IACF,CAAC;IAED,MAAMkB,OAAO,GAAGA,CAAA,KAAY;MAC1BX,IAAI,CAACnC,mBAAmB,CAAC,SAAS,EAAE0C,SAAS,CAAC;MAC9C,IAAIH,YAAY,KAAK,IAAI,EAAE;QACzBQ,YAAY,CAACR,YAAY,CAAC;QAC1BA,YAAY,GAAG,IAAI;MACrB;MACA,IAAIC,eAAe,KAAK,IAAI,EAAE;QAC5BO,YAAY,CAACP,eAAe,CAAC;QAC7BA,eAAe,GAAG,IAAI;MACxB;MACA,IAAIC,SAAS,KAAK,IAAI,EAAE;QACtBO,aAAa,CAACP,SAAS,CAAC;QACxBA,SAAS,GAAG,IAAI;MAClB;IACF,CAAC;IAED,SAASI,MAAMA,CAACI,OAA0B,EAAQ;MAChD,IAAIX,OAAO,EAAE;MACbA,OAAO,GAAG,IAAI;MACdQ,OAAO,CAAC,CAAC;MACTT,OAAO,CAACY,OAAO,CAAC;IAClB;IAEAd,IAAI,CAACpC,gBAAgB,CAAC,SAAS,EAAE2C,SAAS,CAAC;IAE3CH,YAAY,GAAGW,UAAU,CAAC,MAAML,MAAM,CAAC;MAAEjB,IAAI,EAAE;IAAY,CAAC,CAAC,EAAEM,SAAS,CAAC;IAEzEO,SAAS,GAAGU,WAAW,CAAC,MAAM;MAC5B,MAAMC,eAAe,GAAGrC,6BAA6B,CAACR,KAAK,EAAES,WAAW,EAAEC,aAAa,CAAC;MACxF,IAAImC,eAAe,EAAE;QACnBP,MAAM,CAACO,eAAe,CAAC;QACvB;MACF;MAEA,IAAI,CAAC7C,KAAK,CAACK,MAAM,EAAE;MACnB;MACA;MACA,IAAI6B,SAAS,KAAK,IAAI,EAAE;QACtBO,aAAa,CAACP,SAAS,CAAC;QACxBA,SAAS,GAAG,IAAI;MAClB;MACAD,eAAe,GAAGU,UAAU,CAAC,MAAML,MAAM,CAAC;QAAEjB,IAAI,EAAE;MAAS,CAAC,CAAC,EAAElC,cAAc,CAAC;IAChF,CAAC,EAAED,sBAAsB,CAAC;EAC5B,CAAC,CAAC;AACJ","ignoreList":[]}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runtime validation for the popup OAuth `postMessage` channel.
|
|
5
|
+
*
|
|
6
|
+
* Everything arriving on `window`'s `message` event is untrusted: any frame on
|
|
7
|
+
* the page, any other popup, and any browser extension can post to us. This
|
|
8
|
+
* module is the ONLY place that decides whether an incoming event is a genuine
|
|
9
|
+
* authorization response, and it answers with a value — never a thrown error.
|
|
10
|
+
*
|
|
11
|
+
* A message is accepted only when ALL of these hold:
|
|
12
|
+
* 1. `event.origin` is EXACTLY the authorize endpoint's origin,
|
|
13
|
+
* 2. `event.source` is the exact `Window` reference we opened,
|
|
14
|
+
* 3. `event.data` matches one of the two frozen message shapes,
|
|
15
|
+
* 4. the `state` it carries matches the one this RP sent.
|
|
16
|
+
*
|
|
17
|
+
* Failing (1)–(3) is indistinguishable from unrelated page traffic, so the
|
|
18
|
+
* message is IGNORED and the flow keeps waiting. Failing (4) means our own
|
|
19
|
+
* popup answered a different request than the one in flight, which is terminal:
|
|
20
|
+
* it is reported as a mismatch rather than left to hang until the timeout.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { logger } from '@oxyhq/core';
|
|
24
|
+
/** `postMessage` discriminator for a successful authorization. */
|
|
25
|
+
export const OXY_OAUTH_CODE_MESSAGE_TYPE = 'oxy:oauth:code';
|
|
26
|
+
|
|
27
|
+
/** `postMessage` discriminator for a typed OAuth failure. */
|
|
28
|
+
export const OXY_OAUTH_ERROR_MESSAGE_TYPE = 'oxy:oauth:error';
|
|
29
|
+
|
|
30
|
+
/** Verdict for one incoming `message` event. */
|
|
31
|
+
|
|
32
|
+
/** What {@link readOAuthPopupMessage} validates an event against. */
|
|
33
|
+
|
|
34
|
+
function isNonEmptyString(value) {
|
|
35
|
+
return typeof value === 'string' && value.length > 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Reference equality across two `unknown` values.
|
|
40
|
+
*
|
|
41
|
+
* `event.source` is a `WindowProxy` and {@link OAuthPopupHandle} is a narrow
|
|
42
|
+
* structural type, so comparing them directly is a type error. Widening both to
|
|
43
|
+
* `unknown` keeps the check a plain identity comparison — which is exactly the
|
|
44
|
+
* security property we want — without a cast.
|
|
45
|
+
*/
|
|
46
|
+
function isSameWindowReference(a, b) {
|
|
47
|
+
return a === b;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parse untrusted `event.data` into one of the two frozen message shapes, or
|
|
52
|
+
* `null` when it is anything else (including `null`, primitives, arrays, and
|
|
53
|
+
* objects with missing/wrong-typed fields).
|
|
54
|
+
*
|
|
55
|
+
* Unknown extra properties are tolerated but never read: only the fields below
|
|
56
|
+
* are ever surfaced, so a hostile sender cannot smuggle values past this point.
|
|
57
|
+
*/
|
|
58
|
+
export function parseOAuthPopupMessage(data) {
|
|
59
|
+
if (typeof data !== 'object' || data === null || Array.isArray(data)) return null;
|
|
60
|
+
const record = data;
|
|
61
|
+
if (record.type === OXY_OAUTH_CODE_MESSAGE_TYPE) {
|
|
62
|
+
if (!isNonEmptyString(record.code) || !isNonEmptyString(record.state)) return null;
|
|
63
|
+
return {
|
|
64
|
+
type: OXY_OAUTH_CODE_MESSAGE_TYPE,
|
|
65
|
+
code: record.code,
|
|
66
|
+
state: record.state
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (record.type === OXY_OAUTH_ERROR_MESSAGE_TYPE) {
|
|
70
|
+
if (!isNonEmptyString(record.error)) return null;
|
|
71
|
+
return {
|
|
72
|
+
type: OXY_OAUTH_ERROR_MESSAGE_TYPE,
|
|
73
|
+
error: record.error,
|
|
74
|
+
...(isNonEmptyString(record.errorDescription) ? {
|
|
75
|
+
errorDescription: record.errorDescription
|
|
76
|
+
} : {}),
|
|
77
|
+
...(isNonEmptyString(record.state) ? {
|
|
78
|
+
state: record.state
|
|
79
|
+
} : {})
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Classify one `message` event against the in-flight authorize request.
|
|
87
|
+
*
|
|
88
|
+
* Never throws. See the module header for the acceptance rules.
|
|
89
|
+
*/
|
|
90
|
+
export function readOAuthPopupMessage(event, context) {
|
|
91
|
+
if (event.origin !== context.expectedOrigin) return {
|
|
92
|
+
kind: 'ignore'
|
|
93
|
+
};
|
|
94
|
+
if (!isSameWindowReference(event.source, context.popup)) return {
|
|
95
|
+
kind: 'ignore'
|
|
96
|
+
};
|
|
97
|
+
const message = parseOAuthPopupMessage(event.data);
|
|
98
|
+
if (!message) {
|
|
99
|
+
// Origin and source matched, so this came from the IdP window we opened —
|
|
100
|
+
// a shape we cannot read is worth a breadcrumb, unlike ordinary page noise.
|
|
101
|
+
logger.debug('Ignored an unrecognised message from the OAuth popup', {
|
|
102
|
+
component: 'oauthPopupMessages'
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
kind: 'ignore'
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (message.type === OXY_OAUTH_CODE_MESSAGE_TYPE) {
|
|
109
|
+
if (message.state !== context.expectedState) return {
|
|
110
|
+
kind: 'state-mismatch'
|
|
111
|
+
};
|
|
112
|
+
return {
|
|
113
|
+
kind: 'code',
|
|
114
|
+
code: message.code,
|
|
115
|
+
state: message.state
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// An error MAY carry `state` (the IdP omits it when the request never got far
|
|
120
|
+
// enough to bind one). When present it must match: a foreign error must not be
|
|
121
|
+
// able to end an unrelated in-flight sign-in.
|
|
122
|
+
if (message.state !== undefined && message.state !== context.expectedState) {
|
|
123
|
+
return {
|
|
124
|
+
kind: 'state-mismatch'
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
kind: 'oauth-error',
|
|
129
|
+
error: message.error,
|
|
130
|
+
...(message.errorDescription ? {
|
|
131
|
+
errorDescription: message.errorDescription
|
|
132
|
+
} : {})
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=oauthPopupMessages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["logger","OXY_OAUTH_CODE_MESSAGE_TYPE","OXY_OAUTH_ERROR_MESSAGE_TYPE","isNonEmptyString","value","length","isSameWindowReference","a","b","parseOAuthPopupMessage","data","Array","isArray","record","type","code","state","error","errorDescription","readOAuthPopupMessage","event","context","origin","expectedOrigin","kind","source","popup","message","debug","component","expectedState","undefined"],"sourceRoot":"../../../../src","sources":["ui/oauth/oauthPopupMessages.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../../../src","sources":["ui/oauth/types.ts"],"mappings":"","ignoreList":[]}
|
package/lib/module/ui/server.js
CHANGED
|
@@ -25,8 +25,6 @@ export const LogoIcon = noopComponent;
|
|
|
25
25
|
export const LogoText = noopComponent;
|
|
26
26
|
export const FollowButton = noopComponent;
|
|
27
27
|
export const OxyPayButton = noopComponent;
|
|
28
|
-
export const FontLoader = noopComponent;
|
|
29
|
-
export const setupFonts = async () => true;
|
|
30
28
|
|
|
31
29
|
// Context
|
|
32
30
|
export const useOxy = noopHook;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["noopComponent","noopHook","noopStorageResult","storage","isReady","OxyProvider","OxySignInButton","LogoIcon","LogoText","FollowButton","OxyPayButton","
|
|
1
|
+
{"version":3,"names":["noopComponent","noopHook","noopStorageResult","storage","isReady","OxyProvider","OxySignInButton","LogoIcon","LogoText","FollowButton","OxyPayButton","useOxy","useAuth","useFollow","useStorage","ProfileScreen","useAuthStore","useAccountStore","toast","Object","assign","success","error","info","warning","loading","dismiss","handleAuthError","isInvalidSessionError","isTimeoutOrNetworkError","extractErrorMessage"],"sourceRoot":"../../../src","sources":["ui/server.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAMA,aAAa,GAAGA,CAAA,KAAM,IAAI;AAChC,MAAMC,QAAQ,GAAGA,CAAA,MAAO,CAAC,CAAC,CAAC;AAC3B,MAAMC,iBAAiB,GAAG;EAAEC,OAAO,EAAE,IAAI;EAAEC,OAAO,EAAE;AAAM,CAAC;;AAE3D;AACA,OAAO,MAAMC,WAAW,GAAGL,aAAa;AACxC,OAAO,MAAMM,eAAe,GAAGN,aAAa;AAC5C,OAAO,MAAMO,QAAQ,GAAGP,aAAa;AACrC,OAAO,MAAMQ,QAAQ,GAAGR,aAAa;AACrC,OAAO,MAAMS,YAAY,GAAGT,aAAa;AACzC,OAAO,MAAMU,YAAY,GAAGV,aAAa;;AAEzC;AACA,OAAO,MAAMW,MAAM,GAAGV,QAAQ;;AAE9B;AACA,OAAO,MAAMW,OAAO,GAAGX,QAAQ;AAC/B,OAAO,MAAMY,SAAS,GAAGZ,QAAQ;AACjC,OAAO,MAAMa,UAAU,GAAGA,CAAA,KAAMZ,iBAAiB;;AAEjD;AACA,OAAO,MAAMa,aAAa,GAAGf,aAAa;;AAE1C;AACA,OAAO,MAAMgB,YAAY,GAAGf,QAAQ;AACpC,OAAO,MAAMgB,eAAe,GAAGhB,QAAQ;;AAEvC;AACA,OAAO,MAAMiB,KAAK,GAAGC,MAAM,CAACC,MAAM,CAC9B,MAAM,CAAC,CAAC,EACR;EACIC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,KAAK,EAAEA,CAAA,KAAM,CAAC,CAAC;EACfC,IAAI,EAAEA,CAAA,KAAM,CAAC,CAAC;EACdC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,OAAO,EAAEA,CAAA,KAAM,CAAC;AACpB,CACJ,CAAC;;AAED;AACA,SACIC,eAAe,EACfC,qBAAqB,EACrBC,uBAAuB,EACvBC,mBAAmB,QAChB,0BAAuB","ignoreList":[]}
|
|
@@ -7,87 +7,17 @@
|
|
|
7
7
|
* (`deviceId` + `deviceSecret`) per origin (web) / per device (native), and the
|
|
8
8
|
* SDK re-mints the access token from that credential on cold boot. `@oxyhq/core`
|
|
9
9
|
* owns the store shape + logic (`createWebAuthStateStore` /
|
|
10
|
-
* `createNativeAuthStateStore`); this module only
|
|
10
|
+
* `createNativeAuthStateStore`); this module only selects the platform storage
|
|
11
11
|
* seam:
|
|
12
12
|
*
|
|
13
13
|
* - web → `createWebAuthStateStore()` (localStorage, in-memory fallback).
|
|
14
14
|
* - native → `createNativeAuthStateStore(secureKV)` for the SESSION blob over
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
* `expo-secure-store` is loaded via a runtime-computed dynamic import (the same
|
|
18
|
-
* optional-native-module pattern `OxyProvider` uses for netinfo / keyboard
|
|
19
|
-
* controller), so the web bundle never pulls it and a device without it falls
|
|
20
|
-
* back to AsyncStorage rather than crashing.
|
|
15
|
+
* the shared `createNativeSecureKeyValueStorage()` adapter
|
|
16
|
+
* (`expo-secure-store`, AsyncStorage fallback).
|
|
21
17
|
*/
|
|
22
18
|
import { createWebAuthStateStore, createNativeAuthStateStore } from '@oxyhq/core';
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
// Variable indirection so Metro's static analyzer never traces expo-secure-store
|
|
26
|
-
// into the web bundle; the module is native-only and optional.
|
|
27
|
-
const SECURE_STORE_MODULE = 'expo-secure-store';
|
|
28
|
-
let secureStorePromise = null;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Resolve the `expo-secure-store` module once (memoised), or `null` when it is
|
|
32
|
-
* unavailable — callers then fall back to AsyncStorage. Never throws.
|
|
33
|
-
*/
|
|
34
|
-
function loadSecureStore() {
|
|
35
|
-
if (!secureStorePromise) {
|
|
36
|
-
const moduleName = SECURE_STORE_MODULE;
|
|
37
|
-
secureStorePromise = import(moduleName).then(mod => {
|
|
38
|
-
if (typeof mod.getItemAsync === 'function' && typeof mod.setItemAsync === 'function' && typeof mod.deleteItemAsync === 'function') {
|
|
39
|
-
return {
|
|
40
|
-
getItemAsync: mod.getItemAsync.bind(mod),
|
|
41
|
-
setItemAsync: mod.setItemAsync.bind(mod),
|
|
42
|
-
deleteItemAsync: mod.deleteItemAsync.bind(mod)
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}).catch(() => null);
|
|
47
|
-
}
|
|
48
|
-
return secureStorePromise;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* A native `NativeKeyValueStorage` that prefers `expo-secure-store` (encrypted
|
|
53
|
-
* at rest) and falls back to AsyncStorage when SecureStore is not installed.
|
|
54
|
-
* The SecureStore module is resolved lazily on first access so construction
|
|
55
|
-
* stays synchronous.
|
|
56
|
-
*/
|
|
57
|
-
function createNativeSecureKeyValueStorage() {
|
|
58
|
-
let asyncStorage = null;
|
|
59
|
-
const getAsyncStorage = async () => {
|
|
60
|
-
if (!asyncStorage) {
|
|
61
|
-
asyncStorage = await createPlatformStorage();
|
|
62
|
-
}
|
|
63
|
-
return asyncStorage;
|
|
64
|
-
};
|
|
65
|
-
return {
|
|
66
|
-
getItem: async key => {
|
|
67
|
-
const secure = await loadSecureStore();
|
|
68
|
-
if (secure) {
|
|
69
|
-
return secure.getItemAsync(key);
|
|
70
|
-
}
|
|
71
|
-
return (await getAsyncStorage()).getItem(key);
|
|
72
|
-
},
|
|
73
|
-
setItem: async (key, value) => {
|
|
74
|
-
const secure = await loadSecureStore();
|
|
75
|
-
if (secure) {
|
|
76
|
-
await secure.setItemAsync(key, value);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
await (await getAsyncStorage()).setItem(key, value);
|
|
80
|
-
},
|
|
81
|
-
removeItem: async key => {
|
|
82
|
-
const secure = await loadSecureStore();
|
|
83
|
-
if (secure) {
|
|
84
|
-
await secure.deleteItemAsync(key);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
await (await getAsyncStorage()).removeItem(key);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
}
|
|
19
|
+
import { isReactNative } from "../utils/storageHelpers.js";
|
|
20
|
+
import { createNativeSecureKeyValueStorage } from "./nativeSecureStorage.js";
|
|
91
21
|
|
|
92
22
|
/**
|
|
93
23
|
* Build the platform {@link AuthStateStore} for this runtime.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createWebAuthStateStore","createNativeAuthStateStore","
|
|
1
|
+
{"version":3,"names":["createWebAuthStateStore","createNativeAuthStateStore","isReactNative","createNativeSecureKeyValueStorage","createPlatformAuthStateStore"],"sourceRoot":"../../../../src","sources":["ui/session/authStore.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SACEA,uBAAuB,EACvBC,0BAA0B,QAErB,aAAa;AACpB,SAASC,aAAa,QAAQ,4BAAyB;AACvD,SAASC,iCAAiC,QAAQ,0BAAuB;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,4BAA4BA,CAAA,EAAmB;EAC7D,IAAI,CAACF,aAAa,CAAC,CAAC,EAAE;IACpB,OAAOF,uBAAuB,CAAC,CAAC;EAClC;EAEA,OAAOC,0BAA0B,CAACE,iCAAiC,CAAC,CAAC,CAAC;AACxE","ignoreList":[]}
|
|
@@ -30,14 +30,22 @@ import { createTokenTransport } from "./tokenTransport.js";
|
|
|
30
30
|
*
|
|
31
31
|
* The realtime socket uses bearer when authenticated, or deviceId+deviceSecret
|
|
32
32
|
* when signed out (after the one-shot join redirect).
|
|
33
|
+
*
|
|
34
|
+
* `getPinnedAccountId` reports the account an IDENTITY-BOUND provider
|
|
35
|
+
* (`sessionMode: 'identity'`) is pinned to, and `null` for every account-mode
|
|
36
|
+
* provider — which is exactly the value `SessionClient` and the transport read
|
|
37
|
+
* when the option is absent, so account mode is unchanged. While it reports an
|
|
38
|
+
* account, the client tracks device state truthfully but never re-binds its
|
|
39
|
+
* bearer to the device's mutable active account.
|
|
33
40
|
*/
|
|
34
|
-
export function createSessionClient(oxyServices, onUnauthenticated) {
|
|
41
|
+
export function createSessionClient(oxyServices, onUnauthenticated, getPinnedAccountId) {
|
|
35
42
|
const host = createSessionClientHost(oxyServices);
|
|
36
|
-
const transport = createTokenTransport(oxyServices);
|
|
43
|
+
const transport = createTokenTransport(oxyServices, getPinnedAccountId);
|
|
37
44
|
const client = new SessionClient(host, {
|
|
38
45
|
transport,
|
|
39
46
|
socketFactory: io,
|
|
40
|
-
onUnauthenticated
|
|
47
|
+
onUnauthenticated,
|
|
48
|
+
getPinnedAccountId
|
|
41
49
|
});
|
|
42
50
|
return {
|
|
43
51
|
client,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["io","SessionClient","createSessionClientHost","createTokenTransport","createSessionClient","oxyServices","onUnauthenticated","host","transport","client","socketFactory"],"sourceRoot":"../../../../src","sources":["ui/session/createSessionClient.ts"],"mappings":";;AAAA,SAASA,EAAE,QAAQ,kBAAkB;AACrC,SACEC,aAAa,EACbC,uBAAuB,QAGlB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,qBAAkB;;AAEvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CACjCC,WAAwB,EACxBC,iBAAwD,
|
|
1
|
+
{"version":3,"names":["io","SessionClient","createSessionClientHost","createTokenTransport","createSessionClient","oxyServices","onUnauthenticated","getPinnedAccountId","host","transport","client","socketFactory"],"sourceRoot":"../../../../src","sources":["ui/session/createSessionClient.ts"],"mappings":";;AAAA,SAASA,EAAE,QAAQ,kBAAkB;AACrC,SACEC,aAAa,EACbC,uBAAuB,QAGlB,aAAa;AACpB,SAASC,oBAAoB,QAAQ,qBAAkB;;AAEvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CACjCC,WAAwB,EACxBC,iBAAwD,EACxDC,kBAAwC,EAIxC;EACA,MAAMC,IAAI,GAAGN,uBAAuB,CAACG,WAAW,CAAC;EACjD,MAAMI,SAAS,GAAGN,oBAAoB,CAACE,WAAW,EAAEE,kBAAkB,CAAC;EACvE,MAAMG,MAAM,GAAG,IAAIT,aAAa,CAACO,IAAI,EAAE;IACrCC,SAAS;IACTE,aAAa,EAAEX,EAAE;IACjBM,iBAAiB;IACjBC;EACF,CAAC,CAAC;EACF,OAAO;IAAEG,MAAM;IAAEF;EAAK,CAAC;AACzB","ignoreList":[]}
|