From d5230f541afdc8608ec2ca6fa830ec34fca7cc14 Mon Sep 17 00:00:00 2001 From: Roshan Piyush Date: Mon, 20 May 2024 20:31:02 +0530 Subject: [PATCH 1/6] Release fixes to main (#251) * Add mailhog as dependency * Fix auth validation (#250) --- deploy/docker/docker-compose.yml | 2 ++ .../com/crapi/config/JwtAuthTokenFilter.java | 10 ++++++++-- .../java/com/crapi/config/JwtProvider.java | 19 ++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/docker-compose.yml index 0bf8c43f..f0446d33 100755 --- a/deploy/docker/docker-compose.yml +++ b/deploy/docker/docker-compose.yml @@ -52,6 +52,8 @@ services: condition: service_healthy mongodb: condition: service_healthy + mailhog: + condition: service_healthy healthcheck: test: /app/health.sh interval: 15s diff --git a/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java b/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java index 38cf0ba5..5df66e38 100644 --- a/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java +++ b/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java @@ -76,6 +76,9 @@ protected void doFilterInternal( response.sendError( HttpServletResponse.SC_UNAUTHORIZED, UserMessage.ACCOUNT_LOCKED_MESSAGE); } + } else { + tokenLogger.error(UserMessage.INVALID_CREDENTIALS); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UserMessage.INVALID_CREDENTIALS); } } catch (Exception e) { tokenLogger.error("Can NOT set user authentication -> Message:%d", e); @@ -122,10 +125,13 @@ public String getUserFromToken(HttpServletRequest request) throws ParseException String username = null; if (token != null) { if (apiType == ApiType.APIKEY) { + logger.debug("Token is api token"); username = tokenProvider.getUserNameFromApiToken(token); } else { - tokenProvider.validateJwtToken(token); - username = tokenProvider.getUserNameFromJwtToken(token); + logger.debug("Token is jwt token"); + if (tokenProvider.validateJwtToken(token)) { + username = tokenProvider.getUserNameFromJwtToken(token); + } } // checking username from token if (username != null) return username; diff --git a/services/identity/src/main/java/com/crapi/config/JwtProvider.java b/services/identity/src/main/java/com/crapi/config/JwtProvider.java index 268a18db..965ca604 100644 --- a/services/identity/src/main/java/com/crapi/config/JwtProvider.java +++ b/services/identity/src/main/java/com/crapi/config/JwtProvider.java @@ -175,25 +175,26 @@ public boolean validateJwtToken(String authToken) { SignedJWT signedJWT = SignedJWT.parse(authToken); JWSHeader header = signedJWT.getHeader(); Algorithm alg = header.getAlgorithm(); - + boolean valid = false; // JWT Algorithm confusion vulnerability - logger.info("Algorithm: " + alg.getName()); + logger.debug("Algorithm: " + alg.getName()); + JWSVerifier verifier; if (Objects.equals(alg.getName(), "HS256")) { String secret = getJwtSecret(header); - logger.info("JWT Secret: " + secret); - JWSVerifier verifier = new MACVerifier(secret.getBytes(StandardCharsets.UTF_8)); - return signedJWT.verify(verifier); + logger.debug("JWT Secret: " + secret); + verifier = new MACVerifier(secret.getBytes(StandardCharsets.UTF_8)); } else { RSAKey verificationKey = getKeyFromJkuHeader(header); - JWSVerifier verifier; if (verificationKey == null) { + logger.debug("Key from JWKS: " + this.publicRSAKey.toJSONString()); verifier = new RSASSAVerifier(this.publicRSAKey); } else { - logger.info("Key from JKU: " + verificationKey.toJSONString()); + logger.debug("Key from JKU: " + verificationKey.toJSONString()); verifier = new RSASSAVerifier(verificationKey); } - - return signedJWT.verify(verifier); + valid = signedJWT.verify(verifier); + logger.info("JWT valid?: " + valid); + return valid; } } catch (ParseException e) { From 5e6807023f8fdc6260127557be6de1379d6adb91 Mon Sep 17 00:00:00 2001 From: Roshan Piyush Date: Mon, 20 May 2024 21:34:46 +0530 Subject: [PATCH 2/6] Revert "Release fixes to main (#251)" (#252) This reverts commit d5230f541afdc8608ec2ca6fa830ec34fca7cc14. --- deploy/docker/docker-compose.yml | 2 -- .../com/crapi/config/JwtAuthTokenFilter.java | 10 ++-------- .../java/com/crapi/config/JwtProvider.java | 19 +++++++++---------- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/docker-compose.yml index f0446d33..0bf8c43f 100755 --- a/deploy/docker/docker-compose.yml +++ b/deploy/docker/docker-compose.yml @@ -52,8 +52,6 @@ services: condition: service_healthy mongodb: condition: service_healthy - mailhog: - condition: service_healthy healthcheck: test: /app/health.sh interval: 15s diff --git a/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java b/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java index 5df66e38..38cf0ba5 100644 --- a/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java +++ b/services/identity/src/main/java/com/crapi/config/JwtAuthTokenFilter.java @@ -76,9 +76,6 @@ protected void doFilterInternal( response.sendError( HttpServletResponse.SC_UNAUTHORIZED, UserMessage.ACCOUNT_LOCKED_MESSAGE); } - } else { - tokenLogger.error(UserMessage.INVALID_CREDENTIALS); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UserMessage.INVALID_CREDENTIALS); } } catch (Exception e) { tokenLogger.error("Can NOT set user authentication -> Message:%d", e); @@ -125,13 +122,10 @@ public String getUserFromToken(HttpServletRequest request) throws ParseException String username = null; if (token != null) { if (apiType == ApiType.APIKEY) { - logger.debug("Token is api token"); username = tokenProvider.getUserNameFromApiToken(token); } else { - logger.debug("Token is jwt token"); - if (tokenProvider.validateJwtToken(token)) { - username = tokenProvider.getUserNameFromJwtToken(token); - } + tokenProvider.validateJwtToken(token); + username = tokenProvider.getUserNameFromJwtToken(token); } // checking username from token if (username != null) return username; diff --git a/services/identity/src/main/java/com/crapi/config/JwtProvider.java b/services/identity/src/main/java/com/crapi/config/JwtProvider.java index 965ca604..268a18db 100644 --- a/services/identity/src/main/java/com/crapi/config/JwtProvider.java +++ b/services/identity/src/main/java/com/crapi/config/JwtProvider.java @@ -175,26 +175,25 @@ public boolean validateJwtToken(String authToken) { SignedJWT signedJWT = SignedJWT.parse(authToken); JWSHeader header = signedJWT.getHeader(); Algorithm alg = header.getAlgorithm(); - boolean valid = false; + // JWT Algorithm confusion vulnerability - logger.debug("Algorithm: " + alg.getName()); - JWSVerifier verifier; + logger.info("Algorithm: " + alg.getName()); if (Objects.equals(alg.getName(), "HS256")) { String secret = getJwtSecret(header); - logger.debug("JWT Secret: " + secret); - verifier = new MACVerifier(secret.getBytes(StandardCharsets.UTF_8)); + logger.info("JWT Secret: " + secret); + JWSVerifier verifier = new MACVerifier(secret.getBytes(StandardCharsets.UTF_8)); + return signedJWT.verify(verifier); } else { RSAKey verificationKey = getKeyFromJkuHeader(header); + JWSVerifier verifier; if (verificationKey == null) { - logger.debug("Key from JWKS: " + this.publicRSAKey.toJSONString()); verifier = new RSASSAVerifier(this.publicRSAKey); } else { - logger.debug("Key from JKU: " + verificationKey.toJSONString()); + logger.info("Key from JKU: " + verificationKey.toJSONString()); verifier = new RSASSAVerifier(verificationKey); } - valid = signedJWT.verify(verifier); - logger.info("JWT valid?: " + valid); - return valid; + + return signedJWT.verify(verifier); } } catch (ParseException e) { From e9913450ca82083454dfa432bc7df6e73c0922a3 Mon Sep 17 00:00:00 2001 From: Mathew Jose Mammoottil Date: Mon, 26 Aug 2024 19:25:12 +0530 Subject: [PATCH 3/6] added not found page --- services/web/src/components/layout/layout.js | 36 ++++++++------------ 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/services/web/src/components/layout/layout.js b/services/web/src/components/layout/layout.js index f1c07786..4381c688 100644 --- a/services/web/src/components/layout/layout.js +++ b/services/web/src/components/layout/layout.js @@ -41,6 +41,7 @@ import ForumContainer from "../../containers/forum/forum"; import UnlockContainer from "../../containers/unlock/unlock"; import NewPostContainer from "../../containers/newPost/newPost"; import PostContainer from "../../containers/post/post"; +import NotFoundConponent from "../../components/notFound/notFound"; import { logOutUserAction } from "../../actions/userActions"; import { isAccessTokenValid } from "../../utils"; @@ -75,7 +76,10 @@ const AfterLogin = ({ }); } else { if (!componentRole || (componentRole && componentRole === userRole)) - return ; + return <> + + + if (userRole === roleTypes.ROLE_MECHANIC) return ( { {...rest} render={(props) => !hasUserLoggedIn ? ( - + <> + + + ) : ( - + - { - return ( - - ); - }} - /> + From c8b1370069bb84846ea14c5c1586af713abaae1b Mon Sep 17 00:00:00 2001 From: Mathew Jose Mammoottil Date: Mon, 26 Aug 2024 19:25:40 +0530 Subject: [PATCH 4/6] added not found page --- .../web/src/components/notFound/notFound.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 services/web/src/components/notFound/notFound.js diff --git a/services/web/src/components/notFound/notFound.js b/services/web/src/components/notFound/notFound.js new file mode 100644 index 00000000..bebb3384 --- /dev/null +++ b/services/web/src/components/notFound/notFound.js @@ -0,0 +1,27 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the “License”); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an “AS IS” BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; + +const NotFound = () => { + return ( +
+

404 - Page Not Found

+

The page you are looking for does not exist.

+
+ ); +}; + +export default NotFound; \ No newline at end of file From b28240fbbba001a059a1a1cb4fcc10ecc43ff1ea Mon Sep 17 00:00:00 2001 From: Mathew Jose Mammoottil Date: Tue, 27 Aug 2024 11:40:59 +0530 Subject: [PATCH 5/6] revert previous changes --- services/web/src/components/layout/layout.js | 38 +++++++++++-------- .../web/src/components/notFound/notFound.js | 27 ------------- 2 files changed, 22 insertions(+), 43 deletions(-) delete mode 100644 services/web/src/components/notFound/notFound.js diff --git a/services/web/src/components/layout/layout.js b/services/web/src/components/layout/layout.js index 4381c688..df17293f 100644 --- a/services/web/src/components/layout/layout.js +++ b/services/web/src/components/layout/layout.js @@ -41,7 +41,6 @@ import ForumContainer from "../../containers/forum/forum"; import UnlockContainer from "../../containers/unlock/unlock"; import NewPostContainer from "../../containers/newPost/newPost"; import PostContainer from "../../containers/post/post"; -import NotFoundConponent from "../../components/notFound/notFound"; import { logOutUserAction } from "../../actions/userActions"; import { isAccessTokenValid } from "../../utils"; @@ -76,10 +75,7 @@ const AfterLogin = ({ }); } else { if (!componentRole || (componentRole && componentRole === userRole)) - return <> - - - + return ; if (userRole === roleTypes.ROLE_MECHANIC) return ( { {...rest} render={(props) => !hasUserLoggedIn ? ( - <> - - - + ) : ( + - - + { + return ( + + ); + }} + /> @@ -336,4 +342,4 @@ StyledComp.propTypes = { fetchingData: PropTypes.bool, }; -export default StyledComp; +export default StyledComp; \ No newline at end of file diff --git a/services/web/src/components/notFound/notFound.js b/services/web/src/components/notFound/notFound.js deleted file mode 100644 index bebb3384..00000000 --- a/services/web/src/components/notFound/notFound.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Licensed under the Apache License, Version 2.0 (the “License”); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an “AS IS” BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; - -const NotFound = () => { - return ( -
-

404 - Page Not Found

-

The page you are looking for does not exist.

-
- ); -}; - -export default NotFound; \ No newline at end of file From ec0a136266c8d8fda28e685464cf5e35006bc8db Mon Sep 17 00:00:00 2001 From: Mathew Jose Mammoottil Date: Tue, 27 Aug 2024 11:41:27 +0530 Subject: [PATCH 6/6] added nginx conf --- services/web/nginx.conf.template | 12 +++++++++++- services/web/nginx.ssl.conf.template | 11 ++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/services/web/nginx.conf.template b/services/web/nginx.conf.template index 6b468808..d0e7a648 100644 --- a/services/web/nginx.conf.template +++ b/services/web/nginx.conf.template @@ -173,7 +173,8 @@ server { sub_filter_once off; } - location / { + + location ~* ^/(login|unlock|signup|forgot-password|dashboard|mechanic-dashboard|reset-password|my-profile|change-email|verify-vehicle|contact-mechanic|shop|past-orders|orders|forum|new-post|post)$ { try_files $uri /index.html =404; add_header Last-Modified $date_gmt; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; @@ -181,4 +182,13 @@ server { expires off; etag off; } + + location / { + try_files $uri $uri/ =404; + add_header Last-Modified $date_gmt; + add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + if_modified_since off; + expires off; + etag off; + } } diff --git a/services/web/nginx.ssl.conf.template b/services/web/nginx.ssl.conf.template index d4e1defc..ce56a1b4 100644 --- a/services/web/nginx.ssl.conf.template +++ b/services/web/nginx.ssl.conf.template @@ -182,7 +182,7 @@ server { sub_filter_once off; } - location / { + location ~* ^/(login|unlock|signup|forgot-password|dashboard|mechanic-dashboard|reset-password|my-profile|change-email|verify-vehicle|contact-mechanic|shop|past-orders|orders|forum|new-post|post)$ { try_files $uri /index.html =404; add_header Last-Modified $date_gmt; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; @@ -190,4 +190,13 @@ server { expires off; etag off; } + + location / { + try_files $uri $uri/ =404; + add_header Last-Modified $date_gmt; + add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + if_modified_since off; + expires off; + etag off; + } }