diff --git a/src/backend/src/Controller/AuthController.php b/src/backend/src/Controller/AuthController.php
index 602c203..98aaf38 100644
--- a/src/backend/src/Controller/AuthController.php
+++ b/src/backend/src/Controller/AuthController.php
@@ -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)]);
}
-}
\ No newline at end of file
+
+ #[Route('/api/user-check', methods: ['POST'])]
+ public function checkUser() {
+ $user = $this->getUser();
+ if (!$user) {
+ return $this->unauthorized([]);
+ }
+ $user->generateAvatar();
+ return $this->ok($user);
+ }
+}
diff --git a/src/backend/src/Entity/User.php b/src/backend/src/Entity/User.php
index 1abda34..9046569 100644
--- a/src/backend/src/Entity/User.php
+++ b/src/backend/src/Entity/User.php
@@ -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';
+ }
+ }
}
diff --git a/src/backend/src/Traits/JsonResponseTrait.php b/src/backend/src/Traits/JsonResponseTrait.php
index 57751c9..05d03d1 100644
--- a/src/backend/src/Traits/JsonResponseTrait.php
+++ b/src/backend/src/Traits/JsonResponseTrait.php
@@ -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) {
diff --git a/src/frontend/src/app/app.component.html b/src/frontend/src/app/app.component.html
index aa96be6..93df4d0 100644
--- a/src/frontend/src/app/app.component.html
+++ b/src/frontend/src/app/app.component.html
@@ -34,10 +34,9 @@
-
-
+
{{ user.name }} {{ user.surname }}
-
-
+
diff --git a/src/frontend/src/app/app.component.ts b/src/frontend/src/app/app.component.ts
index 8a8b21f..87aea82 100644
--- a/src/frontend/src/app/app.component.ts
+++ b/src/frontend/src/app/app.component.ts
@@ -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() {
diff --git a/src/frontend/src/app/modules/auth/components/auth/auth.component.scss b/src/frontend/src/app/modules/auth/components/auth/auth.component.scss
index 4e2de62..be1a28c 100644
--- a/src/frontend/src/app/modules/auth/components/auth/auth.component.scss
+++ b/src/frontend/src/app/modules/auth/components/auth/auth.component.scss
@@ -6,5 +6,4 @@
margin: 0px auto;
margin-top: -150px;
height: 200px;
- border-radius: 6px;
}
\ No newline at end of file
diff --git a/src/frontend/src/app/modules/auth/services/auth/auth.service.ts b/src/frontend/src/app/modules/auth/services/auth/auth.service.ts
index f3e2bf4..8d32a41 100644
--- a/src/frontend/src/app/modules/auth/services/auth/auth.service.ts
+++ b/src/frontend/src/app/modules/auth/services/auth/auth.service.ts
@@ -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();
+
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('/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 {
@@ -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']);
}
}
diff --git a/src/frontend/src/app/modules/shared/components/not-found/not-found.component.html b/src/frontend/src/app/modules/shared/components/not-found/not-found.component.html
index a8a991b..017680c 100644
--- a/src/frontend/src/app/modules/shared/components/not-found/not-found.component.html
+++ b/src/frontend/src/app/modules/shared/components/not-found/not-found.component.html
@@ -1,3 +1,10 @@
-
- {{ 'ERROR.PAGE_NOT_FOUND' | translate }}
-
\ No newline at end of file
+
+
+
+
+
+ {{ 'ERROR.PAGE_NOT_FOUND' | translate }}
+
+
+
+
diff --git a/src/frontend/src/app/modules/shared/components/not-found/not-found.component.scss b/src/frontend/src/app/modules/shared/components/not-found/not-found.component.scss
index e69de29..3b40699 100644
--- a/src/frontend/src/app/modules/shared/components/not-found/not-found.component.scss
+++ b/src/frontend/src/app/modules/shared/components/not-found/not-found.component.scss
@@ -0,0 +1,10 @@
+.primary-background{
+ background-color: var(--toolbar-background);
+ height: 100px;
+}
+.content{
+ margin: 0px auto;
+ margin-top: -100px;
+ height: 200px;
+ display: flex;
+}
\ No newline at end of file
diff --git a/src/frontend/src/app/modules/shared/models/user.model.ts b/src/frontend/src/app/modules/shared/models/user.model.ts
new file mode 100644
index 0000000..7ed8173
--- /dev/null
+++ b/src/frontend/src/app/modules/shared/models/user.model.ts
@@ -0,0 +1,9 @@
+export class User {
+ id: number;
+ email: string;
+ name: string;
+ surname: string;
+ avatar: string;
+ country: string;
+ state: string;
+}
\ No newline at end of file
diff --git a/src/frontend/src/app/modules/shared/shared.module.ts b/src/frontend/src/app/modules/shared/shared.module.ts
index 344df7e..97bf26b 100644
--- a/src/frontend/src/app/modules/shared/shared.module.ts
+++ b/src/frontend/src/app/modules/shared/shared.module.ts
@@ -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: {