1
1
import * as dotenv from 'dotenv' ;
2
+ import * as jwt from 'jsonwebtoken' ;
2
3
3
4
import { ExtractJwt , Strategy } from 'passport-jwt' ;
4
- import { Injectable , Logger , UnauthorizedException , NotFoundException } from '@nestjs/common' ;
5
+ import { Injectable , Logger , NotFoundException , UnauthorizedException } from '@nestjs/common' ;
5
6
7
+ import { AuthzService } from './authz.service' ;
8
+ import { CommonConstants } from '@credebl/common/common.constant' ;
9
+ import { IOrganization } from '@credebl/common/interfaces/organization.interface' ;
6
10
import { JwtPayload } from './jwt-payload.interface' ;
11
+ import { OrganizationService } from '../organization/organization.service' ;
7
12
import { PassportStrategy } from '@nestjs/passport' ;
13
+ import { ResponseMessages } from '@credebl/common/response-messages' ;
8
14
import { UserService } from '../user/user.service' ;
9
- import * as jwt from 'jsonwebtoken' ;
10
15
import { passportJwtSecret } from 'jwks-rsa' ;
11
- import { CommonConstants } from '@credebl/common/common.constant' ;
12
- import { OrganizationService } from '../organization/organization.service' ;
13
- import { IOrganization } from '@credebl/common/interfaces/organization.interface' ;
14
- import { ResponseMessages } from '@credebl/common/response-messages' ;
15
16
16
17
dotenv . config ( ) ;
17
18
@@ -21,15 +22,20 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
21
22
22
23
constructor (
23
24
private readonly usersService : UserService ,
24
- private readonly organizationService : OrganizationService
25
- ) {
26
-
25
+ private readonly organizationService : OrganizationService ,
26
+ private readonly authzService : AuthzService
27
+ ) {
27
28
super ( {
28
29
jwtFromRequest : ExtractJwt . fromAuthHeaderAsBearerToken ( ) ,
29
- secretOrKeyProvider : ( request , jwtToken , done ) => {
30
+ secretOrKeyProvider : async ( request , jwtToken , done ) => {
31
+ // Todo: We need to add this logic in seprate jwt gurd to handle the token expiration functionality.
30
32
// eslint-disable-next-line @typescript-eslint/no-explicit-any
31
33
const decodedToken : any = jwt . decode ( jwtToken ) ;
32
-
34
+ const currentTime = Math . floor ( Date . now ( ) / 1000 ) ;
35
+ if ( decodedToken ?. exp < currentTime ) {
36
+ const sessionIds = { sessions : [ decodedToken ?. sid ] } ;
37
+ await this . authzService . logout ( sessionIds ) ;
38
+ }
33
39
if ( ! decodedToken ) {
34
40
throw new UnauthorizedException ( ResponseMessages . user . error . invalidAccessToken ) ;
35
41
}
@@ -49,26 +55,25 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
49
55
} ) ;
50
56
} ,
51
57
algorithms : [ 'RS256' ]
52
- } ) ;
58
+ } ) ;
53
59
}
54
60
55
61
async validate ( payload : JwtPayload ) : Promise < object > {
56
-
57
62
let userDetails = null ;
58
63
let userInfo ;
59
64
60
65
if ( payload ?. email ) {
61
66
userInfo = await this . usersService . getUserByUserIdInKeycloak ( payload ?. email ) ;
62
67
}
63
-
68
+
64
69
if ( payload . hasOwnProperty ( 'client_id' ) ) {
65
70
const orgDetails : IOrganization = await this . organizationService . findOrganizationOwner ( payload [ 'client_id' ] ) ;
66
-
71
+
67
72
this . logger . log ( 'Organization details fetched' ) ;
68
73
if ( ! orgDetails ) {
69
74
throw new NotFoundException ( ResponseMessages . organisation . error . orgNotFound ) ;
70
75
}
71
-
76
+
72
77
// eslint-disable-next-line prefer-destructuring
73
78
const userOrgDetails = 0 < orgDetails . userOrgRoles . length && orgDetails . userOrgRoles [ 0 ] ;
74
79
@@ -83,11 +88,10 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
83
88
} ) ;
84
89
85
90
this . logger . log ( 'User details set' ) ;
86
-
87
91
} else {
88
92
userDetails = await this . usersService . findUserinKeycloak ( payload . sub ) ;
89
93
}
90
-
94
+
91
95
if ( ! userDetails ) {
92
96
throw new NotFoundException ( ResponseMessages . user . error . notFound ) ;
93
97
}
0 commit comments