Skip to content

Commit 8eb52f3

Browse files
authored
fix: update jjwt version (#846)
* chore: update jjwt version
1 parent c3406bb commit 8eb52f3

File tree

13 files changed

+226
-94
lines changed

13 files changed

+226
-94
lines changed

CHANGES.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,39 @@
11
twilio-java changelog
22
=====================
33

4+
**AccessToken**
5+
6+
- **Breaking Change**: Updated `AccessTokenBuilder` to use `byte[]` for the `secret` instead of `String`.
7+
- Updated method signatures:
8+
- `AccessTokenBuilder(String accountSid, String keySid, byte[] secret)`
9+
- Example usage:
10+
```java
11+
byte[] secret = "your_secret".getBytes();
12+
AccessTokenBuilder builder = new AccessTokenBuilder(accountSid, keySid, secret);
13+
```
14+
15+
**ClientCapability**
16+
17+
- **Breaking Change**: Updated `ClientCapability.Builder` to use `byte[]` for the `authToken` instead of `String`.
18+
- Updated method signatures:
19+
- `ClientCapability.Builder(String accountSid, byte[] authToken)`
20+
- Example usage:
21+
```java
22+
byte[] authToken = "your_auth_token".getBytes();
23+
ClientCapability.Builder builder = new ClientCapability.Builder(accountSid, authToken);
24+
```
25+
26+
**TaskRouterCapability**
27+
28+
- **Breaking Change**: Updated `TaskRouterCapability.Builder` to use `byte[]` for the `authToken` instead of `String`.
29+
- Updated method signatures:
30+
- `TaskRouterCapability.Builder(String accountSid, byte[] authToken)`
31+
- Example usage:
32+
```java
33+
byte[] authToken = "your_auth_token".getBytes();
34+
TaskRouterCapability.Builder builder = new TaskRouterCapability.Builder(accountSid, authToken);
35+
```
36+
437
[2025-04-07] Version 10.7.2
538
---------------------------
639
**Library - Chore**

UPGRADE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,4 +703,4 @@ Task.reader("WS123").setAssignmentStatus(Lists.newArrayList(
703703
Task.Status.ASSIGNED.toString(),
704704
Task.Status.CANCELED.toString()
705705
)).read();
706-
```
706+
```

pom.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@
169169
<properties>
170170
<jackson.version>2.15.0</jackson.version>
171171
<javadoc.plugin.version>3.3.1</javadoc.plugin.version>
172-
<jjwt.version>0.11.2</jjwt.version>
172+
<jjwt.version>0.12.6</jjwt.version>
173173
<skip.tests>false</skip.tests>
174174
<dependency.skip>false</dependency.skip>
175175
<sonar.organization>twilio</sonar.organization>
@@ -337,6 +337,11 @@
337337
</exclusion>
338338
</exclusions>
339339
</dependency>
340+
<dependency>
341+
<groupId>com.google.code.gson</groupId>
342+
<artifactId>gson</artifactId>
343+
<version>2.8.6</version>
344+
</dependency>
340345
</dependencies>
341346
<build>
342347
<plugins>
@@ -491,4 +496,4 @@
491496
<artifactId>oss-parent</artifactId>
492497
<version>7</version>
493498
</parent>
494-
</project>
499+
</project>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.twilio.example;
2+
3+
import com.twilio.jwt.accesstoken.AccessToken;
4+
import com.twilio.jwt.accesstoken.VoiceGrant;
5+
import java.util.HashMap;
6+
import com.google.gson.Gson;
7+
8+
public class AccessTokenExample {
9+
public static void main(String args[]){
10+
String acctSid = System.getenv("TWILIO_ACCOUNT_SID");
11+
String applicationSid = System.getenv("TWILIO_TWIML_APP_SID");
12+
String apiKey = System.getenv("API_KEY");
13+
String apiSecret = System.getenv("API_SECRET");
14+
// Create Voice grant
15+
VoiceGrant grant = new VoiceGrant();
16+
grant.setOutgoingApplicationSid(applicationSid);
17+
18+
// Optional: add to allow incoming calls
19+
grant.setIncomingAllow(true);
20+
21+
String randomIdentity = "random-identity";
22+
// Create access token
23+
AccessToken accessToken = new AccessToken.Builder(acctSid, apiKey, apiSecret.getBytes())
24+
.identity(randomIdentity)
25+
.grant(grant)
26+
.build();
27+
28+
String token = accessToken.toJwt();
29+
30+
// create JSON response payload
31+
HashMap<String, String> json = new HashMap<>();
32+
json.put("identity", randomIdentity);
33+
json.put("token", token);
34+
35+
Gson gson = new Gson();
36+
System.out.println(gson.toJson(json));
37+
}
38+
}

src/main/java/com/twilio/http/TwilioRestClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public Response request(final Request request) {
104104

105105
return response;
106106
}
107-
107+
108108
public static class Builder {
109109
private String username;
110110
private String password;

src/main/java/com/twilio/jwt/Jwt.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ public abstract class Jwt {
3030
*/
3131
public Jwt(
3232
SignatureAlgorithm algorithm,
33-
String secret,
33+
byte[] secret,
3434
String issuer,
3535
Date expiration
3636
) {
3737
this(
3838
algorithm,
39-
new SecretKeySpec(secret.getBytes(), algorithm.getJcaName()),
39+
new SecretKeySpec(secret, algorithm.getJcaName()),
4040
issuer,
4141
expiration
4242
);

src/main/java/com/twilio/jwt/accesstoken/AccessToken.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public Map<String, Object> getClaims() {
9494
public static class Builder {
9595
private String accountSid;
9696
private String keySid;
97-
private String secret;
97+
private byte[] secret;
9898
private String identity;
9999
private String region;
100100
private Date nbf = null;
@@ -108,7 +108,7 @@ public static class Builder {
108108
* @param keySid key to use
109109
* @param secret secret key
110110
*/
111-
public Builder(String accountSid, String keySid, String secret) {
111+
public Builder(String accountSid, String keySid, byte[] secret) {
112112
this.accountSid = accountSid;
113113
this.keySid = keySid;
114114
this.secret = secret;

src/main/java/com/twilio/jwt/client/ClientCapability.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public Map<String, Object> getClaims() {
5757
/** Builder used to construct a Client Capability. */
5858
public static class Builder {
5959
private String accountSid;
60-
private String authToken;
60+
private byte[] authToken;
6161
private int ttl = 3600;
6262
private List<Scope> scopes = new ArrayList<>();
6363

@@ -67,7 +67,7 @@ public static class Builder {
6767
* @param accountSid account to use
6868
* @param authToken auth token
6969
*/
70-
public Builder(String accountSid, String authToken) {
70+
public Builder(String accountSid, byte[] authToken) {
7171
this.accountSid = accountSid;
7272
this.authToken = authToken;
7373
}

src/main/java/com/twilio/jwt/taskrouter/TaskRouterCapability.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public Map<String, Object> getClaims() {
6666
public static class Builder {
6767

6868
private String accountSid;
69-
private String authToken;
69+
private byte[] authToken;
7070
private String workspaceSid;
7171
private String channelId;
7272
private String friendlyName;
@@ -81,7 +81,7 @@ public static class Builder {
8181
* @param workspaceSid workspace sid to use
8282
* @param channelId channel ID to use
8383
*/
84-
public Builder(String accountSid, String authToken, String workspaceSid, String channelId) {
84+
public Builder(String accountSid, byte[] authToken, String workspaceSid, String channelId) {
8585
this.accountSid = accountSid;
8686
this.authToken = authToken;
8787
this.workspaceSid = workspaceSid;

src/test/java/com/twilio/jwt/accesstoken/AccessTokenTest.java

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
package com.twilio.jwt.accesstoken;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import com.twilio.jwt.Jwt;
45
import io.jsonwebtoken.Claims;
6+
import io.jsonwebtoken.Jws;
57
import io.jsonwebtoken.JwsHeader;
8+
import io.jsonwebtoken.JwtParser;
9+
import io.jsonwebtoken.JwtParserBuilder;
610
import io.jsonwebtoken.Jwts;
11+
import io.jsonwebtoken.security.Keys;
12+
import java.io.IOException;
13+
import java.security.KeyPair;
14+
import java.security.KeyPairGenerator;
15+
import java.security.NoSuchAlgorithmException;
16+
import javax.crypto.KeyGenerator;
17+
import javax.crypto.SecretKey;
718
import org.junit.Assert;
819
import org.junit.Test;
920

@@ -18,7 +29,19 @@ public class AccessTokenTest {
1829

1930
private static final String ACCOUNT_SID = "AC123";
2031
private static final String SIGNING_KEY_SID = "SK123";
21-
private static final String SECRET = "secretsecretsecretsecretsecret00";
32+
private static byte[] SECRET;
33+
34+
static {
35+
KeyGenerator keyGen = null;
36+
try {
37+
keyGen = KeyGenerator.getInstance("HmacSHA256");
38+
keyGen.init(2048); // Use 2048 bits for stronger security
39+
SecretKey pair = keyGen.generateKey();
40+
SECRET = pair.getEncoded();
41+
} catch (NoSuchAlgorithmException e) {
42+
throw new RuntimeException(e);
43+
}
44+
}
2245

2346
private void validateToken(Claims claims) {
2447
Assert.assertEquals(SIGNING_KEY_SID, claims.getIssuer());
@@ -32,14 +55,17 @@ private void validateToken(Claims claims) {
3255
Assert.assertTrue(claims.getExpiration().getTime() > new Date().getTime());
3356
}
3457

35-
private Claims getClaimFromJwtToken(Jwt token) {
36-
return Jwts.parserBuilder()
37-
.setSigningKey(SECRET.getBytes()).build()
38-
.parseClaimsJws(token.toJwt())
39-
.getBody();
58+
private Claims getClaimFromJwtToken(Jwt token) throws IOException {
59+
io.jsonwebtoken.Jwt<?, ?> claims = Jwts.parser()
60+
.verifyWith(Keys.hmacShaKeyFor(SECRET))
61+
.build()
62+
.parse(token.toJwt());
63+
ObjectMapper objectMapper = new ObjectMapper();
64+
Map<String,?> map = (Map<String,?>)objectMapper.readValue((byte[])claims.getPayload(), Map.class);
65+
return Jwts.claims().add(map).build();
4066
}
4167

42-
private void testVoiceToken(Boolean allow) {
68+
private void testVoiceToken(Boolean allow) throws IOException {
4369
Map<String, Object> params = new HashMap<>();
4470
params.put("foo", "bar");
4571

@@ -70,7 +96,7 @@ private void testVoiceToken(Boolean allow) {
7096
}
7197

7298
@Test
73-
public void testEmptyToken() {
99+
public void testEmptyToken() throws IOException {
74100
Jwt token =
75101
new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET)
76102
.build();
@@ -81,7 +107,7 @@ public void testEmptyToken() {
81107
}
82108

83109
@Test
84-
public void testOptionalValues() {
110+
public void testOptionalValues() throws IOException {
85111
Jwt token =
86112
new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET)
87113
.identity(ACCOUNT_SID)
@@ -100,28 +126,28 @@ public void testRegion() {
100126
.region("foo")
101127
.build();
102128

103-
JwsHeader header = Jwts.parserBuilder()
104-
.setSigningKey(SECRET.getBytes()).build()
105-
.parseClaimsJws(token.toJwt())
106-
.getHeader();
129+
io.jsonwebtoken.Jwt<?, ?> jwts = Jwts.parser()
130+
.verifyWith(Keys.hmacShaKeyFor(SECRET))
131+
.build()
132+
.parse(token.toJwt());
107133

108-
Assert.assertEquals("foo", header.get("twr"));
134+
Assert.assertEquals("foo", jwts.getHeader().get("twr"));
109135
}
110136

111137
@Test
112138
public void testEmptyRegion() {
113139
Jwt token = new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET).build();
114140

115-
JwsHeader header = Jwts.parserBuilder()
116-
.setSigningKey(SECRET.getBytes()).build()
117-
.parseClaimsJws(token.toJwt())
118-
.getHeader();
141+
io.jsonwebtoken.Jwt<?, ?> jwts = Jwts.parser()
142+
.verifyWith(Keys.hmacShaKeyFor(SECRET))
143+
.build()
144+
.parse(token.toJwt());
119145

120-
Assert.assertEquals(null, header.get("twr"));
146+
Assert.assertEquals(null, jwts.getHeader().get("twr"));
121147
}
122148

123149
@Test
124-
public void testVideoGrant() {
150+
public void testVideoGrant() throws IOException {
125151
VideoGrant cg = new VideoGrant().setRoom("RM123");
126152
Jwt token =
127153
new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET)
@@ -140,7 +166,7 @@ public void testVideoGrant() {
140166
}
141167

142168
@Test
143-
public void testChatGrant() {
169+
public void testChatGrant() throws IOException {
144170
ChatGrant cg = new ChatGrant()
145171
.setDeploymentRoleSid("RL123")
146172
.setEndpointId("foobar")
@@ -166,7 +192,7 @@ public void testChatGrant() {
166192
}
167193

168194
@Test
169-
public void testSyncGrant() {
195+
public void testSyncGrant() throws IOException {
170196
SyncGrant sg = new SyncGrant()
171197
.setEndpointId("foobar")
172198
.setServiceSid("IS123");
@@ -188,7 +214,7 @@ public void testSyncGrant() {
188214
}
189215

190216
@Test
191-
public void testPlaybackGrant() {
217+
public void testPlaybackGrant() throws IOException {
192218
Map<String, Object> grantPayload = new HashMap<>();
193219
grantPayload.put("requestCredentials", null);
194220
grantPayload.put("playbackUrl", "https://000.us-east-1.playback.live-video.net/api/video/v1/us-east-000.channel.000?token=xxxxx");
@@ -214,7 +240,7 @@ public void testPlaybackGrant() {
214240
}
215241

216242
@Test
217-
public void testTaskRouterGrant() {
243+
public void testTaskRouterGrant() throws IOException {
218244
TaskRouterGrant trg = new TaskRouterGrant()
219245
.setWorkspaceSid("WS123")
220246
.setWorkerSid("WK123")
@@ -239,13 +265,13 @@ public void testTaskRouterGrant() {
239265
}
240266

241267
@Test
242-
public void testVoiceTokenWithIncoming() {
268+
public void testVoiceTokenWithIncoming() throws IOException {
243269
testVoiceToken(true);
244270
testVoiceToken(false);
245271
}
246272

247273
@Test
248-
public void testVoiceTokenWithoutIncoming() {
274+
public void testVoiceTokenWithoutIncoming() throws IOException {
249275
Map<String, Object> params = new HashMap<>();
250276
params.put("foo", "bar");
251277

@@ -274,7 +300,7 @@ public void testVoiceTokenWithoutIncoming() {
274300
}
275301

276302
@Test()
277-
public void testNullValues() {
303+
public void testNullValues() throws IOException {
278304
ChatGrant cg = new ChatGrant().setDeploymentRoleSid("RL123");
279305
Jwt token =
280306
new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET)

0 commit comments

Comments
 (0)