Connecteur Agglopole Provence Eau


#1

Bonjour,

Je démarre un connecteur pour l’Agglopole Provence Eau (ex. Eaux de Marseille). Je cherche à m’authentifier sur le site https://espaceclients-ape.eauxdemarseille.fr/#/login avec la fonction suivante :

    function authenticate(username, password) {
    return signin({
        url: 'https://espaceclients-ape.eauxdemarseille.fr/#/login',
        formSelector: 'form[name=signInForm]',
        formData: { txtUser: username, txtPassword: password },
        // the validate function will check if the login request was a success. Every website has
        // different ways respond: http status code, error message in html ($), http redirection
        // (fullResponse.request.uri.href)...
        validate: (statusCode, $, fullResponse) => {
        return statusCode === 200 || log('error', 'Invalid credentials')
        }
    })
    }

Le bout de code HTML pour l’écran de connexion que je scrape :

      <form name="signInForm" novalidate="" class="ng-pristine ng-invalid ng-invalid-required ng-valid-pattern"
        data-bitwarden-watching="1">
        <div class="form-group has-feedback has-warning" ng-class="{'has-warning' : signInForm.txtUser.$invalid  &amp;&amp; signInForm.txtUser.$touched, 'has-success' : signInForm.txtUser.$touched &amp;&amp; signInForm.txtUser.$valid }"
            style="">
            <label style="font-weight:lighter" ng-hide="login.userLoginMail" class="ng-hide">Identifiant</label>
            <label style="font-weight:lighter" ng-show="login.userLoginMail">E-mail</label>
            <div class="input-group">
                <div class="input-group-addon"><i class="glyphicon glyphicon-user"></i></div>
                <input type="text" name="txtUser" class="form-control ng-pristine ng-empty ng-invalid ng-invalid-required ng-valid-pattern ng-touched"
                    ng-model="login.newUser.login" ng-pattern="[a-zA-Z0-9\+\_\-\@\$\.]{2,255}" placeholder="Identifiant"
                    required="" style="">
            </div>
            <span class="form-control-feedback glyphicon  ng-hide glyphicon-remove text-danger" ng-hide="signInForm.txtUser.$pristine"
                ng-class="{'glyphicon-remove text-danger' : signInForm.txtUser.$invalid , 'glyphicon-ok text-success' : signInForm.txtUser.$valid}"></span>
            <p class="alert alert-danger ng-hide" ng-show="signInForm.txtUser.$error.pattern  &amp;&amp; signInForm.txtUser.$touched">Format
                incorrect</p>
            <p class="alert alert-danger" ng-show="signInForm.txtUser.$error.required  &amp;&amp; signInForm.txtUser.$touched"
                style="">Champ obligatoire</p>
        </div>
        <div class="form-group has-feedback" ng-class="{'has-warning' : signInForm.txtPassword.$invalid  &amp;&amp; signInForm.txtPassword.$touched, 'has-success' : signInForm.txtPassword.$touched &amp;&amp; signInForm.txtPassword.$valid }">
            <label style="font-weight:lighter">Mot de passe</label>
            <div class="input-group">
                <div class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></div>
                <input type="password" name="txtPassword" class="form-control ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required"
                    ng-model="login.newUser.password" placeholder="Mot de passe" required="">
            </div>
            <span class="form-control-feedback glyphicon ng-hide glyphicon-remove text-danger" ng-hide="signInForm.txtPassword.$pristine"
                ng-class="{'glyphicon-remove text-danger' : signInForm.txtPassword.$invalid , 'glyphicon-ok text-success' : signInForm.txtPassword.$valid}"></span>
            <p class="alert alert-danger ng-hide" ng-show="signInForm.txtPassword.$error.maxlength &amp;&amp; signInForm.txtPassword.$touched ">32
                caractères maximun</p>

            <p class="alert alert-danger ng-hide" ng-show="signInForm.txtPassword.$error.pattern
                                        &amp;&amp; !signInForm.txtPassword.$error.minlength
                                        &amp;&amp; !signInForm.txtPassword.$error.maxlength
                                        &amp;&amp; signInForm.txtPassword.$touched">Format
                incorrect</p>
            <p class="alert alert-danger ng-hide" ng-show="signInForm.txtPassword.$error.required  &amp;&amp; signInForm.txtPassword.$touched">Champ
                obligatoire</p>
        </div>
        <div class="form-group">
            <div class="col-xs-12 text-center">
                <button class="btn btn-primary" ng-disabled="!signInForm.$valid" ng-click="login.userlogin();" role="button"
                    disabled="disabled">Me connecter</button><br>
                <a href="#/login" ng-click="login.switchTo('password');" class="mr10" style="color:#fff !important">Mot de
                    passe oublié ?</a><br>

                <p class="alert alert-danger text-left mt5 ng-binding ng-hide" role="alert" ng-bind-html="login.error"
                    ng-show="login.error"></p>
            </div>
            <div class="col-xs-12 ng-scope" ng-controller="GigyaController as gigya">
                <div ng-show="gigya.enabled" class="ng-hide">
                    <h4>Social login</h4>
                    <div class="col-md-offset-1" id="socialLoginDiv"></div>
                </div>
            </div>
        </div>
    </form>

Mon sélecteur CSS semble matcher un élément non considéré comme un form.J’ai l’erreur suivante :

cozy-konnector-libs: error : element matching `form[name=signInForm]` is not a `form

Est-ce que je rate un truc évident ? Le site Web est en Angular c’est peut-être la raison ?

Merci de votre support


#2

Hello @kianby,

:tada:

Si le site est en Angular, je présume que le formulaire de connexion est créé dynamiquement par du JavaScript. Or les technologies que nous utilisons ne permettent pas d’exécuter le JS dans la page que tu analyses, le connecteur accède juste à son code HTML.
Tu ne vas donc probablement pas pouvoir utiliser les techniques classiques d’analyse de la page, mais devoir regarder les requêtes faites par le site, les analyser et les simuler.

Dis-nous si tu vois ce dont je parle ou si tu veux que je sois plus précis :slight_smile:


#3

Je pense voir :slight_smile: regarder les parties JS du site et voir comment il interagit avec des API du site.


#4

Je te conseille de surtout regarder ce qui se passe dans l’onglet Réseau, pour réussir à passer les bonnes requêtes sans te soucier du HTML de la page.
Par exemple, pour te connecter, on dirait qu’il suffit de faire une requête POST vers ‘https://espaceclients-ape.eauxdemarseille.fr/webapi/Utilisateur/authentification’ en passant deux champs, identifiant et motDePasseMD5.