Skip to content

Commit 60ca2ff

Browse files
authored
Merge pull request #42887 from Expensify/techievivek_implement_unvalidated_signup
Implement unvalidated signups for newDot
2 parents 82cdf01 + f5b6e63 commit 60ca2ff

File tree

12 files changed

+168
-29
lines changed

12 files changed

+168
-29
lines changed

src/languages/en.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import type {
3232
LogSizeParams,
3333
ManagerApprovedAmountParams,
3434
ManagerApprovedParams,
35-
NewFaceEnterMagicCodeParams,
3635
NoLongerHaveAccessParams,
3736
NotAllowedExtensionParams,
3837
NotYouParams,
@@ -65,6 +64,7 @@ import type {
6564
SetTheRequestParams,
6665
SettledAfterAddedBankAccountParams,
6766
SettleExpensifyCardParams,
67+
SignUpNewFaceCodeParams,
6868
SizeExceededParams,
6969
SplitAmountParams,
7070
StepCounterParams,
@@ -430,11 +430,11 @@ export default {
430430
anotherLoginPageIsOpen: 'Another login page is open.',
431431
anotherLoginPageIsOpenExplanation: "You've opened the login page in a separate tab, please login from that specific tab.",
432432
welcome: 'Welcome!',
433+
welcomeWithoutExclamation: 'Welcome',
433434
phrase2: "Money talks. And now that chat and payments are in one place, it's also easy.",
434435
phrase3: 'Your payments get to you as fast as you can get your point across.',
435436
enterPassword: 'Please enter your password',
436-
newFaceEnterMagicCode: ({login}: NewFaceEnterMagicCodeParams) =>
437-
`It's always great to see a new face around here! Please enter the magic code sent to ${login}. It should arrive within a minute or two.`,
437+
welcomeNewFace: ({login}: SignUpNewFaceCodeParams) => `${login}, it's always great to see a new face around here!`,
438438
welcomeEnterMagicCode: ({login}: WelcomeEnterMagicCodeParams) => `Please enter the magic code sent to ${login}. It should arrive within a minute or two.`,
439439
},
440440
login: {
@@ -1461,6 +1461,9 @@ export default {
14611461
onceTheAbove: 'Once the above steps are completed, please reach out to ',
14621462
toUnblock: ' to unblock your login.',
14631463
},
1464+
welcomeSignUpForm: {
1465+
join: 'Join',
1466+
},
14641467
detailsPage: {
14651468
localTime: 'Local time',
14661469
},

src/languages/es.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import type {
3232
LogSizeParams,
3333
ManagerApprovedAmountParams,
3434
ManagerApprovedParams,
35-
NewFaceEnterMagicCodeParams,
3635
NoLongerHaveAccessParams,
3736
NotAllowedExtensionParams,
3837
NotYouParams,
@@ -65,6 +64,7 @@ import type {
6564
SetTheRequestParams,
6665
SettledAfterAddedBankAccountParams,
6766
SettleExpensifyCardParams,
67+
SignUpNewFaceCodeParams,
6868
SizeExceededParams,
6969
SplitAmountParams,
7070
StepCounterParams,
@@ -422,11 +422,11 @@ export default {
422422
anotherLoginPageIsOpen: 'Otra página de inicio de sesión está abierta.',
423423
anotherLoginPageIsOpenExplanation: 'Ha abierto la página de inicio de sesión en una pestaña separada, inicie sesión desde esa pestaña específica.',
424424
welcome: '¡Bienvenido!',
425+
welcomeWithoutExclamation: 'Bienvenido',
425426
phrase2: 'El dinero habla. Y ahora que chat y pagos están en un mismo lugar, es también fácil.',
426427
phrase3: 'Tus pagos llegan tan rápido como tus mensajes.',
427428
enterPassword: 'Por favor, introduce tu contraseña',
428-
newFaceEnterMagicCode: ({login}: NewFaceEnterMagicCodeParams) =>
429-
`¡Siempre es genial ver una cara nueva por aquí! Por favor ingresa el código mágico enviado a ${login}. Debería llegar en un par de minutos.`,
429+
welcomeNewFace: ({login}: SignUpNewFaceCodeParams) => `${login}, siempre es genial ver una cara nueva por aquí!`,
430430
welcomeEnterMagicCode: ({login}: WelcomeEnterMagicCodeParams) => `Por favor, introduce el código mágico enviado a ${login}. Debería llegar en un par de minutos.`,
431431
},
432432
login: {
@@ -1463,6 +1463,9 @@ export default {
14631463
onceTheAbove: 'Una vez completados los pasos anteriores, ponte en contacto con ',
14641464
toUnblock: ' para desbloquear el inicio de sesión.',
14651465
},
1466+
welcomeSignUpForm: {
1467+
join: 'Unirse',
1468+
},
14661469
detailsPage: {
14671470
localTime: 'Hora local',
14681471
},

src/languages/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type LoggedInAsParams = {
1818
email: string;
1919
};
2020

21-
type NewFaceEnterMagicCodeParams = {
21+
type SignUpNewFaceCodeParams = {
2222
login: string;
2323
};
2424

@@ -329,7 +329,7 @@ export type {
329329
LoggedInAsParams,
330330
ManagerApprovedAmountParams,
331331
ManagerApprovedParams,
332-
NewFaceEnterMagicCodeParams,
332+
SignUpNewFaceCodeParams,
333333
NoLongerHaveAccessParams,
334334
NotAllowedExtensionParams,
335335
NotYouParams,
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
type BeginSignInParams = {
22
email: string;
3+
useNewBeginSignIn: boolean;
34
};
45

56
export default BeginSignInParams;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type {ValueOf} from 'type-fest';
2+
import type CONST from '@src/CONST';
3+
4+
type SignUpUserParams = {
5+
email?: string;
6+
preferredLocale: ValueOf<typeof CONST.LOCALES> | null;
7+
};
8+
9+
export default SignUpUserParams;

src/libs/API/parameters/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,4 @@ export type {default as SearchParams} from './Search';
224224
export type {default as SendInvoiceParams} from './SendInvoiceParams';
225225
export type {default as PayInvoiceParams} from './PayInvoiceParams';
226226
export type {default as MarkAsCashParams} from './MarkAsCashParams';
227+
export type {default as SignUpUserParams} from './SignUpUserParams';

src/libs/API/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ const WRITE_COMMANDS = {
221221
SEND_INVOICE: 'SendInvoice',
222222
PAY_INVOICE: 'PayInvoice',
223223
MARK_AS_CASH: 'MarkAsCash',
224+
SIGN_UP_USER: 'SignUpUser',
224225
} as const;
225226

226227
type WriteCommand = ValueOf<typeof WRITE_COMMANDS>;
@@ -442,6 +443,7 @@ type WriteCommandParameters = {
442443
[WRITE_COMMANDS.SEND_INVOICE]: Parameters.SendInvoiceParams;
443444
[WRITE_COMMANDS.PAY_INVOICE]: Parameters.PayInvoiceParams;
444445
[WRITE_COMMANDS.MARK_AS_CASH]: Parameters.MarkAsCashParams;
446+
[WRITE_COMMANDS.SIGN_UP_USER]: Parameters.SignUpUserParams;
445447
};
446448

447449
const READ_COMMANDS = {

src/libs/LocalePhoneNumber.ts

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ function formatPhoneNumber(number: string): string {
1919
return '';
2020
}
2121

22+
// eslint-disable-next-line no-param-reassign
23+
number = number.replace(/ /g, '\u00A0');
24+
2225
// do not parse the string, if it doesn't contain the SMS domain and it's not a phone number
2326
if (number.indexOf(CONST.SMS.DOMAIN) === -1 && !CONST.REGEX.DIGITS_AND_PLUS.test(number)) {
2427
return number;

src/libs/actions/Session/index.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
RequestNewValidateCodeParams,
1717
RequestUnlinkValidationLinkParams,
1818
SignInUserWithLinkParams,
19+
SignUpUserParams,
1920
UnlinkLoginParams,
2021
ValidateTwoFactorAuthParams,
2122
} from '@libs/API/parameters';
@@ -405,11 +406,52 @@ function signInAttemptState(): OnyxData {
405406
function beginSignIn(email: string) {
406407
const {optimisticData, successData, failureData} = signInAttemptState();
407408

408-
const params: BeginSignInParams = {email};
409+
const params: BeginSignInParams = {email, useNewBeginSignIn: true};
409410

410411
API.read(READ_COMMANDS.BEGIN_SIGNIN, params, {optimisticData, successData, failureData});
411412
}
412413

414+
/**
415+
* Creates an account for the new user and signs them into the application with the newly created account.
416+
*
417+
*/
418+
function signUpUser() {
419+
const optimisticData: OnyxUpdate[] = [
420+
{
421+
onyxMethod: Onyx.METHOD.MERGE,
422+
key: ONYXKEYS.ACCOUNT,
423+
value: {
424+
...CONST.DEFAULT_ACCOUNT_DATA,
425+
isLoading: true,
426+
},
427+
},
428+
];
429+
430+
const successData: OnyxUpdate[] = [
431+
{
432+
onyxMethod: Onyx.METHOD.MERGE,
433+
key: ONYXKEYS.ACCOUNT,
434+
value: {
435+
isLoading: false,
436+
},
437+
},
438+
];
439+
440+
const failureData: OnyxUpdate[] = [
441+
{
442+
onyxMethod: Onyx.METHOD.MERGE,
443+
key: ONYXKEYS.ACCOUNT,
444+
value: {
445+
isLoading: false,
446+
},
447+
},
448+
];
449+
450+
const params: SignUpUserParams = {email: credentials.login, preferredLocale};
451+
452+
API.write(WRITE_COMMANDS.SIGN_UP_USER, params, {optimisticData, successData, failureData});
453+
}
454+
413455
/**
414456
* Given an idToken from Sign in with Apple, checks the API to see if an account
415457
* exists for that email address and signs the user in if so.
@@ -1004,4 +1046,5 @@ export {
10041046
signInWithSupportAuthToken,
10051047
isSupportAuthToken,
10061048
hasStashedSession,
1049+
signUpUser,
10071050
};

src/pages/settings/Profile/Contacts/ContactMethodDetailsPage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ function ContactMethodDetailsPage({route}: ContactMethodDetailsPageProps) {
186186
}
187187

188188
// Replacing spaces with "hard spaces" to prevent breaking the number
189-
const formattedContactMethod = Str.isSMSLogin(contactMethod) ? formatPhoneNumber(contactMethod).replace(/ /g, '\u00A0') : contactMethod;
189+
const formattedContactMethod = Str.isSMSLogin(contactMethod) ? formatPhoneNumber(contactMethod) : contactMethod;
190190
const hasMagicCodeBeenSent = !!loginData.validateCodeSent;
191191
const isFailedAddContactMethod = !!loginData.errorFields?.addedLogin;
192192
const isFailedRemovedContactMethod = !!loginData.errorFields?.deletedLogin;

src/pages/signin/SignInPage.tsx

+36-19
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import LoginForm from './LoginForm';
3131
import type {InputHandle} from './LoginForm/types';
3232
import SignInPageLayout from './SignInPageLayout';
3333
import type {SignInPageLayoutRef} from './SignInPageLayout/types';
34+
import SignUpWelcomeForm from './SignUpWelcomeForm';
3435
import UnlinkLoginForm from './UnlinkLoginForm';
3536
import ValidateCodeForm from './ValidateCodeForm';
3637

@@ -61,6 +62,7 @@ type RenderOption = {
6162
shouldInitiateSAMLLogin: boolean;
6263
shouldShowWelcomeHeader: boolean;
6364
shouldShowWelcomeText: boolean;
65+
shouldShouldSignUpWelcomeForm: boolean;
6466
};
6567

6668
type GetRenderOptionsParams = {
@@ -71,6 +73,7 @@ type GetRenderOptionsParams = {
7173
isUsingMagicCode: boolean;
7274
hasInitiatedSAMLLogin: boolean;
7375
shouldShowAnotherLoginPageOpenedMessage: boolean;
76+
credentials: OnyxEntry<Credentials>;
7477
};
7578

7679
/**
@@ -90,6 +93,7 @@ function getRenderOptions({
9093
isUsingMagicCode,
9194
hasInitiatedSAMLLogin,
9295
shouldShowAnotherLoginPageOpenedMessage,
96+
credentials,
9397
}: GetRenderOptionsParams): RenderOption {
9498
const hasAccount = !isEmptyObject(account);
9599
const isSAMLEnabled = !!account?.isSAMLEnabled;
@@ -107,22 +111,33 @@ function getRenderOptions({
107111
Session.clearSignInData();
108112
}
109113

114+
// Show the Welcome form if a user is signing up for a new account in a domain that is not controlled
115+
const shouldShouldSignUpWelcomeForm = Boolean(credentials?.login) && !account?.validated && !account?.accountExists && !account?.domainControlled;
110116
const shouldShowLoginForm = !shouldShowAnotherLoginPageOpenedMessage && !hasLogin && !hasValidateCode;
111117
const shouldShowEmailDeliveryFailurePage = hasLogin && hasEmailDeliveryFailure && !shouldShowChooseSSOOrMagicCode && !shouldInitiateSAMLLogin;
112118
const isUnvalidatedSecondaryLogin = hasLogin && !isPrimaryLogin && !account?.validated && !hasEmailDeliveryFailure;
113119
const shouldShowValidateCodeForm =
114-
hasAccount && (hasLogin || hasValidateCode) && !isUnvalidatedSecondaryLogin && !hasEmailDeliveryFailure && !shouldShowChooseSSOOrMagicCode && !isSAMLRequired;
115-
const shouldShowWelcomeHeader = shouldShowLoginForm || shouldShowValidateCodeForm || shouldShowChooseSSOOrMagicCode || isUnvalidatedSecondaryLogin;
116-
const shouldShowWelcomeText = shouldShowLoginForm || shouldShowValidateCodeForm || shouldShowChooseSSOOrMagicCode || shouldShowAnotherLoginPageOpenedMessage;
120+
!shouldShouldSignUpWelcomeForm &&
121+
hasAccount &&
122+
(hasLogin || hasValidateCode) &&
123+
!isUnvalidatedSecondaryLogin &&
124+
!hasEmailDeliveryFailure &&
125+
!shouldShowChooseSSOOrMagicCode &&
126+
!isSAMLRequired;
127+
const shouldShowWelcomeHeader = shouldShowLoginForm || shouldShowValidateCodeForm || shouldShowChooseSSOOrMagicCode || isUnvalidatedSecondaryLogin || shouldShouldSignUpWelcomeForm;
128+
const shouldShowWelcomeText =
129+
shouldShowLoginForm || shouldShowValidateCodeForm || shouldShowChooseSSOOrMagicCode || shouldShowAnotherLoginPageOpenedMessage || shouldShouldSignUpWelcomeForm;
130+
117131
return {
118132
shouldShowLoginForm,
119133
shouldShowEmailDeliveryFailurePage,
120-
shouldShowUnlinkLoginForm: isUnvalidatedSecondaryLogin,
134+
shouldShowUnlinkLoginForm: !shouldShouldSignUpWelcomeForm && isUnvalidatedSecondaryLogin,
121135
shouldShowValidateCodeForm,
122136
shouldShowChooseSSOOrMagicCode,
123137
shouldInitiateSAMLLogin,
124138
shouldShowWelcomeHeader,
125139
shouldShowWelcomeText,
140+
shouldShouldSignUpWelcomeForm,
126141
};
127142
}
128143

@@ -181,6 +196,7 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc
181196
shouldInitiateSAMLLogin,
182197
shouldShowWelcomeHeader,
183198
shouldShowWelcomeText,
199+
shouldShouldSignUpWelcomeForm,
184200
} = getRenderOptions({
185201
hasLogin: !!credentials?.login,
186202
hasValidateCode: !!credentials?.validateCode,
@@ -189,6 +205,7 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc
189205
isUsingMagicCode,
190206
hasInitiatedSAMLLogin,
191207
shouldShowAnotherLoginPageOpenedMessage,
208+
credentials,
192209
});
193210

194211
if (shouldInitiateSAMLLogin) {
@@ -200,6 +217,11 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc
200217
let welcomeText = '';
201218
const headerText = translate('login.hero.header');
202219

220+
const userLogin = Str.removeSMSDomain(credentials?.login ?? '');
221+
222+
// replacing spaces with "hard spaces" to prevent breaking the number
223+
const userLoginToDisplay = Str.isSMSLogin(userLogin) ? formatPhoneNumber(userLogin) : userLogin;
224+
203225
if (shouldShowAnotherLoginPageOpenedMessage) {
204226
welcomeHeader = translate('welcomeText.anotherLoginPageIsOpen');
205227
welcomeText = translate('welcomeText.anotherLoginPageIsOpenExplanation');
@@ -212,21 +234,10 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc
212234
welcomeHeader = shouldUseNarrowLayout ? '' : translate('welcomeText.welcome');
213235
welcomeText = isUsingRecoveryCode ? translate('validateCodeForm.enterRecoveryCode') : translate('validateCodeForm.enterAuthenticatorCode');
214236
} else {
215-
const userLogin = Str.removeSMSDomain(credentials?.login ?? '');
216-
217-
// replacing spaces with "hard spaces" to prevent breaking the number
218-
const userLoginToDisplay = Str.isSMSLogin(userLogin) ? formatPhoneNumber(userLogin).replace(/ /g, '\u00A0') : userLogin;
219-
if (account?.validated) {
220-
welcomeHeader = shouldUseNarrowLayout ? '' : translate('welcomeText.welcome');
221-
welcomeText = shouldUseNarrowLayout
222-
? `${translate('welcomeText.welcome')} ${translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay})}`
223-
: translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay});
224-
} else {
225-
welcomeHeader = shouldUseNarrowLayout ? '' : translate('welcomeText.welcome');
226-
welcomeText = shouldUseNarrowLayout
227-
? `${translate('welcomeText.welcome')} ${translate('welcomeText.newFaceEnterMagicCode', {login: userLoginToDisplay})}`
228-
: translate('welcomeText.newFaceEnterMagicCode', {login: userLoginToDisplay});
229-
}
237+
welcomeHeader = shouldUseNarrowLayout ? '' : translate('welcomeText.welcome');
238+
welcomeText = shouldUseNarrowLayout
239+
? `${translate('welcomeText.welcome')} ${translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay})}`
240+
: translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay});
230241
}
231242
} else if (shouldShowUnlinkLoginForm || shouldShowEmailDeliveryFailurePage || shouldShowChooseSSOOrMagicCode) {
232243
welcomeHeader = shouldUseNarrowLayout ? headerText : translate('welcomeText.welcome');
@@ -235,6 +246,11 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc
235246
if (shouldShowEmailDeliveryFailurePage || shouldShowChooseSSOOrMagicCode) {
236247
welcomeText = '';
237248
}
249+
} else if (shouldShouldSignUpWelcomeForm) {
250+
welcomeHeader = shouldUseNarrowLayout ? headerText : translate('welcomeText.welcome');
251+
welcomeText = shouldUseNarrowLayout
252+
? `${translate('welcomeText.welcomeWithoutExclamation')} ${translate('welcomeText.welcomeNewFace', {login: userLoginToDisplay})}`
253+
: translate('welcomeText.welcomeNewFace', {login: userLoginToDisplay});
238254
} else if (!shouldInitiateSAMLLogin && !hasInitiatedSAMLLogin) {
239255
Log.warn('SignInPage in unexpected state!');
240256
}
@@ -269,6 +285,7 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc
269285
blurOnSubmit={account?.validated === false}
270286
scrollPageToTop={signInPageLayoutRef.current?.scrollPageToTop}
271287
/>
288+
{shouldShouldSignUpWelcomeForm && <SignUpWelcomeForm />}
272289
{shouldShowValidateCodeForm && (
273290
<ValidateCodeForm
274291
isVisible={!shouldShowAnotherLoginPageOpenedMessage}

0 commit comments

Comments
 (0)