diff --git a/application/pom.xml b/application/pom.xml
index 3378d52459..fd90d00d34 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -250,8 +250,8 @@
grpc-stub
- io.springfox
- springfox-swagger2
+ org.thingsboard
+ springfox-boot-starter
com.sun.winsw
@@ -319,10 +319,6 @@
org.javadelight
delight-nashorn-sandbox
-
- io.springfox.ui
- springfox-swagger-ui-rfc6570
-
org.passay
passay
diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java
index 4d15894387..8d39cf65ce 100644
--- a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java
+++ b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java
@@ -20,13 +20,11 @@ import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Arrays;
@SpringBootConfiguration
@EnableAsync
-@EnableSwagger2
@EnableScheduling
@ComponentScan({"org.thingsboard.server"})
public class ThingsboardServerApplication {
diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
index 50532c435e..ba3771616a 100644
--- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
@@ -18,27 +18,60 @@ package org.thingsboard.server.config;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeResolver;
import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.base.Predicate;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
import org.thingsboard.server.common.data.security.Authority;
+import org.thingsboard.server.exception.ThingsboardErrorResponse;
+import org.thingsboard.server.service.security.auth.rest.LoginRequest;
+import org.thingsboard.server.service.security.auth.rest.LoginResponse;
import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.schema.AlternateTypeRule;
+import springfox.documentation.builders.OperationBuilder;
+import springfox.documentation.builders.RepresentationBuilder;
+import springfox.documentation.builders.RequestParameterBuilder;
+import springfox.documentation.builders.ResponseBuilder;
+import springfox.documentation.service.ApiDescription;
import springfox.documentation.service.ApiInfo;
-import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.ApiListing;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
+import springfox.documentation.service.HttpLoginPasswordScheme;
+import springfox.documentation.service.ParameterType;
+import springfox.documentation.service.Response;
import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.service.Tag;
import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.ApiListingBuilderPlugin;
+import springfox.documentation.spi.service.ApiListingScannerPlugin;
+import springfox.documentation.spi.service.contexts.ApiListingContext;
+import springfox.documentation.spi.service.contexts.DocumentationContext;
+import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator;
+import springfox.documentation.swagger.common.SwaggerPluginSupport;
+import springfox.documentation.swagger.web.DocExpansion;
+import springfox.documentation.swagger.web.ModelRendering;
+import springfox.documentation.swagger.web.OperationsSorter;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger.web.UiConfigurationBuilder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
-import static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Lists.newArrayList;
+import static java.util.function.Predicate.not;
+import static springfox.documentation.builders.PathSelectors.any;
import static springfox.documentation.builders.PathSelectors.regex;
@Configuration
@@ -67,6 +100,9 @@ public class SwaggerConfiguration {
@Value("${swagger.version}")
private String version;
+ @Autowired
+ private CachingOperationNameGenerator operationNames;
+
@Bean
public Docket thingsboardApi() {
TypeResolver typeResolver = new TypeResolver();
@@ -77,29 +113,110 @@ public class SwaggerConfiguration {
typeResolver.resolve(
String.class);
- return new Docket(DocumentationType.SWAGGER_2)
+ return new Docket(DocumentationType.OAS_30)
.groupName("thingsboard")
.apiInfo(apiInfo())
- .alternateTypeRules(
+ .additionalModels(
+ typeResolver.resolve(ThingsboardErrorResponse.class),
+ typeResolver.resolve(LoginRequest.class),
+ typeResolver.resolve(LoginResponse.class)
+ )
+ /* .alternateTypeRules(
new AlternateTypeRule(
jsonNodeType,
- stringType))
+ stringType))*/
.select()
.paths(apiPaths())
+ .paths(any())
.build()
- .securitySchemes(newArrayList(jwtTokenKey()))
+ .globalResponses(HttpMethod.GET,
+ List.of(
+ new ResponseBuilder()
+ .code("401")
+ .description("Unauthorized")
+ .representation(MediaType.APPLICATION_JSON)
+ .apply(classRepresentation(ThingsboardErrorResponse.class, true))
+ .build()
+ )
+ )
+ .securitySchemes(newArrayList(httpLogin()))
.securityContexts(newArrayList(securityContext()))
.enableUrlTemplating(true);
}
- private ApiKey jwtTokenKey() {
- return new ApiKey("X-Authorization", "JWT token", "header");
+ @Bean
+ @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER)
+ ApiListingScannerPlugin loginEndpointListingScanner() {
+ return new ApiListingScannerPlugin() {
+ @Override
+ public List apply(DocumentationContext context) {
+ return List.of(loginEndpointApiDescription());
+ }
+
+ @Override
+ public boolean supports(DocumentationType delimiter) {
+ return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter);
+ }
+ };
+ }
+
+ @Bean
+ @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER)
+ ApiListingBuilderPlugin loginEndpointListingBuilder() {
+ return new ApiListingBuilderPlugin() {
+ @Override
+ public void apply(ApiListingContext apiListingContext) {
+ if (apiListingContext.getResourceGroup().getGroupName().equals("default")) {
+ ApiListing apiListing = apiListingContext.apiListingBuilder().build();
+ if (apiListing.getResourcePath().equals("/api/auth/login")) {
+ apiListingContext.apiListingBuilder().tags(Set.of(new Tag("login-endpoint", "Login Endpoint")));
+ apiListingContext.apiListingBuilder().description("Login Endpoint");
+ }
+ }
+ }
+
+ @Override
+ public boolean supports(DocumentationType delimiter) {
+ return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter);
+ }
+ };
+ }
+
+ @Bean
+ UiConfiguration uiConfig() {
+ return UiConfigurationBuilder.builder()
+ .deepLinking(true)
+ .displayOperationId(false)
+ .defaultModelsExpandDepth(1)
+ .defaultModelExpandDepth(1)
+ .defaultModelRendering(ModelRendering.EXAMPLE)
+ .displayRequestDuration(false)
+ .docExpansion(DocExpansion.NONE)
+ .filter(false)
+ .maxDisplayedTags(null)
+ .operationsSorter(OperationsSorter.ALPHA)
+ .showExtensions(false)
+ .showCommonExtensions(false)
+ .supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
+ .validatorUrl(null)
+ .syntaxHighlightActivate(true)
+ .syntaxHighlightTheme("agate")
+ .build();
+ }
+
+ private SecurityScheme httpLogin() {
+ return HttpLoginPasswordScheme
+ .X_AUTHORIZATION_BUILDER
+ .loginEndpoint("/api/auth/login")
+ .name("HTTP login form")
+ .description("Enter Username / Password")
+ .build();
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
- .forPaths(securityPaths())
+ .operationSelector(securityPathOperationSelector())
.build();
}
@@ -107,11 +224,8 @@ public class SwaggerConfiguration {
return regex(apiPathRegex);
}
- private Predicate securityPaths() {
- return and(
- regex(securityPathRegex),
- not(regex(nonSecurityPathRegex))
- );
+ private Predicate securityPathOperationSelector() {
+ return new SecurityPathOperationSelector(securityPathRegex, nonSecurityPathRegex);
}
List defaultAuth() {
@@ -120,7 +234,7 @@ public class SwaggerConfiguration {
authorizationScopes[1] = new AuthorizationScope(Authority.TENANT_ADMIN.name(), "Tenant administrator");
authorizationScopes[2] = new AuthorizationScope(Authority.CUSTOMER_USER.name(), "Customer");
return newArrayList(
- new SecurityReference("X-Authorization", authorizationScopes));
+ new SecurityReference("HTTP login form", authorizationScopes));
}
private ApiInfo apiInfo() {
@@ -134,4 +248,75 @@ public class SwaggerConfiguration {
.build();
}
+ private ApiDescription loginEndpointApiDescription() {
+ return new ApiDescription(null, "/api/auth/login", "Login method to get user JWT token data", "Login endpoint", Collections.singletonList(
+ new OperationBuilder(operationNames)
+ .summary("Login method to get user JWT token data")
+ .tags(Set.of("login-endpoint"))
+ .authorizations(new ArrayList<>())
+ .position(0)
+ .codegenMethodNameStem("loginPost")
+ .method(HttpMethod.POST)
+ .notes("Login method to get user JWT token data.\n\nValue of the response **token** field can be used as JWT token value for authorization.")
+ .requestParameters(
+ List.of(
+ new RequestParameterBuilder()
+ .in(ParameterType.BODY)
+ .required(true)
+ .description("Login request")
+ .content(c ->
+ c.requestBody(true)
+ .representation(MediaType.APPLICATION_JSON)
+ .apply(classRepresentation(LoginRequest.class, false))
+ )
+ .build()
+ )
+ )
+ .responses(loginResponses())
+ .build()
+ ), false);
+ }
+
+ private Collection loginResponses() {
+ return List.of(
+ new ResponseBuilder()
+ .code("200")
+ .description("OK")
+ .representation(MediaType.APPLICATION_JSON)
+ .apply(classRepresentation(LoginResponse.class, true)).
+ build()
+ );
+ }
+
+ /** Helper methods **/
+
+ private Consumer classRepresentation(Class clazz, boolean isResponse) {
+ return r -> r.model(
+ m ->
+ m.referenceModel(ref ->
+ ref.key(k ->
+ k.qualifiedModelName(q ->
+ q.namespace(clazz.getPackageName())
+ .name(clazz.getSimpleName())).isResponse(isResponse)))
+ );
+ }
+
+ private static class SecurityPathOperationSelector implements Predicate {
+
+ private final Predicate securityPathSelector;
+
+ SecurityPathOperationSelector(String securityPathRegex, String nonSecurityPathRegex) {
+ this.securityPathSelector = regex(securityPathRegex).and(
+ not(
+ regex(nonSecurityPathRegex)
+ ));
+ }
+
+ @Override
+ public boolean test(OperationContext operationContext) {
+ return this.securityPathSelector.test(operationContext.requestMappingPattern());
+ }
+ }
+
+
}
diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
index 2718b455b9..1a5b2f86fd 100644
--- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
@@ -64,6 +64,7 @@ import java.util.List;
public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapter {
public static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization";
+ public static final String JWT_TOKEN_HEADER_PARAM_V2 = "Authorization";
public static final String JWT_TOKEN_QUERY_PARAM = "token";
public static final String WEBJARS_ENTRY_POINT = "/webjars/**";
diff --git a/application/src/main/java/org/thingsboard/server/config/WebConfig.java b/application/src/main/java/org/thingsboard/server/config/WebConfig.java
index 500d1bd06e..e4a1eea01b 100644
--- a/application/src/main/java/org/thingsboard/server/config/WebConfig.java
+++ b/application/src/main/java/org/thingsboard/server/config/WebConfig.java
@@ -18,12 +18,20 @@ package org.thingsboard.server.config;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
@Controller
public class WebConfig {
- @RequestMapping(value = {"/assets", "/assets/", "/{path:^(?!api$)(?!assets$)(?!static$)(?!webjars$)[^\\.]*}/**"})
+ @RequestMapping(value = {"/assets", "/assets/", "/{path:^(?!api$)(?!assets$)(?!static$)(?!webjars$)(?!swagger-ui$)[^\\.]*}/**"})
public String redirect() {
return "forward:/index.html";
}
+ @RequestMapping("/swagger-ui.html")
+ public void redirectSwagger(HttpServletResponse response) throws IOException {
+ response.sendRedirect("/swagger-ui/");
+ }
+
}
diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
index 7c881e8b67..185f8ff526 100644
--- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
+++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java
@@ -44,6 +44,7 @@ public class ControllerConstants {
protected static final String OTA_PACKAGE_ID_PARAM_DESCRIPTION = "A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'";
protected static final String RULE_CHAIN_ID_PARAM_DESCRIPTION = "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
+ protected static final String RULE_NODE_ID_PARAM_DESCRIPTION = "A string value representing the rule node id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String WIDGET_BUNDLE_ID_PARAM_DESCRIPTION = "A string value representing the widget bundle id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String WIDGET_TYPE_ID_PARAM_DESCRIPTION = "A string value representing the widget type id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
protected static final String RESOURCE_ID_PARAM_DESCRIPTION = "A string value representing the resource id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
index 8996367c36..bb27451349 100644
--- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
@@ -95,6 +95,7 @@ import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_S
import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TEXT_SEARCH_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPES_ALLOWABLE_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPE_DESCRIPTION;
+import static org.thingsboard.server.controller.ControllerConstants.RULE_NODE_ID_PARAM_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
@@ -434,7 +435,7 @@ public class RuleChainController extends BaseController {
@RequestMapping(value = "/ruleNode/{ruleNodeId}/debugIn", method = RequestMethod.GET)
@ResponseBody
public JsonNode getLatestRuleNodeDebugInput(
- @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION)
+ @ApiParam(value = RULE_NODE_ID_PARAM_DESCRIPTION)
@PathVariable(RULE_NODE_ID) String strRuleNodeId) throws ThingsboardException {
checkParameter(RULE_NODE_ID, strRuleNodeId);
try {
diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
index a6cc14dce1..facee5d87f 100644
--- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
@@ -79,7 +79,7 @@ public class WidgetsBundleController extends BaseController {
@ApiOperation(value = "Create Or Update Widget Bundle (saveWidgetsBundle)",
notes = "Create or update the Widget Bundle. " + WIDGET_BUNDLE_DESCRIPTION + " " +
- "When creating the bundle, platform generates Widget Bundle Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " +
+ "When creating the bundle, platform generates Widget Bundle Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). " +
"The newly created Widget Bundle Id will be present in the response. " +
"Specify existing Widget Bundle id to update the Widget Bundle. " +
"Referencing non-existing Widget Bundle Id will cause 'Not Found' error." +
diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
index 7c9dd55c87..1f1200752f 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
@@ -30,7 +30,10 @@ public class JwtHeaderTokenExtractor implements TokenExtractor {
public String extract(HttpServletRequest request) {
String header = request.getHeader(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM);
if (StringUtils.isBlank(header)) {
- throw new AuthenticationServiceException("Authorization header cannot be blank!");
+ header = request.getHeader(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM_V2);
+ if (StringUtils.isBlank(header)) {
+ throw new AuthenticationServiceException("Authorization header cannot be blank!");
+ }
}
if (header.length() < HEADER_PREFIX.length()) {
diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java
index a90effdd36..f645b989d2 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java
@@ -17,9 +17,14 @@ package org.thingsboard.server.service.security.auth.rest;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+@ApiModel
public class LoginRequest {
+
private String username;
+
private String password;
@JsonCreator
@@ -28,10 +33,12 @@ public class LoginRequest {
this.password = password;
}
+ @ApiModelProperty(position = 1, required = true, value = "User email", example = "tenant@thingsboard.org")
public String getUsername() {
return username;
}
+ @ApiModelProperty(position = 2, required = true, value = "User password", example = "tenant")
public String getPassword() {
return password;
}
diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java
new file mode 100644
index 0000000000..e39e0af14f
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright © 2016-2021 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.thingsboard.server.service.security.auth.rest;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel
+@Data
+public class LoginResponse {
+
+ @ApiModelProperty(position = 1, required = true, value = "JWT token",
+ example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...")
+ private String token;
+
+ @ApiModelProperty(position = 2, required = true, value = "Refresh token",
+ example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...")
+ private String refreshToken;
+
+}
diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml
index 6644e1b62e..b7867360aa 100644
--- a/application/src/main/resources/thingsboard.yml
+++ b/application/src/main/resources/thingsboard.yml
@@ -845,9 +845,9 @@ edges:
persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}"
swagger:
- api_path_regex: "${SWAGGER_API_PATH_REGEX:/api.*}"
- security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api.*}"
- non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/noauth.*}"
+ api_path_regex: "${SWAGGER_API_PATH_REGEX:/api/.*}"
+ security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api/.*}"
+ non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/(?:noauth|v1)/.*}"
title: "${SWAGGER_TITLE:ThingsBoard REST API}"
description: "${SWAGGER_DESCRIPTION:For instructions how to authorize requests please visit REST API documentation page.}"
contact:
diff --git a/pom.xml b/pom.xml
index 0ca42294fa..cf419aa9b4 100755
--- a/pom.xml
+++ b/pom.xml
@@ -46,8 +46,8 @@
2.4.3
3.3.0
0.7.0
- 1.7.7
- 1.2.3
+ 1.7.32
+ 1.2.6
0.10
4.10.0
4.0.5
@@ -83,9 +83,8 @@
4.8.0
2.19.1
3.0.2
- 2.6.1
- 1.0.0
- 1.5.10
+ 3.0.1
+ 1.6.3
0.7
1.15.0
1.67
@@ -1620,8 +1619,8 @@
${curator.version}
- io.springfox
- springfox-swagger2
+ org.thingsboard
+ springfox-boot-starter
${springfox-swagger.version}
@@ -1699,11 +1698,6 @@
fst
${fst.version}
-
- io.springfox.ui
- springfox-swagger-ui-rfc6570
- ${springfox-swagger-ui-rfc6570.version}
-
org.locationtech.spatial4j
spatial4j