diff --git a/rest/index.php b/rest/index.php
index d07466cee6263a6f6988777f9cdd73ae687fc0ed..226bfcd5c76e061de4634d437f801a4837f9e38b 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -99,6 +99,7 @@ $app->get('/users/{id}', \User\controllers\UserController::class . ':getById');
 $app->put('/users/{id}', \User\controllers\UserController::class . ':update');
 $app->delete('/users/{id}', \User\controllers\UserController::class . ':delete');
 $app->get('/users/{id}/picture', \User\controllers\UserController::class . ':getPictureById');
+$app->put('/users/{id}/picture', \User\controllers\UserController::class . ':updatePicture');
 $app->get('/users/{id}/substitute', \User\controllers\UserController::class . ':getSubstituteById');
 $app->put('/users/{id}/preferences', \User\controllers\UserController::class . ':updatePreferences');
 $app->put('/users/{id}/substitute', \User\controllers\UserController::class . ':updateSubstitute');
diff --git a/src/app/user/controllers/UserController.php b/src/app/user/controllers/UserController.php
index fdead4ca42a556900097e35bd8125405d4bad33c..1e6877b9931bf01c1d807fc44be3ca4d60b5b0e8 100755
--- a/src/app/user/controllers/UserController.php
+++ b/src/app/user/controllers/UserController.php
@@ -176,30 +176,65 @@ class UserController
             'email'         => $body['email']
         ];
 
-        if ($GLOBALS['id'] == $args['id'] && !empty($body['picture'])) {
-            $infoContent = '';
-            if (preg_match('/^data:image\/(\w+);base64,/', $body['picture'])) {
-                $infoContent = substr($body['picture'], 0, strpos($body['picture'], ',') + 1);
-                $body['picture'] = substr($body['picture'], strpos($body['picture'], ',') + 1);
-            }
-            $picture    = base64_decode($body['picture']);
-            $finfo      = new \finfo(FILEINFO_MIME_TYPE);
-            $mimeType   = $finfo->buffer($picture);
-            $type       = explode('/', $mimeType);
+        UserModel::update([
+            'set'   => $set,
+            'where' => ['id = ?'],
+            'data'  => [$args['id']]
+        ]);
 
-            if ($type[0] != 'image') {
-                return $response->withStatus(400)->withJson(['errors' => 'Picture is not an image']);
-            }
+        HistoryController::add([
+            'code'          => 'OK',
+            'objectType'    => 'users',
+            'objectId'      => $args['id'],
+            'type'          => 'MODIFICATION',
+            'message'       => "{userUpdated} : {$body['firstname']} {$body['lastname']}"
+        ]);
 
-            if (!empty($body['pictureOrientation'])) {
-                $imagick = new \Imagick();
-                $imagick->readImageBlob(base64_decode($body['picture']));
-                $imagick->rotateImage(new \ImagickPixel(), $body['pictureOrientation']);
-                $body['picture'] = base64_encode($imagick->getImageBlob());
-            }
-            $set['picture'] = $infoContent . $body['picture'];
+        return $response->withJson(['user' => UserController::getUserInformationsById(['id' => $args['id']])]);
+    }
+
+    public function updatePicture(Request $request, Response $response, array $args)
+    {
+        if ($GLOBALS['id'] != $args['id']) {
+            return $response->withStatus(403)->withJson(['errors' => 'Privilege forbidden']);
         }
 
+        $body = $request->getParsedBody();
+
+        if (!Validator::stringType()->notEmpty()->validate($body['picture'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body picture is empty']);
+        }
+
+        $user = UserModel::getById(['id' => $args['id'], 'select' => ['firstname', 'lastname']]);
+        if (empty($user)) {
+            return $response->withStatus(400)->withJson(['errors' => 'User does not exist']);
+        }
+
+        $infoContent = '';
+        if (preg_match('/^data:image\/(\w+);base64,/', $body['picture'])) {
+            $infoContent = substr($body['picture'], 0, strpos($body['picture'], ',') + 1);
+            $body['picture'] = substr($body['picture'], strpos($body['picture'], ',') + 1);
+        }
+        $picture    = base64_decode($body['picture']);
+        $finfo      = new \finfo(FILEINFO_MIME_TYPE);
+        $mimeType   = $finfo->buffer($picture);
+        $type       = explode('/', $mimeType);
+
+        if ($type[0] != 'image') {
+            return $response->withStatus(400)->withJson(['errors' => 'Picture is not an image']);
+        }
+
+        if (!empty($body['pictureOrientation'])) {
+            $imagick = new \Imagick();
+            $imagick->readImageBlob(base64_decode($body['picture']));
+            $imagick->rotateImage(new \ImagickPixel(), $body['pictureOrientation']);
+            $body['picture'] = base64_encode($imagick->getImageBlob());
+        }
+
+        $set = [
+            'picture'     => $infoContent . $body['picture']
+        ];
+
         UserModel::update([
             'set'   => $set,
             'where' => ['id = ?'],
@@ -211,10 +246,10 @@ class UserController
             'objectType'    => 'users',
             'objectId'      => $args['id'],
             'type'          => 'MODIFICATION',
-            'message'       => "{userUpdated} : {$body['firstname']} {$body['lastname']}"
+            'message'       => "{userUpdated} : {$user['firstname']} {$user['lastname']}"
         ]);
 
-        return $response->withJson(['user' => UserController::getUserInformationsById(['id' => $args['id']])]);
+        return $response->withJson(['success']);
     }
 
     public function delete(Request $request, Response $response, array $args)
diff --git a/src/frontend/app/profile/profile.component.html b/src/frontend/app/profile/profile.component.html
index 0bd3f49d47bf8d81b9b2b5d9876c01a53702fb74..146d6c83c01c606c3a3486dfc8b18e19bf79ec0e 100644
--- a/src/frontend/app/profile/profile.component.html
+++ b/src/frontend/app/profile/profile.component.html
@@ -7,8 +7,8 @@
         <div class="user">
             {{'lang.myProfil' | translate}}
         </div>
-        <div class="avatarProfile"
-            [ngStyle]="{'background': 'url(' + this.profileInfo.picture + ') no-repeat scroll center center / cover'}"
+        <div #avatarProfile class="avatarProfile"
+            [ngStyle]="{'background': 'url(' + this.avatarInfo.picture + ') no-repeat scroll center center / cover'}"
             (tap)="uploadFile.click();">
         </div>
         <input #uploadFile type="file" style="display:none;" (change)="handleFileInput($event.target.files)">
@@ -93,8 +93,8 @@
                                 <legend align="left">{{'lang.notifications' | translate}}</legend>
                                 <div class="form-container">
                                     <div class="form-2-col">
-                                        <mat-slide-toggle [checked]="this.profileInfo.preferences.notifications"
-                                            (change)="this.profileInfo.preferences.notifications=!this.profileInfo.preferences.notifications"
+                                        <mat-slide-toggle [checked]="this.preferenceInfo.notifications"
+                                            (change)="this.preferenceInfo.notifications=!this.preferenceInfo.notifications"
                                             color="primary">{{'lang.receiveNotif' | translate}}</mat-slide-toggle>
                                     </div>
                                     <div class="form-2-col" style="text-align: justify;font-size: 12px;">
@@ -110,7 +110,7 @@
                                     <div class="form-2-col">
                                         <mat-form-field>
                                             <mat-select #langSelect name="langUser"
-                                                [(ngModel)]="this.profileInfo.preferences.lang">
+                                                [(ngModel)]="this.preferenceInfo.lang">
                                                 <mat-option *ngFor="let lang of this.profileInfo['availableLanguages']"
                                                     [value]="lang">{{'lang.'+lang | translate }}</mat-option>
                                             </mat-select>
@@ -129,7 +129,7 @@
                                     <div class="form-2-col">
                                         <mat-form-field>
                                             <mat-select name="writingMode"
-                                                [(ngModel)]="this.profileInfo.preferences.writingMode">
+                                                [(ngModel)]="this.preferenceInfo.writingMode">
                                                 <mat-option value="direct">{{'lang.free' | translate}}</mat-option>
                                                 <mat-option value="stylus">{{'lang.appleStylus' | translate}} <i
                                                         class="fab fa-apple"></i>
@@ -137,11 +137,11 @@
                                             </mat-select>
                                         </mat-form-field>
                                     </div>
-                                    <div *ngIf="this.profileInfo.preferences.writingMode == 'stylus'" class="form-2-col"
+                                    <div *ngIf="this.preferenceInfo.writingMode == 'stylus'" class="form-2-col"
                                         style="text-align: justify;font-size: 12px;"
                                         [innerHTML]="'lang.freeModeInfo' | translate">
                                     </div>
-                                    <div *ngIf="this.profileInfo.preferences.writingMode == 'direct'" class="form-2-col"
+                                    <div *ngIf="this.preferenceInfo.writingMode == 'direct'" class="form-2-col"
                                         style="text-align: justify;font-size: 12px;"
                                         [innerHTML]="'lang.standardModeInfo' | translate">
                                     </div>
@@ -156,7 +156,7 @@
                                     <div class="form-2-col">
                                         <mat-form-field>
                                             <mat-select name="writingSize"
-                                                [(ngModel)]="this.profileInfo.preferences.writingSize"
+                                                [(ngModel)]="this.preferenceInfo.writingSize"
                                                 (selectionChange)="drawSample();">
                                                 <mat-option *ngFor='let in of counter(10) ;let i = index' [value]="i+1">
                                                     {{i+1}}</mat-option>
@@ -176,7 +176,7 @@
                                     <div class="form-2-col">
                                         <mat-form-field>
                                             <mat-select name="writingColor"
-                                                [(ngModel)]="this.profileInfo.preferences.writingColor">
+                                                [(ngModel)]="this.preferenceInfo.writingColor">
                                                 <mat-option style="color:#000000" value="#000000">
                                                     {{'lang.black' | translate}}</mat-option>
                                                 <mat-option style="color:#1a75ff" value="#1a75ff">
@@ -188,7 +188,7 @@
                                     </div>
                                     <div class="form-2-col">
                                         <div style="height:50px;width:100px;margin:auto;"
-                                            [style.backgroundColor]="this.profileInfo.preferences.writingColor">
+                                            [style.backgroundColor]="this.preferenceInfo.writingColor">
                                         </div>
                                     </div>
                                 </div>
diff --git a/src/frontend/app/profile/profile.component.ts b/src/frontend/app/profile/profile.component.ts
index 96cbdc2d006f7836383da2463456394222f881a8..8adf05a009ac721a32381a4beeb0f412396a6b10 100644
--- a/src/frontend/app/profile/profile.component.ts
+++ b/src/frontend/app/profile/profile.component.ts
@@ -1,6 +1,6 @@
-import { Component, OnInit, Input, ViewChild } from '@angular/core';
+import { Component, OnInit, Input, ViewChild, Renderer2, ElementRef } from '@angular/core';
 import { DomSanitizer } from '@angular/platform-browser';
-import { MatIconRegistry, MatSidenav, MatExpansionPanel, MatTabGroup } from '@angular/material';
+import { MatSidenav, MatExpansionPanel, MatTabGroup } from '@angular/material';
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { SignaturesContentService } from '../service/signatures.service';
 import { NotificationService } from '../service/notification.service';
@@ -9,9 +9,9 @@ import * as EXIF from 'exif-js';
 import { TranslateService } from '@ngx-translate/core';
 import { FiltersService } from '../service/filters.service';
 import { Router } from '@angular/router';
-import { finalize, tap, exhaustMap, filter, catchError } from 'rxjs/operators';
+import { tap, exhaustMap, filter, catchError, takeUntil, finalize } from 'rxjs/operators';
 import { AuthService } from '../service/auth.service';
-import { of } from 'rxjs';
+import { of, Subject } from 'rxjs';
 
 @Component({
     selector: 'app-my-profile',
@@ -26,11 +26,17 @@ export class ProfileComponent implements OnInit {
 
 
     @ViewChild('passwordContent') passwordContent: MatExpansionPanel;
+    @ViewChild('avatarProfile') avatarProfile: ElementRef;
 
     profileInfo: any = {
         substitute: null,
         preferences: []
     };
+    preferenceInfo: any = {};
+    avatarInfo: any = {
+        picture: '',
+        pictureOrientation : ''
+    };
     hideCurrentPassword: Boolean = true;
     hideNewPassword: Boolean = true;
     hideNewPasswordConfirm: Boolean = true;
@@ -65,17 +71,34 @@ export class ProfileComponent implements OnInit {
     msgButton = 'lang.validate';
     loading: boolean = false;
 
-    constructor(private translate: TranslateService, public http: HttpClient, private router: Router, public sanitizer: DomSanitizer, public notificationService: NotificationService, public signaturesService: SignaturesContentService, public authService: AuthService, private cookieService: CookieService, public filtersService: FiltersService) { }
+    constructor(private translate: TranslateService,
+        public http: HttpClient,
+        private router: Router,
+        public sanitizer: DomSanitizer,
+        public notificationService: NotificationService,
+        public signaturesService: SignaturesContentService,
+        public authService: AuthService,
+        private cookieService: CookieService,
+        public filtersService: FiltersService,
+        private renderer: Renderer2) { }
 
     ngOnInit(): void {
+        this.initProfileInfo();
+    }
+
+    initProfileInfo() {
         this.profileInfo = JSON.parse(JSON.stringify(this.authService.user));
+        this.preferenceInfo = this.profileInfo.preferences;
+        this.avatarInfo.picture = this.profileInfo.picture;
+        delete this.profileInfo.picture;
+        delete this.profileInfo.preferences;
     }
 
     closeProfile() {
-        $('.avatarProfile').css({ 'transform': 'rotate(0deg)' });
-        $('.avatarProfile').css({ 'content': '' });
+        this.renderer.setStyle(this.avatarProfile.nativeElement, 'transform', 'rotate(0deg)');
+        this.renderer.setStyle(this.avatarProfile.nativeElement, 'content', '');
         setTimeout(() => {
-            this.profileInfo = JSON.parse(JSON.stringify(this.authService.user));
+            this.initProfileInfo();
         }, 200);
         this.passwordContent.close();
 
@@ -187,34 +210,15 @@ export class ProfileComponent implements OnInit {
     submitProfile() {
         this.disableState = true;
         this.msgButton = 'lang.sending';
-        const profileToSend = {
-            'firstname': this.profileInfo.firstname,
-            'lastname': this.profileInfo.lastname,
-            'email': this.profileInfo.email,
-            'picture': this.profileInfo.picture,
-            'preferences': this.profileInfo.preferences,
-            'substitute': this.profileInfo.substitute,
-        };
-
-        if (this.profileInfo.picture === this.authService.user.picture) {
-            profileToSend.picture = '';
-        } else {
-            const orientation = $('.avatarProfile').css('content');
-            profileToSend['pictureOrientation'] = orientation.replace(/\"/g, '');
-        }
 
-        this.http.put('../rest/users/' + this.authService.user.id, profileToSend).pipe(
-            tap((data: any) => {
-                this.authService.user.picture = data.user.picture;
-                this.profileInfo.picture = data.user.picture;
-            }),
-            exhaustMap(() => this.http.put('../rest/users/' + this.authService.user.id + '/preferences', profileToSend.preferences)),
+        this.http.put('../rest/users/' + this.authService.user.id, this.profileInfo).pipe(
+            exhaustMap(() => this.http.put('../rest/users/' + this.authService.user.id + '/preferences', this.preferenceInfo)),
             tap(() => {
                 this.disableState = false;
                 this.msgButton = 'lang.validate';
-                this.setLang(this.authService.user.preferences.lang);
-                this.cookieService.set('maarchParapheurLang', this.authService.user.preferences.lang);
-                $('.avatarProfile').css({ 'transform': 'rotate(0deg)' });
+                this.setLang(this.preferenceInfo.lang);
+                this.cookieService.set('maarchParapheurLang', this.preferenceInfo.lang);
+                // this.renderer.setStyle(this.avatarProfile.nativeElement, 'transform', 'rotate(0deg)');
                 this.authService.updateUserInfoWithTokenRefresh();
             }),
             exhaustMap(() => {
@@ -248,6 +252,25 @@ export class ProfileComponent implements OnInit {
         ).subscribe();
     }
 
+    changePicture() {
+        this.msgButton = 'lang.sending';
+        this.disableState = true;
+        this.http.put('../rest/users/' + this.authService.user.id + '/picture', this.avatarInfo).pipe(
+            tap(() => {
+                this.authService.user.picture = this.avatarInfo.picture;
+                this.renderer.setStyle(this.avatarProfile.nativeElement, 'background-size', 'cover');
+                this.renderer.setStyle(this.avatarProfile.nativeElement, 'background-position', 'center');
+                this.renderer.setStyle(this.avatarProfile.nativeElement, 'transform', 'rotate(' + this.avatarInfo.pictureOrientation + 'deg)');
+                this.renderer.setStyle(this.avatarProfile.nativeElement, 'content', '\'' + this.avatarInfo.pictureOrientation + '\'');
+                this.notificationService.success('lang.profileUpdated');
+            }),
+            finalize(() => {
+                this.msgButton = 'lang.validate';
+                this.disableState = false;
+            })
+        ).subscribe();
+    }
+
     selectSubstitute(ev: any) {
         if (this.profileInfo.substitute !== null) {
             alert(this.translate.instant('lang.substitutionWarn'));
@@ -286,37 +309,16 @@ export class ProfileComponent implements OnInit {
     handleFileInput(files: FileList) {
         this.passwordContent.close();
         const fileToUpload = files.item(0);
-        $('.avatarProfile').css({ 'content': '' });
+        this.renderer.setStyle(this.avatarProfile.nativeElement, 'content', '');
 
         if (fileToUpload.size <= 5000000) {
-            if (['image/png', 'image/svg+xml', 'image/jpg', 'image/jpeg', 'image/gif'].indexOf(fileToUpload.type) !== -1) {
+            if (['image/png', 'image/jpg', 'image/jpeg', 'image/gif'].indexOf(fileToUpload.type) !== -1) {
                 const myReader: FileReader = new FileReader();
                 myReader.onloadend = (e) => {
-                    this.profileInfo.picture = myReader.result;
                     const image = new Image();
-
                     image.src = myReader.result.toString();
-                    image.onload = function () {
-                        EXIF.getData((image as any), () => {
-                            let deg = 0;
-                            const orientation = EXIF.getTag(this, 'Orientation');
-                            switch (orientation) {
-                                case 3:
-                                    deg = 180;
-                                    break;
-                                case 6:
-                                    deg = 90;
-                                    break;
-                                case 8:
-                                    deg = -90;
-                                    break;
-                            }
-                            $('.avatarProfile').css({ 'background-size': 'cover' });
-                            $('.avatarProfile').css({ 'background-position': 'center' });
-                            $('.avatarProfile').css({ 'transform': 'rotate(' + deg + 'deg)' });
-                            $('.avatarProfile').css({ 'content': '\'' + deg + '\'' });
-                        });
-                    };
+                    this.avatarInfo.picture = myReader.result;
+                    image.onload = () => this.fixImgOrientation(image);
                 };
                 myReader.readAsDataURL(fileToUpload);
             } else {
@@ -327,12 +329,32 @@ export class ProfileComponent implements OnInit {
         }
     }
 
+    fixImgOrientation(image: any) {
+        EXIF.getData((image as any), () => {
+            let deg = 0;
+            const orientation = EXIF.getTag(image, 'Orientation');
+            switch (orientation) {
+                case 3:
+                    deg = 180;
+                    break;
+                case 6:
+                    deg = 90;
+                    break;
+                case 8:
+                    deg = -90;
+                    break;
+            }
+            this.avatarInfo.pictureOrientation = deg;
+            this.changePicture();
+        });
+    }
+
     drawSample() {
         const c = document.getElementById('sampleNote');
         const ctx = (<HTMLCanvasElement>c).getContext('2d');
         ctx.clearRect(0, 0, 150, 150);
         ctx.beginPath();
-        ctx.lineWidth = this.profileInfo.preferences.writingSize;
+        ctx.lineWidth = this.preferenceInfo.writingSize;
         ctx.moveTo(0, 0);
         ctx.lineTo(150, 150);
         ctx.moveTo(150, 0);