ebay-api 8.7.1 → 8.7.2-RC.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,7 +21,7 @@ It supports `client credentials grant` and `authorization code grant` \(Auth'N'A
21
21
 
22
22
  ## Changelog
23
23
 
24
- * `v8.7.1` is the latest release.
24
+ * `v8.7.2-RC.0` is the latest release.
25
25
  * See [here](https://github.com/hendt/ebay-api/blob/master/CHANGELOG.md) for the full changelog.
26
26
 
27
27
  ## Implementation status
@@ -1,4 +1,5 @@
1
1
  import { Cipher, Headers } from '../types/index.js';
2
+ export declare const getUnixTimestamp: () => number;
2
3
  export declare const generateContentDigestValue: (payload: unknown, cipher?: Cipher) => string;
3
4
  export type SignatureComponents = {
4
5
  method: string;
@@ -1,7 +1,7 @@
1
1
  import { createHash, sign } from 'crypto';
2
2
  const beginPrivateKey = '-----BEGIN PRIVATE KEY-----';
3
3
  const endPrivateKey = '-----END PRIVATE KEY-----';
4
- const getUnixTimestamp = () => Date.now() / 1000 | 0;
4
+ export const getUnixTimestamp = () => Math.floor(Date.now() / 1000);
5
5
  const getSignatureParams = (payload) => [
6
6
  ...payload ? ['content-digest'] : [],
7
7
  'x-ebay-signature-key',
package/dist/api/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import Auth from '../auth/index.js';
2
2
  import Base from './base.js';
3
- import { generateContentDigestValue, generateSignature, generateSignatureInput } from './digitalSignature.js';
3
+ import { generateContentDigestValue, generateSignature, generateSignatureInput, getUnixTimestamp } from './digitalSignature.js';
4
4
  export default class Api extends Base {
5
5
  constructor(config, req, auth) {
6
6
  super(config, req);
@@ -10,17 +10,18 @@ export default class Api extends Base {
10
10
  if (!this.config.signature) {
11
11
  return {};
12
12
  }
13
+ const timestamp = getUnixTimestamp();
13
14
  const digitalSignatureHeaders = {
14
15
  'x-ebay-enforce-signature': true,
15
16
  'x-ebay-signature-key': this.config.signature.jwe,
16
17
  ...payload ? {
17
18
  'content-digest': generateContentDigestValue(payload, this.config.signature.cipher ?? 'sha256')
18
19
  } : {},
19
- 'signature-input': generateSignatureInput(payload)
20
+ 'signature-input': generateSignatureInput(payload, timestamp)
20
21
  };
21
22
  return {
22
23
  ...digitalSignatureHeaders,
23
- 'signature': generateSignature(digitalSignatureHeaders, this.config.signature.privateKey, signatureComponents, payload)
24
+ 'signature': generateSignature(digitalSignatureHeaders, this.config.signature.privateKey, signatureComponents, payload, timestamp)
24
25
  };
25
26
  }
26
27
  }
@@ -9,7 +9,7 @@ export default class Analytics extends Restful implements OpenApi<operations> {
9
9
  getTrafficReport({ dimension, filter, metric, sort }?: {
10
10
  dimension?: string;
11
11
  filter?: string;
12
- metric?: Metric | `${Metric}`;
12
+ metric?: string | Metric | `${Metric}`;
13
13
  sort?: string;
14
14
  }): Promise<any>;
15
15
  getCustomerServiceMetric(customerServiceMetricType: string, evaluationType: string): Promise<any>;
@@ -8,6 +8,7 @@ export default class Traditional extends Api {
8
8
  createMerchandisingApi(): Merchandising;
9
9
  createBusinessPolicyManagementApi(): void;
10
10
  private createXMLRequest;
11
+ private shouldRefreshToken;
11
12
  private request;
12
13
  private getConfig;
13
14
  private createTraditionalXMLApi;
@@ -1,5 +1,5 @@
1
1
  import { stringify } from 'qs';
2
- import { EBayIAFTokenExpired, EBayIAFTokenInvalid, handleEBayError } from '../../errors/index.js';
2
+ import { EBayAuthTokenIsHardExpired, EBayIAFTokenExpired, EBayIAFTokenInvalid, handleEBayError } from '../../errors/index.js';
3
3
  import Api from '../index.js';
4
4
  import ClientAlertsCalls from './clientAlerts/index.js';
5
5
  import FindingCalls from './finding/index.js';
@@ -16,7 +16,7 @@ export default class Traditional extends Api {
16
16
  return await this.request(apiConfig, api, callName, fields);
17
17
  }
18
18
  catch (error) {
19
- if (this.config.autoRefreshToken && (error.name === EBayIAFTokenExpired.name || error.name === EBayIAFTokenInvalid.name)) {
19
+ if (this.shouldRefreshToken(error)) {
20
20
  return await this.request(apiConfig, api, callName, fields, true);
21
21
  }
22
22
  throw error;
@@ -140,6 +140,14 @@ export default class Traditional extends Api {
140
140
  createBusinessPolicyManagementApi() {
141
141
  throw new Error('Important! This API is deprecated and will be decommissioned on January 31, 2022. We recommend that you migrate to the fulfillment_policy, payment_policy, and return_policy resources of the Account API to set up and manage all of your fulfillment, payment, and return business policies.');
142
142
  }
143
+ shouldRefreshToken(error) {
144
+ if (!this.config.autoRefreshToken) {
145
+ return false;
146
+ }
147
+ return error.name === EBayIAFTokenExpired.name
148
+ || error.name === EBayIAFTokenInvalid.name
149
+ || error.name === EBayAuthTokenIsHardExpired.name;
150
+ }
143
151
  async request(apiConfig, api, callName, fields, refreshToken = false) {
144
152
  try {
145
153
  if (refreshToken) {
@@ -1,5 +1,5 @@
1
- import { EventCallback } from '../nanoevents.js';
2
1
  import Base from '../api/base.js';
2
+ import { EventCallback } from '../nanoevents.js';
3
3
  import { IEBayApiRequest } from '../request.js';
4
4
  import { AppConfig, Scope } from '../types/index.js';
5
5
  export type Token = {
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug';
2
- import { createNanoEvents } from '../nanoevents.js';
3
2
  import Base from '../api/base.js';
3
+ import { createNanoEvents } from '../nanoevents.js';
4
4
  const log = debug('ebay:oauth2');
5
5
  class OAuth2 extends Base {
6
6
  constructor(config, req) {
@@ -60,13 +60,13 @@ class OAuth2 extends Base {
60
60
  throw new Error('Missing Cert Id (Client Secret)');
61
61
  }
62
62
  try {
63
- const response = await this.req.postForm(this.identityEndpoint, {
63
+ const response = await this.req.post(this.identityEndpoint, {
64
64
  scope: this.scope.join(' '),
65
- grant_type: 'client_credentials'
65
+ grant_type: 'client_credentials',
66
66
  }, {
67
- auth: {
68
- username: this.config.appId,
69
- password: this.config.certId
67
+ headers: {
68
+ 'Content-Type': 'application/x-www-form-urlencoded',
69
+ 'Authorization': 'Basic ' + btoa(this.config.appId + ':' + this.config.certId)
70
70
  }
71
71
  });
72
72
  return response.data;
@@ -98,15 +98,21 @@ class OAuth2 extends Base {
98
98
  return OAuth2.generateAuthUrl(this.config.sandbox, this.config.appId, ruName, scope, state);
99
99
  }
100
100
  async mintUserAccessToken(code, ruName = this.config.ruName) {
101
+ if (!this.config.appId) {
102
+ throw new Error('Missing App ID (Client Id)');
103
+ }
104
+ if (!this.config.certId) {
105
+ throw new Error('Missing Cert Id (Client Secret)');
106
+ }
101
107
  try {
102
- const response = await this.req.postForm(this.identityEndpoint, {
108
+ const response = await this.req.post(this.identityEndpoint, {
103
109
  grant_type: 'authorization_code',
104
110
  code,
105
111
  redirect_uri: ruName
106
112
  }, {
107
- auth: {
108
- username: this.config.appId,
109
- password: this.config.certId
113
+ headers: {
114
+ 'Content-Type': 'application/x-www-form-urlencoded',
115
+ 'Authorization': 'Basic ' + btoa(this.config.appId + ':' + this.config.certId)
110
116
  }
111
117
  });
112
118
  const token = response.data;
@@ -127,14 +133,14 @@ class OAuth2 extends Base {
127
133
  throw new Error('Failed to refresh the user access token. Token or refresh_token is not set.');
128
134
  }
129
135
  try {
130
- const response = await this.req.postForm(this.identityEndpoint, {
136
+ const response = await this.req.post(this.identityEndpoint, {
131
137
  grant_type: 'refresh_token',
132
138
  refresh_token: this._authToken.refresh_token,
133
139
  scope: this.scope.join(' ')
134
140
  }, {
135
- auth: {
136
- username: this.config.appId,
137
- password: this.config.certId
141
+ headers: {
142
+ 'Content-Type': 'application/x-www-form-urlencoded',
143
+ 'Authorization': 'Basic ' + btoa(this.config.appId + ':' + this.config.certId)
138
144
  }
139
145
  });
140
146
  const token = response.data;