mirror of
https://github.com/jambonz/speech-utils.git
synced 2026-01-25 02:08:26 +00:00
added function to get an AWS security token using STS
This commit is contained in:
11
index.js
11
index.js
@@ -3,10 +3,12 @@ const {noopLogger} = require('./lib/utils');
|
||||
module.exports = (opts, logger) => {
|
||||
logger = logger || noopLogger;
|
||||
let client = opts.redis_client;
|
||||
if (!client) {
|
||||
const {client: redisClient} = require('@jambonz/realtimedb-helpers')(opts, logger);
|
||||
client = redisClient;
|
||||
}
|
||||
const {
|
||||
client: redisClient,
|
||||
createHash,
|
||||
retrieveHash
|
||||
} = require('@jambonz/realtimedb-helpers')(opts, logger);
|
||||
client = opts.redis_client || redisClient;
|
||||
|
||||
return {
|
||||
client,
|
||||
@@ -15,6 +17,7 @@ module.exports = (opts, logger) => {
|
||||
synthAudio: require('./lib/synth-audio').bind(null, client, logger),
|
||||
getNuanceAccessToken: require('./lib/get-nuance-access-token').bind(null, client, logger),
|
||||
getIbmAccessToken: require('./lib/get-ibm-access-token').bind(null, client, logger),
|
||||
getAwsAuthToken: require('./lib/get-aws-sts-token').bind(null, logger, createHash, retrieveHash),
|
||||
getTtsVoices: require('./lib/get-tts-voices').bind(null, client, logger),
|
||||
};
|
||||
};
|
||||
|
||||
44
lib/get-aws-sts-token.js
Normal file
44
lib/get-aws-sts-token.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const { STSClient, GetSessionTokenCommand } = require('@aws-sdk/client-sts');
|
||||
const {makeAwsKey, noopLogger} = require('./utils');
|
||||
const debug = require('debug')('jambonz:speech-utils');
|
||||
const EXPIRY = 3600;
|
||||
|
||||
async function getAwsAuthToken(
|
||||
logger,
|
||||
createHash, retrieveHash,
|
||||
awsAccessKeyId, awsSecretAccessKey, awsRegion) {
|
||||
logger = logger || noopLogger;
|
||||
try {
|
||||
const key = makeAwsKey(awsAccessKeyId);
|
||||
const obj = await retrieveHash(key);
|
||||
if (obj) return {...obj, servedFromCache: true};
|
||||
|
||||
/* access token not found in cache, so generate it using STS */
|
||||
const stsClient = new STSClient({ region: awsRegion });
|
||||
const params = {
|
||||
accessKeyId: awsAccessKeyId,
|
||||
secretAccessKey: awsSecretAccessKey,
|
||||
DurationSeconds: EXPIRY
|
||||
};
|
||||
const command = new GetSessionTokenCommand(params);
|
||||
const data = await stsClient.send(command);
|
||||
|
||||
const credentials = {
|
||||
accessKeyId: data.Credentials.AccessKeyId,
|
||||
secretAccessKey: data.Credentials.SecretAccessKey,
|
||||
sessionToken: data.Credentials.SessionToken
|
||||
};
|
||||
|
||||
/* expire 10 minutes before the hour, so we don't lose the use of it during a call */
|
||||
createHash(key, credentials, EXPIRY - 600)
|
||||
.catch((err) => logger.error(err, `Error saving hash for key ${key}`));
|
||||
|
||||
return {...credentials, servedFromCache: false};
|
||||
} catch (err) {
|
||||
debug(err, 'getAwsAuthToken: Error retrieving AWS auth token');
|
||||
logger.error(err, 'getAwsAuthToken: Error retrieving AWS auth token');
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = getAwsAuthToken;
|
||||
@@ -43,6 +43,12 @@ function makeIbmKey(apiKey) {
|
||||
return `ibm:${hash.digest('hex')}`;
|
||||
}
|
||||
|
||||
function makeAwsKey(awsAccessKeyId) {
|
||||
const hash = crypto.createHash('sha1');
|
||||
hash.update(awsAccessKeyId);
|
||||
return `aws:${hash.digest('hex')}`;
|
||||
}
|
||||
|
||||
function makeNuanceKey(clientId, secret, scope) {
|
||||
const hash = crypto.createHash('sha1');
|
||||
hash.update(`${clientId}:${secret}:${scope}`);
|
||||
@@ -110,6 +116,7 @@ module.exports = {
|
||||
makeSynthKey,
|
||||
makeNuanceKey,
|
||||
makeIbmKey,
|
||||
makeAwsKey,
|
||||
getNuanceAccessToken,
|
||||
createNuanceClient,
|
||||
createKryptonClient,
|
||||
|
||||
5441
package-lock.json
generated
5441
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@
|
||||
"homepage": "https://github.com/jambonz/speech-utils#readme",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-polly": "^3.359.0",
|
||||
"@aws-sdk/client-sts": "^3.458.0",
|
||||
"@google-cloud/text-to-speech": "^4.2.1",
|
||||
"@grpc/grpc-js": "^1.8.13",
|
||||
"@jambonz/realtimedb-helpers": "^0.8.7",
|
||||
|
||||
40
test/aws.js
Normal file
40
test/aws.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const test = require('tape').test ;
|
||||
const config = require('config');
|
||||
const opts = config.get('redis');
|
||||
const logger = require('pino')({level: 'error'});
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
test('AWS - create and cache auth token', async(t) => {
|
||||
const fn = require('..');
|
||||
const {client, getAwsAuthToken} = fn(opts, logger);
|
||||
|
||||
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY || !process.env.AWS_REGION) {
|
||||
t.pass('skipping AWS auth token tests since no AWS credentials provided');
|
||||
t.end();
|
||||
client.quit();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let obj = await getAwsAuthToken(process.env.AWS_ACCESS_KEY_ID, process.env.AWS_SECRET_ACCESS_KEY, process.env.AWS_REGION);
|
||||
console.log({obj}, 'received auth token from AWS');
|
||||
t.ok(obj.sessionToken && !obj.servedFromCache, 'successfullY generated auth token from AWS');
|
||||
|
||||
await sleep(250);
|
||||
obj = await getAwsAuthToken(process.env.AWS_ACCESS_KEY_ID, process.env.AWS_SECRET_ACCESS_KEY, process.env.AWS_REGION);
|
||||
console.log({obj}, 'received auth token from AWS - second request');
|
||||
t.ok(obj.sessionToken && obj.servedFromCache, 'successfully received access token from cache');
|
||||
|
||||
await client.flushall();
|
||||
t.end();
|
||||
}
|
||||
catch (err) {
|
||||
console.error(err);
|
||||
t.end(err);
|
||||
}
|
||||
client.quit();
|
||||
});
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
require('./docker_start');
|
||||
require('./synth');
|
||||
require('./list-voices');
|
||||
require('./aws');
|
||||
require('./ibm');
|
||||
require('./nuance');
|
||||
require('./docker_stop');
|
||||
|
||||
Reference in New Issue
Block a user