generator-jhipster 6.10.1 → 6.10.5

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.
package/README.md CHANGED
@@ -12,7 +12,7 @@ Please read our [guidelines](/CONTRIBUTING.md#submitting-an-issue) before submit
12
12
 
13
13
  ## Contributing
14
14
 
15
- We are honoured by any contributions you may have small or large. Please refer to our [contribution guidelines and instructions document](https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md) for any information about contributing to the project.
15
+ We are honoured by any contributions you may have small or large. Please refer to our [contribution guidelines and instructions document](https://github.com/jhipster/generator-jhipster/blob/main/CONTRIBUTING.md) for any information about contributing to the project.
16
16
 
17
17
  ## Sponsors
18
18
 
@@ -35,119 +35,27 @@ Support this project by becoming a sponsor! [Become a sponsor](https://opencolle
35
35
  <img width="200em" src="https://www.jhipster.tech/images/open-collective/octoconsulting.png">
36
36
  </a>
37
37
  </td>
38
- </tr>
39
- </tbody>
40
- </table>
41
-
42
- ### Bronze sponsors
43
-
44
- <table>
45
- <tbody>
46
- <tr>
47
- <td align="center" valign="middle">
48
- <a href="https://forsyslab.com/" target="_blank">
49
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/forsyslab.png">
50
- </a>
51
- </td>
52
- <td align="center" valign="middle">
53
- <a href="https://www.cuba-platform.com/" target="_blank">
54
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/cubaplatform.png">
55
- </a>
56
- </td>
57
- <td align="center" valign="middle">
58
- <a href="https://www.codefirst.co.uk" target="_blank">
59
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/codefirst.png">
60
- </a>
61
- </td>
62
38
  <td align="center" valign="middle">
63
- <a href="https://blokt.com/" target="_blank">
64
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/blokt.png">
65
- </a>
66
- </td>
67
- <td align="center" valign="middle">
68
- <a href="https://clay.global/" target="_blank">
69
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/clay.png">
70
- </a>
71
- </td>
72
- </tr>
73
- <tr>
74
- <td align="center" valign="middle">
75
- <a href="https://uxplanet.org/" target="_blank">
76
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/uxplanet.png">
77
- </a>
78
- </td>
79
- <td align="center" valign="middle">
80
- <a href="https://opencollective.com/top-web-design-agencies" target="_blank">
81
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/top-web-design-agencies.png">
82
- </a>
83
- </td>
84
- <td align="center" valign="middle">
85
- <a href="https://fair-laan.se/" target="_blank">
86
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/fair-laan.png">
87
- </a>
88
- </td>
89
- <td align="center" valign="middle">
90
- <a href="https://superkredit.net" target="_blank">
91
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/superkredit.png">
92
- </a>
93
- </td>
94
- <td align="center" valign="middle">
95
- <a href="https://matchbanker.pl/" target="_blank">
96
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/matchbanker.png">
97
- </a>
98
- </td>
99
- </tr>
100
- <tr>
101
- <td align="center" valign="middle">
102
- <a href="https://matchbanker.no/" target="_blank">
103
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/matchbanker.png">
104
- </a>
105
- </td>
106
- <td align="center" valign="middle">
107
- <a href="https://www.banksecrets.eu/" target="_blank">
108
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/banksecrets.png">
109
- </a>
110
- </td>
111
- <td align="center" valign="middle">
112
- <a href="https://writersperhour.com/urgent-essay-writing-service" target="_blank">
113
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/writersperhour.png">
114
- </a>
115
- </td>
116
- <td align="center" valign="middle">
117
- <a href="https://www.minitool.com/" target="_blank">
118
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/minitool.png">
119
- </a>
120
- </td>
121
- <td align="center" valign="middle">
122
- <a href="https://unscramblex.com/" target="_blank">
123
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/unscramblex.png">
124
- </a>
125
- </td>
126
- </tr>
127
- <tr>
128
- <td align="center" valign="middle">
129
- <a href="https://edubirdie.com/" target="_blank">
130
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/edubirdie.png">
131
- </a>
132
- </td>
133
- <td align="center" valign="middle">
134
- <a href="https://www.zadluzenia.com/" target="_blank">
135
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/zadluzenia.png">
136
- </a>
137
- </td>
138
- <td align="center" valign="middle">
139
- <a href="https://opencollective.com/jim-van-dam" target="_blank">
140
- <img width="50em" src="https://www.jhipster.tech/images/open-collective/jim-van-dam.png">
39
+ <a href="https://dev.entando.org/jhipster" target="_blank">
40
+ <img width="200em" src="https://www.jhipster.tech/images/open-collective/entandoe.png">
141
41
  </a>
142
42
  </td>
143
43
  </tr>
144
44
  </tbody>
145
45
  </table>
146
46
 
47
+ ### Bronze sponsors
48
+
49
+ [![BronzeSponsors][bronze-sponsors-image]][bronze-sponsors-url]
50
+
51
+ ### Backers
52
+
147
53
  **Thank you to all our backers!**
148
54
 
149
55
  [![Backers][backers-image]][backers-url]
150
56
 
57
+ <object data="https://opencollective.com/generator-jhipster/tiers/backer.svg?avatarHeight=40&width=890&button=false" type="image/svg+xml"></object>
58
+
151
59
  ## Azure Builds
152
60
 
153
61
  Additional builds at [hipster-labs/jhipster-daily-builds](https://github.com/hipster-labs/jhipster-daily-builds)
@@ -164,14 +72,11 @@ Additional builds at [hipster-labs/jhipster-daily-builds](https://github.com/hip
164
72
  | [![React Gradle NoSQL][github-react-gradle-nosql]][github-actions] |
165
73
  | [![Elasticsearch][github-elasticsearch]][github-actions] |
166
74
  | [![Monolith OAuth2][github-monolith-oauth2]][github-actions] |
167
- | [![Yarn][github-yarn]][github-actions] |
168
75
  | [![No Database][github-no-database]][github-actions] |
169
76
  | [![Microservices JWT][github-ms-jwt]][github-actions] |
170
77
  | [![Microservices OAuth2][github-ms-oauth2]][github-actions] |
171
78
  | [![Microservices UAA][github-ms-uaa]][github-actions] |
172
79
  | [![Docker Image][github-docker-image]][github-actions] |
173
- | [![Neo4j][github-neo4j]][github-actions] |
174
- | [![Couchbase][github-couchbase]][github-actions] |
175
80
  | [![Official Windows][github-official-windows]][github-actions] |
176
81
 
177
82
  ## Analysis of the sample JHipster project
@@ -190,32 +95,31 @@ Additional builds at [hipster-labs/jhipster-daily-builds](https://github.com/hip
190
95
  [github-react-gradle-nosql]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/React%20Gradle%20NoSQL/badge.svg
191
96
  [github-elasticsearch]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Elasticsearch/badge.svg
192
97
  [github-monolith-oauth2]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Monolith%20OAuth2/badge.svg
193
- [github-yarn]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Yarn/badge.svg
194
98
  [github-no-database]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/No%20Database/badge.svg
195
99
  [github-ms-jwt]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Microservices%20JWT/badge.svg
196
100
  [github-ms-oauth2]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Microservices%20OAuth2/badge.svg
197
101
  [github-ms-uaa]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Microservices%20UAA/badge.svg
198
102
  [github-docker-image]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Docker%20Image/badge.svg
199
- [github-neo4j]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Neo4j/badge.svg
200
- [github-couchbase]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Couchbase/badge.svg
201
103
  [sonar-url]: https://sonarcloud.io/dashboard?id=jhipster-sample-application
202
104
  [sonar-quality-gate]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=alert_status
203
105
  [sonar-coverage]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=coverage
204
106
  [sonar-bugs]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=bugs
205
107
  [sonar-vulnerabilities]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=vulnerabilities
206
- [jhipster-image]: https://raw.githubusercontent.com/jhipster/jhipster-artwork/master/logos/JHipster%20RGB-small100x25px.png
108
+ [jhipster-image]: https://raw.githubusercontent.com/jhipster/jhipster-artwork/main/logos/JHipster%20RGB-small100x25px.png
207
109
  [jhipster-url]: https://www.jhipster.tech/
208
110
  [npm-image]: https://badge.fury.io/js/generator-jhipster.svg
209
111
  [npm-url]: https://npmjs.org/package/generator-jhipster
210
- [azure-devops-image]: https://dev.azure.com/jhipster/generator-jhipster/_apis/build/status/jhipster.generator-jhipster?branchName=master
112
+ [azure-devops-image]: https://dev.azure.com/jhipster/generator-jhipster/_apis/build/status/jhipster.generator-jhipster?branchName=main
211
113
  [azure-devops-url-main]: https://dev.azure.com/jhipster/generator-jhipster/_build
212
114
  [github-actions-generator-image]: https://github.com/jhipster/generator-jhipster/workflows/Generator/badge.svg
213
115
  [github-actions-angular-image]: https://github.com/jhipster/generator-jhipster/workflows/Angular/badge.svg
214
116
  [github-actions-react-image]: https://github.com/jhipster/generator-jhipster/workflows/React/badge.svg
215
117
  [github-actions-webflux-image]: https://github.com/jhipster/generator-jhipster/workflows/Webflux/badge.svg
216
118
  [github-actions-url]: https://github.com/jhipster/generator-jhipster/actions
217
- [backers-image]: https://opencollective.com/generator-jhipster/tiers/backer.svg?avatarHeight=40&width=890
119
+ [backers-image]: https://opencollective.com/generator-jhipster/tiers/backer.svg?avatarHeight=70&width=890
218
120
  [backers-url]: https://opencollective.com/generator-jhipster
121
+ [bronze-sponsors-image]: https://opencollective.com/generator-jhipster/tiers/bronze-sponsor.svg?avatarHeight=120&width=890
122
+ [bronze-sponsors-url]: https://opencollective.com/generator-jhipster
219
123
  [issue-template]: https://github.com/jhipster/generator-jhipster/issues/new?template=BUG_REPORT.md
220
124
  [feature-template]: https://github.com/jhipster/generator-jhipster/issues/new?template=FEATURE_REQUEST.md
221
125
  [npmcharts-image]: https://img.shields.io/npm/dm/generator-jhipster.svg?label=Downloads&style=flat
package/cli/jdl.js CHANGED
@@ -83,7 +83,7 @@ module.exports = (args, options = {}, env, forkProcess) => {
83
83
  if (options.skipSampleRepository) {
84
84
  return Promise.reject(new Error(`Could not find ${filename}, make sure the path is correct.`));
85
85
  }
86
- url = new URL(filename, 'https://raw.githubusercontent.com/jhipster/jdl-samples/master/').toString();
86
+ url = new URL(filename, 'https://raw.githubusercontent.com/jhipster/jdl-samples/main/').toString();
87
87
  filename = path.basename(filename);
88
88
  }
89
89
  return downloadFile(url, filename);
@@ -46,7 +46,7 @@
46
46
  "bootswatch": "4.5.0",
47
47
  <%_ } _%>
48
48
  "moment": "2.27.0",
49
- "ng-jhipster": "0.14.0",
49
+ "ng-jhipster": "0.15.0",
50
50
  "ngx-cookie-service": "3.0.4",
51
51
  "ngx-infinite-scroll": "9.0.0",
52
52
  "ngx-webstorage": "5.0.0",
@@ -73,7 +73,7 @@ limitations under the License.
73
73
  <%_ if (protractorTests) { _%>
74
74
  "@types/chai": "4.2.11",
75
75
  <%_ } _%>
76
- "@types/enzyme": "3.10.5",
76
+ "@types/enzyme": "3.10.7",
77
77
  "@types/jest": "25.2.1",
78
78
  "@types/lodash": "4.14.150",
79
79
  <%_ if (protractorTests) { _%>
@@ -88,7 +88,7 @@ function checkImageExist(opts = { cwd: './', appConfig: null }) {
88
88
  this.dockerBuildCommand = './mvnw -ntp -Pprod verify jib:dockerBuild';
89
89
  } else {
90
90
  imagePath = this.destinationPath(`${opts.cwd + opts.cwd}/build/docker`);
91
- this.dockerBuildCommand = './gradlew bootWar -Pprod jibDockerBuild';
91
+ this.dockerBuildCommand = './gradlew bootJar -Pprod jibDockerBuild';
92
92
  }
93
93
 
94
94
  if (shelljs.ls(imagePath).length === 0) {
@@ -237,7 +237,7 @@ _%>
237
237
  this.dataUtils.openFile(contentType, base64String);
238
238
  }
239
239
 
240
- setFileData(event: Event, field: string, isImage: boolean): void {
240
+ setFileData(event: any, field: string, isImage: boolean): void {
241
241
  this.dataUtils.loadFileToForm(event, this.editForm, field, isImage).subscribe(null, (err: JhiFileLoadError) => {
242
242
  this.eventManager.broadcast(
243
243
  new JhiEventWithContent<AlertError>('<%= angularAppName %>.error', { <% if (enableTranslation) { %>...err, key: 'error.file.' + err.key<% } else { %>message: err.message<% } %> })
@@ -31,7 +31,7 @@ const GRADLE_VERSION = '6.5';
31
31
  const JIB_VERSION = '2.4.0';
32
32
 
33
33
  // Libraries version
34
- const JHIPSTER_DEPENDENCIES_VERSION = '3.9.0';
34
+ const JHIPSTER_DEPENDENCIES_VERSION = '3.9.1';
35
35
  // The spring-boot version should match the one managed by https://mvnrepository.com/artifact/io.github.jhipster/jhipster-dependencies/JHIPSTER_DEPENDENCIES_VERSION
36
36
  const SPRING_BOOT_VERSION = '2.2.7.RELEASE';
37
37
  const LIQUIBASE_VERSION = '3.9.0';
@@ -77,7 +77,7 @@ const DOCKER_JHIPSTER_IMPORT_DASHBOARDS = 'jhipster/jhipster-import-dashboards:v
77
77
  const DOCKER_JHIPSTER_ZIPKIN = 'jhipster/jhipster-zipkin:v4.1.0';
78
78
  const DOCKER_TRAEFIK = 'traefik:1.7.24'; // waiting for https://github.com/jhipster/generator-jhipster/issues/11198
79
79
  const DOCKER_CONSUL = 'consul:1.7.3';
80
- const DOCKER_CONSUL_CONFIG_LOADER = 'jhipster/consul-config-loader:v0.3.1';
80
+ const DOCKER_CONSUL_CONFIG_LOADER = 'jhipster/consul-config-loader:v0.4.1';
81
81
  const DOCKER_PROMETHEUS = 'prom/prometheus:v2.18.1';
82
82
  const DOCKER_PROMETHEUS_ALERTMANAGER = 'prom/alertmanager:v0.20.0';
83
83
  const DOCKER_GRAFANA = 'grafana/grafana:7.0.1';
@@ -18,7 +18,7 @@
18
18
  */
19
19
  const path = require('path');
20
20
  const shelljs = require('shelljs');
21
- const request = require('sync-request');
21
+ const request = require('then-request');
22
22
 
23
23
  module.exports = {
24
24
  askActionType,
@@ -26,11 +26,11 @@ module.exports = {
26
26
  askGenerationInfos,
27
27
  };
28
28
 
29
- function fetchSwaggerResources(input) {
29
+ async function fetchSwaggerResources(input) {
30
30
  const availableDocs = [];
31
31
 
32
32
  const baseUrl = input.replace(/\/$/, '');
33
- const swaggerResources = request('GET', `${baseUrl}/swagger-resources`, {
33
+ const swaggerResources = await request('GET', `${baseUrl}/swagger-resources`, {
34
34
  // This header is needed to use the custom /swagger-resources controller
35
35
  // and not the default one that has only the gateway's swagger resource
36
36
  headers: { Accept: 'application/json, text/javascript;' },
@@ -49,11 +49,9 @@ function fetchSwaggerResources(input) {
49
49
 
50
50
  function askActionType() {
51
51
  if (this.options.regen) {
52
- return;
52
+ return undefined;
53
53
  }
54
54
 
55
- const done = this.async();
56
-
57
55
  const hasExistingApis = Object.keys(this.openApiClients).length !== 0;
58
56
 
59
57
  const actionList = [
@@ -95,9 +93,9 @@ function askActionType() {
95
93
  name: 'jhipsterEndpoint',
96
94
  message: 'Enter the URL of the running Jhipster instance',
97
95
  default: 'http://localhost:8080',
98
- validate: input => {
96
+ validate: async input => {
99
97
  try {
100
- const availableDocs = fetchSwaggerResources(input);
98
+ const availableDocs = await fetchSwaggerResources(input);
101
99
 
102
100
  if (availableDocs.length === 0) {
103
101
  return `No live doc found at ${input}`;
@@ -135,10 +133,10 @@ function askActionType() {
135
133
  message: 'Where is your Swagger/OpenAPI spec (URL or path) ?',
136
134
  default: 'http://petstore.swagger.io/v2/swagger.json',
137
135
  store: true,
138
- validate: input => {
136
+ validate: async input => {
139
137
  try {
140
138
  if (/^((http|https):\/\/)/.test(input)) {
141
- request('GET', `${input}`, {
139
+ await request('GET', `${input}`, {
142
140
  // headers: { Accept: 'application/json, text/javascript;' }
143
141
  });
144
142
  } else if (!shelljs.test('-f', input)) {
@@ -152,15 +150,7 @@ function askActionType() {
152
150
  },
153
151
  ];
154
152
 
155
- this.prompt(prompts).then(props => {
156
- if (props.jhipsterEndpoint !== undefined) {
157
- props.availableDocs = fetchSwaggerResources(props.jhipsterEndpoint);
158
- } else if (props.jhipsterDirectory !== undefined) {
159
- props.inputSpec = `${props.jhipsterDirectory}/src/main/resources/swagger/api.yml`;
160
- } else if (props.customEndpoint !== undefined) {
161
- props.inputSpec = props.customEndpoint;
162
- }
163
-
153
+ return this.prompt(prompts).then(props => {
164
154
  if (newClient) {
165
155
  props.action = 'new';
166
156
  }
@@ -168,15 +158,24 @@ function askActionType() {
168
158
  props.generatorName = this.config.get('reactive') ? 'java' : 'spring';
169
159
 
170
160
  this.props = props;
171
- done();
161
+ if (props.jhipsterEndpoint !== undefined) {
162
+ return fetchSwaggerResources(props.jhipsterEndpoint).then(availableDocs => {
163
+ props.availableDocs = availableDocs;
164
+ });
165
+ }
166
+ if (props.jhipsterDirectory !== undefined) {
167
+ props.inputSpec = `${props.jhipsterDirectory}/src/main/resources/swagger/api.yml`;
168
+ } else if (props.customEndpoint !== undefined) {
169
+ props.inputSpec = props.customEndpoint;
170
+ }
171
+ return undefined;
172
172
  });
173
173
  }
174
174
 
175
175
  function askExistingAvailableDocs() {
176
176
  if (this.options.regen) {
177
- return;
177
+ return undefined;
178
178
  }
179
- const done = this.async();
180
179
 
181
180
  const prompts = [
182
181
  {
@@ -188,21 +187,19 @@ function askExistingAvailableDocs() {
188
187
  },
189
188
  ];
190
189
 
191
- this.prompt(prompts).then(props => {
190
+ return this.prompt(prompts).then(props => {
192
191
  if (props.availableDoc !== undefined) {
193
192
  this.props.inputSpec = props.availableDoc.url;
194
193
  this.props.cliName = props.availableDoc.name === 'default' ? 'apidocs' : props.availableDoc.name; // "default" cannot be used as it's a keyword in java
195
194
  }
196
- done();
197
195
  });
198
196
  }
199
197
 
200
198
  function askGenerationInfos() {
201
199
  if (this.options.regen) {
202
- return;
200
+ return undefined;
203
201
  }
204
202
 
205
- const done = this.async();
206
203
  const prompts = [
207
204
  {
208
205
  when:
@@ -255,12 +252,11 @@ function askGenerationInfos() {
255
252
  },
256
253
  ];
257
254
 
258
- this.prompt(prompts).then(props => {
255
+ return this.prompt(prompts).then(props => {
259
256
  if (props.cliName !== undefined) {
260
257
  this.props.cliName = props.cliName;
261
258
  }
262
259
  this.props.saveConfig = props.saveConfig;
263
260
  this.props.selected = props.selected;
264
- done();
265
261
  });
266
262
  }
@@ -31,6 +31,8 @@ import <%= packageName %>.repository.search.UserSearchRepository;
31
31
  import <%= packageName %>.security.AuthoritiesConstants;
32
32
  <%_ if (authenticationType !== 'oauth2') { _%>
33
33
  import <%= packageName %>.service.MailService;
34
+ import org.springframework.data.domain.Sort;
35
+ import java.util.Collections;
34
36
  <%_ } _%>
35
37
  import <%= packageName %>.service.UserService;
36
38
  import <%= packageName %>.service.dto.<%= asDto('User') %>;
@@ -90,6 +92,7 @@ import java.util.*;
90
92
  <%_ if (reactive) { _%>
91
93
  import java.util.ArrayList;
92
94
  import java.util.List;
95
+ import java.util.Arrays;
93
96
  <%_ } _%>
94
97
  <%_ if (searchEngine === 'elasticsearch' && !reactive) { _%>
95
98
  import java.util.stream.Collectors;
@@ -125,6 +128,9 @@ import static org.elasticsearch.index.query.QueryBuilders.*;
125
128
  @RestController
126
129
  @RequestMapping("/api")
127
130
  public class UserResource {
131
+ <%_ if (authenticationType !== 'oauth2') { _%>
132
+ private static final List<String> ALLOWED_ORDERED_PROPERTIES = Collections.unmodifiableList(Arrays.asList("id", "login", "firstName", "lastName", "email", "activated", "langKey"));
133
+ <%_ } _%>
128
134
 
129
135
  private final Logger log = LoggerFactory.getLogger(UserResource.class);
130
136
 
@@ -286,11 +292,23 @@ public class UserResource {
286
292
  <%_ if (databaseType === 'sql' || databaseType === 'mongodb' || databaseType === 'neo4j' || databaseType === 'couchbase') { _%>
287
293
  <%_ if (!reactive) { _%>
288
294
  public ResponseEntity<List<<%= asDto('User') %>>> getAllUsers(Pageable pageable) {
295
+ <%_ if (authenticationType !== 'oauth2') { _%>
296
+ if (!onlyContainsAllowedProperties(pageable)) {
297
+ return ResponseEntity.badRequest().build();
298
+ }
299
+ <%_ } _%>
300
+
289
301
  final Page<<%= asDto('User') %>> page = userService.getAllManagedUsers(pageable);
290
302
  HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
291
303
  return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
292
304
  <%_ } else { _%>
293
305
  public Mono<ResponseEntity<Flux<<%= asDto('User') %>>>> getAllUsers(ServerHttpRequest request, Pageable pageable) {
306
+ <%_ if (authenticationType !== 'oauth2') { _%>
307
+ if (!onlyContainsAllowedProperties(pageable)) {
308
+ return Mono.just(ResponseEntity.badRequest().build());
309
+ }
310
+ <%_ } _%>
311
+
294
312
  return userService.countManagedUsers()
295
313
  .map(total -> new PageImpl<>(new ArrayList<>(), pageable, total))
296
314
  .map(page -> PaginationUtil.generatePaginationHttpHeaders(UriComponentsBuilder.fromHttpRequest(request), page))
@@ -298,6 +316,12 @@ public class UserResource {
298
316
  <%_ } _%>
299
317
  }
300
318
 
319
+ <%_ if (authenticationType !== 'oauth2') { _%>
320
+ private boolean onlyContainsAllowedProperties(Pageable pageable) {
321
+ return pageable.getSort().stream().map(Sort.Order::getProperty).allMatch(ALLOWED_ORDERED_PROPERTIES::contains);
322
+ }
323
+ <%_ } _%>
324
+
301
325
  /**
302
326
  * Gets a list of all roles.
303
327
  * @return a string list of all roles.
@@ -18,13 +18,19 @@
18
18
  -%>
19
19
  package <%= packageName %>.web.rest.errors;
20
20
 
21
+ import io.github.jhipster.config.JHipsterConstants;
21
22
  import io.github.jhipster.web.util.HeaderUtil;
22
23
 
24
+ import org.apache.commons.lang3.StringUtils;
23
25
  import org.springframework.beans.factory.annotation.Value;
24
26
  <%_ if (databaseType !== 'no' && databaseType !== 'cassandra') { _%>
25
27
  import org.springframework.dao.ConcurrencyFailureException;
26
28
  <%_ } _%>
29
+ <%_ if (databaseType !== 'no') { _%>
30
+ import org.springframework.dao.DataAccessException;
31
+ <%_ } _%>
27
32
  import org.springframework.http.ResponseEntity;
33
+ import org.springframework.http.converter.HttpMessageConversionException;
28
34
  <%_ if (reactive && databaseType === 'sql') { _%>
29
35
  import org.springframework.stereotype.Component;
30
36
  <%_ } _%>
@@ -41,10 +47,12 @@ import org.springframework.web.server.ServerWebExchange;
41
47
  <%_ if (!reactive) { _%>
42
48
  import org.springframework.web.context.request.NativeWebRequest;
43
49
  <%_ } _%>
50
+ import org.springframework.core.env.Environment;
44
51
  import org.zalando.problem.DefaultProblem;
45
52
  import org.zalando.problem.Problem;
46
53
  import org.zalando.problem.ProblemBuilder;
47
54
  import org.zalando.problem.Status;
55
+ import org.zalando.problem.StatusType;
48
56
  import org.zalando.problem.spring.web<% if (reactive) { %>flux<% } %>.advice.ProblemHandling;
49
57
  import org.zalando.problem.spring.web<% if (reactive) { %>flux<% } %>.advice.security.SecurityAdviceTrait;
50
58
  import org.zalando.problem.violations.ConstraintViolationProblem;
@@ -57,7 +65,11 @@ import javax.annotation.Nullable;
57
65
  <%_ if (!reactive) { _%>
58
66
  import javax.servlet.http.HttpServletRequest;
59
67
  <%_ } _%>
68
+ import java.net.URI;
69
+ import java.util.Arrays;
70
+ import java.util.Collection;
60
71
  import java.util.List;
72
+ import java.util.Optional;
61
73
  import java.util.stream.Collectors;
62
74
 
63
75
  /**
@@ -89,6 +101,12 @@ _%>
89
101
  @Value("${jhipster.clientApp.name}")
90
102
  private String applicationName;
91
103
 
104
+ private final Environment env;
105
+
106
+ public ExceptionTranslator(Environment env) {
107
+ this.env = env;
108
+ }
109
+
92
110
  /**
93
111
  * Post-process the Problem payload to add the message key for the front-end if needed.
94
112
  */
@@ -187,4 +205,64 @@ _%>
187
205
  return create(ex, problem, request);
188
206
  }
189
207
  <%_ } _%>
190
- }
208
+
209
+ @Override
210
+ public ProblemBuilder prepare(final Throwable throwable, final StatusType status, final URI type) {
211
+
212
+ Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
213
+
214
+ if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
215
+ if (throwable instanceof HttpMessageConversionException) {
216
+ return Problem.builder()
217
+ .withType(type)
218
+ .withTitle(status.getReasonPhrase())
219
+ .withStatus(status)
220
+ .withDetail("Unable to convert http message")
221
+ .withCause(Optional.ofNullable(throwable.getCause())
222
+ .filter(cause -> isCausalChainsEnabled())
223
+ .map(this::toProblem)
224
+ .orElse(null));
225
+ }
226
+ <%_ if (databaseType !== 'no') { _%>
227
+ if (throwable instanceof DataAccessException) {
228
+ return Problem.builder()
229
+ .withType(type)
230
+ .withTitle(status.getReasonPhrase())
231
+ .withStatus(status)
232
+ .withDetail("Failure during data access")
233
+ .withCause(Optional.ofNullable(throwable.getCause())
234
+ .filter(cause -> isCausalChainsEnabled())
235
+ .map(this::toProblem)
236
+ .orElse(null));
237
+ }
238
+ <%_ } _%>
239
+ if (containsPackageName(throwable.getMessage())) {
240
+ return Problem.builder()
241
+ .withType(type)
242
+ .withTitle(status.getReasonPhrase())
243
+ .withStatus(status)
244
+ .withDetail("Unexpected runtime exception")
245
+ .withCause(Optional.ofNullable(throwable.getCause())
246
+ .filter(cause -> isCausalChainsEnabled())
247
+ .map(this::toProblem)
248
+ .orElse(null));
249
+ }
250
+ }
251
+
252
+ return Problem.builder()
253
+ .withType(type)
254
+ .withTitle(status.getReasonPhrase())
255
+ .withStatus(status)
256
+ .withDetail(throwable.getMessage())
257
+ .withCause(Optional.ofNullable(throwable.getCause())
258
+ .filter(cause -> isCausalChainsEnabled())
259
+ .map(this::toProblem)
260
+ .orElse(null));
261
+ }
262
+
263
+ private boolean containsPackageName(String message) {
264
+
265
+ // This list is for sure not complete
266
+ return StringUtils.containsAny(message, "org.", "java.", "net.", "javax.", "com.", "io.", "de.", "<%= packageName %>");
267
+ }
268
+ }
@@ -16,13 +16,10 @@
16
16
  See the License for the specific language governing permissions and
17
17
  limitations under the License.
18
18
  -%>
19
-
20
19
  package <%= packageName %>;
21
20
 
22
21
  import org.junit.jupiter.api.extension.BeforeAllCallback;
23
22
  import org.junit.jupiter.api.extension.ExtensionContext;
24
- import org.springframework.test.context.DynamicPropertyRegistry;
25
- import org.springframework.test.context.DynamicPropertySource;
26
23
  import org.testcontainers.containers.GenericContainer;
27
24
 
28
25
  import java.util.concurrent.atomic.AtomicBoolean;
@@ -31,18 +28,16 @@ public class RedisTestContainerExtension implements BeforeAllCallback {
31
28
 
32
29
  private static AtomicBoolean started = new AtomicBoolean(false);
33
30
 
34
- private static GenericContainer redis;
35
-
36
- @DynamicPropertySource
37
- static void redisProperties(DynamicPropertyRegistry registry) {
38
- registry.add("jhipster.cache.redis.server", () -> "redis://" + redis.getContainerIpAddress() + ":" + redis.getMappedPort(6379));
39
- }
31
+ private static GenericContainer redis = new GenericContainer("<%= DOCKER_REDIS %>").withExposedPorts(6379);
40
32
 
41
33
  @Override
42
34
  public void beforeAll(ExtensionContext extensionContext) throws Exception {
43
35
  if (!started.get()) {
44
- redis = new GenericContainer("<%= DOCKER_REDIS %>").withExposedPorts(6379);
45
36
  redis.start();
37
+ System.setProperty(
38
+ "jhipster.cache.redis.server",
39
+ "redis://" + redis.getContainerIpAddress() + ":" + redis.getMappedPort(6379)
40
+ );
46
41
  started.set(true);
47
42
  }
48
43
  }
@@ -35,7 +35,7 @@ import <%= packageName %>.service.UserService;
35
35
 
36
36
  import org.junit.jupiter.api.BeforeEach;
37
37
  import org.junit.jupiter.api.Test;
38
- <%_ if (databaseType === 'neo4j') { _%>
38
+ <%_ if (databaseType === 'neo4j' || cacheProvider === 'redis') { _%>
39
39
  import org.junit.jupiter.api.extension.ExtendWith;
40
40
  <%_ } _%>
41
41
  import org.springframework.beans.factory.annotation.Autowired;
@@ -504,7 +504,7 @@ public class UserResourceIT <% if (databaseType === 'cassandra') { %>extends Abs
504
504
  <%_ } _%>
505
505
  .andExpect(jsonPath("$.[*].langKey").value(hasItem(DEFAULT_LANGKEY)));
506
506
  <%_ } else { _%>
507
- <%= asDto('User') %> foundUser = webTestClient.get().uri("/api/users?sort=createdDate,DESC")
507
+ <%= asDto('User') %> foundUser = webTestClient.get().uri("/api/users?sort=id,DESC")
508
508
  .accept(MediaType.APPLICATION_JSON)
509
509
  .exchange()
510
510
  .expectStatus().isOk()
@@ -522,6 +522,29 @@ public class UserResourceIT <% if (databaseType === 'cassandra') { %>extends Abs
522
522
  <%_ } _%>
523
523
  }
524
524
 
525
+ <%_ if (databaseType === 'sql' && authenticationType !== 'oauth2') { _%>
526
+ @Test
527
+ <%_ if (!reactive) { _%>
528
+ @Transactional
529
+ <%_ } _%>
530
+ void getAllUsersSortedByParameters() throws Exception {
531
+ // Initialize the database
532
+ userRepository.<% if (reactive) { %>save<% } else { %>saveAndFlush<% } %>(user)<% if (reactive) { %>.block()<% } %>;
533
+
534
+ <%_ if (!reactive) { _%>
535
+ restUserMockMvc.perform(get("/api/users?sort=resetKey,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest());
536
+ restUserMockMvc.perform(get("/api/users?sort=password,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest());
537
+ restUserMockMvc.perform(get("/api/users?sort=resetKey,id,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest());
538
+ restUserMockMvc.perform(get("/api/users?sort=id,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
539
+ <%_ } else { _%>
540
+ webTestClient.get().uri("/api/users?sort=resetKey,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isBadRequest();
541
+ webTestClient.get().uri("/api/users?sort=password,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isBadRequest();
542
+ webTestClient.get().uri("/api/users?sort=resetKey,id,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isBadRequest();
543
+ webTestClient.get().uri("/api/users?sort=id,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk();
544
+ <%_ } _%>
545
+ }
546
+ <%_ } _%>
547
+
525
548
  @Test
526
549
  <%_ if (databaseType === 'sql' && !reactive) { _%>
527
550
  @Transactional
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-jhipster",
3
- "version": "6.10.1",
3
+ "version": "6.10.5",
4
4
  "description": "Spring Boot + Angular/React in one handy generator",
5
5
  "files": [
6
6
  "cli",
@@ -73,13 +73,13 @@
73
73
  "os-locale": "5.0.0",
74
74
  "parse-gitignore": "1.0.1",
75
75
  "pluralize": "8.0.0",
76
- "prettier": "2.0.5",
77
- "prettier-plugin-java": "0.8.0",
76
+ "prettier": "2.1.2",
77
+ "prettier-plugin-java": "0.8.2",
78
78
  "progress": "2.0.3",
79
79
  "randexp": "0.5.3",
80
80
  "semver": "7.3.2",
81
81
  "shelljs": "0.8.4",
82
- "sync-request": "6.1.0",
82
+ "then-request": "6.0.2",
83
83
  "tabtab": "2.2.2",
84
84
  "test": "^0.6.0",
85
85
  "through2": "3.0.2",