Skip to content

Commit b8b21d1

Browse files
committed
bdcli api wssurl :: sign WSS URL for connecting to Boiling WebSocket API e.g. with wscat
1 parent 4ef3097 commit b8b21d1

File tree

7 files changed

+1464
-559
lines changed

7 files changed

+1464
-559
lines changed

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@
5656
}
5757
},
5858
"dependencies": {
59-
"@aws-sdk/client-iam": "^3.395.0",
60-
"@aws-sdk/client-sts": "^3.395.0",
59+
"@aws-amplify/core": "^3.8.8",
60+
"@aws-sdk/client-cognito-identity": "^3.533.0",
61+
"@aws-sdk/client-iam": "^3.533.0",
62+
"@aws-sdk/client-sts": "^3.533.0",
63+
"@aws-sdk/credential-provider-cognito-identity": "^3.533.0",
6164
"amazon-cognito-identity-js": "^6.3.4",
6265
"aws-jwt-verify": "^4.0.0",
6366
"chalk": "^4.0.0",
@@ -79,6 +82,7 @@
7982
"@swc/core": "^1.3.78",
8083
"@swc/jest": "^0.2.29",
8184
"@tsconfig/node-lts": "^18.12.4",
85+
"@types/commander": "^2.12.2",
8286
"@types/jest": "^29.5.4",
8387
"@types/js-yaml": "^4.0.5",
8488
"@types/jsonwebtoken": "^9.0.2",
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as cmd from "commander";
2+
import { ELogLevel, getLogger } from "../../utils/logger_util.js";
3+
import { spinnerError, spinnerSuccess, updateSpinnerText } from "../../utils/spinner_util.js";
4+
import { addGlobalOptions } from "../../utils/options_util.js";
5+
import { getIdToken } from "../../utils/auth_util.js";
6+
import { combineOptsWithSettings } from "../../utils/config_util.js";
7+
import { getSignedWssUrl } from "../../../integration/aws/sign-wss-url.js";
8+
import { outputResults } from "../../utils/output_util.js";
9+
10+
const logger = getLogger("bdcli-api");
11+
logger.setLogLevel(ELogLevel.WARN);
12+
13+
async function wssurl(options: any, _command: cmd.Command): Promise<void> {
14+
try {
15+
options = await combineOptsWithSettings(options, logger);
16+
17+
updateSpinnerText("Authenticating");
18+
const { idToken: token, cached, region } = await getIdToken(logger);
19+
updateSpinnerText(cached ? "Authenticating: cached" : "Authenticating: success");
20+
spinnerSuccess();
21+
22+
updateSpinnerText("Getting signed WebSocket URL (ws://)");
23+
const signedUrl = await getSignedWssUrl(logger, token, region);
24+
spinnerSuccess();
25+
await outputResults(signedUrl, options.disableSpinner);
26+
} catch (err: any) {
27+
spinnerError(err?.message);
28+
}
29+
}
30+
31+
const program = new cmd.Command("bdcli api wssurl").action(async (options, command) => await wssurl(options, command));
32+
33+
(async () => {
34+
await addGlobalOptions(program, logger);
35+
await program.parseAsync(process.argv);
36+
})();

src/bdcli/commands/bdcli-api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Command } from "commander";
2+
3+
const program = new Command("bdcli api")
4+
.executableDir("api")
5+
.command("wssurl", "Get signed WebSocket (wss://) URL for connecting to Boiling Data");
6+
7+
program.parse(process.argv);

src/bdcli/utils/auth_util.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import qrcode from "qrcode";
88
import { resumeSpinner, spinnerError, spinnerInfo, stopSpinner, updateSpinnerText } from "./spinner_util.js";
99
import ms from "ms";
1010

11-
const userPoolId = "eu-west-1_0GLV9KO1p"; // eu-west-1 preview
12-
const clientId = "6timr8knllr4frovfvq8r2o6oo"; // eu-west-1 preview
11+
export const userPoolId = "eu-west-1_0GLV9KO1p"; // eu-west-1 preview
12+
export const clientId = "6timr8knllr4frovfvq8r2o6oo"; // eu-west-1 preview
1313

1414
export async function authSpinnerWithConfigCheck(): Promise<boolean> {
1515
updateSpinnerText("Authenticating");

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ program
1111
.command("account", "Setup and configure your BoilingData account")
1212
.command("aws", "Setup and configure your AWS account integration with BoilingData")
1313
.command("domain", "Admin setup and configuration for your domain (.e.g @boilingdata.com, @mycompany.com)")
14-
.command("sandbox", "Managa Boiling S3 Sandboxes with IaC templates");
14+
.command("sandbox", "Managa Boiling S3 Sandboxes with IaC templates")
15+
.command("api", "Get signed WSS URL etc.");
1516

1617
program.parse(process.argv);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity";
2+
import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity";
3+
import { ILogger } from "../../bdcli/utils/logger_util.js";
4+
import { UserPoolId } from "../boilingdata/boilingdata_api.js";
5+
import { Signer } from "@aws-amplify/core";
6+
7+
interface AwsCredentials {
8+
readonly accessKeyId: string;
9+
readonly secretAccessKey: string;
10+
readonly sessionToken?: string;
11+
readonly credentialScope?: string;
12+
}
13+
14+
async function getAwsCredentials(jwtIdToken: string, region: string): Promise<AwsCredentials> {
15+
const IdentityPoolId = "eu-west-1:bce21571-e3a6-47a4-8032-fd015213405f";
16+
// const poolData = { UserPoolId, ClientId: "6timr8knllr4frovfvq8r2o6oo" };
17+
// const Pool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
18+
const Logins = `cognito-idp.${region}.amazonaws.com/${UserPoolId}`;
19+
const cognitoidentity = new CognitoIdentityClient({
20+
credentials: fromCognitoIdentityPool({
21+
client: new CognitoIdentityClient(),
22+
identityPoolId: IdentityPoolId,
23+
logins: {
24+
[Logins]: jwtIdToken,
25+
},
26+
}),
27+
});
28+
return cognitoidentity.config.credentials();
29+
}
30+
31+
export async function getSignedWssUrl(_logger: ILogger, token: string, region: string): Promise<string> {
32+
const creds = await getAwsCredentials(token, region);
33+
const url = "wss://4rpyi2ae3f.execute-api.eu-west-1.amazonaws.com/prodbd";
34+
const signedWsUrl = Signer.signUrl(url, {
35+
access_key: creds.accessKeyId,
36+
secret_key: creds.secretAccessKey,
37+
session_token: creds.sessionToken,
38+
});
39+
return signedWsUrl;
40+
}

0 commit comments

Comments
 (0)