generator-jhipster 7.3.1 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/cli/jhipster-command.js +2 -2
  2. package/cli/program.js +31 -29
  3. package/generators/app/index.js +30 -25
  4. package/generators/aws/index.js +8 -8
  5. package/generators/aws/lib/eb.js +1 -1
  6. package/generators/azure-app-service/index.js +13 -9
  7. package/generators/azure-spring-cloud/index.js +13 -9
  8. package/generators/bootstrap/index.js +49 -59
  9. package/generators/ci-cd/index.js +10 -8
  10. package/generators/client/files-common.js +6 -2
  11. package/generators/client/files-react.js +10 -1
  12. package/generators/client/files-vue.js +40 -1
  13. package/generators/client/index.js +42 -31
  14. package/generators/client/needle-api/needle-client-vue.js +1 -1
  15. package/generators/client/templates/angular/.eslintrc.json.ejs +1 -0
  16. package/generators/client/templates/angular/package.json +14 -14
  17. package/generators/client/templates/angular/src/main/webapp/app/admin/metrics/blocks/jvm-memory/jvm-memory.component.html.ejs +2 -2
  18. package/generators/client/templates/common/package.json +3 -3
  19. package/generators/client/templates/common/webpack/webpack.microfrontend.js.jhi.ejs +56 -0
  20. package/generators/client/templates/react/.eslintrc.json.ejs +1 -0
  21. package/generators/client/templates/react/package.json +44 -43
  22. package/generators/client/templates/react/package.json.ejs +3 -0
  23. package/generators/client/templates/react/src/main/webapp/app/app.scss.ejs +0 -3
  24. package/generators/client/templates/react/src/main/webapp/app/modules/administration/configuration/configuration.tsx.ejs +2 -2
  25. package/generators/client/templates/react/src/main/webapp/app/modules/administration/gateway/gateway.tsx.ejs +2 -2
  26. package/generators/client/templates/react/src/main/webapp/app/modules/administration/metrics/metrics.tsx.ejs +6 -6
  27. package/generators/client/templates/react/src/main/webapp/app/modules/administration/user-management/user-management.tsx.ejs +8 -8
  28. package/generators/client/templates/react/src/main/webapp/app/modules/home/home.tsx.ejs +1 -1
  29. package/generators/client/templates/react/src/main/webapp/app/shared/layout/header/header.tsx.ejs +1 -1
  30. package/generators/client/templates/react/src/main/webapp/app/shared/layout/menus/account.tsx.ejs +3 -3
  31. package/generators/client/templates/react/src/main/webapp/app/shared/layout/menus/admin.tsx.ejs +7 -7
  32. package/generators/client/templates/react/src/main/webapp/app/shared/layout/menus/menu-components.tsx.ejs +1 -1
  33. package/generators/client/templates/react/webpack/webpack.dev.js.ejs +17 -1
  34. package/generators/client/templates/react/webpack/webpack.prod.js.ejs +13 -1
  35. package/generators/client/templates/vue/.eslintrc.js.ejs +8 -5
  36. package/generators/client/templates/vue/package.json +31 -38
  37. package/generators/client/templates/vue/package.json.ejs +8 -10
  38. package/generators/client/templates/vue/src/main/webapp/app/account/account.service.ts.ejs +1 -2
  39. package/generators/client/templates/vue/src/main/webapp/app/account/settings/settings.vue.ejs +7 -1
  40. package/generators/client/templates/vue/src/main/webapp/app/admin/configuration/configuration.vue.ejs +1 -1
  41. package/generators/client/templates/vue/src/main/webapp/app/admin/metrics/metrics.component.ts.ejs +1 -1
  42. package/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.ts.ejs +12 -1
  43. package/generators/client/templates/vue/src/main/webapp/app/core/jhi-navbar/jhi-navbar.vue.ejs +6 -0
  44. package/generators/client/templates/vue/src/main/webapp/app/declarations.d.ts.ejs +41 -0
  45. package/generators/client/templates/vue/src/main/webapp/app/entities/entities-menu.component.ts.ejs +34 -0
  46. package/generators/client/templates/vue/src/main/webapp/app/entities/entities-menu.vue.ejs +13 -0
  47. package/generators/client/templates/vue/src/main/webapp/app/entities/entities.component.ts.ejs +12 -0
  48. package/generators/client/templates/vue/src/main/webapp/app/entities/entities.vue.ejs +5 -0
  49. package/generators/client/templates/vue/src/main/webapp/app/index.ts.ejs +19 -0
  50. package/generators/client/templates/vue/src/main/webapp/app/locale/translation.service.ts.ejs +25 -8
  51. package/generators/client/templates/vue/src/main/webapp/app/main.ts.ejs +9 -4
  52. package/generators/client/templates/vue/src/main/webapp/app/router/entities.ts.ejs +44 -1
  53. package/generators/client/templates/vue/src/main/webapp/app/router/index.ts.ejs +11 -0
  54. package/generators/client/templates/vue/src/main/webapp/app/shims-vue.d.ts.ejs +0 -10
  55. package/generators/client/templates/vue/src/test/javascript/jest.conf.js.ejs +19 -8
  56. package/generators/client/templates/vue/src/test/javascript/spec/app/entities/entities-menu.spec.ts.ejs +52 -0
  57. package/generators/client/templates/vue/src/test/javascript/spec/app/microfrontends/entities-menu.component.ts.ejs +4 -0
  58. package/generators/client/templates/vue/src/test/javascript/spec/app/microfrontends/entities-menu.vue.ejs +7 -0
  59. package/generators/client/templates/vue/src/test/javascript/spec/app/microfrontends/entities-router.ts.ejs +1 -0
  60. package/generators/client/templates/vue/tsconfig.json.ejs +5 -9
  61. package/generators/client/templates/vue/tsconfig.spec.json.ejs +37 -0
  62. package/generators/client/templates/vue/webpack/config.js.ejs +2 -0
  63. package/generators/client/templates/vue/webpack/vue.utils.js.ejs +13 -12
  64. package/generators/client/templates/vue/webpack/webpack.common.js.ejs +64 -50
  65. package/generators/client/templates/vue/webpack/webpack.dev.js.ejs +17 -68
  66. package/generators/client/templates/vue/webpack/webpack.microfrontend.js.jhi.vue.ejs +77 -0
  67. package/generators/client/templates/vue/webpack/webpack.prod.js.ejs +1 -30
  68. package/generators/cloudfoundry/index.js +9 -9
  69. package/generators/common/index.js +12 -10
  70. package/generators/common/templates/package.json +4 -4
  71. package/generators/cypress/index.js +12 -9
  72. package/generators/cypress/templates/cypress.json.ejs +3 -0
  73. package/generators/cypress/templates/src/test/javascript/cypress/plugins/index.ts.ejs +3 -3
  74. package/generators/cypress/templates/src/test/javascript/cypress/support/entity.ts.ejs +2 -2
  75. package/generators/database-changelog/index.js +33 -22
  76. package/generators/database-changelog-liquibase/index.js +12 -8
  77. package/generators/docker-compose/index.js +11 -12
  78. package/generators/entities/index.js +35 -26
  79. package/generators/entities-client/index.js +10 -7
  80. package/generators/entity/index.js +25 -28
  81. package/generators/entity-client/files.js +6 -11
  82. package/generators/entity-client/index.js +9 -7
  83. package/generators/entity-client/templates/common/src/test/javascript/cypress/integration/entity/entity.spec.ts.ejs +4 -4
  84. package/generators/entity-client/templates/react/src/main/webapp/app/entities/entity-update.tsx.ejs +1 -1
  85. package/generators/entity-client/templates/react/src/main/webapp/app/entities/entity.tsx.ejs +7 -7
  86. package/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity.component.ts.ejs +2 -1
  87. package/generators/entity-client/templates/vue/src/main/webapp/app/entities/entity.service.ts.ejs +2 -6
  88. package/generators/entity-i18n/index.js +7 -4
  89. package/generators/entity-server/index.js +11 -8
  90. package/generators/entity-server/templates/src/main/java/package/web/rest/EntityResource.java.ejs +39 -41
  91. package/generators/gae/index.js +10 -10
  92. package/generators/generator-base-blueprint.js +7 -44
  93. package/generators/generator-base.js +7 -0
  94. package/generators/generator-constants.js +20 -18
  95. package/generators/generator-transforms.js +27 -23
  96. package/generators/heroku/index.js +12 -10
  97. package/generators/init/constants.cjs +1 -1
  98. package/generators/kubernetes/files.js +3 -0
  99. package/generators/kubernetes/index.js +10 -10
  100. package/generators/kubernetes/templates/db/couchbase.yml.ejs +1 -1
  101. package/generators/kubernetes/templates/deployment.yml.ejs +8 -3
  102. package/generators/kubernetes/templates/istio/destination-rule.yml.ejs +1 -1
  103. package/generators/kubernetes/templates/istio/gateway/grafana-gateway.yml.ejs +5 -2
  104. package/generators/kubernetes/templates/istio/gateway/jhipster-grafana-gateway.yml.ejs +5 -2
  105. package/generators/kubernetes/templates/istio/gateway/kiali-gateway.yml.ejs +10 -8
  106. package/generators/kubernetes/templates/istio/gateway/zipkin-gateway.yml.ejs +5 -2
  107. package/generators/kubernetes/templates/istio/gateway.yml.ejs +7 -5
  108. package/generators/kubernetes/templates/secret/couchbase-secret.yml.ejs +9 -0
  109. package/generators/kubernetes-base.js +1 -0
  110. package/generators/kubernetes-helm/files.js +3 -8
  111. package/generators/kubernetes-helm/index.js +10 -10
  112. package/generators/kubernetes-helm/templates/README-KUBERNETES-HELM.md.ejs +0 -1
  113. package/generators/kubernetes-helm/templates/app/Chart.yml.ejs +5 -0
  114. package/generators/kubernetes-helm/templates/app/helpers.tpl.ejs +0 -11
  115. package/generators/kubernetes-helm/templates/app/requirements.yml.ejs +5 -0
  116. package/generators/kubernetes-helm/templates/app/values.yml.ejs +68 -5
  117. package/generators/kubernetes-helm/templates/csvc/Chart.yml.ejs +1 -1
  118. package/generators/kubernetes-helm/templates/csvc/requirements.yml.ejs +1 -1
  119. package/generators/kubernetes-knative/index.js +10 -10
  120. package/generators/kubernetes-knative/templates/istio/gateway.yml.ejs +6 -4
  121. package/generators/kubernetes-knative/templates/service.yml.ejs +1 -1
  122. package/generators/languages/index.js +13 -13
  123. package/generators/openapi-client/index.js +13 -10
  124. package/generators/openshift/index.js +10 -11
  125. package/generators/openshift/templates/deployment.yml.ejs +1 -1
  126. package/generators/page/index.js +12 -10
  127. package/generators/server/__snapshots__/generator.spec.mjs.snap +12 -0
  128. package/generators/server/files.js +12 -0
  129. package/generators/server/index.js +32 -18
  130. package/generators/server/templates/gradle.properties.ejs +10 -10
  131. package/generators/server/templates/pom.xml.ejs +6 -6
  132. package/generators/server/templates/src/main/docker/app.yml.ejs +1 -1
  133. package/generators/server/templates/src/main/java/package/config/SecurityConfiguration_reactive.java.ejs +2 -2
  134. package/generators/server/templates/src/main/java/package/config/WebConfigurer.java.ejs +0 -1
  135. package/generators/server/templates/src/main/java/package/management/SecurityMetersService.java.ejs +68 -0
  136. package/generators/server/templates/src/main/java/package/security/jwt/TokenProvider.java.ejs +29 -4
  137. package/generators/server/templates/src/main/java/package/security/oauth2/CustomClaimConverter.java.ejs +21 -9
  138. package/generators/server/templates/src/main/java/package/service/UserService.java.ejs +13 -5
  139. package/generators/server/templates/src/main/resources/static/microservices_index.html.ejs +1 -1
  140. package/generators/server/templates/src/test/java/package/management/SecurityMetersServiceTests.java.ejs +113 -0
  141. package/generators/server/templates/src/test/java/package/security/jwt/JWTFilterTest.java.ejs +6 -1
  142. package/generators/server/templates/src/test/java/package/security/jwt/TokenProviderSecurityMetersTests.java.ejs +198 -0
  143. package/generators/server/templates/src/test/java/package/security/jwt/TokenProviderTest.java.ejs +13 -3
  144. package/generators/server/templates/src/test/java/package/security/oauth2/AuthorizationHeaderUtilTest.java.ejs +16 -2
  145. package/generators/server/templates/src/test/java/package/security/oauth2/CustomClaimConverterIT.java.ejs +63 -0
  146. package/generators/spring-controller/index.js +9 -7
  147. package/generators/spring-service/index.js +10 -7
  148. package/generators/upgrade/index.js +3 -4
  149. package/generators/utils.js +2 -2
  150. package/generators/workspaces/index.js +16 -7
  151. package/jdl/jhipster/default-application-options.js +9 -7
  152. package/package.json +15 -15
  153. package/utils/entity.js +14 -0
  154. package/utils/multi-step-transform/index.js +8 -8
@@ -78,7 +78,7 @@
78
78
 
79
79
  <ul>
80
80
  <%_ if (microfrontend) { %>
81
- <li>Microfrontends packages don't provide a stand-alone front-end. Packaged microfrontend should be accessed through a JHipster gateway.</li>
81
+ <li>JHipster's microfrontends implementation doesn't provide a stand-alone UI. Packaged microfrontends should be accessed through a JHipster gateway.</li>
82
82
  <li>Stand-alone development server can be started by `npm start`.</li>
83
83
  <%_ } else { %>
84
84
  <li>It does not have a front-end. The front-end should be generated on a JHipster gateway.</li>
@@ -0,0 +1,113 @@
1
+ <%#
2
+ Copyright 2013-2021 the original author or authors from the JHipster project.
3
+
4
+ This file is part of the JHipster project, see https://www.jhipster.tech/
5
+ for more information.
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ https://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+ -%>
19
+ package <%= packageName %>.management;
20
+
21
+ import io.micrometer.core.instrument.Counter;
22
+ import io.micrometer.core.instrument.MeterRegistry;
23
+ import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
24
+ import org.junit.jupiter.api.BeforeEach;
25
+ import org.junit.jupiter.api.Test;
26
+
27
+ import java.util.Collection;
28
+
29
+ import static org.assertj.core.api.Assertions.assertThat;
30
+
31
+ class SecurityMetersServiceTests {
32
+ private static final String INVALID_TOKENS_METER_EXPECTED_NAME = "security.authentication.invalid-tokens";
33
+
34
+ private MeterRegistry meterRegistry;
35
+
36
+ private SecurityMetersService securityMetersService;
37
+
38
+ @BeforeEach
39
+ public void setup() {
40
+ meterRegistry = new SimpleMeterRegistry();
41
+
42
+ securityMetersService = new SecurityMetersService(meterRegistry);
43
+ }
44
+
45
+ @Test
46
+ public void testInvalidTokensCountersByCauseAreCreated() {
47
+ meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME).counter();
48
+
49
+ meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
50
+ .tag("cause", "expired")
51
+ .counter();
52
+
53
+ meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
54
+ .tag("cause", "unsupported")
55
+ .counter();
56
+
57
+ meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
58
+ .tag("cause", "invalid-signature")
59
+ .counter();
60
+
61
+ meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
62
+ .tag("cause", "malformed")
63
+ .counter();
64
+
65
+ Collection<Counter> counters = meterRegistry.find(INVALID_TOKENS_METER_EXPECTED_NAME).counters();
66
+
67
+ assertThat(counters.size()).isEqualTo(4);
68
+ }
69
+
70
+ @Test
71
+ public void testCountMethodsShouldBeBoundToCorrectCounters() {
72
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
73
+ .tag("cause", "expired")
74
+ .counter().count()).isEqualTo(0);
75
+
76
+ securityMetersService.trackTokenExpired();
77
+
78
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
79
+ .tag("cause", "expired")
80
+ .counter().count()).isEqualTo(1);
81
+
82
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
83
+ .tag("cause", "unsupported")
84
+ .counter().count()).isEqualTo(0);
85
+
86
+ securityMetersService.trackTokenUnsupported();
87
+
88
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
89
+ .tag("cause", "unsupported")
90
+ .counter().count()).isEqualTo(1);
91
+
92
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
93
+ .tag("cause", "invalid-signature")
94
+ .counter().count()).isEqualTo(0);
95
+
96
+ securityMetersService.trackTokenInvalidSignature();
97
+
98
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
99
+ .tag("cause", "invalid-signature")
100
+ .counter().count()).isEqualTo(1);
101
+
102
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
103
+ .tag("cause", "malformed")
104
+ .counter().count()).isEqualTo(0);
105
+
106
+ securityMetersService.trackTokenMalformed();
107
+
108
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
109
+ .tag("cause", "malformed")
110
+ .counter().count()).isEqualTo(1);
111
+ }
112
+
113
+ }
@@ -18,8 +18,10 @@
18
18
  -%>
19
19
  package <%= packageName %>.security.jwt;
20
20
 
21
+ import <%= packageName %>.management.SecurityMetersService;
21
22
  import <%= packageName %>.security.AuthoritiesConstants;
22
23
  import tech.jhipster.config.JHipsterProperties;
24
+ import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
23
25
  import io.jsonwebtoken.io.Decoders;
24
26
  import io.jsonwebtoken.security.Keys;
25
27
 
@@ -63,7 +65,10 @@ class JWTFilterTest {
63
65
  JHipsterProperties jHipsterProperties = new JHipsterProperties();
64
66
  String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8";
65
67
  jHipsterProperties.getSecurity().getAuthentication().getJwt().setBase64Secret(base64Secret);
66
- tokenProvider = new TokenProvider(jHipsterProperties);
68
+
69
+ SecurityMetersService securityMetersService = new SecurityMetersService(new SimpleMeterRegistry());
70
+
71
+ tokenProvider = new TokenProvider(jHipsterProperties, securityMetersService);
67
72
  ReflectionTestUtils.setField(tokenProvider, "key", Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret)));
68
73
 
69
74
  ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", 60000);
@@ -0,0 +1,198 @@
1
+ <%#
2
+ Copyright 2013-2021 the original author or authors from the JHipster project.
3
+
4
+ This file is part of the JHipster project, see https://www.jhipster.tech/
5
+ for more information.
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ https://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+ -%>
19
+ package <%= packageName %>.security.jwt;
20
+
21
+ import <%= packageName %>.security.AuthoritiesConstants;
22
+ import <%= packageName %>.management.SecurityMetersService;
23
+
24
+ import io.jsonwebtoken.Jwts;
25
+ import io.jsonwebtoken.SignatureAlgorithm;
26
+ import io.jsonwebtoken.io.Decoders;
27
+ import io.jsonwebtoken.security.Keys;
28
+
29
+ import io.micrometer.core.instrument.Counter;
30
+ import io.micrometer.core.instrument.MeterRegistry;
31
+ import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
32
+
33
+ import org.junit.jupiter.api.BeforeEach;
34
+ import org.junit.jupiter.api.Test;
35
+
36
+ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
37
+ import org.springframework.security.core.Authentication;
38
+ import org.springframework.security.core.GrantedAuthority;
39
+ import org.springframework.security.core.authority.SimpleGrantedAuthority;
40
+ import org.springframework.test.util.ReflectionTestUtils;
41
+ import tech.jhipster.config.JHipsterProperties;
42
+
43
+ import java.security.Key;
44
+ import java.util.ArrayList;
45
+ import java.util.Collection;
46
+ import java.util.Date;
47
+
48
+ import static org.assertj.core.api.Assertions.assertThat;
49
+
50
+ class TokenProviderSecurityMetersTests {
51
+
52
+ private static final long ONE_MINUTE = 60000;
53
+ private static final String INVALID_TOKENS_METER_EXPECTED_NAME = "security.authentication.invalid-tokens";
54
+
55
+ private MeterRegistry meterRegistry;
56
+
57
+ private TokenProvider tokenProvider;
58
+
59
+ @BeforeEach
60
+ public void setup() {
61
+ JHipsterProperties jHipsterProperties = new JHipsterProperties();
62
+ String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8";
63
+ jHipsterProperties.getSecurity().getAuthentication().getJwt().setBase64Secret(base64Secret);
64
+
65
+ meterRegistry = new SimpleMeterRegistry();
66
+
67
+ SecurityMetersService securityMetersService = new SecurityMetersService(meterRegistry);
68
+
69
+ tokenProvider = new TokenProvider(jHipsterProperties, securityMetersService);
70
+ Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret));
71
+
72
+ ReflectionTestUtils.setField(tokenProvider, "key", key);
73
+ ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", ONE_MINUTE);
74
+ }
75
+
76
+ @Test
77
+ public void testValidTokenShouldNotCountAnything() {
78
+ Collection<Counter> counters = meterRegistry.find(INVALID_TOKENS_METER_EXPECTED_NAME).counters();
79
+
80
+ assertThat(aggregate(counters)).isEqualTo(0);
81
+
82
+ String validToken = createValidToken();
83
+
84
+ tokenProvider.validateToken(validToken);
85
+
86
+ assertThat(aggregate(counters)).isEqualTo(0);
87
+ }
88
+
89
+ @Test
90
+ public void testTokenExpiredCount() {
91
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
92
+ .tag("cause", "expired")
93
+ .counter().count()).isEqualTo(0);
94
+
95
+ String expiredToken = createExpiredToken();
96
+
97
+ tokenProvider.validateToken(expiredToken);
98
+
99
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
100
+ .tag("cause", "expired")
101
+ .counter().count()).isEqualTo(1);
102
+ }
103
+
104
+ @Test
105
+ void testTokenUnsupportedCount() {
106
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
107
+ .tag("cause", "unsupported")
108
+ .counter().count()).isEqualTo(0);
109
+
110
+ String unsupportedToken = createUnsupportedToken();
111
+
112
+ tokenProvider.validateToken(unsupportedToken);
113
+
114
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
115
+ .tag("cause", "unsupported")
116
+ .counter().count()).isEqualTo(1);
117
+ }
118
+
119
+ @Test
120
+ public void testTokenSignatureInvalidCount() {
121
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
122
+ .tag("cause", "invalid-signature")
123
+ .counter().count()).isEqualTo(0);
124
+
125
+ String tokenWithDifferentSignature = createTokenWithDifferentSignature();
126
+
127
+ tokenProvider.validateToken(tokenWithDifferentSignature);
128
+
129
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
130
+ .tag("cause", "invalid-signature")
131
+ .counter().count()).isEqualTo(1);
132
+ }
133
+
134
+ @Test
135
+ public void testTokenMalformedCount() {
136
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
137
+ .tag("cause", "malformed")
138
+ .counter().count()).isEqualTo(0);
139
+
140
+ String malformedToken = createMalformedToken();
141
+
142
+ tokenProvider.validateToken(malformedToken);
143
+
144
+ assertThat(meterRegistry.get(INVALID_TOKENS_METER_EXPECTED_NAME)
145
+ .tag("cause", "malformed")
146
+ .counter().count()).isEqualTo(1);
147
+ }
148
+
149
+ private String createValidToken() {
150
+ Authentication authentication = createAuthentication();
151
+
152
+ return tokenProvider.createToken(authentication, false);
153
+ }
154
+
155
+ private String createExpiredToken() {
156
+ ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", -ONE_MINUTE);
157
+
158
+ Authentication authentication = createAuthentication();
159
+
160
+ return tokenProvider.createToken(authentication, false);
161
+ }
162
+
163
+ private Authentication createAuthentication() {
164
+ Collection<GrantedAuthority> authorities = new ArrayList<>();
165
+ authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
166
+ return new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities);
167
+ }
168
+
169
+ private String createUnsupportedToken() {
170
+ Key key = (Key) ReflectionTestUtils.getField(tokenProvider, "key");
171
+
172
+ return Jwts.builder().setPayload("payload").signWith(key, SignatureAlgorithm.HS256).compact();
173
+ }
174
+
175
+ private String createMalformedToken() {
176
+ String validToken = createValidToken();
177
+
178
+ return "X" + validToken;
179
+ }
180
+
181
+ private String createTokenWithDifferentSignature() {
182
+ Key otherKey = Keys.hmacShaKeyFor(
183
+ Decoders.BASE64.decode("Xfd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8")
184
+ );
185
+
186
+ return Jwts
187
+ .builder()
188
+ .setSubject("anonymous")
189
+ .signWith(otherKey, SignatureAlgorithm.HS512)
190
+ .setExpiration(new Date(new Date().getTime() + ONE_MINUTE))
191
+ .compact();
192
+ }
193
+
194
+ private double aggregate(Collection<Counter> counters) {
195
+ return counters.stream().mapToDouble(Counter::count).sum();
196
+ }
197
+
198
+ }
@@ -19,6 +19,7 @@
19
19
  package <%= packageName %>.security.jwt;
20
20
 
21
21
  import <%= packageName %>.security.AuthoritiesConstants;
22
+ import <%= packageName %>.management.SecurityMetersService;
22
23
 
23
24
  import java.security.Key;
24
25
  import java.util.*;
@@ -31,6 +32,8 @@ import org.springframework.security.core.GrantedAuthority;
31
32
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
32
33
  import org.springframework.test.util.ReflectionTestUtils;
33
34
 
35
+ import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
36
+
34
37
  import tech.jhipster.config.JHipsterProperties;
35
38
  import io.jsonwebtoken.Jwts;
36
39
  import io.jsonwebtoken.SignatureAlgorithm;
@@ -53,7 +56,10 @@ class TokenProviderTest {
53
56
  JHipsterProperties jHipsterProperties = new JHipsterProperties();
54
57
  String base64Secret = "fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8";
55
58
  jHipsterProperties.getSecurity().getAuthentication().getJwt().setBase64Secret(base64Secret);
56
- tokenProvider = new TokenProvider(jHipsterProperties);
59
+
60
+ SecurityMetersService securityMetersService = new SecurityMetersService(new SimpleMeterRegistry());
61
+
62
+ tokenProvider = new TokenProvider(jHipsterProperties, securityMetersService);
57
63
  key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret));
58
64
 
59
65
  ReflectionTestUtils.setField(tokenProvider, "key", key);
@@ -111,7 +117,9 @@ class TokenProviderTest {
111
117
  JHipsterProperties jHipsterProperties = new JHipsterProperties();
112
118
  jHipsterProperties.getSecurity().getAuthentication().getJwt().setSecret(secret);
113
119
 
114
- TokenProvider tokenProvider = new TokenProvider(jHipsterProperties);
120
+ SecurityMetersService securityMetersService = new SecurityMetersService(new SimpleMeterRegistry());
121
+
122
+ TokenProvider tokenProvider = new TokenProvider(jHipsterProperties, securityMetersService);
115
123
 
116
124
  Key key = (Key) ReflectionTestUtils.getField(tokenProvider, "key");
117
125
  assertThat(key).isNotNull().isEqualTo(Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)));
@@ -123,7 +131,9 @@ class TokenProviderTest {
123
131
  JHipsterProperties jHipsterProperties = new JHipsterProperties();
124
132
  jHipsterProperties.getSecurity().getAuthentication().getJwt().setBase64Secret(base64Secret);
125
133
 
126
- TokenProvider tokenProvider = new TokenProvider(jHipsterProperties);
134
+ SecurityMetersService securityMetersService = new SecurityMetersService(new SimpleMeterRegistry());
135
+
136
+ TokenProvider tokenProvider = new TokenProvider(jHipsterProperties, securityMetersService);
127
137
 
128
138
  Key key = (Key) ReflectionTestUtils.getField(tokenProvider, "key");
129
139
  assertThat(key).isNotNull().isEqualTo(Keys.hmacShaKeyFor(Decoders.BASE64.decode(base64Secret)));
@@ -50,6 +50,7 @@ import java.util.List;
50
50
  import java.util.Map;
51
51
  import java.util.Optional;
52
52
 
53
+ import static org.junit.jupiter.api.Assertions.fail;
53
54
  import static org.mockito.ArgumentMatchers.*;
54
55
  import static org.mockito.Mockito.*;
55
56
 
@@ -179,6 +180,20 @@ class AuthorizationHeaderUtilTest {
179
180
  }
180
181
 
181
182
  private OAuth2AuthorizedClient getTestOAuth2AuthorizedClient(boolean accessTokenExpired) {
183
+ Instant issuedAt = Instant.now();
184
+ Instant expiresAt;
185
+ if (accessTokenExpired) {
186
+ expiresAt = issuedAt.plus(Duration.ofNanos(1));
187
+ try {
188
+ Thread.sleep(1);
189
+ } catch (Exception e) {
190
+ fail("Error in Thread.sleep(1) : " + e.getMessage());
191
+ }
192
+ } else {
193
+ expiresAt = issuedAt.plus(Duration.ofMinutes(3));
194
+ }
195
+ OAuth2AccessToken token = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "tokenVal", issuedAt, expiresAt);
196
+
182
197
  return new OAuth2AuthorizedClient(
183
198
  ClientRegistration.withRegistrationId(VALID_REGISTRATION_ID)
184
199
  .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
@@ -189,8 +204,7 @@ class AuthorizationHeaderUtilTest {
189
204
  .tokenUri("https://localhost:8080/auth/realms/master/protocol/openid-connect/token")
190
205
  .build(),
191
206
  "sub",
192
- new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "tokenVal", Instant.now(),
193
- accessTokenExpired ? Instant.now() : Instant.now().plus(Duration.ofMinutes(3))),
207
+ token,
194
208
  new OAuth2RefreshToken("refreshVal", Instant.now()));
195
209
  }
196
210
 
@@ -50,6 +50,9 @@ class CustomClaimConverterIT {
50
50
  private static final String USERNAME = "admin";
51
51
  private static final String NAME = "John";
52
52
  private static final String FAMILY_NAME = "Doe";
53
+ private static final String FULL_NAME = NAME + " " + FAMILY_NAME;
54
+ private static final String NAME_SUFFIX = "Sr.";
55
+ private static final String EMAIL = "john.doe@gmail.com";
53
56
 
54
57
  private final ObjectMapper mapper = new ObjectMapper();
55
58
 
@@ -161,4 +164,64 @@ class CustomClaimConverterIT {
161
164
  .doesNotContainKeys("given_name", "family_name");
162
165
  }).doesNotThrowAnyException();
163
166
  }
167
+
168
+ @Test
169
+ void testConvert_withName() {
170
+ // GIVEN
171
+ Map<String, Object> claims = new HashMap<>();
172
+ claims.put("sub", "123");
173
+ // AND
174
+ ObjectNode user = mapper.createObjectNode();
175
+ user.put("preferred_username", USERNAME);
176
+ user.put("name", FULL_NAME);
177
+ mockHttpGetUserInfo(user);
178
+
179
+ assertThatCode(() -> {
180
+ Map<String, Object> convertedClaims = customClaimConverter.convert(claims);
181
+ assertThat(convertedClaims)
182
+ .containsEntry("preferred_username", USERNAME)
183
+ .containsEntry("given_name", NAME)
184
+ .containsEntry("family_name", FAMILY_NAME);
185
+ }).doesNotThrowAnyException();
186
+ }
187
+
188
+ @Test
189
+ void testConvert_withLastNameMultipleWords() {
190
+ // GIVEN
191
+ Map<String, Object> claims = new HashMap<>();
192
+ claims.put("sub", "123");
193
+ // AND
194
+ ObjectNode user = mapper.createObjectNode();
195
+ user.put("preferred_username", USERNAME);
196
+ user.put("name", FULL_NAME + " " + NAME_SUFFIX);
197
+ mockHttpGetUserInfo(user);
198
+
199
+ assertThatCode(() -> {
200
+ Map<String, Object> convertedClaims = customClaimConverter.convert(claims);
201
+ System.out.println(convertedClaims);
202
+ assertThat(convertedClaims)
203
+ .containsEntry("preferred_username", USERNAME)
204
+ .containsEntry("given_name", NAME)
205
+ .containsEntry("family_name", FAMILY_NAME + " " + NAME_SUFFIX);
206
+ }).doesNotThrowAnyException();
207
+ }
208
+
209
+ @Test
210
+ void testConvert_withEmail() {
211
+ // GIVEN
212
+ Map<String, Object> claims = new HashMap<>();
213
+ claims.put("sub", "123");
214
+ // AND
215
+ ObjectNode user = mapper.createObjectNode();
216
+ user.put("preferred_username", USERNAME);
217
+ user.put("email", EMAIL);
218
+ mockHttpGetUserInfo(user);
219
+
220
+ assertThatCode(() -> {
221
+ Map<String, Object> convertedClaims = customClaimConverter.convert(claims);
222
+ assertThat(convertedClaims)
223
+ .containsEntry("preferred_username", USERNAME)
224
+ .containsEntry("email", EMAIL);
225
+ }).doesNotThrowAnyException();
226
+ }
164
227
  }
@@ -45,8 +45,6 @@ const {
45
45
  const NO_CACHE_PROVIDER = cacheProviders.NO;
46
46
  const NO_MESSAGE_BROKER = messageBrokers.NO;
47
47
 
48
- let useBlueprints;
49
-
50
48
  module.exports = class extends BaseBlueprintGenerator {
51
49
  constructor(args, options, features) {
52
50
  super(args, options, features);
@@ -60,8 +58,12 @@ module.exports = class extends BaseBlueprintGenerator {
60
58
  description: 'default option',
61
59
  });
62
60
  this.defaultOption = this.options.default;
61
+ }
63
62
 
64
- useBlueprints = !this.fromBlueprint && this.instantiateBlueprints(GENERATOR_SPRING_CONTROLLER, { arguments: [this.name] });
63
+ async _postConstruct() {
64
+ if (!this.fromBlueprint) {
65
+ await this.composeWithBlueprints(GENERATOR_SPRING_CONTROLLER, { arguments: [this.name] });
66
+ }
65
67
  }
66
68
 
67
69
  // Public API method used by the getter and also by Blueprints
@@ -94,7 +96,7 @@ module.exports = class extends BaseBlueprintGenerator {
94
96
  }
95
97
 
96
98
  get initializing() {
97
- if (useBlueprints) return;
99
+ if (this.delegateToBlueprint) return {};
98
100
  return this._initializing();
99
101
  }
100
102
 
@@ -106,7 +108,7 @@ module.exports = class extends BaseBlueprintGenerator {
106
108
  }
107
109
 
108
110
  get prompting() {
109
- if (useBlueprints) return;
111
+ if (this.delegateToBlueprint) return {};
110
112
  return this._prompting();
111
113
  }
112
114
 
@@ -120,7 +122,7 @@ module.exports = class extends BaseBlueprintGenerator {
120
122
  }
121
123
 
122
124
  get default() {
123
- if (useBlueprints) return;
125
+ if (this.delegateToBlueprint) return {};
124
126
  return this._default();
125
127
  }
126
128
 
@@ -177,7 +179,7 @@ module.exports = class extends BaseBlueprintGenerator {
177
179
  }
178
180
 
179
181
  get writing() {
180
- if (useBlueprints) return;
182
+ if (this.delegateToBlueprint) return {};
181
183
  return this._writing();
182
184
  }
183
185
  };
@@ -27,7 +27,6 @@ const { GENERATOR_SPRING_SERVICE } = require('../generator-list');
27
27
  const { BASE_NAME, PACKAGE_NAME, PACKAGE_FOLDER, DATABASE_TYPE } = OptionNames;
28
28
  const SERVER_MAIN_SRC_DIR = constants.SERVER_MAIN_SRC_DIR;
29
29
 
30
- let useBlueprints;
31
30
  module.exports = class extends BaseBlueprintGenerator {
32
31
  constructor(args, options, features) {
33
32
  super(args, options, features);
@@ -41,8 +40,12 @@ module.exports = class extends BaseBlueprintGenerator {
41
40
  description: 'default option',
42
41
  });
43
42
  this.defaultOption = this.options.default;
43
+ }
44
44
 
45
- useBlueprints = !this.fromBlueprint && this.instantiateBlueprints(GENERATOR_SPRING_SERVICE, { arguments: [this.name] });
45
+ async _postConstruct() {
46
+ if (!this.fromBlueprint) {
47
+ await this.composeWithBlueprints(GENERATOR_SPRING_SERVICE, { arguments: [this.name] });
48
+ }
46
49
  }
47
50
 
48
51
  // Public API method used by the getter and also by Blueprints
@@ -64,7 +67,7 @@ module.exports = class extends BaseBlueprintGenerator {
64
67
  }
65
68
 
66
69
  get initializing() {
67
- if (useBlueprints) return;
70
+ if (this.delegateToBlueprint) return {};
68
71
  return this._initializing();
69
72
  }
70
73
 
@@ -94,7 +97,7 @@ module.exports = class extends BaseBlueprintGenerator {
94
97
  }
95
98
 
96
99
  get prompting() {
97
- if (useBlueprints) return;
100
+ if (this.delegateToBlueprint) return {};
98
101
  return this._prompting();
99
102
  }
100
103
 
@@ -108,7 +111,7 @@ module.exports = class extends BaseBlueprintGenerator {
108
111
  }
109
112
 
110
113
  get loading() {
111
- if (useBlueprints) return;
114
+ if (this.delegateToBlueprint) return {};
112
115
  return this._loading();
113
116
  }
114
117
 
@@ -122,7 +125,7 @@ module.exports = class extends BaseBlueprintGenerator {
122
125
  }
123
126
 
124
127
  get default() {
125
- if (useBlueprints) return;
128
+ if (this.delegateToBlueprint) return {};
126
129
  return this._default();
127
130
  }
128
131
 
@@ -151,7 +154,7 @@ module.exports = class extends BaseBlueprintGenerator {
151
154
  }
152
155
 
153
156
  get writing() {
154
- if (useBlueprints) return;
157
+ if (this.delegateToBlueprint) return {};
155
158
  return this._writing();
156
159
  }
157
160
  };
@@ -89,10 +89,9 @@ module.exports = class extends BaseGenerator {
89
89
  // Used for isJhipsterVersionLessThan on cleanup.upgradeFiles
90
90
  this.jhipsterOldVersion = this.config.get('jhipsterVersion');
91
91
 
92
- // Verify 6.6.0 app blueprint bug
93
- if (!this.config.existed && !this.options.blueprints && !this.options.help) {
94
- this.error(
95
- 'This seems to be an app blueprinted project with jhipster 6.6.0 bug (https://github.com/jhipster/generator-jhipster/issues/11045), you should pass --blueprints to jhipster upgrade commmand.'
92
+ if (!this.config.existed) {
93
+ throw new Error(
94
+ "Could not find a valid JHipster application configuration, check if the '.yo-rc.json' file exists and if the 'generator-jhipster' key exists inside it."
96
95
  );
97
96
  }
98
97
  }
@@ -522,7 +522,7 @@ function getEnumInfo(field, clientRootFolder) {
522
522
  const customValuesState = getCustomValuesState(enums);
523
523
  return {
524
524
  enumName: fieldType,
525
- javadoc: field.fieldTypeJavadoc && this.getJavadoc(field.fieldTypeJavadoc),
525
+ javadoc: field.fieldTypeJavadoc && getJavadoc(field.fieldTypeJavadoc),
526
526
  enumInstance: field.enumInstance,
527
527
  enums,
528
528
  ...customValuesState,
@@ -794,7 +794,7 @@ function vueReplaceTranslation(generator, files) {
794
794
  const regexp = ['v-text', 'v-bind:placeholder', 'v-html', 'v-bind:title', 'v-bind:label', 'v-bind:value', 'v-bind:html']
795
795
  .map(s => `${s}="\\$t\\(.*?\\)"`)
796
796
  .join(')|(');
797
- this.replaceContent(
797
+ replaceContent(
798
798
  {
799
799
  file: filePath,
800
800
  pattern: new RegExp(` ?(${regexp})`, 'g'),