Skip to content

Commit 95a820a

Browse files
committed
feat(spring-boot-starter): look for jwt parser customizers
1 parent f41639c commit 95a820a

File tree

5 files changed

+64
-3
lines changed

5 files changed

+64
-3
lines changed

client/src/main/java/dev/caceresenzo/privy/client/impl/PrivyClientImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@
4040
import io.jsonwebtoken.JwtParser;
4141
import io.jsonwebtoken.JwtParserBuilder;
4242
import io.jsonwebtoken.Jwts;
43+
import lombok.Getter;
4344
import lombok.SneakyThrows;
4445

46+
@Getter
4547
public class PrivyClientImpl implements PrivyClient {
4648

4749
private static final CustomMetadata EMPTY_METADATA = CustomMetadata.fromValues(Collections.emptyMap());

spring-boot-starter/src/main/java/dev/caceresenzo/privy/spring/boot/autoconfigure/PrivyAutoConfiguration.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.caceresenzo.privy.spring.boot.autoconfigure;
22

33
import java.io.IOException;
4+
import java.util.List;
45

56
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
67
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -22,7 +23,10 @@ public class PrivyAutoConfiguration {
2223
@Bean
2324
@ConditionalOnProperty(PrivyProperties.PREFIX_APPLICATION_ID)
2425
@ConditionalOnMissingBean
25-
PrivyClient privyClient(PrivyProperties properties) throws IOException {
26+
PrivyClient privyClient(
27+
PrivyProperties properties,
28+
List<PrivyJwtParserCustomizer> jwtParserCustomizers
29+
) throws IOException {
2630
log.info("Configuring Privy Client");
2731

2832
final PrivyClient.Builder builder = PrivyClient.builder()
@@ -39,6 +43,21 @@ PrivyClient privyClient(PrivyProperties properties) throws IOException {
3943
builder.maxPageSize(maxPageSize);
4044
}
4145

46+
final var cacheVerificationKey = properties.getCacheVerificationKey();
47+
if (cacheVerificationKey != null) {
48+
builder.cacheVerificationKey(cacheVerificationKey);
49+
}
50+
51+
if (!jwtParserCustomizers.isEmpty()) {
52+
builder.jwtParserCustomizer((jwtParserBuilder) -> {
53+
for (final var customizer : jwtParserCustomizers) {
54+
jwtParserBuilder = customizer.customize(jwtParserBuilder);
55+
}
56+
57+
return jwtParserBuilder;
58+
});
59+
}
60+
4261
return builder.build();
4362
}
4463

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dev.caceresenzo.privy.spring.boot.autoconfigure;
2+
3+
import io.jsonwebtoken.JwtParserBuilder;
4+
5+
@FunctionalInterface
6+
public interface PrivyJwtParserCustomizer {
7+
8+
JwtParserBuilder customize(JwtParserBuilder jwtParserBuilder);
9+
10+
}

spring-boot-starter/src/main/java/dev/caceresenzo/privy/spring/boot/autoconfigure/PrivyProperties.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ public class PrivyProperties {
1818
private String applicationSecret;
1919
private String webhookSigningKey;
2020
private Long maxPageSize;
21+
private Boolean cacheVerificationKey;
2122

2223
}
Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,53 @@
11
package dev.caceresenzo.privy.spring.boot;
22

3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
5+
36
import org.junit.jupiter.api.Test;
7+
import org.junit.platform.commons.util.ReflectionUtils;
48
import org.springframework.beans.factory.annotation.Autowired;
59
import org.springframework.boot.test.context.SpringBootTest;
10+
import org.springframework.context.annotation.Bean;
11+
import org.springframework.context.annotation.Configuration;
612

713
import dev.caceresenzo.privy.client.PrivyClient;
14+
import dev.caceresenzo.privy.client.impl.PrivyClientImpl;
815
import dev.caceresenzo.privy.spring.boot.autoconfigure.PrivyAutoConfiguration;
16+
import dev.caceresenzo.privy.spring.boot.autoconfigure.PrivyJwtParserCustomizer;
917
import dev.caceresenzo.privy.spring.boot.autoconfigure.PrivyProperties;
18+
import io.jsonwebtoken.impl.DefaultJwtParser;
19+
import lombok.SneakyThrows;
1020

1121
@SpringBootTest(
1222
classes = {
1323
PrivyAutoConfiguration.class,
14-
}, properties = {
24+
ClientAutoConfigurationTest.ContextConfiguration.class,
25+
},
26+
properties = {
1527
PrivyProperties.PREFIX_APPLICATION_ID + "=hello",
1628
PrivyProperties.PREFIX_APPLICATION_SECRET + "=world"
1729
}
1830
)
1931
class ClientAutoConfigurationTest {
2032

2133
@Test
22-
void contextLoads(@Autowired PrivyClient client) {}
34+
@SneakyThrows
35+
void contextLoads(@Autowired PrivyClient client) {
36+
final var clientImpl = assertInstanceOf(PrivyClientImpl.class, client);
37+
final var jwtParser = assertInstanceOf(DefaultJwtParser.class, clientImpl.getJwtParser());
38+
39+
final var clockSkew = ReflectionUtils.tryToReadFieldValue(DefaultJwtParser.class, "allowedClockSkewMillis", jwtParser);
40+
assertEquals(42_000l, clockSkew.get());
41+
}
42+
43+
@Configuration
44+
static class ContextConfiguration {
45+
46+
@Bean
47+
public PrivyJwtParserCustomizer clockSkewJwtParserCustomizer() {
48+
return (builder) -> builder.clockSkewSeconds(42);
49+
}
50+
51+
}
2352

2453
}

0 commit comments

Comments
 (0)