Skip to content

Commit 01776c3

Browse files
committed
added auth service and auth store
1 parent 8273b6a commit 01776c3

File tree

8 files changed

+131
-0
lines changed

8 files changed

+131
-0
lines changed

src/app/app.module.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { NgModule } from '@angular/core';
2+
import { NgxsModule } from '@ngxs/store';
3+
import { AuthState } from '@core/store/auth';
4+
5+
@NgModule({
6+
imports: [NgxsModule.forRoot([AuthState])],
7+
})
8+
export class AppModule {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export class SetAuthToken {
2+
static readonly type = '[Auth] Set Auth Token';
3+
4+
constructor(public accessToken: string) {}
5+
}
6+
7+
export class ClearAuth {
8+
static readonly type = '[Auth] Clear Auth';
9+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface AuthStateModel {
2+
accessToken: string | null;
3+
isAuthenticated: boolean;
4+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Selector } from '@ngxs/store';
2+
import { AuthState } from './auth.state';
3+
import { AuthStateModel } from './auth.model';
4+
5+
export class AuthSelectors {
6+
@Selector([AuthState])
7+
static isAuthenticated(state: AuthStateModel): boolean {
8+
return state.isAuthenticated;
9+
}
10+
11+
@Selector([AuthState])
12+
static getAuthToken(state: AuthStateModel): string | null {
13+
return state.accessToken;
14+
}
15+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Injectable } from '@angular/core';
2+
import { State, Action, StateContext } from '@ngxs/store';
3+
import { AuthStateModel } from './auth.model';
4+
import { SetAuthToken, ClearAuth } from './auth.actions';
5+
6+
@State<AuthStateModel>({
7+
name: 'auth',
8+
defaults: {
9+
accessToken: null,
10+
isAuthenticated: false,
11+
},
12+
})
13+
@Injectable()
14+
export class AuthState {
15+
@Action(SetAuthToken)
16+
setAuthToken(ctx: StateContext<AuthStateModel>, action: SetAuthToken) {
17+
ctx.patchState({
18+
accessToken: action.accessToken,
19+
isAuthenticated: true,
20+
});
21+
}
22+
23+
@Action(ClearAuth)
24+
clearAuth(ctx: StateContext<AuthStateModel>) {
25+
ctx.patchState({
26+
accessToken: null,
27+
isAuthenticated: false,
28+
});
29+
}
30+
}

src/app/core/store/auth/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './auth.actions';
2+
export * from './auth.model';
3+
export * from './auth.selectors';
4+
export * from './auth.state';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export interface LoginCredentials {
2+
email: string;
3+
password: string;
4+
}
5+
6+
export interface AuthResponse {
7+
accessToken: string;
8+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Injectable, inject } from '@angular/core';
2+
import { HttpClient } from '@angular/common/http';
3+
import { Store } from '@ngxs/store';
4+
import { firstValueFrom } from 'rxjs';
5+
import { LoginCredentials, AuthResponse } from './auth.entity';
6+
import { SetAuthToken, ClearAuth } from '@core/store/auth';
7+
8+
@Injectable({
9+
providedIn: 'root',
10+
})
11+
export class AuthService {
12+
private readonly API_URL: string = 'VALID_API_URL';
13+
private readonly AUTH_TOKEN_KEY: string = '';
14+
15+
private readonly http: HttpClient = inject(HttpClient);
16+
private readonly store: Store = inject(Store);
17+
18+
async login(credentials: LoginCredentials): Promise<void> {
19+
try {
20+
const response: AuthResponse = await firstValueFrom(
21+
this.http.post<AuthResponse>(`${this.API_URL}/auth/login`, credentials),
22+
);
23+
24+
if (response.accessToken) {
25+
this.setAuthToken(response.accessToken);
26+
this.store.dispatch(new SetAuthToken(response.accessToken));
27+
}
28+
} catch (error) {
29+
console.error('Login failed:', error);
30+
throw error;
31+
}
32+
}
33+
34+
logout(): void {
35+
localStorage.removeItem(this.AUTH_TOKEN_KEY);
36+
this.store.dispatch(new ClearAuth());
37+
}
38+
39+
getAuthToken(): string | null {
40+
return localStorage.getItem(this.AUTH_TOKEN_KEY);
41+
}
42+
43+
private setAuthToken(token: string): void {
44+
localStorage.setItem(this.AUTH_TOKEN_KEY, token);
45+
}
46+
47+
private checkInitialAuthState(): void {
48+
const token: string | null = this.getAuthToken();
49+
if (token) {
50+
this.store.dispatch(new SetAuthToken(token));
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)