@sp-api-sdk/auth
Advanced tools
Comparing version 1.11.6 to 2.0.0
@@ -17,2 +17,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./src"), exports); | ||
__exportStar(require("./src/index"), exports); |
@@ -8,5 +8,5 @@ "use strict"; | ||
const node_process_1 = __importDefault(require("node:process")); | ||
const access_token_1 = require("./access-token"); | ||
const sts_1 = require("./sts"); | ||
const package_1 = require("./utils/package"); | ||
const axios_1 = require("axios"); | ||
const error_1 = require("./error"); | ||
const axios_2 = require("./utils/axios"); | ||
/** | ||
@@ -16,25 +16,12 @@ * Class for simplify auth with Selling Partner API | ||
class SellingPartnerApiAuth { | ||
clientId; | ||
clientSecret; | ||
refreshToken; | ||
scopes; | ||
accessToken; | ||
_sts; | ||
_accessKeyId; | ||
_secretAccessKey; | ||
_sessionToken; | ||
accessTokenExpiration; | ||
constructor(parameters) { | ||
const clientId = parameters.clientId ?? node_process_1.default.env.LWA_CLIENT_ID; | ||
const clientSecret = parameters.clientSecret ?? node_process_1.default.env.LWA_CLIENT_SECRET; | ||
const accessKeyId = parameters.accessKeyId ?? node_process_1.default.env.AWS_ACCESS_KEY_ID; | ||
const secretAccessKey = parameters.secretAccessKey ?? node_process_1.default.env.AWS_SECRET_ACCESS_KEY; | ||
const sessionToken = parameters.sessionToken ?? node_process_1.default.env.AWS_SESSION_TOKEN; | ||
const region = parameters.region ?? node_process_1.default.env.AWS_DEFAULT_REGION; | ||
const roleArn = parameters.role?.arn ?? node_process_1.default.env.AWS_ROLE_ARN; | ||
const roleSessionName = parameters.role?.sessionName ?? | ||
node_process_1.default.env.AWS_ROLE_SESSION_NAME ?? | ||
`sp-api-sdk-auth@${package_1.packageJson.version}`; | ||
let role = null; | ||
if (roleArn) { | ||
role = { | ||
arn: roleArn, | ||
sessionName: roleSessionName, | ||
}; | ||
} | ||
const refreshToken = parameters.refreshToken ?? node_process_1.default.env.LWA_REFRESH_TOKEN; | ||
if (!clientId) { | ||
@@ -46,56 +33,50 @@ throw new Error('Missing required `clientId` configuration value'); | ||
} | ||
if (!accessKeyId) { | ||
throw new Error('Missing required `accessKeyId` configuration value'); | ||
} | ||
if (!secretAccessKey) { | ||
throw new Error('Missing required `secretAccessKey` configuration value'); | ||
} | ||
this._accessKeyId = accessKeyId; | ||
this._secretAccessKey = secretAccessKey; | ||
this._sessionToken = sessionToken; | ||
if (parameters.refreshToken) { | ||
this.accessToken = new access_token_1.AccessTokenFactory({ | ||
clientId, | ||
clientSecret, | ||
refreshToken: parameters.refreshToken, | ||
}); | ||
} | ||
else if (parameters.scopes) { | ||
this.accessToken = new access_token_1.AccessTokenFactory({ | ||
clientId, | ||
clientSecret, | ||
scopes: parameters.scopes, | ||
}); | ||
} | ||
else { | ||
if (!refreshToken && !parameters.scopes) { | ||
throw new TypeError('Either `refreshToken` or `scopes` must be specified'); | ||
} | ||
if (role) { | ||
this._sts = new sts_1.SecurityTokenService({ | ||
accessKeyId, | ||
secretAccessKey, | ||
sessionToken, | ||
region, | ||
role, | ||
}); | ||
} | ||
this.clientId = clientId; | ||
this.clientSecret = clientSecret; | ||
this.refreshToken = refreshToken; | ||
this.scopes = parameters.scopes; | ||
} | ||
/** | ||
* Get AWS credentials from STS or user | ||
* Get access token | ||
*/ | ||
async getCredentials() { | ||
if (this._sts) { | ||
return this._sts.getCredentials(); | ||
async getAccessToken() { | ||
if (!this.accessToken || | ||
(this.accessTokenExpiration && Date.now() >= this.accessTokenExpiration.getTime())) { | ||
const body = { | ||
client_id: this.clientId, | ||
client_secret: this.clientSecret, | ||
...(this.refreshToken | ||
? { | ||
grant_type: 'refresh_token', | ||
refresh_token: this.refreshToken, | ||
} | ||
: { | ||
grant_type: 'client_credentials', | ||
scope: this.scopes.join(' '), | ||
}), | ||
}; | ||
try { | ||
const expiration = new Date(); | ||
const { data } = await axios_2.axios.post('/o2/token', body); | ||
expiration.setSeconds(expiration.getSeconds() + data.expires_in); | ||
this.accessToken = data.access_token; | ||
this.accessTokenExpiration = expiration; | ||
} | ||
catch (error) { | ||
if (error instanceof axios_1.AxiosError) { | ||
throw new error_1.SellingPartnerApiAuthError(error); | ||
} | ||
throw error; | ||
} | ||
} | ||
return { | ||
AccessKeyId: this._accessKeyId, | ||
SecretAccessKey: this._secretAccessKey, | ||
SessionToken: this._sessionToken, | ||
}; | ||
return this.accessToken; | ||
} | ||
} | ||
exports.SellingPartnerApiAuth = SellingPartnerApiAuth; | ||
var error_1 = require("./error"); | ||
Object.defineProperty(exports, "SellingPartnerApiAuthError", { enumerable: true, get: function () { return error_1.SellingPartnerApiAuthError; } }); | ||
var error_2 = require("./error"); | ||
Object.defineProperty(exports, "SellingPartnerApiAuthError", { enumerable: true, get: function () { return error_2.SellingPartnerApiAuthError; } }); | ||
var scope_1 = require("./types/scope"); | ||
Object.defineProperty(exports, "AuthorizationScope", { enumerable: true, get: function () { return scope_1.AuthorizationScope; } }); |
@@ -1,1 +0,1 @@ | ||
export * from './src'; | ||
export * from './src/index'; |
import process from 'node:process'; | ||
import { AccessTokenFactory } from './access-token'; | ||
import { SecurityTokenService } from './sts'; | ||
import { packageJson } from './utils/package'; | ||
import { AxiosError } from 'axios'; | ||
import { SellingPartnerApiAuthError } from './error'; | ||
import { axios } from './utils/axios'; | ||
/** | ||
@@ -9,25 +9,12 @@ * Class for simplify auth with Selling Partner API | ||
export class SellingPartnerApiAuth { | ||
clientId; | ||
clientSecret; | ||
refreshToken; | ||
scopes; | ||
accessToken; | ||
_sts; | ||
_accessKeyId; | ||
_secretAccessKey; | ||
_sessionToken; | ||
accessTokenExpiration; | ||
constructor(parameters) { | ||
const clientId = parameters.clientId ?? process.env.LWA_CLIENT_ID; | ||
const clientSecret = parameters.clientSecret ?? process.env.LWA_CLIENT_SECRET; | ||
const accessKeyId = parameters.accessKeyId ?? process.env.AWS_ACCESS_KEY_ID; | ||
const secretAccessKey = parameters.secretAccessKey ?? process.env.AWS_SECRET_ACCESS_KEY; | ||
const sessionToken = parameters.sessionToken ?? process.env.AWS_SESSION_TOKEN; | ||
const region = parameters.region ?? process.env.AWS_DEFAULT_REGION; | ||
const roleArn = parameters.role?.arn ?? process.env.AWS_ROLE_ARN; | ||
const roleSessionName = parameters.role?.sessionName ?? | ||
process.env.AWS_ROLE_SESSION_NAME ?? | ||
`sp-api-sdk-auth@${packageJson.version}`; | ||
let role = null; | ||
if (roleArn) { | ||
role = { | ||
arn: roleArn, | ||
sessionName: roleSessionName, | ||
}; | ||
} | ||
const refreshToken = parameters.refreshToken ?? process.env.LWA_REFRESH_TOKEN; | ||
if (!clientId) { | ||
@@ -39,50 +26,44 @@ throw new Error('Missing required `clientId` configuration value'); | ||
} | ||
if (!accessKeyId) { | ||
throw new Error('Missing required `accessKeyId` configuration value'); | ||
} | ||
if (!secretAccessKey) { | ||
throw new Error('Missing required `secretAccessKey` configuration value'); | ||
} | ||
this._accessKeyId = accessKeyId; | ||
this._secretAccessKey = secretAccessKey; | ||
this._sessionToken = sessionToken; | ||
if (parameters.refreshToken) { | ||
this.accessToken = new AccessTokenFactory({ | ||
clientId, | ||
clientSecret, | ||
refreshToken: parameters.refreshToken, | ||
}); | ||
} | ||
else if (parameters.scopes) { | ||
this.accessToken = new AccessTokenFactory({ | ||
clientId, | ||
clientSecret, | ||
scopes: parameters.scopes, | ||
}); | ||
} | ||
else { | ||
if (!refreshToken && !parameters.scopes) { | ||
throw new TypeError('Either `refreshToken` or `scopes` must be specified'); | ||
} | ||
if (role) { | ||
this._sts = new SecurityTokenService({ | ||
accessKeyId, | ||
secretAccessKey, | ||
sessionToken, | ||
region, | ||
role, | ||
}); | ||
} | ||
this.clientId = clientId; | ||
this.clientSecret = clientSecret; | ||
this.refreshToken = refreshToken; | ||
this.scopes = parameters.scopes; | ||
} | ||
/** | ||
* Get AWS credentials from STS or user | ||
* Get access token | ||
*/ | ||
async getCredentials() { | ||
if (this._sts) { | ||
return this._sts.getCredentials(); | ||
async getAccessToken() { | ||
if (!this.accessToken || | ||
(this.accessTokenExpiration && Date.now() >= this.accessTokenExpiration.getTime())) { | ||
const body = { | ||
client_id: this.clientId, | ||
client_secret: this.clientSecret, | ||
...(this.refreshToken | ||
? { | ||
grant_type: 'refresh_token', | ||
refresh_token: this.refreshToken, | ||
} | ||
: { | ||
grant_type: 'client_credentials', | ||
scope: this.scopes.join(' '), | ||
}), | ||
}; | ||
try { | ||
const expiration = new Date(); | ||
const { data } = await axios.post('/o2/token', body); | ||
expiration.setSeconds(expiration.getSeconds() + data.expires_in); | ||
this.accessToken = data.access_token; | ||
this.accessTokenExpiration = expiration; | ||
} | ||
catch (error) { | ||
if (error instanceof AxiosError) { | ||
throw new SellingPartnerApiAuthError(error); | ||
} | ||
throw error; | ||
} | ||
} | ||
return { | ||
AccessKeyId: this._accessKeyId, | ||
SecretAccessKey: this._secretAccessKey, | ||
SessionToken: this._sessionToken, | ||
}; | ||
return this.accessToken; | ||
} | ||
@@ -89,0 +70,0 @@ } |
@@ -1,1 +0,1 @@ | ||
export * from './src'; | ||
export * from './src/index'; |
@@ -1,5 +0,3 @@ | ||
import type { Credentials } from '@aws-sdk/client-sts'; | ||
import type { RequireExactlyOne, SetOptional } from 'type-fest'; | ||
import { AccessTokenFactory } from './access-token'; | ||
import type { AuthorizationScope } from './types/scope'; | ||
import { type RequireExactlyOne } from 'type-fest'; | ||
import { type AuthorizationScope } from './types/scope'; | ||
export interface SellingPartnerAuthParameters { | ||
@@ -10,10 +8,2 @@ clientId?: string; | ||
scopes?: AuthorizationScope[]; | ||
accessKeyId?: string; | ||
secretAccessKey?: string; | ||
sessionToken?: string; | ||
region?: string; | ||
role?: { | ||
arn: string; | ||
sessionName?: string; | ||
}; | ||
} | ||
@@ -24,14 +14,15 @@ /** | ||
export declare class SellingPartnerApiAuth { | ||
readonly accessToken: AccessTokenFactory; | ||
private readonly _sts?; | ||
private readonly _accessKeyId; | ||
private readonly _secretAccessKey; | ||
private readonly _sessionToken?; | ||
private readonly clientId; | ||
private readonly clientSecret; | ||
private readonly refreshToken?; | ||
private readonly scopes?; | ||
private accessToken?; | ||
private accessTokenExpiration?; | ||
constructor(parameters: RequireExactlyOne<SellingPartnerAuthParameters, 'refreshToken' | 'scopes'>); | ||
/** | ||
* Get AWS credentials from STS or user | ||
* Get access token | ||
*/ | ||
getCredentials(): Promise<SetOptional<Credentials, 'Expiration' | 'SessionToken'>>; | ||
getAccessToken(): Promise<string>; | ||
} | ||
export { SellingPartnerApiAuthError } from './error'; | ||
export { AuthorizationScope } from './types/scope'; |
@@ -5,3 +5,3 @@ { | ||
"description": "Amazon Selling Partner API authentication package", | ||
"version": "1.11.6", | ||
"version": "2.0.0", | ||
"main": "dist/cjs/index.js", | ||
@@ -22,3 +22,2 @@ "module": "dist/es/index.js", | ||
"dependencies": { | ||
"@aws-sdk/client-sts": "^3.418.0", | ||
"axios": "^1.5.1", | ||
@@ -46,3 +45,3 @@ "read-pkg-up": "^7.0.1" | ||
], | ||
"gitHead": "504bc3889d8c5dba1870b3c1a3b3f4ab1cf8b7cc" | ||
"gitHead": "a278405620f714b7bf6c42692d265f76d952bd49" | ||
} |
@@ -9,48 +9,2 @@ # `@sp-api-sdk/auth` | ||
## Authentication models | ||
This library supports both authentication models: IAM user credentials, or an IAM role (using [STS](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) AssumeRole). | ||
### Using an AWS IAM user | ||
```javascript | ||
import { SellingPartnerApiAuth } from "@sp-api-sdk/auth"; | ||
const auth = new SellingPartnerApiAuth({ | ||
clientId: "", | ||
clientSecret: "", | ||
refreshToken: "Atzr|...", | ||
accessKeyId: "", | ||
secretAccessKey: "", | ||
sessionToken: "", // If you’re authenticated using temporary credentials | ||
}); | ||
const accessToken = await auth.accessToken.get(); | ||
const { AccessKeyId, SecretAccessKey } = await auth.getCredentials(); | ||
``` | ||
### Using an AWS IAM role | ||
```javascript | ||
import { SellingPartnerApiAuth } from "@sp-api-sdk/auth"; | ||
const auth = new SellingPartnerApiAuth({ | ||
clientId: "", | ||
clientSecret: "", | ||
refreshToken: "Atzr|...", | ||
accessKeyId: "", | ||
secretAccessKey: "", | ||
region: "", // You can provide an AWS region that will be used for the STS calls | ||
role: { | ||
arn: "", | ||
sessionName: "SellingPartnerAPI", // Optional | ||
}, | ||
}); | ||
const accessToken = await auth.accessToken.get(); | ||
const { AccessKeyId, SecretAccessKey, SessionToken } = await auth.getCredentials(); | ||
``` | ||
`getCredentials` will return a set of temporary security credentials that last for 1 hour. | ||
## Default values from the environment | ||
@@ -60,12 +14,7 @@ | ||
| Property Name | Environement variable | | ||
| ------------------ | --------------------- | | ||
| `clientId` | LWA_CLIENT_ID | | ||
| `clientSecret` | LWA_CLIENT_SECRET | | ||
| `accessKeyId` | AWS_ACCESS_KEY_ID | | ||
| `secretAccessKey` | AWS_SECRET_ACCESS_KEY | | ||
| `sessionToken` | AWS_SESSION_TOKEN | | ||
| `region` | AWS_DEFAULT_REGION | | ||
| `role.arn` | AWS_ROLE_ARN | | ||
| `role.sessionName` | AWS_ROLE_SESSION_NAME | | ||
| Property Name | Environement variable | | ||
| -------------- | --------------------- | | ||
| `clientId` | LWA_CLIENT_ID | | ||
| `clientSecret` | LWA_CLIENT_SECRET | | ||
| `refreshToken` | LWA_REFRESH_TOKEN | | ||
@@ -85,8 +34,5 @@ ## Grantless APIs support | ||
scopes: Object.values(AuthorizationScope), // Or choose the only ones you need | ||
accessKeyId: "", | ||
secretAccessKey: "", | ||
}); | ||
const accessToken = await auth.accessToken.get(); | ||
const credentials = await auth.getCredentials(); | ||
const accessToken = await auth.getAccessToken(); | ||
``` | ||
@@ -96,4 +42,2 @@ | ||
`accessToken.get()` caches the access token for its whole duration, it will only request a new token if the current one has expired. | ||
The same goes for the STS temporary credentials returned by `getCredentials`, the credentials are cached until they expire. | ||
`getAccessToken()` caches the access token for its whole duration, it will only request a new token if the current one has expired. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 6 instances in 1 package
2
3
15429
24
312
40
1
- Removed@aws-sdk/client-sts@^3.418.0
- Removed@aws-sdk/client-sts@3.565.0(transitive)