Integration

Documentation

Several integration solutions are available to simplify developers' work. We provide server-side and client-side libraries.

Documentation

Server Component (Yii2)

Ce composant permet d'installer en quelques minutes tous les pré-requis serveur

NginX
Apache
Maria db
Mysql
Redis
PHP
Yii

Installation

install.sh
composer require blackcube/powshield

Module configuration

Edit Yii2 application configuration to activate the module

config.php
'bootstrap' => [
    // modules to bootstrap
    // ...
    'powshield', ], 'modules' => [
// app modules 
// ...
    'powshield' => [
        'class' => blackcube\powshield\Module::class, 'antiReplay' => true, // activate antireplay
        'antiReplayTimeout' => 300, // antireplay timeout
        'algorithm' => 'SHA-256', // cypher algo
        'key' => 'sdfghjklmnbvcxwqertyuiop', // cypher key
        'minIterations' => 0, // min iterations to solve the challenge
        'maxIterations' => 50000, // max iterations to solve the challenge
        'saltLength' => 12, 'timeValidity' => 900, // time validity
    ], ]

API

Once the module is activated, the endpoints

  • /powshield/generate-challenge
  • /powshield/verify-solution

become available.

Validation Model

To validate the CAPTCHA on the server side, it is necessary to add a validator

FormModel.php
namespace app\models;

use yii\base\Model;

class FormModel extends Model
{
    public $email;
    public $subject;
    public $message;
    public $captchaSolution;

    public function rules()
    {
        return [
            [['email', 'subject', 'message', 'captchaSolution'], 'required'], 
            [['captchaSolution'], 'powshield'], // CAPTCHA validator
        ];
    }
}

Front-end component(Aurelia 2)

This component allows you to install client prerequisites.

Aurelia
Typescript
NPM

Installation

install.sh
npm install --save @blackcube/aurelia2-powshield
startup.ts
import Aurelia, { ConsoleSink, LoggerConfiguration, LogLevel } from 'aurelia';
import { PowshieldConfiguration} from '@blackcube/aurelia2-powshield';
import {Enhance} from "./app/enhance";

declare var webpackBaseUrl: string;
declare var __webpack_public_path__: string;
if ((window as any).webpackBaseUrl) {
    __webpack_public_path__ = webpackBaseUrl;
} else {
    __webpack_public_path__ = '';
}
declare var PRODUCTION:boolean;


const page = document.querySelector('body') as HTMLElement;
const au = new Aurelia();

    au.register(PowshieldConfiguration.configure({}));

    if(PRODUCTION == false) {
        au.register(LoggerConfiguration.create({
            level: LogLevel.trace, colorOptions: 'colors', sinks: [ConsoleSink]
        }));

    }

    au.enhance({
        host: page, component: Enhance
    });

Form Input

Here is the form input for the user

form.php
use yii\helpers\Html;
use yii\helpers\Url;

echo Html::beginForm(Url::to(['form']), 'post', ['novalidate' => 'novalidate', 'bc-powshield' => '']);

echo Html::errorSummary($formModel);
echo Html::activeHiddenInput($formModel, 'captchaSolution', ['id' => 'powshieldSolution']);

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'email');
echo Html::activeInput('email', $formModel, 'email', ['placeholder' => 'Email *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Subject *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Message *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo Html::submitButton('Send');
echo Html::endTag('div');

echo Html::endForm();

This is it!

This setup integrates the CAPTCHA seamlessly with the form, and the powshield validator ensures everything is correct. After these slight modifications, your form is protected!

Front-end component (Vanilla JS)

This component allows you to install client prerequisites

Javascript
NPM

Installation

install.sh
npm install --save @blackcube/vanilla-powshield

Form Input

Here is the form input for the user

form.php
use yii\helpers\Html;
use yii\helpers\Url;

echo Html::beginForm(Url::to(['form']), 'post', ['novalidate' => 'novalidate']);

echo Html::errorSummary($formModel);
echo Html::activeHiddenInput($formModel, 'captchaSolution', ['id' => 'powshieldSolution']);

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'email');
echo Html::activeInput('email', $formModel, 'email', ['placeholder' => 'Email *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Subject *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Message *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo Html::submitButton('Send');
echo Html::endTag('div');

echo Html::endForm();

Form management

And here is a snippet of JavaScript code to handle form submission.

form.js
import {Powshield} from '@blackcube/vanilla-powshield';

const powshield = new Powshield();

const form = document.querySelector('form');

if (form) {
    form.addEventListener('submit', function (event) {
        event.preventDefault();
        powshield.getChallenge('/powshield/generate-challenge')
            .then(challenge => {
                return powshield.solveChallenge(challenge)
            })
            .then(response => {
                console.log('challenge:', response);
                return powshield.solveChallenge(response)
            })
            .then(response => {
                console.log('solution:', response);
                const promises = [];
                promises.push(powshield.verifySolution('/powshield/verify-solution', response));
                promises.push(response);
                return Promise.all(promises);
            })
            .then(response => {
                const verified = response[0];
                const solution = response[1];
                console.log('verified:', solution);
                if (!verified) {
                    throw new Error('Solution is not verified');
                }
                const b64 = btoa(JSON.stringify(solution));
                return b64;
            })
            .then(response => {
                const hiddenField = document.getElementById('powshieldSolution');
                if (hiddenField) {
                    hiddenField.value = response;
                    // finally submit form
                    event.target.submit();
                } else {
                    throw new Error('Hidden field not found');
                }
                console.log('encoded:', response);
            })
    });
}