diff --git a/server/depl/deploy.sh b/server/depl/deploy.sh new file mode 100755 index 0000000..76006da --- /dev/null +++ b/server/depl/deploy.sh @@ -0,0 +1,17 @@ + +mvn clean package + +echo 'Copy files...' + +scp -i ~/Downloads/horizon.pem \ + ./target/*.jar \ + ubuntu@3.34.2.208:~/horizon/horizon-builder.jar + +echo 'Restart the server...' + +ssh -i ~/Downloads/horizon.pem ubuntu@3.34.2.208 << EOF +pgrep java | xargs kill -9 +nohup java -jar horizon/horizon-builder.jar & +EOF + +echo 'Bye!' \ No newline at end of file diff --git a/server/src/main/java/com/horizonbuilders/server/ServerApplication.java b/server/src/main/java/com/horizonbuilders/server/ServerApplication.java index 125d0c6..3e993ac 100644 --- a/server/src/main/java/com/horizonbuilders/server/ServerApplication.java +++ b/server/src/main/java/com/horizonbuilders/server/ServerApplication.java @@ -1,13 +1,17 @@ package com.horizonbuilders.server; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.system.ApplicationPid; @SpringBootApplication +@Slf4j public class ServerApplication { public static void main(String[] args) { SpringApplication.run(ServerApplication.class, args); + log.info("id of process: " + new ApplicationPid().toString()); } } diff --git a/server/src/main/java/com/horizonbuilders/server/config/AppSecurityConfiguration.java b/server/src/main/java/com/horizonbuilders/server/config/AppSecurityConfiguration.java index 8f81524..3476fd8 100644 --- a/server/src/main/java/com/horizonbuilders/server/config/AppSecurityConfiguration.java +++ b/server/src/main/java/com/horizonbuilders/server/config/AppSecurityConfiguration.java @@ -26,20 +26,26 @@ public class AppSecurityConfiguration { final JwtFilter jwtFilter; final AuthEntryPoint authEntryPoint; - private static final String[] SWAGGER_WHITELIST = { + private static final String[] WHITELIST = { + //swagger "/swagger-resources/**", "/api-docs/**", "/v3/api-docs/**", "/webjars/**", - "/error/**" + + //errors + "/error/**", + + //endpoints + "/api/authenticate/**", + "/api/refresh-token/**" }; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeHttpRequests(request -> request - .requestMatchers("/api/authenticate").permitAll() - .requestMatchers(SWAGGER_WHITELIST).permitAll() + .requestMatchers(WHITELIST).permitAll() .anyRequest().authenticated()) .exceptionHandling().authenticationEntryPoint(authEntryPoint) .and() diff --git a/server/src/main/java/com/horizonbuilders/server/config/CloudinaryConfiguration.java b/server/src/main/java/com/horizonbuilders/server/config/CloudinaryConfiguration.java index d2a0535..93a48b6 100644 --- a/server/src/main/java/com/horizonbuilders/server/config/CloudinaryConfiguration.java +++ b/server/src/main/java/com/horizonbuilders/server/config/CloudinaryConfiguration.java @@ -2,19 +2,27 @@ import com.cloudinary.Cloudinary; import com.cloudinary.utils.ObjectUtils; -import io.github.cdimascio.dotenv.Dotenv; +import lombok.AccessLevel; +import lombok.experimental.FieldDefaults; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration +@FieldDefaults(level = AccessLevel.PRIVATE) public class CloudinaryConfiguration { + @Value("${cloud.name}") + String cloud; + + @Value("${api.secret}") + String api_secret; + + @Value("${api.key}") + String api_key; + @Bean Cloudinary cloudinary() { - Dotenv dotenv = Dotenv.load(); - final String cloud = dotenv.get("cloudinary.cloud_name"); - final String api_key = dotenv.get("cloudinary.api_key"); - final String api_secret = dotenv.get("cloudinary.api_secret"); return new Cloudinary(ObjectUtils.asMap( "cloud_name", cloud, diff --git a/server/src/main/java/com/horizonbuilders/server/config/SwaggerConfig.java b/server/src/main/java/com/horizonbuilders/server/config/SwaggerConfig.java new file mode 100644 index 0000000..0ea3c8d --- /dev/null +++ b/server/src/main/java/com/horizonbuilders/server/config/SwaggerConfig.java @@ -0,0 +1,43 @@ +package com.horizonbuilders.server.config; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Contact; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@OpenAPIDefinition( + info = @Info( + title = "Horizon Builders - Construction Company", + version = "1.0", + contact = @Contact( + name = "Bekzhan Satiev", email = "tarantuldeveloper@gmail.com" + ), + description = """ + Restfull server with access and refresh tokens. Access token is valid + for 30 min, refresh - 2 hours. + """ + ) +) +public class SwaggerConfig { + @Bean + public OpenAPI customizeOpenAPI() { + final String securitySchemeName = "Bearer_Token_Authorization"; + + return new OpenAPI() + .addSecurityItem(new SecurityRequirement() + .addList(securitySchemeName)) + .components(new Components() + .addSecuritySchemes(securitySchemeName, new SecurityScheme() + .name(securitySchemeName) + .type(SecurityScheme.Type.HTTP) + .description("Just paste your access token here.") + .scheme("Bearer") + .bearerFormat("JWT"))); + } +} diff --git a/server/src/main/java/com/horizonbuilders/server/controller/AuthController.java b/server/src/main/java/com/horizonbuilders/server/controller/AuthController.java index d70d47f..c3ac6dc 100644 --- a/server/src/main/java/com/horizonbuilders/server/controller/AuthController.java +++ b/server/src/main/java/com/horizonbuilders/server/controller/AuthController.java @@ -5,6 +5,8 @@ import com.horizonbuilders.server.dto.response.LoginResponse; import com.horizonbuilders.server.service.AuthService; import com.horizonbuilders.server.service.RefreshTokenService; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; import jakarta.validation.Valid; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -23,11 +25,13 @@ public class AuthController { final AuthService authService; final RefreshTokenService refreshTokenService; + @SecurityRequirements @PostMapping("/authenticate") public LoginResponse authenticate(@RequestBody LoginRequest loginRequest) { return authService.authenticate(loginRequest.username(), loginRequest.password()); } + @SecurityRequirements @PostMapping("/refresh-token") public LoginResponse refreshAccessTokenByRefreshToken(@Valid @RequestBody RefreshAccessTokenRequest request) { return refreshTokenService.generateAccessTokenByRefreshToken(request); diff --git a/server/src/main/java/com/horizonbuilders/server/exception/ErrorResponse.java b/server/src/main/java/com/horizonbuilders/server/exception/ErrorResponse.java index 418cff6..8c6be9a 100644 --- a/server/src/main/java/com/horizonbuilders/server/exception/ErrorResponse.java +++ b/server/src/main/java/com/horizonbuilders/server/exception/ErrorResponse.java @@ -13,12 +13,12 @@ @Setter public class ErrorResponse { int statusCode; - String timeStamp; + String timestamp; String message; String description; public ErrorResponse() { - this.timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + this.timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); } } diff --git a/server/src/main/resources/application-dev.properties b/server/src/main/resources/application-dev.properties deleted file mode 100644 index 49de584..0000000 --- a/server/src/main/resources/application-dev.properties +++ /dev/null @@ -1,9 +0,0 @@ - -spring.datasource.url=jdbc:mysql://localhost:3306/horizon_builders -spring.datasource.username=root -spring.datasource.password=${MYSQL_PASSWORD} -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -#--------------------JPA-ORM Properties----------------- -spring.jpa.show-sql=true -spring.jpa.hibernate.ddl-auto=update diff --git a/server/src/main/resources/application.properties b/server/src/main/resources/application.properties index bb26c2f..4401d03 100644 --- a/server/src/main/resources/application.properties +++ b/server/src/main/resources/application.properties @@ -1,7 +1,9 @@ -jwt_secret=${JWT_SECRET} +jwt_secret=67566B5970337336763979244226452948404D635166546A576D5A7134743777 jwt_access_token_expiration_in_minutes=30 jwt_refresh_token_expiration_in_hours=2 +server.port=5000 + # swagger-ui custom path springdoc.swagger-ui.path=/api-docs/ @@ -15,6 +17,16 @@ spring.servlet.multipart.max-file-size=3MB # Max Request Size spring.servlet.multipart.max-request-size=3MB -spring.profiles.active=dev +spring.datasource.url=jdbc:mysql://aws.connect.psdb.cloud/horizon_builders?sslMode=VERIFY_IDENTITY +spring.datasource.username=${MYSQL_USER} +spring.datasource.password=${MYSQL_PASSWORD} +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +#--------------------JPA-ORM Properties----------------- +#spring.jpa.show-sql=true +spring.jpa.hibernate.ddl-auto=none +cloud.name=${CLOUD_NAME} +api.secret=${API_SECRET} +api.key=${API_KEY}