@@ -55,6 +55,57 @@ describe("requireBearerAuth middleware", () => {
5555 expect ( mockResponse . status ) . not . toHaveBeenCalled ( ) ;
5656 expect ( mockResponse . json ) . not . toHaveBeenCalled ( ) ;
5757 } ) ;
58+
59+ it ( "should reject expired tokens" , async ( ) => {
60+ const expiredAuthInfo : AuthInfo = {
61+ token : "expired-token" ,
62+ clientId : "client-123" ,
63+ scopes : [ "read" , "write" ] ,
64+ expiresAt : Math . floor ( Date . now ( ) / 1000 ) - 100 , // Token expired 100 seconds ago
65+ } ;
66+ mockVerifyAccessToken . mockResolvedValue ( expiredAuthInfo ) ;
67+
68+ mockRequest . headers = {
69+ authorization : "Bearer expired-token" ,
70+ } ;
71+
72+ const middleware = requireBearerAuth ( { provider : mockProvider } ) ;
73+ await middleware ( mockRequest as Request , mockResponse as Response , nextFunction ) ;
74+
75+ expect ( mockVerifyAccessToken ) . toHaveBeenCalledWith ( "expired-token" ) ;
76+ expect ( mockResponse . status ) . toHaveBeenCalledWith ( 401 ) ;
77+ expect ( mockResponse . set ) . toHaveBeenCalledWith (
78+ "WWW-Authenticate" ,
79+ expect . stringContaining ( 'Bearer error="invalid_token"' )
80+ ) ;
81+ expect ( mockResponse . json ) . toHaveBeenCalledWith (
82+ expect . objectContaining ( { error : "invalid_token" , error_description : "Token has expired" } )
83+ ) ;
84+ expect ( nextFunction ) . not . toHaveBeenCalled ( ) ;
85+ } ) ;
86+
87+ it ( "should accept non-expired tokens" , async ( ) => {
88+ const nonExpiredAuthInfo : AuthInfo = {
89+ token : "valid-token" ,
90+ clientId : "client-123" ,
91+ scopes : [ "read" , "write" ] ,
92+ expiresAt : Math . floor ( Date . now ( ) / 1000 ) + 3600 , // Token expires in an hour
93+ } ;
94+ mockVerifyAccessToken . mockResolvedValue ( nonExpiredAuthInfo ) ;
95+
96+ mockRequest . headers = {
97+ authorization : "Bearer valid-token" ,
98+ } ;
99+
100+ const middleware = requireBearerAuth ( { provider : mockProvider } ) ;
101+ await middleware ( mockRequest as Request , mockResponse as Response , nextFunction ) ;
102+
103+ expect ( mockVerifyAccessToken ) . toHaveBeenCalledWith ( "valid-token" ) ;
104+ expect ( mockRequest . auth ) . toEqual ( nonExpiredAuthInfo ) ;
105+ expect ( nextFunction ) . toHaveBeenCalled ( ) ;
106+ expect ( mockResponse . status ) . not . toHaveBeenCalled ( ) ;
107+ expect ( mockResponse . json ) . not . toHaveBeenCalled ( ) ;
108+ } ) ;
58109
59110 it ( "should require specific scopes when configured" , async ( ) => {
60111 const authInfo : AuthInfo = {
0 commit comments