generator-jhipster 8.10.0 → 8.11.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 (130) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/cli.mjs +0 -13
  3. package/dist/cli/environment-builder.mjs +3 -1
  4. package/dist/generators/angular/resources/package.json +18 -18
  5. package/dist/generators/angular/templates/README.md.jhi.client.angular.ejs +1 -1
  6. package/dist/generators/angular/templates/eslint.config.js.jhi.angular.ejs +4 -6
  7. package/dist/generators/angular/templates/src/main/webapp/app/admin/user-management/list/user-management.component.html.ejs +1 -1
  8. package/dist/generators/angular/templates/src/main/webapp/app/core/tracker/tracker.service.ts.ejs +1 -1
  9. package/dist/generators/angular/templates/src/main/webapp/app/entities/_entityFolder_/list/_entityFile_.component.html.ejs +1 -1
  10. package/dist/generators/angular/templates/src/main/webapp/app/entities/_entityFolder_/update/_entityFile_-update.component.html.ejs +1 -1
  11. package/dist/generators/angular/templates/src/main/webapp/app/shared/sort/sort.service.ts.ejs +3 -3
  12. package/dist/generators/base/api.d.ts +3 -1
  13. package/dist/generators/base/shared-data.js +1 -0
  14. package/dist/generators/base/support/contents.d.ts +10 -1
  15. package/dist/generators/base/support/contents.js +9 -0
  16. package/dist/generators/base/support/index.d.ts +1 -0
  17. package/dist/generators/base/support/index.js +1 -0
  18. package/dist/generators/base/support/needles.js +2 -6
  19. package/dist/generators/base/support/os.d.ts +1 -0
  20. package/dist/generators/base/support/os.js +20 -0
  21. package/dist/generators/base/support/write-files.d.ts +18 -0
  22. package/dist/generators/base/support/write-files.js +0 -26
  23. package/dist/generators/base-core/generator.js +7 -4
  24. package/dist/generators/bootstrap/generator.js +31 -2
  25. package/dist/generators/bootstrap/support/auto-crlf-transform.js +2 -2
  26. package/dist/generators/bootstrap-application-base/generator.js +1 -3
  27. package/dist/generators/client/resources/package.json +4 -4
  28. package/dist/generators/common/resources/package.json +1 -1
  29. package/dist/generators/cypress/templates/src/test/javascript/cypress/e2e/account/logout.cy.ts.ejs +11 -3
  30. package/dist/generators/cypress/templates/src/test/javascript/cypress/support/oauth2.ts.ejs +4 -4
  31. package/dist/generators/generate-blueprint/resources/package.json +2 -2
  32. package/dist/generators/generator-constants.d.ts +1 -1
  33. package/dist/generators/generator-constants.js +1 -1
  34. package/dist/generators/gradle/templates/gradle/wrapper/gradle-wrapper.properties +1 -1
  35. package/dist/generators/init/resources/.node-version +1 -1
  36. package/dist/generators/java/generators/graalvm/internal/constants.d.ts +1 -1
  37. package/dist/generators/java/generators/graalvm/internal/constants.js +1 -1
  38. package/dist/generators/java/generators/node/generator.js +2 -1
  39. package/dist/generators/javascript/generators/eslint/templates/eslint.config.js.jhi.ejs +8 -0
  40. package/dist/generators/javascript/resources/package.json +3 -3
  41. package/dist/generators/languages/support/languages.js +1 -0
  42. package/dist/generators/languages/templates/entity/i18n/entity_he.json.ejs +78 -0
  43. package/dist/generators/languages/templates/src/main/resources/i18n/messages_he.properties.ejs +41 -0
  44. package/dist/generators/languages/templates/src/main/webapp/i18n/he/activate.json.ejs +27 -0
  45. package/dist/generators/languages/templates/src/main/webapp/i18n/he/configuration.json +11 -0
  46. package/dist/generators/languages/templates/src/main/webapp/i18n/he/error.json +15 -0
  47. package/dist/generators/languages/templates/src/main/webapp/i18n/he/gateway.json +16 -0
  48. package/dist/generators/languages/templates/src/main/webapp/i18n/he/global.json.ejs +172 -0
  49. package/dist/generators/languages/templates/src/main/webapp/i18n/he/health.json.ejs +75 -0
  50. package/dist/generators/languages/templates/src/main/webapp/i18n/he/home.json.ejs +20 -0
  51. package/dist/generators/languages/templates/src/main/webapp/i18n/he/login.json +20 -0
  52. package/dist/generators/languages/templates/src/main/webapp/i18n/he/logs.json +12 -0
  53. package/dist/generators/languages/templates/src/main/webapp/i18n/he/metrics.json +103 -0
  54. package/dist/generators/languages/templates/src/main/webapp/i18n/he/password.json +13 -0
  55. package/dist/generators/languages/templates/src/main/webapp/i18n/he/register.json +25 -0
  56. package/dist/generators/languages/templates/src/main/webapp/i18n/he/reset.json.ejs +45 -0
  57. package/dist/generators/languages/templates/src/main/webapp/i18n/he/sessions.json +16 -0
  58. package/dist/generators/languages/templates/src/main/webapp/i18n/he/settings.json +33 -0
  59. package/dist/generators/languages/templates/src/main/webapp/i18n/he/tracker.json +13 -0
  60. package/dist/generators/languages/templates/src/main/webapp/i18n/he/user-management.json +32 -0
  61. package/dist/generators/languages/templates/src/test/resources/i18n/messages_he.properties.ejs +4 -0
  62. package/dist/generators/react/resources/package.json +23 -23
  63. package/dist/generators/react/templates/src/main/webapp/app/entities/_entityFolder_/_entityFile_-delete-dialog.tsx.ejs +2 -1
  64. package/dist/generators/react/templates/src/main/webapp/app/entities/_entityFolder_/_entityFile_.reducer.ts.ejs +4 -4
  65. package/dist/generators/react/templates/src/main/webapp/app/modules/administration/administration.reducer.spec.ts.ejs +0 -6
  66. package/dist/generators/react/templates/src/main/webapp/app/shared/reducers/application-profile.spec.ts.ejs +0 -6
  67. package/dist/generators/react/templates/src/main/webapp/app/shared/reducers/locale.spec.ts.ejs +0 -47
  68. package/dist/generators/react/templates/src/main/webapp/app/shared/reducers/reducer.utils.ts.ejs +1 -1
  69. package/dist/generators/react/templates/src/main/webapp/app/shared/util/entity-utils.ts.ejs +1 -1
  70. package/dist/generators/server/resources/Dockerfile +11 -11
  71. package/dist/generators/server/resources/gradle/libs.versions.toml +6 -6
  72. package/dist/generators/server/resources/pom.xml +7 -7
  73. package/dist/generators/spring-boot/generator.js +2 -3
  74. package/dist/generators/spring-boot/resources/spring-boot-dependencies.pom +115 -105
  75. package/dist/generators/spring-boot/templates/src/main/java/_package_/config/SecurityJwtConfiguration.java.ejs +0 -1
  76. package/dist/generators/spring-boot/templates/src/main/java/_package_/security/DomainUserDetailsService.java.ejs +61 -5
  77. package/dist/generators/spring-boot/templates/src/main/java/_package_/security/SecurityUtils.java.ejs +29 -1
  78. package/dist/generators/spring-boot/templates/src/main/java/_package_/web/rest/AuthenticateController.java.ejs +11 -5
  79. package/dist/generators/spring-boot/templates/src/test/java/_package_/security/SecurityUtilsUnitTest_imperative.java.ejs +35 -11
  80. package/dist/generators/spring-boot/templates/src/test/java/_package_/security/SecurityUtilsUnitTest_reactive.java.ejs +35 -6
  81. package/dist/generators/spring-boot/templates/src/test/java/_package_/security/jwt/JwtAuthenticationTestUtils.java.ejs +3 -2
  82. package/dist/generators/spring-cache/resources/gradle/libs.versions.toml +1 -1
  83. package/dist/generators/vue/cleanup.js +7 -1
  84. package/dist/generators/vue/files-vue.js +3 -8
  85. package/dist/generators/vue/resources/package.json +20 -20
  86. package/dist/generators/vue/templates/src/main/webapp/app/account/account.service.ts.ejs +9 -9
  87. package/dist/generators/vue/templates/src/main/webapp/app/account/activate/activate.component.spec.ts.ejs +21 -7
  88. package/dist/generators/vue/templates/src/main/webapp/app/account/activate/activate.component.ts.ejs +23 -9
  89. package/dist/generators/vue/templates/src/main/webapp/app/account/activate/activate.service.ts.ejs +1 -1
  90. package/dist/generators/vue/templates/src/main/webapp/app/account/activate/activate.vue.ejs +1 -1
  91. package/dist/generators/vue/templates/src/main/webapp/app/account/change-password/change-password.vue.ejs +1 -1
  92. package/dist/generators/vue/templates/src/main/webapp/app/account/login-form/login-form.component.spec.ts.ejs +22 -10
  93. package/dist/generators/vue/templates/src/main/webapp/app/account/login-form/login-form.component.ts.ejs +24 -5
  94. package/dist/generators/vue/templates/src/main/webapp/app/account/login-modal.ts.ejs +38 -0
  95. package/dist/generators/vue/templates/src/main/webapp/app/account/login.service.spec.ts.ejs +0 -4
  96. package/dist/generators/vue/templates/src/main/webapp/app/account/login.service.ts.ejs +3 -25
  97. package/dist/generators/vue/templates/src/main/webapp/app/account/register/register.component.spec.ts.ejs +24 -8
  98. package/dist/generators/vue/templates/src/main/webapp/app/account/register/register.component.ts.ejs +23 -9
  99. package/dist/generators/vue/templates/src/main/webapp/app/account/register/register.service.ts.ejs +1 -1
  100. package/dist/generators/vue/templates/src/main/webapp/app/account/register/register.vue.ejs +1 -1
  101. package/dist/generators/vue/templates/src/main/webapp/app/account/reset-password/finish/reset-password-finish.component.spec.ts.ejs +20 -4
  102. package/dist/generators/vue/templates/src/main/webapp/app/account/reset-password/finish/reset-password-finish.component.ts.ejs +23 -13
  103. package/dist/generators/vue/templates/src/main/webapp/app/account/reset-password/finish/reset-password-finish.vue.ejs +1 -1
  104. package/dist/generators/vue/templates/src/main/webapp/app/account/settings/settings.vue.ejs +1 -1
  105. package/dist/generators/vue/templates/src/main/webapp/app/admin/configuration/configuration.service.ts.ejs +2 -2
  106. package/dist/generators/vue/templates/src/main/webapp/app/admin/gateway/gateway.service.ts.ejs +1 -1
  107. package/dist/generators/vue/templates/src/main/webapp/app/admin/health/health.service.ts.ejs +10 -10
  108. package/dist/generators/vue/templates/src/main/webapp/app/admin/logs/logs.service.ts.ejs +2 -2
  109. package/dist/generators/vue/templates/src/main/webapp/app/admin/metrics/metrics-modal.vue.ejs +2 -2
  110. package/dist/generators/vue/templates/src/main/webapp/app/admin/metrics/metrics.service.ts.ejs +2 -2
  111. package/dist/generators/vue/templates/src/main/webapp/app/admin/tracker/tracker.service.ts.ejs +5 -5
  112. package/dist/generators/vue/templates/src/main/webapp/app/admin/user-management/user-management.service.ts.ejs +6 -6
  113. package/dist/generators/vue/templates/src/main/webapp/app/app.component.ts.ejs +29 -7
  114. package/dist/generators/vue/templates/src/main/webapp/app/app.vue.ejs +19 -1
  115. package/dist/generators/vue/templates/src/main/webapp/app/core/error/error.component.spec.ts.ejs +66 -51
  116. package/dist/generators/vue/templates/src/main/webapp/app/core/error/error.component.ts.ejs +30 -8
  117. package/dist/generators/vue/templates/src/main/webapp/app/core/home/home.component.spec.ts.ejs +41 -11
  118. package/dist/generators/vue/templates/src/main/webapp/app/core/home/home.component.ts.ejs +10 -11
  119. package/dist/generators/vue/templates/src/main/webapp/app/core/home/home.vue.ejs +2 -2
  120. package/dist/generators/vue/templates/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.spec.ts.ejs +43 -16
  121. package/dist/generators/vue/templates/src/main/webapp/app/core/jhi-navbar/jhi-navbar.component.ts.ejs +14 -9
  122. package/dist/generators/vue/templates/src/main/webapp/app/core/jhi-navbar/jhi-navbar.vue.ejs +1 -1
  123. package/dist/generators/vue/templates/src/main/webapp/app/entities/_entityFolder_/_entityFile_.service.ts.ejs +7 -7
  124. package/dist/generators/vue/templates/src/main/webapp/app/entities/user/user.service.ts.ejs +1 -1
  125. package/dist/generators/vue/templates/src/main/webapp/app/locale/translation.service.ts.ejs +5 -5
  126. package/dist/generators/vue/templates/src/main/webapp/app/main.ts.ejs +18 -14
  127. package/dist/generators/vue/templates/src/main/webapp/app/shared/alert/alert.service.ts.ejs +4 -4
  128. package/dist/lib/testing/apply-patch-to-template.d.ts +13 -0
  129. package/dist/lib/testing/apply-patch-to-template.js +90 -0
  130. package/package.json +26 -26
@@ -27,6 +27,7 @@ import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator;
27
27
  import org.slf4j.Logger;
28
28
  import org.slf4j.LoggerFactory;
29
29
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
30
+ import org.springframework.security.core.GrantedAuthority;
30
31
  <%_ if (reactive) { _%>
31
32
  import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
32
33
  <%_ } _%>
@@ -42,6 +43,9 @@ import org.springframework.transaction.annotation.Transactional;
42
43
  <%_ if (reactive) { _%>
43
44
  import reactor.core.publisher.Mono;
44
45
  <%_ } _%>
46
+ <%_ if (user?.primaryKey?.hasUUID) { _%>
47
+ import java.util.UUID;
48
+ <%_ } _%>
45
49
 
46
50
  import java.util.*;
47
51
 
@@ -89,10 +93,62 @@ public class DomainUserDetailsService implements <% if (reactive) { %>Reactive<%
89
93
  if (!user.isActivated()) {
90
94
  throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
91
95
  }
92
- List<SimpleGrantedAuthority> grantedAuthorities = user.getAuthorities().stream()<% if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j) { %>
93
- .map(Authority::getName)<% } %>
94
- .map(SimpleGrantedAuthority::new)
95
- .toList();
96
- return new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPassword(), grantedAuthorities);
96
+ <%_ if (user) { _%>
97
+ return UserWithId.fromUser(user);
98
+ <%_ } else { _%>
99
+ return org.springframework.security.core.userdetails.User.withUsername(user.getLogin())
100
+ .password(user.getPassword())
101
+ .authorities(
102
+ user.getAuthorities()
103
+ .stream()
104
+ <%_ if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j) { _%>
105
+ .map(Authority::getName)
106
+ <%_ } _%>
107
+ .map(SimpleGrantedAuthority::new)
108
+ .toList()
109
+ )
110
+ .build();
111
+ <%_ } _%>
112
+ }
113
+ <%_ if (user) { _%>
114
+
115
+ public static class UserWithId extends org.springframework.security.core.userdetails.User {
116
+
117
+ private final <%= user.primaryKey.type %> id;
118
+
119
+ public UserWithId(String login, String password, Collection<? extends GrantedAuthority> authorities, <%= user.primaryKey.type %> id) {
120
+ super(login, password, authorities);
121
+ this.id = id;
122
+ }
123
+
124
+ public <%= user.primaryKey.type %> getId() {
125
+ return id;
126
+ }
127
+
128
+ @Override
129
+ public boolean equals(Object obj) {
130
+ return super.equals(obj);
131
+ }
132
+
133
+ @Override
134
+ public int hashCode() {
135
+ return super.hashCode();
136
+ }
137
+
138
+ public static UserWithId fromUser(<%= user.persistClass %> user) {
139
+ return new UserWithId(
140
+ user.getLogin(),
141
+ user.getPassword(),
142
+ user.getAuthorities()
143
+ .stream()
144
+ <%_ if (databaseTypeSql || databaseTypeMongodb || databaseTypeNeo4j) { _%>
145
+ .map(Authority::getName)
146
+ <%_ } _%>
147
+ .map(SimpleGrantedAuthority::new)
148
+ .toList(),
149
+ user.getId()
150
+ );
151
+ }
97
152
  }
153
+ <%_ } _%>
98
154
  }
@@ -34,6 +34,7 @@ import org.springframework.security.core.userdetails.UserDetails;
34
34
  <%_ if (authenticationTypeJwt) { _%>
35
35
  import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
36
36
  import org.springframework.security.oauth2.jwt.Jwt;
37
+ import org.springframework.security.oauth2.core.ClaimAccessor;
37
38
  <%_ } _%>
38
39
  <%_ if (authenticationTypeOauth2) { _%>
39
40
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -65,6 +66,9 @@ import java.util.HashMap;
65
66
  import java.util.Map;
66
67
  import java.util.stream.Collectors;
67
68
  <%_ } _%>
69
+ <%_ if (user?.primaryKey?.hasUUID) { _%>
70
+ import java.util.UUID;
71
+ <%_ } _%>
68
72
 
69
73
  /**
70
74
  * Utility class for Spring Security.
@@ -76,7 +80,11 @@ public final class SecurityUtils {
76
80
 
77
81
  public static final MacAlgorithm JWT_ALGORITHM = MacAlgorithm.HS512;
78
82
 
79
- public static final String AUTHORITIES_KEY = "auth";
83
+ public static final String AUTHORITIES_CLAIM = "auth";
84
+ <%_ if (user) { _%>
85
+
86
+ public static final String USER_ID_CLAIM = "userId";
87
+ <%_ } _%>
80
88
  <%_ } _%>
81
89
 
82
90
  private SecurityUtils() {}
@@ -139,6 +147,26 @@ public final class SecurityUtils {
139
147
  .filter(authentication -> authentication.getCredentials() instanceof String)
140
148
  .map(authentication -> (String) authentication.getCredentials());
141
149
  }
150
+ <%_ if (user) { _%>
151
+
152
+ /**
153
+ * Get the Id of the current user.
154
+ *
155
+ * @return the Id of the current user.
156
+ */
157
+ public static <%- optionalOrMono %><<%= user.primaryKey.type %>> getCurrentUserId() {
158
+ <%_ if (reactive) { _%>
159
+ return ReactiveSecurityContextHolder.getContext()
160
+ .map(SecurityContext::getAuthentication)
161
+ <%_ } else { _%>
162
+ SecurityContext securityContext = SecurityContextHolder.getContext();
163
+ return Optional.ofNullable(securityContext.getAuthentication())
164
+ <%_ } _%>
165
+ .filter(authentication -> authentication.getPrincipal() instanceof ClaimAccessor)
166
+ .map(authentication -> (ClaimAccessor) authentication.getPrincipal())
167
+ .map(principal -> principal.getClaim(USER_ID_CLAIM));
168
+ }
169
+ <%_ } _%>
142
170
  <%_ } _%>
143
171
 
144
172
  /**
@@ -18,10 +18,12 @@
18
18
  -%>
19
19
  package <%= packageName %>.web.rest;
20
20
 
21
- import static <%= packageName %>.security.SecurityUtils.AUTHORITIES_KEY;
21
+ import static <%= packageName %>.security.SecurityUtils.AUTHORITIES_CLAIM;
22
22
  import static <%= packageName %>.security.SecurityUtils.JWT_ALGORITHM;
23
+ import static <%= packageName %>.security.SecurityUtils.USER_ID_CLAIM;
23
24
 
24
25
  import <%= packageName %>.web.rest.vm.LoginVM;
26
+ import <%= packageName %>.security.DomainUserDetailsService.UserWithId;
25
27
 
26
28
  import com.fasterxml.jackson.annotation.JsonProperty;
27
29
 
@@ -140,15 +142,19 @@ public class AuthenticateController {
140
142
  }
141
143
 
142
144
  // @formatter:off
143
- JwtClaimsSet claims = JwtClaimsSet.builder()
145
+ JwtClaimsSet.Builder builder = JwtClaimsSet.builder()
144
146
  .issuedAt(now)
145
147
  .expiresAt(validity)
146
148
  .subject(authentication.getName())
147
- .claim(AUTHORITIES_KEY, authorities)
148
- .build();
149
+ .claim(AUTHORITIES_CLAIM, authorities);
150
+ <%_ if (user) { _%>
151
+ if (authentication.getPrincipal() instanceof UserWithId user) {
152
+ builder.claim(USER_ID_CLAIM, user.getId());
153
+ }
154
+ <%_ } _%>
149
155
 
150
156
  JwsHeader jwsHeader = JwsHeader.with(JWT_ALGORITHM).build();
151
- return this.jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, claims)).getTokenValue();
157
+ return this.jwtEncoder.encode(JwtEncoderParameters.from(jwsHeader, builder.build())).getTokenValue();
152
158
  }
153
159
 
154
160
  /**
@@ -18,6 +18,10 @@
18
18
  -%>
19
19
  package <%= packageName %>.security;
20
20
 
21
+ <%_ if (authenticationTypeJwt) { _%>
22
+ import static <%= packageName %>.security.SecurityUtils.USER_ID_CLAIM;
23
+ <%_ } _%>
24
+
21
25
  import org.junit.jupiter.api.AfterEach;
22
26
  import org.junit.jupiter.api.BeforeEach;
23
27
  import org.junit.jupiter.api.Test;
@@ -26,6 +30,10 @@ import org.springframework.security.core.GrantedAuthority;
26
30
  import org.springframework.security.core.authority.SimpleGrantedAuthority;
27
31
  import org.springframework.security.core.context.SecurityContext;
28
32
  import org.springframework.security.core.context.SecurityContextHolder;
33
+ <%_ if (authenticationTypeJwt) { _%>
34
+ import java.time.Instant;
35
+ import org.springframework.security.oauth2.jwt.Jwt;
36
+ <%_ } _%>
29
37
  <%_ if (authenticationTypeOauth2) { _%>
30
38
  import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
31
39
  import org.springframework.security.oauth2.core.oidc.OidcIdToken;
@@ -39,6 +47,7 @@ import java.util.ArrayList;
39
47
  import java.util.Collection;
40
48
  import java.util.Optional;
41
49
  <%_ } _%>
50
+ import java.util.Collections;
42
51
 
43
52
  import static org.assertj.core.api.Assertions.assertThat;
44
53
  <%_ if (authenticationTypeOauth2) { _%>
@@ -128,6 +137,25 @@ class SecurityUtilsUnitTest {
128
137
  Optional<String> jwt = SecurityUtils.getCurrentUserJWT();
129
138
  assertThat(jwt).contains("token");
130
139
  }
140
+ <%_ if (user) { _%>
141
+
142
+ @Test
143
+ void testGetCurrentUserId() {
144
+ var userId = <%- user.primaryKey.javaSampleValues[0] %>;
145
+ var securityContext = SecurityContextHolder.createEmptyContext();
146
+ var now = Instant.now();
147
+ var jwt = Jwt.withTokenValue("token")
148
+ .issuedAt(now)
149
+ .expiresAt(now.plusSeconds(60))
150
+ .claim(USER_ID_CLAIM, userId)
151
+ .header("Test", "test")
152
+ .build();
153
+ securityContext.setAuthentication(new UsernamePasswordAuthenticationToken(jwt, "token"));
154
+ SecurityContextHolder.setContext(securityContext);
155
+ var contextUserId = SecurityUtils.getCurrentUserId();
156
+ assertThat(contextUserId.orElse(null)).isEqualTo(userId);
157
+ }
158
+ <%_ } _%>
131
159
  <%_ } _%>
132
160
 
133
161
  @Test
@@ -142,8 +170,7 @@ class SecurityUtilsUnitTest {
142
170
  @Test
143
171
  void testAnonymousIsNotAuthenticated() {
144
172
  SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
145
- Collection<GrantedAuthority> authorities = new ArrayList<>();
146
- authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
173
+ var authorities = Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
147
174
  securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities));
148
175
  SecurityContextHolder.setContext(securityContext);
149
176
  boolean isAuthenticated = SecurityUtils.isAuthenticated();
@@ -153,9 +180,8 @@ class SecurityUtilsUnitTest {
153
180
  @Test
154
181
  void testHasCurrentUserThisAuthority() {
155
182
  SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
156
- Collection<GrantedAuthority> authorities = new ArrayList<>();
157
- authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
158
- securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("user", "user", authorities));
183
+ var authorities = Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
184
+ securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities));
159
185
  SecurityContextHolder.setContext(securityContext);
160
186
 
161
187
  assertThat(SecurityUtils.hasCurrentUserThisAuthority(AuthoritiesConstants.USER)).isTrue();
@@ -165,9 +191,8 @@ class SecurityUtilsUnitTest {
165
191
  @Test
166
192
  void testHasCurrentUserAnyOfAuthorities() {
167
193
  SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
168
- Collection<GrantedAuthority> authorities = new ArrayList<>();
169
- authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
170
- securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("user", "user", authorities));
194
+ var authorities = Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
195
+ securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities));
171
196
  SecurityContextHolder.setContext(securityContext);
172
197
 
173
198
  assertThat(SecurityUtils.hasCurrentUserAnyOfAuthorities(AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN)).isTrue();
@@ -177,9 +202,8 @@ class SecurityUtilsUnitTest {
177
202
  @Test
178
203
  void testHasCurrentUserNoneOfAuthorities() {
179
204
  SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
180
- Collection<GrantedAuthority> authorities = new ArrayList<>();
181
- authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
182
- securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("user", "user", authorities));
205
+ var authorities = Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
206
+ securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities));
183
207
  SecurityContextHolder.setContext(securityContext);
184
208
 
185
209
  assertThat(SecurityUtils.hasCurrentUserNoneOfAuthorities(AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN)).isFalse();
@@ -18,6 +18,14 @@
18
18
  -%>
19
19
  package <%= packageName %>.security;
20
20
 
21
+ import static org.assertj.core.api.Assertions.assertThat;
22
+ <%_ if (authenticationTypeOauth2) { _%>
23
+ import static org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames.ID_TOKEN;
24
+ <%_ } _%>
25
+ <%_ if (authenticationTypeJwt) { _%>
26
+ import static <%= packageName %>.security.SecurityUtils.USER_ID_CLAIM;
27
+ <%_ } _%>
28
+
21
29
  import org.junit.jupiter.api.AfterEach;
22
30
  import org.junit.jupiter.api.BeforeEach;
23
31
  import org.junit.jupiter.api.Test;
@@ -27,6 +35,11 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
27
35
  import org.springframework.security.core.context.ReactiveSecurityContextHolder;
28
36
  import reactor.util.context.Context;
29
37
 
38
+ <%_ if (authenticationTypeJwt) { _%>
39
+ import java.time.Instant;
40
+ import org.springframework.security.oauth2.jwt.Jwt;
41
+ import reactor.core.publisher.Mono;
42
+ <%_ } _%>
30
43
  <%_ if (authenticationTypeOauth2) { _%>
31
44
  import java.time.Instant;
32
45
  import java.util.*;
@@ -35,11 +48,6 @@ import java.util.ArrayList;
35
48
  import java.util.Collection;
36
49
  <%_ } _%>
37
50
 
38
- import static org.assertj.core.api.Assertions.assertThat;
39
- <%_ if (authenticationTypeOauth2) { _%>
40
- import static org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames.ID_TOKEN;
41
- <%_ } _%>
42
-
43
51
  /**
44
52
  * Test class for the {@link SecurityUtils} utility class.
45
53
  */
@@ -52,7 +60,7 @@ class SecurityUtilsUnitTest {
52
60
  .block();
53
61
  assertThat(login).isEqualTo("admin");
54
62
  }
55
- <%_ if (authenticationTypeJwt) { _%>
63
+ <%_ if (authenticationTypeJwt) { _%>
56
64
 
57
65
  @Test
58
66
  void testgetCurrentUserJWT() {
@@ -61,7 +69,28 @@ class SecurityUtilsUnitTest {
61
69
  .block();
62
70
  assertThat(jwt).isEqualTo("token");
63
71
  }
72
+
73
+ <%_ if (user) { _%>
74
+ @Test
75
+ void testGetCurrentUserId() {
76
+ var userId = <%- user.primaryKey.javaSampleValues[0] %>;
77
+ var now = Instant.now();
78
+ var jwt = Jwt.withTokenValue("token")
79
+ .issuedAt(now)
80
+ .expiresAt(now.plusSeconds(60))
81
+ .claim(USER_ID_CLAIM, userId)
82
+ .header("Test", "test")
83
+ .build();
84
+
85
+ var authentication = new UsernamePasswordAuthenticationToken(jwt, "token");
86
+ var contextUserId = SecurityUtils.getCurrentUserId()
87
+ .contextWrite(ReactiveSecurityContextHolder.withAuthentication(authentication))
88
+ .block();
89
+
90
+ assertThat(contextUserId).isEqualTo(userId);
91
+ }
64
92
  <%_ } _%>
93
+ <%_ } _%>
65
94
 
66
95
  @Test
67
96
  void testIsAuthenticated() {
@@ -1,7 +1,8 @@
1
1
  package <%= packageName %>.security.jwt;
2
2
 
3
- import static <%= packageName %>.security.SecurityUtils.AUTHORITIES_KEY;
3
+ import static <%= packageName %>.security.SecurityUtils.AUTHORITIES_CLAIM;
4
4
  import static <%= packageName %>.security.SecurityUtils.JWT_ALGORITHM;
5
+ import static <%= packageName %>.security.AuthoritiesConstants.ADMIN;
5
6
 
6
7
  import com.nimbusds.jose.jwk.source.ImmutableSecret;
7
8
  import com.nimbusds.jose.util.Base64;
@@ -77,7 +78,7 @@ public class JwtAuthenticationTestUtils {
77
78
  .issuedAt(now)
78
79
  .expiresAt(now.plusSeconds(60))
79
80
  .subject(user)
80
- .claims(customClaim -> customClaim.put(AUTHORITIES_KEY, Collections.singletonList("ROLE_ADMIN")))
81
+ .claims(customClaim -> customClaim.put(AUTHORITIES_CLAIM, Collections.singletonList(ADMIN)))
81
82
  .build();
82
83
 
83
84
  JwsHeader jwsHeader = JwsHeader.with(JWT_ALGORITHM).build();
@@ -12,4 +12,4 @@ xmemcached-provider = { module = 'com.google.code.simple-spring-memcached:xmemca
12
12
 
13
13
  xmemcached = { module = 'com.googlecode.xmemcached:xmemcached', version = '2.4.8' }
14
14
 
15
- redisson = { module = 'org.redisson:redisson', version = '3.45.1' }
15
+ redisson = { module = 'org.redisson:redisson', version = '3.46.0' }
@@ -21,7 +21,7 @@ import { asWritingTask } from '../base-application/support/task-type-inference.j
21
21
  * Removes files that where generated in previous JHipster versions and therefore
22
22
  * need to be removed.
23
23
  */
24
- export default asWritingTask(function cleanupOldFilesTask({ application }) {
24
+ export default asWritingTask(async function cleanupOldFilesTask({ application, control }) {
25
25
  if (this.isJhipsterVersionLessThan('7.0.0-beta.0')) {
26
26
  this.removeFile(`${application.clientSrcDir}app/admin/audits/audits.component.ts`);
27
27
  this.removeFile(`${application.clientSrcDir}app/admin/audits/audits.service.ts`);
@@ -104,4 +104,10 @@ export default asWritingTask(function cleanupOldFilesTask({ application }) {
104
104
  this.removeFile('vite.config.ts');
105
105
  this.removeFile('vitest.config.ts');
106
106
  }
107
+ await control.cleanupFiles({
108
+ '8.10.1': [
109
+ [application.authenticationTypeJwt, `${application.clientSrcDir}app/account/login.service.ts`],
110
+ [application.authenticationTypeJwt, `${application.clientSrcDir}app/account/login.service.spec.ts`],
111
+ ],
112
+ });
107
113
  });
@@ -147,7 +147,7 @@ export const vueFiles = {
147
147
  'account/login-form/login-form.vue',
148
148
  'account/login-form/login-form.component.ts',
149
149
  'account/login-form/login-form.component.spec.ts',
150
- 'account/login.service.ts',
150
+ 'account/login-modal.ts',
151
151
  'router/account.ts',
152
152
  ],
153
153
  },
@@ -180,15 +180,10 @@ export const vueFiles = {
180
180
  {
181
181
  condition: generator => generator.authenticationTypeSession && generator.generateUserManagement,
182
182
  ...clientApplicationTemplatesBlock(),
183
- templates: [
184
- 'account/sessions/sessions.vue',
185
- 'account/sessions/sessions.component.ts',
186
- 'account/sessions/sessions.component.spec.ts',
187
- 'account/login.service.spec.ts',
188
- ],
183
+ templates: ['account/sessions/sessions.vue', 'account/sessions/sessions.component.ts', 'account/sessions/sessions.component.spec.ts'],
189
184
  },
190
185
  {
191
- condition: generator => generator.authenticationTypeOauth2,
186
+ condition: generator => generator.authenticationUsesCsrf,
192
187
  ...clientApplicationTemplatesBlock(),
193
188
  templates: ['account/login.service.ts', 'account/login.service.spec.ts'],
194
189
  },
@@ -6,24 +6,24 @@
6
6
  "@stomp/rx-stomp": "2.0.1",
7
7
  "@vuelidate/core": "2.0.3",
8
8
  "@vuelidate/validators": "2.0.4",
9
- "@vueuse/core": "13.0.0",
10
- "axios": "1.8.4",
9
+ "@vueuse/core": "13.1.0",
10
+ "axios": "1.9.0",
11
11
  "bootstrap": "4.6.2",
12
12
  "bootstrap-vue": "2.23.1",
13
13
  "bootswatch": "4.6.2",
14
14
  "deepmerge": "4.3.1",
15
15
  "js-cookie": "3.0.5",
16
- "pinia": "3.0.1",
16
+ "pinia": "3.0.2",
17
17
  "rxjs": "7.8.2",
18
18
  "sockjs-client": "1.6.1",
19
19
  "vue": "3.5.13",
20
- "vue-i18n": "11.1.2",
21
- "vue-router": "4.5.0"
20
+ "vue-i18n": "11.1.3",
21
+ "vue-router": "4.5.1"
22
22
  },
23
23
  "devDependencies": {
24
- "@eslint/js": "9.23.0",
25
- "@module-federation/enhanced": "0.11.2",
26
- "@pinia/testing": "1.0.0",
24
+ "@eslint/js": "9.26.0",
25
+ "@module-federation/enhanced": "0.13.1",
26
+ "@pinia/testing": "1.0.1",
27
27
  "@tsconfig/node18": "18.2.4",
28
28
  "@types/node": "20.11.25",
29
29
  "@types/sinon": "17.0.4",
@@ -36,12 +36,12 @@
36
36
  "copy-webpack-plugin": "13.0.0",
37
37
  "css-loader": "7.1.2",
38
38
  "css-minimizer-webpack-plugin": "7.0.2",
39
- "eslint": "9.23.0",
40
- "eslint-plugin-prettier": "5.2.5",
41
- "eslint-plugin-vue": "10.0.0",
39
+ "eslint": "9.26.0",
40
+ "eslint-plugin-prettier": "5.4.0",
41
+ "eslint-plugin-vue": "10.1.0",
42
42
  "flush-promises": "1.0.2",
43
43
  "folder-hash": "4.1.1",
44
- "happy-dom": "17.4.4",
44
+ "happy-dom": "17.4.6",
45
45
  "html-webpack-plugin": "5.6.3",
46
46
  "merge-jsons-webpack-plugin": "2.0.1",
47
47
  "mini-css-extract-plugin": "2.9.2",
@@ -55,16 +55,16 @@
55
55
  "sinon": "20.0.0",
56
56
  "terser-webpack-plugin": "5.3.14",
57
57
  "ts-loader": "9.5.2",
58
- "typescript": "5.8.2",
59
- "typescript-eslint": "8.28.0",
60
- "vite": "6.2.4",
61
- "vite-plugin-static-copy": "2.3.0",
62
- "vitest": "3.0.9",
63
- "vitest-sonar-reporter": "2.0.0",
58
+ "typescript": "5.8.3",
59
+ "typescript-eslint": "8.32.0",
60
+ "vite": "6.3.5",
61
+ "vite-plugin-static-copy": "2.3.1",
62
+ "vitest": "3.1.3",
63
+ "vitest-sonar-reporter": "2.0.1",
64
64
  "vue-loader": "17.4.2",
65
65
  "vue-style-loader": "4.1.3",
66
- "vue-tsc": "2.2.8",
67
- "webpack": "5.98.0",
66
+ "vue-tsc": "2.2.10",
67
+ "webpack": "5.99.7",
68
68
  "webpack-bundle-analyzer": "4.10.2",
69
69
  "webpack-cli": "6.0.1",
70
70
  "webpack-dev-server": "5.2.1",
@@ -5,7 +5,7 @@ import { type AccountStore } from '@/store';
5
5
  export default class AccountService {
6
6
  constructor(private store: AccountStore) {}
7
7
 
8
- public async update(): Promise<void> {
8
+ async update(): Promise<void> {
9
9
  if (!this.store.profilesLoaded) {
10
10
  await this.retrieveProfiles();
11
11
  this.store.setProfilesLoaded();
@@ -13,7 +13,7 @@ export default class AccountService {
13
13
  await this.loadAccount();
14
14
  }
15
15
 
16
- public async retrieveProfiles(): Promise<boolean> {
16
+ async retrieveProfiles(): Promise<boolean> {
17
17
  try {
18
18
  const res = await axios.get<any>('management/info');
19
19
  if (res.data && res.data.activeProfiles) {
@@ -21,12 +21,12 @@ export default class AccountService {
21
21
  this.store.setActiveProfiles(res.data.activeProfiles);
22
22
  }
23
23
  return true;
24
- } catch (error) {
24
+ } catch {
25
25
  return false;
26
26
  }
27
27
  }
28
28
 
29
- public async retrieveAccount(): Promise<boolean> {
29
+ async retrieveAccount(): Promise<boolean> {
30
30
  try {
31
31
  const response = await axios.get<any>('api/account');
32
32
  if (response.status === 200 && response.data?.login) {
@@ -34,7 +34,7 @@ export default class AccountService {
34
34
  this.store.setAuthentication(account);
35
35
  return true;
36
36
  }
37
- } catch (error) {
37
+ } catch {
38
38
  // Ignore error
39
39
  }
40
40
 
@@ -42,7 +42,7 @@ export default class AccountService {
42
42
  return false;
43
43
  }
44
44
 
45
- public async loadAccount() {
45
+ async loadAccount() {
46
46
  if (this.store.logon) {
47
47
  return this.store.logon;
48
48
  }
@@ -61,7 +61,7 @@ export default class AccountService {
61
61
  await promise;
62
62
  }
63
63
 
64
- public async hasAnyAuthorityAndCheckAuth(authorities: any): Promise<boolean> {
64
+ async hasAnyAuthorityAndCheckAuth(authorities: any): Promise<boolean> {
65
65
  if (typeof authorities === 'string') {
66
66
  authorities = [authorities];
67
67
  }
@@ -69,11 +69,11 @@ export default class AccountService {
69
69
  return this.checkAuthorities(authorities);
70
70
  }
71
71
 
72
- public get authenticated(): boolean {
72
+ get authenticated(): boolean {
73
73
  return this.store.authenticated;
74
74
  }
75
75
 
76
- public get userAuthorities(): string[] {
76
+ get userAuthorities(): string[] {
77
77
  return this.store.account?.authorities;
78
78
  }
79
79
 
@@ -1,10 +1,28 @@
1
+ <%#
2
+ Copyright 2013-2025 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
+ -%>
1
19
  import { vitest } from 'vitest';
2
- import { shallowMount, type ComponentMountingOptions } from '@vue/test-utils';
20
+ import { type ComponentMountingOptions, shallowMount } from '@vue/test-utils';
21
+ import { createTestingPinia } from '@pinia/testing';
3
22
  import axios from 'axios';
4
23
  import sinon from 'sinon';
5
24
 
6
25
  import Activate from './activate.vue';
7
- import LoginService from '../login.service';
8
26
 
9
27
  type ActivateComponentType = InstanceType<typeof Activate>;
10
28
 
@@ -21,16 +39,12 @@ const axiosStub = {
21
39
 
22
40
  describe('Activate Component', () => {
23
41
  let activate: ActivateComponentType;
24
- let loginService: LoginService;
25
42
  let mountOptions: ComponentMountingOptions<ActivateComponentType>;
26
43
 
27
44
  beforeEach(() => {
28
- loginService = new LoginService({ emit: vitest.fn() });
29
45
  mountOptions = {
30
46
  global: {
31
- provide: {
32
- loginService,
33
- },
47
+ plugins: [createTestingPinia()],
34
48
  },
35
49
  };
36
50
  });