Standalone Registration: Better handle incorrect verification codes

Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
automated-signal
2026-07-23 20:59:30 +00:00
committed by GitHub
co-authored by Scott Nonnenberg
parent 950bfe43c7
commit 9afd63e413
5 changed files with 65 additions and 26 deletions
+1 -1
View File
@@ -162,7 +162,7 @@
"@react-spring/web": "10.0.3",
"@signalapp/lame": "workspace:*",
"@signalapp/minimask": "1.0.1",
"@signalapp/mock-server": "25.0.0",
"@signalapp/mock-server": "25.0.1",
"@signalapp/parchment-cjs": "3.0.1",
"@signalapp/quill-cjs": "2.1.2",
"@storybook/addon-a11y": "8.4.4",
+5 -5
View File
@@ -153,8 +153,8 @@ importers:
specifier: 1.0.1
version: 1.0.1
'@signalapp/mock-server':
specifier: 25.0.0
version: 25.0.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
specifier: 25.0.1
version: 25.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
'@signalapp/parchment-cjs':
specifier: 3.0.1
version: 3.0.1
@@ -4476,8 +4476,8 @@ packages:
'@signalapp/minimask@1.0.1':
resolution: {integrity: sha512-QAwo0joA60urTNbW9RIz6vLKQjy+jdVtH7cvY0wD9PVooD46MAjE40MLssp4xUJrph91n2XvtJ3pbEUDrmT2AA==, tarball: https://registry.npmjs.org/@signalapp/minimask/-/minimask-1.0.1.tgz}
'@signalapp/mock-server@25.0.0':
resolution: {integrity: sha512-gEOYKlwppfs8XT7feg82NQKab8XOVAaQw2rAOGth60BVpzeZI0eiTF2JoNBjVdLbJamFX8Cz2CrZAyXvJhp7Jg==, tarball: https://registry.npmjs.org/@signalapp/mock-server/-/mock-server-25.0.0.tgz}
'@signalapp/mock-server@25.0.1':
resolution: {integrity: sha512-bOQ76sRp32ry7u8thgC9DAHmRuyx+P6JXHJ0g64onjrydjpcHOc0b/u5Y68HDFdvfB1LyG1FWvOO/Fg3C0f37Q==, tarball: https://registry.npmjs.org/@signalapp/mock-server/-/mock-server-25.0.1.tgz}
'@signalapp/parchment-cjs@3.0.1':
resolution: {integrity: sha512-hSBMQ1M7wE4GcC8ZeNtvpJF+DAJg3eIRRf1SiHS3I3Algav/sgJJNm6HIYm6muHuK7IJmuEjkL3ILSXgmu0RfQ==, tarball: https://registry.npmjs.org/@signalapp/parchment-cjs/-/parchment-cjs-3.0.1.tgz}
@@ -15254,7 +15254,7 @@ snapshots:
'@signalapp/minimask@1.0.1': {}
'@signalapp/mock-server@25.0.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
'@signalapp/mock-server@25.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
dependencies:
'@indutny/parallel-prettier': 3.0.0(prettier@3.8.3)
'@indutny/protopiler': 4.0.0
+19 -15
View File
@@ -38,7 +38,10 @@ import {
ValidStepsBeforeComplete,
} from '../../types/StandaloneRegistration.std.ts';
import { ErrorCode, LibSignalErrorBase } from '@signalapp/libsignal-client';
import { SessionNotAllowedToRequestCodeError } from '../../textsecure/Errors.std.ts';
import {
SessionNotAllowedToRequestCodeError,
SessionNotVerifiedError,
} from '../../textsecure/Errors.std.ts';
import { openInbox } from './app.preload.ts';
import { PhoneNumberDiscoverability } from '../../util/phoneNumberDiscoverability.std.ts';
import { itemStorage } from '../../textsecure/Storage.preload.ts';
@@ -566,25 +569,26 @@ export function submitVerificationCode({
} catch (error) {
log.error(`${logId}: error submitting code`, toLogFormat(error));
if (error instanceof SessionNotVerifiedError) {
workflow = {
...workflow,
failedSubmitCodeCount: workflow.failedSubmitCodeCount + 1,
status: {
type: 'failed',
error: 'incorrect-code',
},
};
dispatch(updateWorkflow(workflow));
return;
}
if (error instanceof LibSignalErrorBase) {
if (
error.is(ErrorCode.RegistrationRequestInvalid) ||
error.is(ErrorCode.RegistrationRequestRejected) ||
error.is(ErrorCode.RegistrationSessionIdInvalid)
error.is(ErrorCode.RegistrationSessionIdInvalid) ||
error.is(ErrorCode.RegistrationSessionNotReadyForVerification)
) {
workflow = {
...workflow,
failedSubmitCodeCount: workflow.failedSubmitCodeCount + 1,
status: {
type: 'failed',
error: 'incorrect-code',
},
};
dispatch(updateWorkflow(workflow));
return;
}
if (error.is(ErrorCode.RegistrationSessionNotReadyForVerification)) {
workflow = {
...workflow,
failedSubmitCodeCount: workflow.failedSubmitCodeCount + 1,
@@ -69,10 +69,40 @@ describe('registration', function (this: Mocha.Suite) {
}
{
debug('VERIFICATION_CODE: enter code');
const CODE = '111111';
for (let i = 0; i < CODE.length; i += 1) {
const char = CODE[i];
debug('VERIFICATION_CODE: enter incorrect code');
const INCORRECT_CODE = '123456';
for (let i = 0; i < INCORRECT_CODE.length; i += 1) {
const char = INCORRECT_CODE[i];
if (!char) {
continue;
}
const codeInput = window.getByLabel(`Character ${i + 1} of 6`);
// oxlint-disable-next-line no-await-in-loop
await typeIntoInput(codeInput, char, '');
}
await window.getByRole('button', { name: 'Continue' }).click();
// Dismiss the dialog that comes up
await window.getByRole('button', { name: 'OK' }).click();
}
{
debug('VERIFICATION_CODE: enter correct code');
const CORRECT_CODE = '111111';
// We need to delete the content from the left-most input 6 times
const firstInput = window.getByLabel(`Character 1 of 6`);
await firstInput.clear();
await firstInput.clear();
await firstInput.clear();
await firstInput.clear();
await firstInput.clear();
await firstInput.clear();
for (let i = 0; i < CORRECT_CODE.length; i += 1) {
const char = CORRECT_CODE[i];
if (!char) {
continue;
}
+6 -1
View File
@@ -2863,7 +2863,12 @@ export async function submitCodeForVerificationSession(options: {
sessionId: options.verificationSessionId,
});
await session.verifySession(options.code);
const success = await session.verifySession(options.code);
if (!success) {
throw new SessionNotVerifiedError(
'submitCodeForVerificationSession: verifySession returned false!'
);
}
// Verify that the code worked to make the session ready for account creation
if (!session.sessionState.verified) {