1
+ import app from '../../src/app' ;
2
+ import supertest , { SuperTest } from 'supertest' ;
3
+ import ApiKeyRepo from '../../src/database/repository/ApiKeyRepo' ;
4
+ import UserRepo from '../../src/database/repository/UserRepo' ;
5
+ import { IUser } from '../../src/database/model/User' ;
6
+ import { Types } from 'mongoose' ;
7
+ import { mockFindApiKey , API_KEY } from './apikey.test' ;
8
+ import JWT , { ValidationParams , JwtPayload } from '../../src/core/JWT' ;
9
+ import { BadTokenError } from '../../src/core/ApiError' ;
10
+ import { IKeystore } from '../../src/database/model/Keystore' ;
11
+ import KeystoreRepo from '../../src/database/repository/KeystoreRepo' ;
12
+
13
+ export const ACCESS_TOKEN = 'xyz' ;
14
+
15
+ export const USER_ID = new Types . ObjectId ( '5e7b95923085872d3c378f35' ) ; // random id with object id format
16
+
17
+ const mockUserFindById = jest . fn ( async ( id : Types . ObjectId ) => {
18
+ if ( USER_ID . equals ( id ) ) return < IUser > { _id : new Types . ObjectId ( id ) } ;
19
+ else return null ;
20
+ } ) ;
21
+
22
+ const mockJwtValidate = jest . fn (
23
+ async ( token : string , validations : ValidationParams ) : Promise < JwtPayload > => {
24
+ if ( token == ACCESS_TOKEN ) return < JwtPayload > { prm : 'abcdef' } ;
25
+ throw new BadTokenError ( ) ;
26
+ } ) ;
27
+
28
+ const mockKeystoreFindForKey = jest . fn (
29
+ async ( client : IUser , key : string ) : Promise < IKeystore > => ( < IKeystore > { client : client , primaryKey : key } ) ) ;
30
+
31
+ jest . mock ( '../../src/auth/authUtils' , ( ) => ( {
32
+ get validateTokenData ( ) {
33
+ return jest . fn ( async ( payload : JwtPayload , userId : Types . ObjectId ) : Promise < JwtPayload > => payload ) ;
34
+ }
35
+ } ) ) ;
36
+
37
+ describe ( 'authentication validation' , ( ) => {
38
+
39
+ const endpoint = '/v1/profile/my/test' ;
40
+ const request = supertest ( app ) ;
41
+
42
+ UserRepo . findById = mockUserFindById ;
43
+ ApiKeyRepo . findByKey = mockFindApiKey ;
44
+ JWT . validate = mockJwtValidate ;
45
+ KeystoreRepo . findforKey = mockKeystoreFindForKey ;
46
+
47
+ beforeEach ( ( ) => {
48
+ mockUserFindById . mockClear ( ) ;
49
+ mockJwtValidate . mockClear ( ) ;
50
+ mockKeystoreFindForKey . mockClear ( ) ;
51
+ } ) ;
52
+
53
+ it ( 'Should response with 400 if x-access-token header is not passed' , async ( ) => {
54
+ const response = await addHeaders ( request . get ( endpoint ) )
55
+ . set ( 'x-user-id' , USER_ID . toHexString ( ) ) ;
56
+ expect ( response . status ) . toBe ( 400 ) ;
57
+ expect ( response . body . message ) . toMatch ( / x - a c c e s s - t o k e n / ) ;
58
+ expect ( mockUserFindById ) . toBeCalledTimes ( 0 ) ;
59
+ } ) ;
60
+
61
+ it ( 'Should response with 400 if x-user-id header is not passed' , async ( ) => {
62
+ const response = await addHeaders ( request . get ( endpoint ) )
63
+ . set ( 'x-access-token' , ACCESS_TOKEN ) ;
64
+ expect ( response . status ) . toBe ( 400 ) ;
65
+ expect ( response . body . message ) . toMatch ( / x - u s e r - i d / ) ;
66
+ expect ( mockUserFindById ) . toBeCalledTimes ( 0 ) ;
67
+ } ) ;
68
+
69
+ it ( 'Should response with 400 if x-user-id header is not mongoose id' , async ( ) => {
70
+ const response = await addHeaders ( request . get ( endpoint ) )
71
+ . set ( 'x-access-token' , ACCESS_TOKEN )
72
+ . set ( 'x-user-id' , '123' ) ;
73
+ expect ( response . status ) . toBe ( 400 ) ;
74
+ expect ( response . body . message ) . toMatch ( / x - u s e r - i d / ) ;
75
+ expect ( mockUserFindById ) . toBeCalledTimes ( 0 ) ;
76
+ } ) ;
77
+
78
+ it ( 'Should response with 401 if wrong x-user-id header is provided' , async ( ) => {
79
+ const response = await addHeaders ( request . get ( endpoint ) )
80
+ . set ( 'x-access-token' , ACCESS_TOKEN )
81
+ . set ( 'x-user-id' , '5e7b8c22d347fc2407c564a6' ) ; // some random mongoose id
82
+ expect ( response . status ) . toBe ( 401 ) ;
83
+ expect ( response . body . message ) . toMatch ( / n o t r e g i s t e r e d / ) ;
84
+ expect ( mockUserFindById ) . toBeCalledTimes ( 1 ) ;
85
+ } ) ;
86
+
87
+ it ( 'Should response with 401 if wrong x-access-token header is provided' , async ( ) => {
88
+ const response = await addHeaders ( request . get ( endpoint ) )
89
+ . set ( 'x-access-token' , '123' )
90
+ . set ( 'x-user-id' , USER_ID ) ;
91
+ expect ( response . status ) . toBe ( 401 ) ;
92
+ expect ( response . body . message ) . toMatch ( / t o k e n / i) ;
93
+ expect ( mockUserFindById ) . toBeCalledTimes ( 1 ) ;
94
+ } ) ;
95
+
96
+ it ( 'Should response with 404 if correct x-access-token and x-user-id header are provided' , async ( ) => {
97
+ const response = await addHeaders ( request . get ( endpoint ) )
98
+ . set ( 'x-access-token' , ACCESS_TOKEN )
99
+ . set ( 'x-user-id' , USER_ID . toHexString ( ) ) ;
100
+ expect ( response . body . message ) . not . toMatch ( / n o t r e g i s t e r e d / ) ;
101
+ expect ( response . body . message ) . not . toMatch ( / t o k e n / i) ;
102
+ expect ( response . status ) . toBe ( 404 ) ;
103
+ expect ( mockUserFindById ) . toBeCalledTimes ( 1 ) ;
104
+ } ) ;
105
+ } ) ;
106
+
107
+ export const addHeaders = ( request : any ) => request
108
+ . set ( 'Content-Type' , 'application/json' )
109
+ . set ( 'x-api-key' , API_KEY ) ;
110
+
111
+ export const addAuthHeaders = ( request : any ) => request
112
+ . set ( 'Content-Type' , 'application/json' )
113
+ . set ( 'x-api-key' , API_KEY )
114
+ . set ( 'x-access-token' , ACCESS_TOKEN )
115
+ . set ( 'x-user-id' , USER_ID ) ;
0 commit comments