auth
This commit is contained in:
parent
239713c4f5
commit
6020575c5a
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -6,5 +6,4 @@
|
|||
margin: 0px auto;
|
||||
margin-top: -150px;
|
||||
height: 200px;
|
||||
border-radius: 6px;
|
||||
}
|
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
.primary-background{
|
||||
background-color: var(--toolbar-background);
|
||||
height: 100px;
|
||||
}
|
||||
.content{
|
||||
margin: 0px auto;
|
||||
margin-top: -100px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export class User {
|
||||
id: number;
|
||||
email: string;
|
||||
name: string;
|
||||
surname: string;
|
||||
avatar: string;
|
||||
country: string;
|
||||
state: string;
|
||||
}
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in New Issue