Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c49a668

Browse files
write code documentation
1 parent fb90a2e commit c49a668

File tree

12 files changed

+123
-46
lines changed

12 files changed

+123
-46
lines changed

‎src/app/core/auth/auth-guard.service.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ import { Observable, catchError, of, switchMap, throwError } from 'rxjs';
44
import { AuthService } from './auth.service';
55
import { HttpErrorResponse } from '@angular/common/http';
66

7+
/**
8+
* AuthGuard
9+
*
10+
* This is a route guard that implements the CanActivate interface and is used
11+
* to protect certain routes from unauthorized access. It checks if the user is
12+
* authenticated using the `AuthService.isAuthenticated` method. If the user is
13+
* not authenticated, it navigates to the '/login' route and returns `false`.
14+
* If the user is authenticated, it then calls the `AuthService.validateToken`
15+
* method to check if the user's token is still valid. If the token is valid,
16+
* it allows access to the protected route and returns `true`. Otherwise, it
17+
* logs out the user and returns `false`.
18+
*/
719
@Injectable()
820
export class AuthGuard implements CanActivate {
921
constructor(private authService: AuthService, private router: Router) {}
@@ -31,6 +43,7 @@ export class AuthGuard implements CanActivate {
3143

3244
private handleError = (error: HttpErrorResponse): Observable<never> => {
3345
console.error('An error occurred:', error);
46+
// If the error status is 401 (Unauthorized), log out the user
3447
if (error.status == 401) {
3548
this.authService.logout();
3649
}

‎src/app/core/auth/auth.service.spec.ts‎

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -111,26 +111,6 @@ describe('AuthService', () => {
111111
expect(result).toBe(mockToken);
112112
});
113113

114-
it('should call refreshToken API and update loginUserSubject', () => {
115-
const mockToken = 'mock_token';
116-
spyOn(authService, 'getToken').and.returnValue(mockToken);
117-
spyOn(authService['http'], 'get').and.returnValue(
118-
of({
119-
id: '123',
120-
name: 'John Doe',
121-
email: 'john@example.com',
122-
photoUrl: 'avatar_url',
123-
provider: 'google',
124-
})
125-
);
126-
127-
const spyNext = spyOn(authService.loginUserSubject, 'next');
128-
129-
authService.refreshToken().subscribe((user) => {
130-
expect(spyNext).toHaveBeenCalledOnceWith(user);
131-
});
132-
});
133-
134114
it('should make a POST request to validate the token', () => {
135115
const mockToken = 'mock_token';
136116
spyOn(authService, 'getToken').and.returnValue(mockToken);

‎src/app/core/auth/auth.service.ts‎

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
import {
2-
GoogleLoginProvider,
3-
SocialAuthService,
4-
SocialUser,
5-
} from '@abacritt/angularx-social-login';
1+
import { SocialAuthService, SocialUser } from '@abacritt/angularx-social-login';
62
import { HttpClient } from '@angular/common/http';
73
import { Injectable } from '@angular/core';
84
import { Router } from '@angular/router';
95
import { BehaviorSubject, Observable, map } from 'rxjs';
106
import { environment } from 'src/environments/environment';
117

8+
/**
9+
* AuthService
10+
*
11+
* This service handles authentication-related functionalities, including login, logout,
12+
* token management, and checking the authentication status. It interacts with the
13+
* `@abacritt/angularx-social-login` library to handle social logins and stores the
14+
* login state using BehaviorSubject. It also provides methods to refresh and validate
15+
* tokens with the backend auth server. The service is provided at the root level to ensure
16+
* a singleton instance throughout the application.
17+
*/
1218
@Injectable({
1319
providedIn: 'root',
1420
})
@@ -51,41 +57,31 @@ export class AuthService {
5157
this.loginUserSubject.next(user);
5258
}
5359

60+
//log in the user with a token and update the authentication status
5461
login(token: string): void {
5562
localStorage.setItem('token', token);
5663
this.isAuthenticatedSubject.next(true);
5764
}
5865

66+
// log out the user, clear the token, and navigate to the login page
5967
logout(): void {
6068
localStorage.removeItem('token');
6169
this.isAuthenticatedSubject.next(false);
6270
this.authService.signOut();
6371
this.router.navigate(['/login']);
6472
}
6573

74+
// check if the user is authenticated based on the presence of a token
6675
isAuthenticated(): boolean {
6776
const token = localStorage.getItem('token');
6877
return !!token;
6978
}
70-
79+
// get the stored token from local storage
7180
getToken(): string {
7281
return localStorage.getItem('token') || '';
7382
}
7483

75-
refreshToken() {
76-
const encodedIdToken = encodeURIComponent(this.getToken());
77-
return this.http
78-
.get<any>(
79-
`https://oauth2.googleapis.com/tokeninfo?id_token=${encodedIdToken}`
80-
)
81-
.pipe(
82-
map((user) => {
83-
this.loginUserSubject.next(user);
84-
return user;
85-
})
86-
);
87-
}
88-
84+
// validate the user's token with the backend server
8985
public validateToken(): Observable<any> {
9086
const token = encodeURIComponent(this.getToken());
9187
return this.http.post<any>(`${environment.auth_uri}validate-token`, {
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
/**
2+
* Configuration object for authentication.
3+
* The client ID of your application obtained from the Google Developer Console.
4+
* This is used for authenticating with the Google API.
5+
*/
16
export const authConfig = {
27
clientId:
3-
'60528208097-0m6p833tdtob9gcgvmr01iqi8d6c5bsn.apps.googleusercontent.com',// Your client ID
8+
'60528208097-0m6p833tdtob9gcgvmr01iqi8d6c5bsn.apps.googleusercontent.com',
49
responseType: 'code',
510
};

‎src/app/core/auth/login/login.component.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import { Component, OnInit } from '@angular/core';
77
import { Router } from '@angular/router';
88
import { AuthService } from '../auth.service';
99

10+
/**
11+
* Login Component
12+
*
13+
* This component provides a login functionality for users using the SocialAuthService
14+
* from '@abacritt/angularx-social-login' to authenticate with google sso.
15+
* It also utilizes the AuthService to handle the authentication state and navigation
16+
* to the '/users' route upon successful login.
17+
*/
1018
@Component({
1119
selector: 'app-login',
1220
templateUrl: './login.component.html',
@@ -19,10 +27,19 @@ export class LoginComponent implements OnInit {
1927
private router: Router
2028
) {}
2129

30+
/**
31+
* Calls the checkIsLogin method to handle the login logic.
32+
*/
2233
ngOnInit() {
2334
this.checkIsLogin();
2435
}
2536

37+
/**
38+
* Checks if the user is already authenticated and redirects to '/users'
39+
* if they are. It subscribes to the authState from the SocialAuthService
40+
* and the isAuthenticated$ from the AuthService to detect successful logins
41+
* and automatically navigate to the '/users' route.
42+
*/
2643
checkIsLogin() {
2744
this.socialAuthService.authState.subscribe((user) => {
2845
if (user && user.idToken) this.onLoginSuccess();
@@ -37,6 +54,11 @@ export class LoginComponent implements OnInit {
3754
}
3855
}
3956

57+
/**
58+
* Handles the navigation to the '/users' route upon successful login.
59+
* Called when the user is successfully authenticated via SocialAuthService
60+
* or AuthService.
61+
*/
4062
onLoginSuccess() {
4163
this.router.navigate(['/users']);
4264
}

‎src/app/core/http/auth-interceptor.service.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ import {
88
import { Observable } from 'rxjs';
99
import { AuthService } from '../auth/auth.service';
1010

11+
/**
12+
* AuthInterceptor
13+
*
14+
* This is an HTTP interceptor that adds an Authorization header with the user's token
15+
* to each outgoing HTTP request. The interceptor gets the user's token from the
16+
* 'AuthService' and attaches it to the 'Authorization' header as a Bearer token.
17+
* This ensures that the user's authentication token is included with each request,
18+
* allowing the backend server to identify and authenticate the user.
19+
*/
1120
@Injectable()
1221
export class AuthInterceptor implements HttpInterceptor {
1322
constructor(private authService: AuthService) {}

‎src/app/core/theme/header/header.component.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ import { Component, OnInit } from '@angular/core';
22
import { Observable } from 'rxjs';
33
import { AuthService } from '../../auth/auth.service';
44

5+
/**
6+
* HeaderComponent
7+
*
8+
* This component represents the header of the application. It displays navigation links
9+
* and user-related information based on the user's authentication status. The component
10+
* uses the 'AuthService' to determine if the user is authenticated, and the
11+
* 'isAuthenticated$' observable to update the header based on changes in the
12+
* authentication state. The component provides a 'logOut' method to log out the user
13+
* when the 'Log Out' button is clicked, which calls the 'logout' method from the
14+
* 'AuthService' to clear the user's authentication token and log them out.
15+
*/
516
@Component({
617
selector: 'app-header',
718
templateUrl: './header.component.html',
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import { Component, OnInit } from '@angular/core';
22
import { LoadingService } from '../../services/loading.service';
33

4+
/**
5+
* LoadingComponent
6+
*
7+
* This component represents a loading spinner or progress indicator that is displayed
8+
* during asynchronous operations or when the application is waiting for data to load.
9+
* The component uses the 'LoadingService' to track the loading state of the application.
10+
* By subscribing to the 'loading$' observable of the 'LoadingService', the component
11+
* automatically updates its visibility based on changes in the loading state.
12+
* When the 'loading$' observable emits 'true', the loading spinner is shown, and when it
13+
* emits 'false', the spinner is hidden. The component template displays a material design
14+
* progress bar ('mat-progress-bar') in case of loading, and it is hidden otherwise.
15+
*/
416
@Component({
517
selector: 'app-loading',
618
templateUrl: './loading.component.html',
719
styleUrls: ['./loading.component.scss'],
820
})
9-
export class LoadingComponent implementsOnInit{
21+
export class LoadingComponent {
1022
constructor(public loadingService: LoadingService) {}
11-
12-
ngOnInit() {}
1323
}

‎src/app/shared/services/users.service.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,25 @@ import { Observable } from 'rxjs';
44
import { User } from '../models/user.model';
55
import { environment } from 'src/environments/environment';
66

7+
/**
8+
* UsersService
9+
* This service is responsible for handling HTTP requests related to users.
10+
*/
711
@Injectable({
812
providedIn: 'root',
913
})
1014
export class UsersService {
1115
constructor(private http: HttpClient) {}
1216

17+
/**
18+
* Retrieves a list of users from the backend API based on the optional 'pageIndex',
19+
* 'pageSize', and 'filterStr' parameters.
20+
*
21+
* @param pageIndex Optional. The page index for pagination.
22+
* @param pageSize Optional. The number of items per page for pagination.
23+
* @param filterStr Optional. The filter string to search for users by name.
24+
* @returns An Observable<User[]> representing the list of users retrieved from the API.
25+
*/
1326
getUsers(
1427
pageIndex?: number,
1528
pageSize?: number,
@@ -29,6 +42,12 @@ export class UsersService {
2942
return this.http.get<User[]>(environment.apiUrl + 'users', { params });
3043
}
3144

45+
/**
46+
* Adds a new user to the backend API by sending a POST request to the 'users' endpoint.
47+
*
48+
* @param user The user object to be added to the API.
49+
* @returns An Observable<User> representing the response from the API.
50+
*/
3251
addUser(user: User): Observable<User> {
3352
return this.http.post<User>(environment.apiUrl + 'users', user);
3453
}

‎src/app/users/user-list/user-list.component.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ import {
1414
Subject,
1515
debounceTime,
1616
finalize,
17-
map,
1817
switchMap,
1918
takeUntil,
2019
tap,
2120
} from 'rxjs';
2221
import { User } from 'src/app/shared/models/user.model';
2322
import { LoadingService } from 'src/app/shared/services/loading.service';
2423
import { UsersService } from 'src/app/shared/services/users.service';
25-
24+
/**
25+
* UserListComponent
26+
* This component represents the user list page, displaying a table with user data.
27+
*/
2628
@Component({
2729
selector: 'app-user-list',
2830
templateUrl: './user-list.component.html',

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /