Skip to content

Commit

Permalink
chore(auth): jwt-decode from v2 to v4 (#1527)
Browse files Browse the repository at this point in the history
* chore(auth): jwt-decode from v2 to v4

* chore(auth/core): add an interface for jwt token handling

* wip

* simplification

* chore(auth): decoding token could return null

* chore(auth): substitute as with satisfies

* chore(core): extends BaseUser interface to avoid circular dependencies

* chore(core): analytics set user, optional user value to mandatory

* simplification

* wip

* chore(dependency): remove jwt-decode as commonjs

* chore(auth): handle null return form token decoding

* wip
  • Loading branch information
pelord authored Dec 6, 2023
1 parent 3a05ebf commit 38fbe45
Show file tree
Hide file tree
Showing 17 changed files with 52 additions and 43 deletions.
1 change: 0 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@
"jspdf",
"jspdf-autotable",
"jszip",
"jwt-decode",
"moment",
"nosleep.js",
"raf",
Expand Down
13 changes: 8 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"jspdf": "^2.5.1",
"jspdf-autotable": "^3.5.29",
"jszip": "^3.10.1",
"jwt-decode": "^2.2.0",
"jwt-decode": "^4.0.0",
"moment": "^2.29.4",
"ngx-color": "^9.0.0",
"ngx-indexed-db": "^11.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
}
},
"dependencies": {
"jwt-decode": "^2.2.0",
"jwt-decode": "^4.0.0",
"ts-cacheable": "^1.0.6",
"ts-md5": "^1.3.0",
"tslib": "^2.6.0"
Expand Down
3 changes: 1 addition & 2 deletions packages/auth/src/lib/shared/admin.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export class AdminGuard {
) {}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const token = this.authService.decodeToken();
if (token && token.user && token.user.isAdmin) {
if (this.authService.isAdmin) {
return true;
}

Expand Down
9 changes: 2 additions & 7 deletions packages/auth/src/lib/shared/auth.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,8 @@ export class AuthInterceptor implements HttpInterceptor {
headers: req.headers.set('Authorization', authHeader)
});

const tokenDecoded: any = this.tokenService.decode();
if (
authReq.params.get('_i') === 'true' &&
tokenDecoded &&
tokenDecoded.user &&
tokenDecoded.user.sourceId
) {
const tokenDecoded = this.tokenService.decode();
if (authReq.params.get('_i') === 'true' && tokenDecoded?.user?.sourceId) {
const hashUser = Md5.hashStr(tokenDecoded.user.sourceId) as string;
authReq = authReq.clone({
params: authReq.params.set('_i', hashUser)
Expand Down
5 changes: 3 additions & 2 deletions packages/auth/src/lib/shared/auth.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MsalGuardConfiguration } from '@azure/msal-angular';
import { BaseUser } from '@igo2/core';

import { MsalGuardConfiguration } from '@azure/msal-angular';
import { BrowserAuthOptions } from '@azure/msal-browser';

export interface AuthInternOptions {
Expand Down Expand Up @@ -102,7 +103,7 @@ export interface User extends BaseUser {
sourceId?: string;
locale?: string;
isExpired?: boolean;
admin?: boolean;
isAdmin?: boolean;
defaultContextId?: string;
}

Expand Down
13 changes: 7 additions & 6 deletions packages/auth/src/lib/shared/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { catchError, tap } from 'rxjs/operators';
import { globalCacheBusterNotifier } from 'ts-cacheable';

import { AuthOptions, IInfosUser, User } from './auth.interface';
import { IgoJwtPayload } from './token.interface';
import { TokenService } from './token.service';

@Injectable({
Expand All @@ -28,8 +29,8 @@ export class AuthService {
}

get user(): User | null {
const { user = null } = this.decodeToken();
return user;
const decodedToken = this.decodeToken();
return decodedToken?.user ? decodedToken.user : null;
}

constructor(
Expand Down Expand Up @@ -108,11 +109,11 @@ export class AuthService {
return this.tokenService.get();
}

decodeToken() {
decodeToken(): IgoJwtPayload | null {
if (this.isAuthenticated()) {
return this.tokenService.decode();
}
return false;
return;
}

goToRedirectUrl() {
Expand Down Expand Up @@ -163,7 +164,7 @@ export class AuthService {

get isAdmin(): boolean {
const token = this.decodeToken();
if (token && token.user && token.user.isAdmin) {
if (token?.user?.isAdmin) {
return true;
}
return false;
Expand All @@ -176,7 +177,7 @@ export class AuthService {
tap((data: any) => {
this.tokenService.set(data.token);
const tokenDecoded = this.decodeToken();
if (tokenDecoded && tokenDecoded.user) {
if (tokenDecoded?.user) {
if (tokenDecoded.user.locale && !this.languageForce) {
this.languageService.setLanguage(tokenDecoded.user.locale);
}
Expand Down
1 change: 1 addition & 0 deletions packages/auth/src/lib/shared/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './token.service';
export * from './token.interface';
export * from './auth.service';
export * from './auth.interface';
export * from './auth.interceptor';
Expand Down
7 changes: 7 additions & 0 deletions packages/auth/src/lib/shared/token.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { JwtPayload } from 'jwt-decode';

import { User } from './auth.interface';

export interface IgoJwtPayload extends JwtPayload {
user: User;
}
7 changes: 4 additions & 3 deletions packages/auth/src/lib/shared/token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Injectable, Injector } from '@angular/core';

import { ConfigService } from '@igo2/core';

import jwtDecode from 'jwt-decode';
import { jwtDecode } from 'jwt-decode';

import { AuthOptions } from './auth.interface';
import { IgoJwtPayload } from './token.interface';

@Injectable({
providedIn: 'root'
Expand All @@ -31,12 +32,12 @@ export class TokenService {
return localStorage.getItem(this.tokenKey);
}

decode() {
decode(): IgoJwtPayload | null {
const token = this.get();
if (!token) {
return;
}
return jwtDecode(token);
return jwtDecode(token) satisfies IgoJwtPayload;
}

isExpired() {
Expand Down
1 change: 1 addition & 0 deletions packages/auth/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export * from './lib/shared/auth.interceptor';
export * from './lib/shared/auth.interface';
export * from './lib/shared/auth-microsoft.provider';
export * from './lib/shared/protected.directive';
export * from './lib/shared/token.interface';
export * from './lib/shared/token.service';
export * from './lib/shared/auth-storage.interface';
export * from './lib/shared/auth-storage.service';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class UserDialogComponent {
private storageService: StorageService
) {
const decodeToken = this.auth.decodeToken();
this.user = decodeToken.user;
this.user = decodeToken?.user;
this.exp = new Date(decodeToken.exp * 1000).toLocaleString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class ShareMapApiComponent implements OnInit {
ngOnInit(): void {
this.auth.authenticate$.subscribe((auth) => {
const decodeToken = this.auth.decodeToken();
this.userId = decodeToken.user ? decodeToken.user.id : undefined;
this.userId = decodeToken?.user?.id.toString();
this.buildForm();
});
}
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/lib/analytics/shared/analytics.interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { BaseUser } from '../../user/user.interface';

export type AnalyticsProvider = 'matomo';

export interface AnalyticsOptions {
provider?: AnalyticsProvider;
url?: string;
id?: string;
}

export interface AnalyticsBaseUser extends BaseUser {
sourceId?: string | number;
}
15 changes: 5 additions & 10 deletions packages/core/src/lib/analytics/shared/analytics.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';

import { ConfigService } from '../../config/config.service';
import { AnalyticsOptions } from './analytics.interface';
import { AnalyticsBaseUser, AnalyticsOptions } from './analytics.interface';

@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -45,15 +45,10 @@ export class AnalyticsService {
})();
}

public setUser(
user?: {
id: number;
sourceId?: string;
firstName?: string;
lastName?: string;
},
profils?: string[]
) {
/**
* Pass `null` to unset the user.
*/
public setUser(user: AnalyticsBaseUser | null, profils?: string[]) {
if (this.options.provider === 'matomo') {
if (!user) {
this.paq.push(['resetUserId']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ export class AnalyticsListenerService {

listenUser() {
this.authService.authenticate$.subscribe(() => {
const tokenDecoded = this.authService.decodeToken() || {};
if (tokenDecoded.user) {
const tokenDecoded = this.authService.decodeToken();
if (tokenDecoded?.user) {
this.authService
.getProfils()
.subscribe((profils) =>
this.analyticsService.setUser(tokenDecoded.user, profils.profils)
);
} else {
this.analyticsService.setUser();
this.analyticsService.setUser(null);
}
});
}
Expand Down

0 comments on commit 38fbe45

Please sign in to comment.