add the clients
This commit is contained in:
@@ -5,6 +5,7 @@ export type Gate =
|
||||
| 'debug_show_feedcontext'
|
||||
| 'debug_subscriptions'
|
||||
| 'explore_show_suggested_feeds'
|
||||
| 'oauth'
|
||||
| 'old_postonboarding'
|
||||
| 'onboarding_add_video_feed'
|
||||
| 'post_threads_v2_unspecced'
|
||||
|
||||
+108
-14
@@ -32,22 +32,13 @@ import {Ticket_Stroke2_Corner0_Rounded as Ticket} from '#/components/icons/Ticke
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {FormContainer} from './FormContainer'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {getNativeOAuthClient, getWebOAuthClient} from '#/state/session/oauth'
|
||||
|
||||
type ServiceDescription = ComAtprotoServerDescribeServer.OutputSchema
|
||||
|
||||
export const LoginForm = ({
|
||||
error,
|
||||
serviceUrl,
|
||||
serviceDescription,
|
||||
initialHandle,
|
||||
setError,
|
||||
setServiceUrl,
|
||||
onPressRetryConnect,
|
||||
onPressBack,
|
||||
onPressForgotPassword,
|
||||
onAttemptSuccess,
|
||||
onAttemptFailed,
|
||||
}: {
|
||||
interface LoginFormProps {
|
||||
error: string
|
||||
serviceUrl: string
|
||||
serviceDescription: ServiceDescription | undefined
|
||||
@@ -59,7 +50,110 @@ export const LoginForm = ({
|
||||
onPressForgotPassword: () => void
|
||||
onAttemptSuccess: () => void
|
||||
onAttemptFailed: () => void
|
||||
}) => {
|
||||
}
|
||||
|
||||
export function LoginForm(props: LoginFormProps) {
|
||||
const gate = useGate()
|
||||
if (gate('oauth')) {
|
||||
return <OAuthLoginForm {...props} />
|
||||
} else {
|
||||
return <LoginFormInner {...props} />
|
||||
}
|
||||
}
|
||||
|
||||
function OAuthLoginForm({error, initialHandle, onPressBack}: LoginFormProps) {
|
||||
const {_} = useLingui()
|
||||
const [isProcessing, setIsProcessing] = React.useState(false)
|
||||
const identifierValueRef = useRef<string>(initialHandle || '')
|
||||
|
||||
const onPressNext = async () => {
|
||||
setIsProcessing(true)
|
||||
if (isWeb) {
|
||||
const client = getWebOAuthClient()
|
||||
await client.signIn(identifierValueRef.current)
|
||||
} else {
|
||||
const client = getNativeOAuthClient()
|
||||
const res = await client.signIn(identifierValueRef.current)
|
||||
// redirect after result
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<FormContainer testID="loginForm" titleText={<Trans>Sign in</Trans>}>
|
||||
<View>
|
||||
<TextField.LabelText>
|
||||
<Trans>Account</Trans>
|
||||
</TextField.LabelText>
|
||||
<View style={[a.gap_sm]}>
|
||||
<TextField.Root>
|
||||
<TextField.Icon icon={At} />
|
||||
<TextField.Input
|
||||
testID="loginUsernameInput"
|
||||
label={_(msg`Username or email address`)}
|
||||
autoCapitalize="none"
|
||||
autoFocus
|
||||
autoCorrect={false}
|
||||
autoComplete="username"
|
||||
returnKeyType="next"
|
||||
textContentType="username"
|
||||
defaultValue={initialHandle || ''}
|
||||
onChangeText={v => {
|
||||
identifierValueRef.current = v
|
||||
}}
|
||||
onSubmitEditing={() => {}}
|
||||
blurOnSubmit={false} // prevents flickering due to onSubmitEditing going to next field
|
||||
editable={!isProcessing}
|
||||
accessibilityHint={_(
|
||||
msg`Enter the username or email address you used when you created your account`,
|
||||
)}
|
||||
/>
|
||||
</TextField.Root>
|
||||
</View>
|
||||
</View>
|
||||
<FormError error={error} />
|
||||
<View style={[a.flex_row, a.align_center, a.pt_md]}>
|
||||
<Button
|
||||
label={_(msg`Back`)}
|
||||
variant="solid"
|
||||
color="secondary"
|
||||
size="large"
|
||||
onPress={onPressBack}>
|
||||
<ButtonText>
|
||||
<Trans>Back</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<View style={a.flex_1} />
|
||||
<Button
|
||||
testID="loginNextButton"
|
||||
label={_(msg`Login`)}
|
||||
accessibilityHint={_(msg`Navigates to the login screen`)}
|
||||
variant="solid"
|
||||
color="primary"
|
||||
size="large"
|
||||
onPress={onPressNext}>
|
||||
<ButtonText>
|
||||
<Trans>Login</Trans>
|
||||
</ButtonText>
|
||||
{isProcessing && <ButtonIcon icon={Loader} />}
|
||||
</Button>
|
||||
</View>
|
||||
</FormContainer>
|
||||
)
|
||||
}
|
||||
|
||||
const LoginFormInner = ({
|
||||
error,
|
||||
serviceUrl,
|
||||
serviceDescription,
|
||||
initialHandle,
|
||||
setError,
|
||||
setServiceUrl,
|
||||
onPressRetryConnect,
|
||||
onPressBack,
|
||||
onPressForgotPassword,
|
||||
onAttemptSuccess,
|
||||
onAttemptFailed,
|
||||
}: LoginFormProps) => {
|
||||
const t = useTheme()
|
||||
const [isProcessing, setIsProcessing] = useState<boolean>(false)
|
||||
const [isAuthFactorTokenNeeded, setIsAuthFactorTokenNeeded] =
|
||||
|
||||
@@ -21,6 +21,8 @@ import {
|
||||
} from './moderation'
|
||||
import {SessionAccount} from './types'
|
||||
import {isSessionExpired, isSignupQueued} from './util'
|
||||
import {BSKY_OAUTH_CLIENT} from './oauth'
|
||||
import {ExpoOAuthClient} from 'expo-atproto-auth'
|
||||
|
||||
export function createPublicAgent() {
|
||||
configureModerationForGuest() // Side effect but only relevant for tests
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import {ExpoOAuthClient} from 'expo-atproto-auth'
|
||||
import {BrowserOAuthClient} from '@atproto/oauth-client-browser'
|
||||
import {OAuthClient} from '@atproto/oauth-client'
|
||||
import {Platform} from 'react-native'
|
||||
|
||||
export const BSKY_OAUTH_CLIENT: OAuthClient =
|
||||
Platform.OS === 'web' ? createWebOAuthClient() : createNativeOAuthClient()
|
||||
|
||||
export function createWebOAuthClient() {
|
||||
return new BrowserOAuthClient({
|
||||
clientMetadata: {
|
||||
client_id: 'https://bsky.hailey.at/oauth-client-metadata.json',
|
||||
client_name: 'Bluesky (Hailey Demo)',
|
||||
client_uri: 'https://bsky.hailey.at',
|
||||
redirect_uris: ['https://bsky.hailey.at/auth/callback'],
|
||||
scope: 'atproto transition:generic',
|
||||
token_endpoint_auth_method: 'none',
|
||||
response_types: ['code'],
|
||||
grant_types: ['authorization_code', 'refresh_token'],
|
||||
application_type: 'web',
|
||||
dpop_bound_access_tokens: true,
|
||||
},
|
||||
handleResolver: 'https://bsky.social',
|
||||
})
|
||||
}
|
||||
|
||||
export function createNativeOAuthClient() {
|
||||
return new ExpoOAuthClient({
|
||||
clientMetadata: {
|
||||
client_id: 'https://bsky.hailey.at/oauth-client-metadata.native.json',
|
||||
client_name: 'Bluesky Native App (Hailey Demo)',
|
||||
client_uri: 'https://hailey.at',
|
||||
redirect_uris: ['at.hailey:/auth/callback'],
|
||||
scope: 'atproto transition:generic',
|
||||
token_endpoint_auth_method: 'none',
|
||||
response_types: ['code'],
|
||||
grant_types: ['authorization_code', 'refresh_token'],
|
||||
application_type: 'native',
|
||||
dpop_bound_access_tokens: true,
|
||||
},
|
||||
handleResolver: 'https://bsky.social',
|
||||
})
|
||||
}
|
||||
|
||||
export function getNativeOAuthClient() {
|
||||
return BSKY_OAUTH_CLIENT as ExpoOAuthClient
|
||||
}
|
||||
|
||||
export function getWebOAuthClient() {
|
||||
return BSKY_OAUTH_CLIENT as BrowserOAuthClient
|
||||
}
|
||||
Reference in New Issue
Block a user