diff --git a/jwt.md b/jwt.md index 6f7868e..16ed7b9 100644 --- a/jwt.md +++ b/jwt.md @@ -11,12 +11,15 @@ If you can do not care about `tracking`, and your Master Subscribe Token does no There are some scenarios where the payload will need a `tracking` section (such as if it's already set on the Master Subscribe Token). Read more [here](./tracking.md) +The `originCluster` can be set in SST if the MST token uses `auto` (or can be the same value as MST). + ```psuedojson { "streaming": { "tokenId": number, "tokenType": "Subscribe", "streamName": string, + "originCluster": string, "allowedOrigins": string[], "allowedIpAddresses": string[], "tracking": null @@ -45,7 +48,8 @@ We support the following: HS256, HS384, HS512. The JWT signing library may or may not add a `nbf` (NotBefore) field. This is supported, but not strictly required in our JWTs. -This example below shows an example `SST` with **no tracking**, generated from a Master Subscribe Token that does not have `tracking` enabled. +This example below shows an example `SST` with **no tracking**, generated from a Master Subscribe Token that does not have `tracking` enabled. It also overrides the `originCluster` to the `phx-1` cluster. + For other tracking examples, read [here](./tracking.md) ```json @@ -54,6 +58,7 @@ For other tracking examples, read [here](./tracking.md) "tokenId": 1, "tokenType": "Subscribe", "streamName": "teststream", + "originCluster": "phx-1", "allowedOrigins": [], "allowedIpAddresses": [], "tracking": null @@ -62,4 +67,3 @@ For other tracking examples, read [here](./tracking.md) "iat": 1673600857 } ``` -``` diff --git a/src/dotnet/CSharp.SelfSignJwt/Program.cs b/src/dotnet/CSharp.SelfSignJwt/Program.cs index c1dd261..bc8d691 100644 --- a/src/dotnet/CSharp.SelfSignJwt/Program.cs +++ b/src/dotnet/CSharp.SelfSignJwt/Program.cs @@ -26,7 +26,7 @@ sampleTokenWithParentTracking.token, streamName, sampleTokenWithParentTracking.tracking); -Console.WriteLine($"SST With Parent Tracking: {selfSignTokenWithParentTracking}\n\n"); +Console.WriteLine($"SST with Parent Tracking: {selfSignTokenWithParentTracking}\n\n"); @@ -58,7 +58,18 @@ streamName, customViewerData: "uniqueViewer1234"); -Console.WriteLine($"SST With customViewerData: {selfSignTokenWithCustomViewerData}\n\n"); +Console.WriteLine($"SST with customViewerData: {selfSignTokenWithCustomViewerData}\n\n"); + + + +streamName = ChooseStreamName(sampleTokenWithCustomViewerData); +var selfSignTokenWithOriginCluster = tokenGenerator.CreateToken(sampleTokenWithCustomViewerData.tokenId, + sampleTokenWithCustomViewerData.token, + streamName, + originCluster: "phx-1"); + +Console.WriteLine($"SST with OriginCluster: {selfSignTokenWithOriginCluster}\n\n"); + /*** diff --git a/src/dotnet/CSharp.SelfSignJwt/SampleSubscribeToken.cs b/src/dotnet/CSharp.SelfSignJwt/SampleSubscribeToken.cs index e4f16ec..d6b5b18 100644 --- a/src/dotnet/CSharp.SelfSignJwt/SampleSubscribeToken.cs +++ b/src/dotnet/CSharp.SelfSignJwt/SampleSubscribeToken.cs @@ -7,6 +7,7 @@ public class SampleSubscribeToken [JsonPropertyName("id")] public uint tokenId { get; init; } public string token { get; init; } + public string originCluster { get; init; } public List streams { get; init; } public Tracking? tracking { get; init; } @@ -14,6 +15,7 @@ public SampleSubscribeToken() { this.streams = new List(); this.token = string.Empty; + this.originCluster = string.Empty; } } diff --git a/src/dotnet/CSharp.SelfSignJwt/TokenGenerator.cs b/src/dotnet/CSharp.SelfSignJwt/TokenGenerator.cs index dd57d22..e8ac2b2 100644 --- a/src/dotnet/CSharp.SelfSignJwt/TokenGenerator.cs +++ b/src/dotnet/CSharp.SelfSignJwt/TokenGenerator.cs @@ -33,9 +33,11 @@ public string CreateToken(uint tokenId, string tokenString, string streamName, Tracking? tracking = null, IEnumerable? allowedOrigins = null, IEnumerable? allowedIpAddresses = null, int expiresIn = 60, - string? customViewerData = null) + string? customViewerData = null, + string? originCluster = null) { - var payload = new JwtPayload(tokenId, streamName, allowedOrigins, allowedIpAddresses, tracking, customViewerData); + var payload = new JwtPayload(tokenId, streamName, allowedOrigins, allowedIpAddresses, tracking, + customViewerData, originCluster); ValidateStreamingPayload(payload.streaming); var tokenDescriptor = new SecurityTokenDescriptor() @@ -66,10 +68,12 @@ class JwtPayload public JwtPayload(uint tokenId, string streamName, IEnumerable? allowedOrigins, IEnumerable? allowedIpAddresses, Tracking? tracking, - string? customViewerData) + string? customViewerData, + string? originCluster) { this.streaming = new StreamPayload(tokenId, streamName, - allowedOrigins, allowedIpAddresses, tracking, customViewerData); + allowedOrigins, allowedIpAddresses, tracking, + customViewerData, originCluster); } } @@ -89,9 +93,12 @@ class StreamPayload public string? customViewerData { get; } + public string? originCluster { get; } + public StreamPayload(uint tokenId, string streamName, IEnumerable? allowedOrigins, IEnumerable? allowedIpAddresses, Tracking? tracking, - string? customViewerData) + string? customViewerData, + string? originCluster) { this.tokenId = tokenId; this.streamName = streamName; @@ -99,6 +106,7 @@ public StreamPayload(uint tokenId, string streamName, this.allowedIpAddresses = allowedIpAddresses ?? Enumerable.Empty(); this.tracking = tracking; this.customViewerData = customViewerData; + this.originCluster = originCluster; } } } diff --git a/src/nodejs/node-tokengenerator/TokenGenerator.mjs b/src/nodejs/node-tokengenerator/TokenGenerator.mjs index 8db6581..bb2c876 100644 --- a/src/nodejs/node-tokengenerator/TokenGenerator.mjs +++ b/src/nodejs/node-tokengenerator/TokenGenerator.mjs @@ -24,26 +24,30 @@ export default class TokenGenerator { * @param {string} streamName * @param {string[]=} allowedOrigins * @param {string[]=} allowedIpAddresses - * @param {Tracking} tracking + * @param {?Tracking} tracking * @param {?number} [expiresIn = 60] * @param {?string} customViewerData - Viewer data associated with connections using this token. Max length: 1024 + * @param {?string} originCluster * @returns {string} */ createToken(tokenId, token, streamName, - allowedOrigins, allowedIpAddresses , - tracking, + allowedOrigins, allowedIpAddresses, + tracking = null, expiresIn = defaultExpiresIn, - customViewerData = null) { + customViewerData = null, + originCluster = null) { + const streaming = { + tokenId: tokenId, + tokenType: 'Subscribe', + streamName: streamName, + originCluster: originCluster ?? null, + tracking: tracking ?? null, + customViewerData: customViewerData ?? null, + allowedOrigins: allowedOrigins ?? [], + allowedIpAddresses: allowedIpAddresses ?? [] + }; const payload = { - streaming: { - tokenId: tokenId, - tokenType: 'Subscribe', - streamName: streamName, - tracking: tracking ?? null, - customViewerData: customViewerData ?? null, - allowedOrigins: allowedOrigins ?? [], - allowedIpAddresses: allowedIpAddresses ?? [] - } + streaming: Object.fromEntries(Object.entries(streaming).filter(([_, v]) => v !== null)) }; this._validateStreamingPayload(payload.streaming); diff --git a/src/nodejs/node-tokengenerator/Tracking.mjs b/src/nodejs/node-tokengenerator/Tracking.mjs index ef68c95..feb21ca 100644 --- a/src/nodejs/node-tokengenerator/Tracking.mjs +++ b/src/nodejs/node-tokengenerator/Tracking.mjs @@ -1,5 +1,5 @@ -export default class Tracking{ - constructor(trackingId){ +export default class Tracking { + constructor(trackingId) { this.trackingId = trackingId; } } \ No newline at end of file diff --git a/src/nodejs/node-tokengenerator/index.mjs b/src/nodejs/node-tokengenerator/index.mjs index f47759f..d5d864c 100644 --- a/src/nodejs/node-tokengenerator/index.mjs +++ b/src/nodejs/node-tokengenerator/index.mjs @@ -17,10 +17,14 @@ const sstWithCustomTracking = createSSTWithCustomTrackingInformation(); // use basic SST with customViewerData const sstWithCustomViewerData = createSSTWithCustomViewerData(); -console.log('SST with no TrackingID: '+ sstNoTrackingToken + - '\nSST with parent TrackingID: '+ sstWithParentTrackingToken + - '\nSST with custom TrackingID: '+ sstWithCustomTracking + - '\nSST with customViewerData: ' + sstWithCustomViewerData); +// use basic SST with originCluster +const sstWithOriginCluster = createSSTWithOriginCluster(); + +console.log('SST with no TrackingID: ' + sstNoTrackingToken + + '\n\n\nSST with parent TrackingID: ' + sstWithParentTrackingToken + + '\n\n\nSST with custom TrackingID: ' + sstWithCustomTracking + + '\n\n\nSST with customViewerData: ' + sstWithCustomViewerData + + '\n\n\nSST with originCluster: ' + sstWithOriginCluster); function createSSTWithNoTrackingInformation(){ @@ -34,24 +38,37 @@ function createSSTWithParentTrackingInformation(){ const sampleToken = getSampleToken(); const streamName = getStreamName(sampleToken, regexStreamName); - return generator.createToken(sampleToken.id, sampleToken.token, streamName, null, null, sampleToken.tracking); + return generator.createToken(sampleToken.id, sampleToken.token, streamName, + null, null, sampleToken.tracking); } function createSSTWithCustomTrackingInformation(){ const sampleToken = getSampleToken(); const streamName = getStreamName(sampleToken, regexStreamName); - return generator.createToken(sampleToken.id, sampleToken.token, streamName, null, null, new Tracking("customTrackingId")); + return generator.createToken(sampleToken.id, sampleToken.token, streamName, + null, null, + new Tracking("customTrackingId")); } function createSSTWithCustomViewerData() { const sampleToken = getSampleToken(); const streamName = getStreamName(sampleToken, regexStreamName); - return generator.createToken(sampleToken.id, sampleToken.token, streamName, null, null, null, null, + return generator.createToken(sampleToken.id, sampleToken.token, streamName, + null, null, null, null, 'uniqueViewer1234'); } +function createSSTWithOriginCluster() { + const sampleToken = getSampleToken(); + const streamName = getStreamName(sampleToken, regexStreamName); + + return generator.createToken(sampleToken.id, sampleToken.token, streamName, + null, null, null, null, null, + 'phx-1'); +} + function getSampleToken(sampleTokenPath = '../../sample-json/sampleSST.json') { const token = JSON.parse(readFileSync(sampleTokenPath)); if (!token) { diff --git a/src/sample-json/sampleSST.json b/src/sample-json/sampleSST.json index cf1adfa..4524f77 100644 --- a/src/sample-json/sampleSST.json +++ b/src/sample-json/sampleSST.json @@ -1,22 +1,22 @@ { - "id": 527, - "token": "tokenStringtokenStringtokenStringtokenStringtokenStringtokenString", - "label": "sampleSSTLabel", - "addedOn": "2023-03-27T03:52:40Z", - "isActive": true, - "allowedOrigins": [], - "allowedIpAddresses": [], - "allowedCountries": [], - "deniedCountries": [], - "streams": [ - { - "streamName": ".*", - "isRegex": true - }, - { - "streamName": "lday0h9i", - "isRegex": false - } - ], - "originCluster": "do-sfo-legacy" + "id": 527, + "token": "tokenStringtokenStringtokenStringtokenStringtokenStringtokenString", + "label": "sampleSSTLabel", + "addedOn": "2023-03-27T03:52:40Z", + "isActive": true, + "allowedOrigins": [], + "allowedIpAddresses": [], + "allowedCountries": [], + "deniedCountries": [], + "streams": [ + { + "streamName": ".*", + "isRegex": true + }, + { + "streamName": "lday0h9i", + "isRegex": false + } + ], + "originCluster": "auto" } \ No newline at end of file diff --git a/src/sample-json/sampleSSTWithNoParentTracking.json b/src/sample-json/sampleSSTWithNoParentTracking.json index 03ee101..21197ea 100644 --- a/src/sample-json/sampleSSTWithNoParentTracking.json +++ b/src/sample-json/sampleSSTWithNoParentTracking.json @@ -1,21 +1,21 @@ { - "tracking": { - "trackingId": "test-test-test" - }, - "id": 541, - "token": "tokentokentokentokentokentokentokentokentokentokentokentokentokentokentoken", - "label": "sampleSSTLabel", - "addedOn": "2023-03-27T03:52:40Z", - "isActive": true, - "allowedOrigins": [], - "allowedIpAddresses": [], - "allowedCountries": [], - "deniedCountries": [], - "streams": [ - { - "streamName": ".*", - "isRegex": true - } - ], - "originCluster": "do-sfo-legacy" + "tracking": { + "trackingId": "test-test-test" + }, + "id": 541, + "token": "tokentokentokentokentokentokentokentokentokentokentokentokentokentokentoken", + "label": "sampleSSTLabel", + "addedOn": "2023-03-27T03:52:40Z", + "isActive": true, + "allowedOrigins": [], + "allowedIpAddresses": [], + "allowedCountries": [], + "deniedCountries": [], + "streams": [ + { + "streamName": ".*", + "isRegex": true + } + ], + "originCluster": "auto" } \ No newline at end of file diff --git a/src/sample-json/sampleSSTWithParentTracking.json b/src/sample-json/sampleSSTWithParentTracking.json index 640d944..80c5ec4 100644 --- a/src/sample-json/sampleSSTWithParentTracking.json +++ b/src/sample-json/sampleSSTWithParentTracking.json @@ -1,21 +1,21 @@ { - "tracking": { - "trackingId": "test-parent-tracking" - }, - "id": 8538, - "label": "mst-pvt-tracking-2", - "token": "testtokentesttokentesttokentesttokentesttokentesttoken", - "addedOn": "2023-03-27T03:52:40Z", - "isActive": true, - "streams": [ - { - "streamName": ".*", - "isRegex": true - } - ], - "allowedOrigins": [], - "allowedIpAddresses": [], - "allowedCountries": [], - "deniedCountries": [], - "originCluster": "do-sfo-legacy" - } \ No newline at end of file + "tracking": { + "trackingId": "test-parent-tracking" + }, + "id": 8538, + "label": "mst-pvt-tracking-2", + "token": "testtokentesttokentesttokentesttokentesttokentesttoken", + "addedOn": "2023-03-27T03:52:40Z", + "isActive": true, + "streams": [ + { + "streamName": ".*", + "isRegex": true + } + ], + "allowedOrigins": [], + "allowedIpAddresses": [], + "allowedCountries": [], + "deniedCountries": [], + "originCluster": "auto" +} \ No newline at end of file