auth
CureNetMulti/pipeline/head Something is wrong with the build of this commit Details
CureNetMulti/pipeline/pr-dev There was a failure building this commit Details

This commit is contained in:
Sieciech 2021-08-03 16:16:56 +02:00
parent 239713c4f5
commit 6020575c5a
11 changed files with 112 additions and 29 deletions

View File

@ -6,12 +6,9 @@ use App\Entity\User;
use App\Traits\JsonResponseTrait;
use App\Repository\UserRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
class AuthController extends AbstractController
@ -23,7 +20,7 @@ class AuthController extends AbstractController
}
#[Route('/api/register', methods: ["POST"], name: 'register')]
public function register(Request $request, UserPasswordEncoderInterface $encoder)
public function register(Request $request, UserPasswordHasherInterface $encoder)
{
$em = $this->getDoctrine()->getManager();
$name = $request->get('name');
@ -41,7 +38,7 @@ class AuthController extends AbstractController
}
$user = new User();
$user->setPassword($encoder->encodePassword($user, $password));
$user->setPassword($encoder->hashPassword($user, $password));
$user->setEmail($email);
$user->setName($name);
$user->setSurname($surname);
@ -50,9 +47,20 @@ class AuthController extends AbstractController
return $this->created($user);
}
#[Route('/api/login', methods: ["POST"], name: 'login')]
public function login(Request $request, JWTTokenManagerInterface $JWTManager)
#[Route('/api/login', methods: ['POST'], name: 'login')]
public function login(JWTTokenManagerInterface $JWTManager)
{
$user = new User();
return $this->ok(['token' => $JWTManager->create($user)]);
}
}
#[Route('/api/user-check', methods: ['POST'])]
public function checkUser() {
$user = $this->getUser();
if (!$user) {
return $this->unauthorized([]);
}
$user->generateAvatar();
return $this->ok($user);
}
}

View File

@ -6,13 +6,14 @@ use Doctrine\ORM\Mapping as ORM;
use App\Repository\UserRepository;
use App\Entity\Abstraction\BaseEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUserInterface;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ORM\Table(name="`user`")
*/
class User extends BaseEntity implements UserInterface, PasswordAuthenticatedUserInterface
class User extends BaseEntity implements UserInterface, PasswordAuthenticatedUserInterface, JWTUserInterface
{
protected array $hidden = ['password', 'salt', 'userIdentifier', 'username'];
@ -64,6 +65,12 @@ class User extends BaseEntity implements UserInterface, PasswordAuthenticatedUse
*/
private $state;
public static function createFromPayload($username, array $payload)
{
$user = new User();
return $user;
}
public function getId(): ?string
{
return $this->id;
@ -219,4 +226,10 @@ class User extends BaseEntity implements UserInterface, PasswordAuthenticatedUse
return $this;
}
public function generateAvatar() {
if (!$this->avatar) {
$this->avatar = 'https://www.gravatar.com/avatar/' . md5($this->email) . '?s=514&d=robohash';
}
}
}

View File

@ -20,6 +20,10 @@ trait JsonResponseTrait {
return $this->response([ 'error' => 'Not acceptable', 'data' => $data], $code, $headers);
}
protected function unauthorized($data, $code = Response::HTTP_UNAUTHORIZED, $headers = []) {
return $this->response([ 'error' => 'Unauthorized', 'data' => $data], $code, $headers);
}
protected function response($data, $code = Response::HTTP_OK, $headers = []) {
if ($data instanceof BaseEntity) {

View File

@ -34,10 +34,9 @@
</div>
</ng-container>
</ng-container>
</div>
<div>
<div class="d-flex user-box">
<div class="d-flex user-box" *ngIf="user">
<div class="avatar" [style.background-image]="url(user.avatar)"></div>
<div class="d-flex align-items-center flex-grow-1 p-2">{{ user.name }} {{ user.surname }}</div>
<div class="user-menu-container">
@ -53,7 +52,7 @@
<mat-option *ngFor="let lang of langs" [value]="lang">{{ 'LANGUAGE.'+lang.toUpperCase() | translate }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="w-100 px-3">
<mat-label>{{ 'APP.THEME' | translate }}</mat-label>
<mat-select [formControl]="themeControl">
@ -66,11 +65,10 @@
</mat-menu>
</div>
</div>
</div>
</div>
</mat-drawer>
<ng-container *ngIf="isMobile">
<ng-container *ngTemplateOutlet="toolbar"></ng-container>
</ng-container>

View File

@ -7,12 +7,14 @@ import { ThemeService } from './modules/shared/services/theme/theme.service';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { AuthService } from './modules/auth/services/auth/auth.service';
import { Router } from '@angular/router';
import { UserModel } from './modules/auth/models/user.model';
enum SidebarOpenEnum {
Default,
Open,
Closed,
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
@ -31,11 +33,7 @@ export class AppComponent {
themeControl = new FormControl();
langControl = new FormControl();
appRoutes = appRoutes;
user = {
name: 'Name',
surname: 'Surname',
avatar: 'https://www.gravatar.com/avatar/81b206a89f89d5b1123b87606075c6a8?s=514&d=robohash',
};
user: UserModel;
isSidebarHidden = false;
dynamicToolbarComponents = [];
@ -43,13 +41,10 @@ export class AppComponent {
switch (this.sidebarOpen) {
case SidebarOpenEnum.Open:
return true;
break;
case SidebarOpenEnum.Closed:
return false;
break;
default:
return this.defaultSidebarOpen;
break;
}
}
@ -65,6 +60,14 @@ export class AppComponent {
this.configureThemeEvents();
this.configureLanguageEvents();
this.configureResizeEvents();
this.configureUserEvents();
}
configureUserEvents() {
this.user = this.authService.getUser();
this.authService.userChange.subscribe(user => {
this.user = user;
});
}
configureSidebarEvents() {

View File

@ -6,5 +6,4 @@
margin: 0px auto;
margin-top: -150px;
height: 200px;
border-radius: 6px;
}

View File

@ -1,19 +1,47 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { BrowserStorageService } from 'src/app/modules/shared/services/browser-storage/browser-storage.service';
import { LoginModel } from '../../models/login.model';
import { RegisterModel } from '../../models/register.model';
import { TokenResponse } from '../../models/token.response';
import { UserModel } from '../../models/user.model';
import { AuthTokenService } from '../../../shared/services/auth/auth-token.service';
import { Router } from '@angular/router';
@Injectable()
export class AuthService {
private static updateAgent: any;
private user: UserModel;
public userChange = new Subject<UserModel>();
constructor(
private http: HttpClient,
private authTokenService: AuthTokenService,
) {
private router: Router,
) {
this.checkUser();
this.userChange.subscribe(user => {
this.user = user;
});
}
getUser(): UserModel {
return this.user;
}
checkUser() {
this.http.post<UserModel>('/api/user-check', {}).subscribe(user => {
this.userChange.next(user);
if (AuthService.updateAgent) {
clearTimeout(AuthService.updateAgent);
}
AuthService.updateAgent = setTimeout(() => {
this.checkUser();
}, 2000) as any;
}, () => {
this.logout();
});
}
createAccount(data: RegisterModel): Observable<UserModel> {
@ -27,6 +55,7 @@ export class AuthService {
password: data.password,
}).subscribe(data => {
this.authTokenService.setToken(data.token);
this.checkUser();
out.next(data);
});
return out;
@ -34,5 +63,6 @@ export class AuthService {
logout() {
this.authTokenService.removeToken();
this.router.navigate(['/auth']);
}
}

View File

@ -1,3 +1,10 @@
<div class="m-3 p-3">
{{ 'ERROR.PAGE_NOT_FOUND' | translate }}
</div>
<div class="primary-background toolbar-background"></div>
<div class="content align-items-center justify-content-center">
<div class="col-11 col-lg-7 col-xl-5">
<mat-card>
<div class="m-3 p-3">
{{ 'ERROR.PAGE_NOT_FOUND' | translate }}
</div>
</mat-card>
</div>
</div>

View File

@ -0,0 +1,10 @@
.primary-background{
background-color: var(--toolbar-background);
height: 100px;
}
.content{
margin: 0px auto;
margin-top: -100px;
height: 200px;
display: flex;
}

View File

@ -0,0 +1,9 @@
export class User {
id: number;
email: string;
name: string;
surname: string;
avatar: string;
country: string;
state: string;
}

View File

@ -4,6 +4,7 @@ import { NotFoundComponent } from './components/not-found/not-found.component';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { HttpLoaderFactory } from 'src/app/app.module';
import { HttpClient } from '@angular/common/http';
import { MaterialModule } from '../material/material.module';
@NgModule({
declarations: [
@ -11,6 +12,7 @@ import { HttpClient } from '@angular/common/http';
],
imports: [
CommonModule,
MaterialModule,
TranslateModule.forRoot({
defaultLanguage: 'en',
loader: {