visualCaptcha.js
function( numberOfOptions ) {
        var visualCaptchaSession = this.session[ this.namespace ],
            imageValues = [];

        // Avoid the next IF failing if a string with a number is sent
        numberOfOptions = parseInt( numberOfOptions, 10 );

        // If it's not a valid number, default to 5
        if ( ! numberOfOptions || ! _.isNumber(numberOfOptions) || isNaN(numberOfOptions) ) {
            numberOfOptions = 5;
        }

        // Set the minimum numberOfOptions to four
        if ( numberOfOptions < 4 ) {
            numberOfOptions = 4;
        }

        // Shuffle all imageOptions
        this.imageOptions = _.shuffle( this.imageOptions );

        // Get a random sample of X images
        visualCaptchaSession.images = _.sample( this.imageOptions, numberOfOptions );

        // Set a random value for each of the images, to be used in the frontend
        visualCaptchaSession.images.forEach( function( image, index ) {
            var randomValue = crypto.randomBytes( 20 ).toString( 'hex' );

            imageValues.push( randomValue );
            visualCaptchaSession.images[ index ].value = randomValue;
        });

        // Select a random image option, pluck current valid image option
        visualCaptchaSession.validImageOption = _.sample(
            _.without( visualCaptchaSession.images, visualCaptchaSession.validImageOption )
        );

        // Select a random audio option, pluck current valid audio option
        visualCaptchaSession.validAudioOption = _.sample(
            _.without( this.audioOptions, visualCaptchaSession.validAudioOption )
        );

        // Set random hashes for audio and image field names, and add it in the frontend data object
        visualCaptchaSession.frontendData = {
            values: imageValues,
            imageName: this.getValidImageOption().name,
            imageFieldName: crypto.randomBytes( 20 ).toString( 'hex' ),
            audioFieldName: crypto.randomBytes( 20 ).toString( 'hex' )
        };
    }
function( numberOfOptions ) {
        var visualCaptchaSession = this.session[ this.namespace ],
            imageValues = [];

        // Avoid the next IF failing if a string with a number is sent
        numberOfOptions = parseInt( numberOfOptions, 10 );

        // If it's not a valid number, default to 5
        if ( ! numberOfOptions || ! _.isNumber(numberOfOptions) || isNaN(numberOfOptions) ) {
            numberOfOptions = 5;
        }

        // Set the minimum numberOfOptions to four
        if ( numberOfOptions < 4 ) {
            numberOfOptions = 4;
        }

        // Shuffle all imageOptions
        this.imageOptions = _.shuffle( this.imageOptions );

        // Get a random sample of X images
        visualCaptchaSession.images = _.sample( this.imageOptions, numberOfOptions );

        // Set a random value for each of the images, to be used in the frontend
        visualCaptchaSession.images.forEach( function( image, index ) {
            var randomValue = crypto.randomBytes( 20 ).toString( 'hex' );

            imageValues.push( randomValue );
            visualCaptchaSession.images[ index ].value = randomValue;
        });

        // Select a random image option, pluck current valid image option
        visualCaptchaSession.validImageOption = _.sample(
            _.without( visualCaptchaSession.images, visualCaptchaSession.validImageOption )
        );

        // Select a random audio option, pluck current valid audio option
        visualCaptchaSession.validAudioOption = _.sample(
            _.without( this.audioOptions, visualCaptchaSession.validAudioOption )
        );

        // Set random hashes for audio and image field names, and add it in the frontend data object
        visualCaptchaSession.frontendData = {
            values: imageValues,
            imageName: this.getValidImageOption().name,
            imageFieldName: crypto.randomBytes( 20 ).toString( 'hex' ),
            audioFieldName: crypto.randomBytes( 20 ).toString( 'hex' )
        };
    }
function ( numberOfOptions ) { var visualCaptchaSession = this . session [ this . namespace ] , imageValues = [ ] ; // Avoid the next IF failing if a string with a number is sent numberOfOptions = parseInt ( numberOfOptions , 10 ) ; // If it's not a valid number, default to 5 if ( ! numberOfOptions || ! _ . isNumber ( numberOfOptions ) || isNaN ( numberOfOptions ) ) { numberOfOptions = 5 ; } // Set the minimum numberOfOptions to four if ( numberOfOptions < 4 ) { numberOfOptions = 4 ; } // Shuffle all imageOptions this . imageOptions = _ . shuffle ( this . imageOptions ) ; // Get a random sample of X images visualCaptchaSession . images = _ . sample ( this . imageOptions , numberOfOptions ) ; // Set a random value for each of the images, to be used in the frontend visualCaptchaSession . images . forEach ( function ( image , index ) { var randomValue = crypto . randomBytes ( 20 ) . toString ( 'hex' ) ; imageValues . push ( randomValue ) ; visualCaptchaSession . images [ index ] . value = randomValue ; } ) ; // Select a random image option, pluck current valid image option visualCaptchaSession . validImageOption = _ . sample ( _ . without ( visualCaptchaSession . images , visualCaptchaSession . validImageOption ) ) ; // Select a random audio option, pluck current valid audio option visualCaptchaSession . validAudioOption = _ . sample ( _ . without ( this . audioOptions , visualCaptchaSession . validAudioOption ) ) ; // Set random hashes for audio and image field names, and add it in the frontend data object visualCaptchaSession . frontendData = { values : imageValues , imageName : this . getValidImageOption ( ) . name , imageFieldName : crypto . randomBytes ( 20 ) . toString ( 'hex' ) , audioFieldName : crypto . randomBytes ( 20 ) . toString ( 'hex' ) } ; }
Generate a new valid option @param numberOfOptions is optional. Defaults to 5
Generate a new valid option