Skip to content

Commit

Permalink
Merge pull request #553 from lifeomic/first-login-warning
Browse files Browse the repository at this point in the history
feat: Add first time login dialog
  • Loading branch information
bruce-glazier committed May 2, 2024
2 parents 9f9de01 + 604d2d8 commit 8022ed4
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
1 change: 1 addition & 0 deletions example/AppDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function App() {
primaryColor: '#fb5607',
},
apiBaseURL: baseURL,
showPreLoginWarning: false,
}}
>
<RootProviders account="mockaccount" authConfig={authConfig}>
Expand Down
1 change: 1 addition & 0 deletions src/common/DeveloperConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export type DeveloperConfig = {
navigationLinking?: LinkingOptions<any>;
skipInviteParams?: boolean;
tileListMode?: 'list' | 'column';
showPreLoginWarning?: boolean;
};

export type LogoHeaderConfig = { [key in Route]?: LogoHeaderOptions };
Expand Down
49 changes: 44 additions & 5 deletions src/components/OAuthLoginButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,35 @@ import { useStyles } from '../hooks/useStyles';
import { LoginParams, useOAuthFlow } from '../hooks/useOAuthFlow';
import { tID } from '../common/testID';
import { createStyles } from './BrandConfigProvider';
import { useStoredValue } from '../hooks/useStoredValue';
import { useDeveloperConfig } from '../hooks/useDeveloperConfig';
import { t } from 'i18next';
import { Alert } from 'react-native';
import { usePendingInvite } from './Invitations/InviteProvider';

type Props = Omit<ButtonProps, 'onPress' | 'style' | 'children'> &
LoginParams & {
label: string;
style?: OAuthLoginButtonStyles;
};

const newLoginAlert = () => {
return new Promise<Boolean>((resolve) => {
Alert.alert(
t('new-login-title', 'New Login Notice'),
t(
'new-login-notice',
'NOTE: This device has not yet been used to login to the app.\nIf this is your first time using this app then you must first be invited to use this app via email.',
),
[
{ text: 'Proceed Anyway', onPress: () => resolve(true) },
{ text: 'Return', onPress: () => resolve(false) },
],
{ cancelable: false },
);
});
};

export function OAuthLoginButton({
onSuccess,
onFail,
Expand All @@ -21,13 +43,30 @@ export function OAuthLoginButton({
}: Props) {
const { styles } = useStyles(defaultStyles, instanceStyles);
const { login } = useOAuthFlow();
const [priorLoginDetected] = useStoredValue('loginDetected');
const { showPreLoginWarning } = useDeveloperConfig();
const pendingInvite = usePendingInvite();

const handleOnPress = useCallback(async () => {
await login({
onSuccess,
onFail,
});
}, [login, onSuccess, onFail]);
if (showPreLoginWarning && !pendingInvite && !priorLoginDetected) {
// If attempting to login for the first time without a pending invite
// let the user know that they are probably making a mistake
// This can be disabled via developerConfig
const result = await newLoginAlert();
if (result) {
await login({ onSuccess, onFail });
}
} else {
await login({ onSuccess, onFail });
}
}, [
pendingInvite,
priorLoginDetected,
showPreLoginWarning,
login,
onSuccess,
onFail,
]);

return (
<Button
Expand Down
11 changes: 10 additions & 1 deletion src/hooks/useOAuthFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { usePendingInvite } from '../components/Invitations/InviteProvider';
import { useQueryClient } from '@tanstack/react-query';
import { _sdkAnalyticsEvent } from '../common/Analytics';
import { useDeveloperConfig } from './useDeveloperConfig';
import { useStoredValue } from './useStoredValue';

export interface OAuthConfig {
login: (params: LoginParams) => Promise<void>;
Expand Down Expand Up @@ -78,6 +79,7 @@ export const OAuthContextProvider = ({
const pendingInvite = usePendingInvite();
const queryClient = useQueryClient();
const { skipInviteParams } = useDeveloperConfig();
const [_, setLoginDetected] = useStoredValue('loginDetected');

const authConfig = useMemo(
() =>
Expand Down Expand Up @@ -159,6 +161,7 @@ export const OAuthContextProvider = ({
try {
const result = await authorize(authConfig);
await storeAuthResult(result);
setLoginDetected('detected');
_sdkAnalyticsEvent.track('Login', { usedInvite: !!pendingInvite?.evc });
onSuccess?.(result);
} catch (error) {
Expand All @@ -170,7 +173,13 @@ export const OAuthContextProvider = ({
onFail?.(error);
}
},
[authConfig, clearAuthResult, pendingInvite?.evc, storeAuthResult],
[
authConfig,
clearAuthResult,
pendingInvite?.evc,
setLoginDetected,
storeAuthResult,
],
);

const refreshHandler = useCallback(
Expand Down

0 comments on commit 8022ed4

Please sign in to comment.