routes/apiHandlers.js
/**
 * Checks the phone validity and use with the conveyor
 * The user can only request one code every minute to prevent flood
 */
Checks the phone validity and use with the conveyor
The user can only request one code every minute to prevent flood
Checks the phone validity and use with the conveyor The user can only request one code every minute to prevent flood
async function handleRequestSms(req) {
    const decoded = verifyToken(req.body.token, 'signup');
    if (!req.body.phoneNumber) {
        throw new ApiError({
            type: 'error_api_phone_required',
            field: 'phoneNumber',
        });
    }
    if (!req.body.prefix) {
        throw new ApiError({
            type: 'error_api_country_code_required',
            field: 'prefix',
        });
    }
    const countryCode = req.body.prefix.split('_')[1];
    if (!countryCode) {
        throw new ApiError({
            field: 'prefix',
            type: 'error_api_prefix_invalid',
        });
    }
    const user = await database.findUser({
        where: {
            email: decoded.email,
        },
    });
    if (!user) {
        throw new ApiError({
            field: 'phoneNumber',
            type: 'error_api_unknown_user',
        });
    }
    let phoneNumber = phoneUtil.parse(req.body.phoneNumber, countryCode);
    const isValid = phoneUtil.isValidNumber(phoneNumber);
    if (!isValid) {
        throw new ApiError({
            field: 'phoneNumber',
            type: 'error_phone_invalid',
        });
    }
    phoneNumber = phoneUtil.format(phoneNumber, PNF.E164);
    await database.logAction({
        action: 'try_number',
        ip: req.ip,
        metadata: { phoneNumber },
        user_id: user.id,
    });
    try {
        await services.validatePhone(phoneNumber);
    } catch (cause) {
        throw new ApiError({
            field: 'phoneNumber',
            type: 'error_phone_invalid',
            cause,
        });
    }
    await database.actionLimit(req.ip, user.id);
    if (
        user.last_attempt_verify_phone_number &&
        user.last_attempt_verify_phone_number.getTime() >
            Date.now() - 2 * 60 * 1000
    ) {
        throw new ApiError({
            field: 'phoneNumber',
            type: 'error_api_wait',
        });
    }
    const phoneExists = await database.phoneIsInUse(phoneNumber);
    if (phoneExists) {
        throw new ApiError({
            field: 'phoneNumber',
            type: 'error_api_phone_used',
        });
    }
    const phoneRegistered = await services.conveyorCall('is_phone_registered', [
        phoneNumber,
    ]);
    if (phoneRegistered) {
        throw new ApiError({
            field: 'phoneNumber',
            type: 'error_api_phone_used',
        });
    }
    const phoneCode = user.phone_code || generateCode(5);
    await database.updateUsers(
        {
            last_attempt_verify_phone_number: new Date(),
            phone_code: phoneCode,
            phone_number: phoneNumber,
            phone_code_attempts: 0,
        },
        { where: { email: decoded.email } }
    );
    await database.logAction({
        action: 'send_sms',
        ip: req.ip,
        metadata: { phoneNumber },
        user_id: user.id,
    });
    try {
        await services.sendSMS(
            phoneNumber,
            `${phoneCode} is your Steem confirmation code`
        );
    } catch (cause) {
        if (cause.code === 21614 || cause.code === 21211) {
            throw new ApiError({
                cause,
                field: 'phoneNumber',
                type: 'error_phone_format',
            });
        } else {
            throw cause;
        }
    }
    return { success: true, phoneNumber, xref: user.tracking_id };
}
async function handleRequestSms ( req ) { const decoded = verifyToken ( req . body . token , 'signup' ) ; if ( ! req . body . phoneNumber ) { throw new ApiError ( { type : 'error_api_phone_required' , field : 'phoneNumber' , } ) ; } if ( ! req . body . prefix ) { throw new ApiError ( { type : 'error_api_country_code_required' , field : 'prefix' , } ) ; } const countryCode = req . body . prefix . split ( '_' ) [ 1 ] ; if ( ! countryCode ) { throw new ApiError ( { field : 'prefix' , type : 'error_api_prefix_invalid' , } ) ; } const user = await database . findUser ( { where : { email : decoded . email , } , } ) ; if ( ! user ) { throw new ApiError ( { field : 'phoneNumber' , type : 'error_api_unknown_user' , } ) ; } let phoneNumber = phoneUtil . parse ( req . body . phoneNumber , countryCode ) ; const isValid = phoneUtil . isValidNumber ( phoneNumber ) ; if ( ! isValid ) { throw new ApiError ( { field : 'phoneNumber' , type : 'error_phone_invalid' , } ) ; } phoneNumber = phoneUtil . format ( phoneNumber , PNF . E164 ) ; await database . logAction ( { action : 'try_number' , ip : req . ip , metadata : { phoneNumber } , user_id : user . id , } ) ; try { await services . validatePhone ( phoneNumber ) ; } catch ( cause ) { throw new ApiError ( { field : 'phoneNumber' , type : 'error_phone_invalid' , cause , } ) ; } await database . actionLimit ( req . ip , user . id ) ; if ( user . last_attempt_verify_phone_number && user . last_attempt_verify_phone_number . getTime ( ) > Date . now ( ) - 2 * 60 * 1000 ) { throw new ApiError ( { field : 'phoneNumber' , type : 'error_api_wait' , } ) ; } const phoneExists = await database . phoneIsInUse ( phoneNumber ) ; if ( phoneExists ) { throw new ApiError ( { field : 'phoneNumber' , type : 'error_api_phone_used' , } ) ; } const phoneRegistered = await services . conveyorCall ( 'is_phone_registered' , [ phoneNumber , ] ) ; if ( phoneRegistered ) { throw new ApiError ( { field : 'phoneNumber' , type : 'error_api_phone_used' , } ) ; } const phoneCode = user . phone_code || generateCode ( 5 ) ; await database . updateUsers ( { last_attempt_verify_phone_number : new Date ( ) , phone_code : phoneCode , phone_number : phoneNumber , phone_code_attempts : 0 , } , { where : { email : decoded . email } } ) ; await database . logAction ( { action : 'send_sms' , ip : req . ip , metadata : { phoneNumber } , user_id : user . id , } ) ; try { await services . sendSMS ( phoneNumber , ` ${ phoneCode } ` ) ; } catch ( cause ) { if ( cause . code === 21614 || cause . code === 21211 ) { throw new ApiError ( { cause , field : 'phoneNumber' , type : 'error_phone_format' , } ) ; } else { throw cause ; } } return { success : true , phoneNumber , xref : user . tracking_id } ; }
Checks the phone validity and use with the conveyor
 The user can only request one code every minute to prevent flood
Checks the phone validity and use with the conveyor The user can only request one code every minute to prevent flood