diff --git a/build.gradle b/build.gradle index a3c9865..ddbf52e 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + implementation 'org.springframework.boot:spring-boot-starter-validation' // Stats implementation 'org.springframework.boot:spring-boot-starter-actuator' diff --git a/src/main/java/com/example/spring/Application.java b/src/main/java/com/example/spring/Application.java index 4254304..59b01b7 100644 --- a/src/main/java/com/example/spring/Application.java +++ b/src/main/java/com/example/spring/Application.java @@ -1,11 +1,14 @@ package com.example.spring; +import com.example.spring.config.EnvConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching +@EnableConfigurationProperties(EnvConfig.class) public class Application { public static void main(String[] args) { diff --git a/src/main/java/com/example/spring/config/EnvConfig.java b/src/main/java/com/example/spring/config/EnvConfig.java new file mode 100644 index 0000000..dd364df --- /dev/null +++ b/src/main/java/com/example/spring/config/EnvConfig.java @@ -0,0 +1,29 @@ +package com.example.spring.config; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +@Configuration +@ConfigurationProperties(prefix = "") +@Validated +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class EnvConfig { + @Value("${OAUTH_BASE_URL}") private String OAUTH_BASE_URL; + @Value("${OAUTH_SIGN_IN_URL}") private String OAUTH_SIGN_IN_URL; + @Value("${OAUTH_SIGN_OUT_URL}") private String OAUTH_SIGN_OUT_URL; + @Value("${OAUTH_SIGN_IN_REDIRECT_URL}") private String OAUTH_SIGN_IN_REDIRECT_URL; + @Value("${OAUTH_SIGN_OUT_REDIRECT_URL}") private String OAUTH_SIGN_OUT_REDIRECT_URL; + @Value("${STRIPE_PRICE_ID_FREE}") private String STRIPE_PRICE_ID_FREE; + @Value("${STRIPE_PRICE_ID_BASIC}") private String STRIPE_PRICE_ID_BASIC; + @Value("${STRIPE_PRICE_ID_PREMIUM}") private String STRIPE_PRICE_ID_PREMIUM; + @Value("${STRIPE_BILLING_PORTAL_CODE}") private String STRIPE_BILLING_PORTAL_CODE; + @Value("${PUBLIC_POSTHOG_KEY:}") private String PUBLIC_POSTHOG_KEY; + @Value("${PUBLIC_POSTHOG_HOST:}") private String PUBLIC_POSTHOG_HOST; +} diff --git a/src/main/java/com/example/spring/controller/ConfigurationController.java b/src/main/java/com/example/spring/controller/ConfigurationController.java new file mode 100644 index 0000000..669b424 --- /dev/null +++ b/src/main/java/com/example/spring/controller/ConfigurationController.java @@ -0,0 +1,36 @@ +package com.example.spring.controller; + +import com.example.spring.config.EnvConfig; +import com.example.spring.dto.Configuration; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConfigurationController { + + private final EnvConfig envConfig; + + public ConfigurationController(EnvConfig envConfig) { + this.envConfig = envConfig; + } + + // Make sure to flush the cache when updating the env variables + @Cacheable(value = "configCache", unless = "#result == null") + @GetMapping("/configuration") + public Configuration getEnv() { + return Configuration.builder() + .oauthBaseUrl(envConfig.getOAUTH_BASE_URL()) + .oauthSignInUrl(envConfig.getOAUTH_SIGN_IN_URL()) + .oauthSignOutUrl(envConfig.getOAUTH_SIGN_OUT_URL()) + .oauthSignInRedirectUrl(envConfig.getOAUTH_SIGN_IN_REDIRECT_URL()) + .oauthSignOutRedirectUrl(envConfig.getOAUTH_SIGN_OUT_REDIRECT_URL()) + .stripePriceIdFree(envConfig.getSTRIPE_PRICE_ID_FREE()) + .stripePriceIdBasic(envConfig.getSTRIPE_PRICE_ID_BASIC()) + .stripePriceIdPremium(envConfig.getSTRIPE_PRICE_ID_PREMIUM()) + .stripeBillingPortalCode(envConfig.getSTRIPE_BILLING_PORTAL_CODE()) + .publicPostHogKey(envConfig.getPUBLIC_POSTHOG_KEY()) + .publicPostHogHost(envConfig.getPUBLIC_POSTHOG_HOST()) + .build(); + } +} diff --git a/src/main/java/com/example/spring/dto/Configuration.java b/src/main/java/com/example/spring/dto/Configuration.java new file mode 100644 index 0000000..63dd683 --- /dev/null +++ b/src/main/java/com/example/spring/dto/Configuration.java @@ -0,0 +1,24 @@ +package com.example.spring.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +@Getter +@Setter +@Builder +public class Configuration implements Serializable { + private String oauthBaseUrl; + private String oauthSignInUrl; + private String oauthSignOutUrl; + private String oauthSignInRedirectUrl; + private String oauthSignOutRedirectUrl; + private String stripePriceIdFree; + private String stripePriceIdBasic; + private String stripePriceIdPremium; + private String stripeBillingPortalCode; + private String publicPostHogKey; + private String publicPostHogHost; +} diff --git a/src/main/java/com/example/spring/security/SecurityConfig.java b/src/main/java/com/example/spring/security/SecurityConfig.java index a3d0ff2..b46f313 100644 --- a/src/main/java/com/example/spring/security/SecurityConfig.java +++ b/src/main/java/com/example/spring/security/SecurityConfig.java @@ -20,6 +20,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> { // Public endpoints are enabled through the OAuth proxy with allowed endpoints + // TOOD: Set a limit on the endpoint to avoid spamming // Landing page authorize.requestMatchers(HttpMethod.GET, "/v1/company/landing-filter").permitAll(); // AutoComplete @@ -27,6 +28,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/industrySectors").permitAll(); authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/city").permitAll(); authorize.requestMatchers(HttpMethod.GET, "/v1/autocomplete/cities").permitAll(); + // Env + authorize.requestMatchers(HttpMethod.GET, "/configuration").permitAll(); // Stripe authorize.requestMatchers(HttpMethod.POST, "/v1/stripe/webhook").permitAll(); diff --git a/template.env b/template.env index be2094b..2979d83 100644 --- a/template.env +++ b/template.env @@ -27,4 +27,15 @@ STRIPE_PRICE_ID_BASIC= STRIPE_PRICE_ID_PREMIUM= # Spring -SPRING_PROFILES_ACTIVE=prod \ No newline at end of file +SPRING_PROFILES_ACTIVE=prod + +# App configuration +PROXY_BASE_URL=https://localhost:443 +OAUTH_BASE_URL=${PROXY_BASE_URL}/oauth2 +OAUTH_SIGN_IN_URL=${OAUTH_BASE_URL}/sign_in +OAUTH_SIGN_OUT_URL=${OAUTH_BASE_URL}/sign_out +OAUTH_SIGN_IN_REDIRECT_URL=${PROXY_BASE_URL}/ui/dashboard +OAUTH_SIGN_OUT_REDIRECT_URL=${PROXY_BASE_URL} +STRIPE_BILLING_PORTAL_CODE= +PUBLIC_POSTHOG_KEY= +PUBLIC_POSTHOG_HOST=https://eu.i.posthog.com \ No newline at end of file