ebay-api 8.3.0 → 8.4.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 +36 -1
- package/dist/api/digitalSignature.d.ts +43 -0
- package/dist/api/digitalSignature.js +105 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +18 -0
- package/dist/api/restful/developer/keyManagement/index.d.ts +2 -4
- package/dist/api/restful/developer/keyManagement/index.js +5 -3
- package/dist/api/restful/index.d.ts +12 -7
- package/dist/api/restful/index.js +30 -17
- package/dist/api/traditional/XMLRequest.d.ts +3 -1
- package/dist/api/traditional/XMLRequest.js +3 -1
- package/dist/api/traditional/index.d.ts +1 -1
- package/dist/api/traditional/index.js +25 -15
- package/dist/eBayApi.d.ts +2 -1
- package/dist/eBayApi.js +12 -1
- package/dist/ebay-api.min.mjs +1 -1
- package/dist/errors/index.js +5 -0
- package/dist/types/apiTypes.d.ts +7 -0
- package/dist/types/traditonalTypes.d.ts +2 -1
- package/lib/api/digitalSignature.d.ts +43 -0
- package/lib/api/digitalSignature.js +112 -0
- package/lib/api/index.d.ts +2 -0
- package/lib/api/index.js +18 -0
- package/lib/api/restful/developer/keyManagement/index.d.ts +2 -4
- package/lib/api/restful/developer/keyManagement/index.js +5 -3
- package/lib/api/restful/index.d.ts +12 -7
- package/lib/api/restful/index.js +34 -21
- package/lib/api/traditional/XMLRequest.d.ts +3 -1
- package/lib/api/traditional/XMLRequest.js +2 -0
- package/lib/api/traditional/index.d.ts +1 -1
- package/lib/api/traditional/index.js +29 -19
- package/lib/eBayApi.d.ts +2 -1
- package/lib/eBayApi.js +12 -1
- package/lib/ebay-api.min.js +1 -1
- package/lib/errors/index.js +5 -0
- package/lib/types/apiTypes.d.ts +7 -0
- package/lib/types/traditonalTypes.d.ts +2 -1
- package/package.json +2 -1
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.
|
|
24
|
+
* `v8.4.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
|
|
@@ -306,6 +306,41 @@ app.get('/orders/:id', async function (req, res) {
|
|
|
306
306
|
});
|
|
307
307
|
```
|
|
308
308
|
|
|
309
|
+
## Digital Signature
|
|
310
|
+
Signatures are required when the call is made for EU- or UK-domiciled sellers, and only for the following APIs/methods:
|
|
311
|
+
|
|
312
|
+
* All methods in the Finances API
|
|
313
|
+
* issueRefund in the Fulfillment API
|
|
314
|
+
* GetAccount in the Trading API
|
|
315
|
+
* The following methods in the Post-Order API:
|
|
316
|
+
- Issue Inquiry Refund
|
|
317
|
+
- Issue case refund
|
|
318
|
+
- Issue return refund
|
|
319
|
+
- Process Return Request
|
|
320
|
+
- Create Cancellation Request
|
|
321
|
+
- Approve Cancellation Request
|
|
322
|
+
|
|
323
|
+
### How to use Digital Signature
|
|
324
|
+
```js
|
|
325
|
+
// 1. Create singning key and save it appropriatly
|
|
326
|
+
const signingKey = await eBay.developer.keyManagement.createSigningKey('ED25519');
|
|
327
|
+
// 2. Set the signature
|
|
328
|
+
eBay.setSignature(signingKey)
|
|
329
|
+
// or in constructor
|
|
330
|
+
eBay = new eBayApi({
|
|
331
|
+
appId: '...',
|
|
332
|
+
certId: '...',
|
|
333
|
+
signature: {
|
|
334
|
+
jwe: signingKey.jwe,
|
|
335
|
+
privateKey: signingKey.privateKey
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
// 3. Use the 'sign' keyword in Restful API
|
|
339
|
+
const summary = await eBay.sell.finances.sign.getSellerFundsSummary();
|
|
340
|
+
// 3. Or the 'sign' parameter in traditional API
|
|
341
|
+
const account = await eBay.trading.GetAccount(null, {sign: true});
|
|
342
|
+
```
|
|
343
|
+
|
|
309
344
|
## RESTful API
|
|
310
345
|
|
|
311
346
|
### How to set the Scope
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Cipher, Headers } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates the 'Content-Digest' header value for the input payload.
|
|
4
|
+
*
|
|
5
|
+
* @param {any} payload The request payload.
|
|
6
|
+
* @param {string} cipher The algorithm used to calculate the digest.
|
|
7
|
+
* @returns {string} contentDigest The 'Content-Digest' header value.
|
|
8
|
+
*/
|
|
9
|
+
export declare const generateContentDigestValue: (payload: unknown, cipher?: Cipher) => string;
|
|
10
|
+
export type SignatureComponents = {
|
|
11
|
+
method: string;
|
|
12
|
+
authority: string;
|
|
13
|
+
path: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Generates the base string.
|
|
17
|
+
*
|
|
18
|
+
* @param {any} headers The HTTP request headers.
|
|
19
|
+
* @param {SignatureComponents} signatureComponents The config.
|
|
20
|
+
* @param {any} payload The payload.
|
|
21
|
+
* @param {number} timestamp The timestamp.
|
|
22
|
+
* @returns {string} payload The base string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateBaseString(headers: Headers, signatureComponents: SignatureComponents, payload: any, timestamp?: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Generates the Signature-Input header value for the input payload.
|
|
27
|
+
*
|
|
28
|
+
* @param {any} payload The input config.
|
|
29
|
+
* @param {number} timestamp The timestamp.
|
|
30
|
+
* @returns {string} the 'Signature-Input' header value.
|
|
31
|
+
*/
|
|
32
|
+
export declare const generateSignatureInput: (payload: any, timestamp?: number) => string;
|
|
33
|
+
/**
|
|
34
|
+
* Generates the 'Signature' header.
|
|
35
|
+
*
|
|
36
|
+
* @param {any} headers The HTTP headers.
|
|
37
|
+
* @param {string} privateKey The HTTP headers.
|
|
38
|
+
* @param {SignatureComponents} signatureComponents The signature components
|
|
39
|
+
* @param {any} payload The payload
|
|
40
|
+
* @param {number} timestamp The payload
|
|
41
|
+
* @returns {string} the signature header value.
|
|
42
|
+
*/
|
|
43
|
+
export declare function generateSignature(headers: any, privateKey: string, signatureComponents: SignatureComponents, payload: any, timestamp?: number): string;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { createHash, sign } from 'crypto';
|
|
2
|
+
const beginPrivateKey = '-----BEGIN PRIVATE KEY-----';
|
|
3
|
+
const endPrivateKey = '-----END PRIVATE KEY-----';
|
|
4
|
+
// based on https://github.com/ebay/digital-signature-nodejs-sdk
|
|
5
|
+
/**
|
|
6
|
+
* Returns the current UNIX timestamp.
|
|
7
|
+
*
|
|
8
|
+
* @returns {number} The unix timestamp.
|
|
9
|
+
*/
|
|
10
|
+
const getUnixTimestamp = () => Date.now() / 1000 | 0;
|
|
11
|
+
const getSignatureParams = (payload) => [
|
|
12
|
+
...payload ? ['content-digest'] : [],
|
|
13
|
+
'x-ebay-signature-key',
|
|
14
|
+
'@method',
|
|
15
|
+
'@path',
|
|
16
|
+
'@authority'
|
|
17
|
+
];
|
|
18
|
+
const getSignatureParamsValue = (payload) => getSignatureParams(payload).map(param => `"${param}"`).join(' ');
|
|
19
|
+
/**
|
|
20
|
+
* Generates the 'Content-Digest' header value for the input payload.
|
|
21
|
+
*
|
|
22
|
+
* @param {any} payload The request payload.
|
|
23
|
+
* @param {string} cipher The algorithm used to calculate the digest.
|
|
24
|
+
* @returns {string} contentDigest The 'Content-Digest' header value.
|
|
25
|
+
*/
|
|
26
|
+
export const generateContentDigestValue = (payload, cipher = 'sha256') => {
|
|
27
|
+
const payloadBuffer = Buffer.from(typeof payload === 'string' ? payload : JSON.stringify(payload));
|
|
28
|
+
const hash = createHash(cipher).update(payloadBuffer).digest('base64');
|
|
29
|
+
const algo = cipher === 'sha512' ? 'sha-512' : 'sha-256';
|
|
30
|
+
return `${algo}=:${hash}:`;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Generates the base string.
|
|
34
|
+
*
|
|
35
|
+
* @param {any} headers The HTTP request headers.
|
|
36
|
+
* @param {SignatureComponents} signatureComponents The config.
|
|
37
|
+
* @param {any} payload The payload.
|
|
38
|
+
* @param {number} timestamp The timestamp.
|
|
39
|
+
* @returns {string} payload The base string.
|
|
40
|
+
*/
|
|
41
|
+
export function generateBaseString(headers, signatureComponents, payload, timestamp = getUnixTimestamp()) {
|
|
42
|
+
try {
|
|
43
|
+
let baseString = '';
|
|
44
|
+
const signatureParams = getSignatureParams(payload);
|
|
45
|
+
signatureParams.forEach(param => {
|
|
46
|
+
baseString += `"${param.toLowerCase()}": `;
|
|
47
|
+
if (param.startsWith('@')) {
|
|
48
|
+
switch (param.toLowerCase()) {
|
|
49
|
+
case '@method':
|
|
50
|
+
baseString += signatureComponents.method;
|
|
51
|
+
break;
|
|
52
|
+
case '@authority':
|
|
53
|
+
baseString += signatureComponents.authority;
|
|
54
|
+
break;
|
|
55
|
+
case '@path':
|
|
56
|
+
baseString += signatureComponents.path;
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
throw new Error('Unknown pseudo header ' + param);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
if (!headers[param]) {
|
|
64
|
+
throw new Error('Header ' + param + ' not included in message');
|
|
65
|
+
}
|
|
66
|
+
baseString += headers[param];
|
|
67
|
+
}
|
|
68
|
+
baseString += '\n';
|
|
69
|
+
});
|
|
70
|
+
baseString += `"@signature-params": (${getSignatureParamsValue(payload)});created=${timestamp}`;
|
|
71
|
+
return baseString;
|
|
72
|
+
}
|
|
73
|
+
catch (ex) {
|
|
74
|
+
throw new Error(`Error calculating signature base: ${ex.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generates the Signature-Input header value for the input payload.
|
|
79
|
+
*
|
|
80
|
+
* @param {any} payload The input config.
|
|
81
|
+
* @param {number} timestamp The timestamp.
|
|
82
|
+
* @returns {string} the 'Signature-Input' header value.
|
|
83
|
+
*/
|
|
84
|
+
export const generateSignatureInput = (payload, timestamp = getUnixTimestamp()) => `sig1=(${getSignatureParamsValue(payload)});created=${timestamp}`;
|
|
85
|
+
/**
|
|
86
|
+
* Generates the 'Signature' header.
|
|
87
|
+
*
|
|
88
|
+
* @param {any} headers The HTTP headers.
|
|
89
|
+
* @param {string} privateKey The HTTP headers.
|
|
90
|
+
* @param {SignatureComponents} signatureComponents The signature components
|
|
91
|
+
* @param {any} payload The payload
|
|
92
|
+
* @param {number} timestamp The payload
|
|
93
|
+
* @returns {string} the signature header value.
|
|
94
|
+
*/
|
|
95
|
+
export function generateSignature(headers, privateKey, signatureComponents, payload, timestamp = getUnixTimestamp()) {
|
|
96
|
+
const baseString = generateBaseString(headers, signatureComponents, payload, timestamp);
|
|
97
|
+
privateKey = privateKey.trim();
|
|
98
|
+
if (!privateKey.startsWith(beginPrivateKey)) {
|
|
99
|
+
privateKey = beginPrivateKey + '\n' + privateKey + '\n' + endPrivateKey;
|
|
100
|
+
}
|
|
101
|
+
const signatureBuffer = sign(undefined, // If algorithm is undefined, then it is dependent upon the private key type.
|
|
102
|
+
Buffer.from(baseString), privateKey);
|
|
103
|
+
const signature = signatureBuffer.toString('base64');
|
|
104
|
+
return `sig1=:${signature}:`;
|
|
105
|
+
}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ import Auth from '../auth/index.js';
|
|
|
2
2
|
import { IEBayApiRequest } from '../request.js';
|
|
3
3
|
import { AppConfig } from '../types/index.js';
|
|
4
4
|
import Base from './base.js';
|
|
5
|
+
import { SignatureComponents } from './digitalSignature.js';
|
|
5
6
|
/**
|
|
6
7
|
* Superclass with Auth container.
|
|
7
8
|
*/
|
|
8
9
|
export default abstract class Api extends Base {
|
|
9
10
|
readonly auth: Auth;
|
|
10
11
|
constructor(config: AppConfig, req?: IEBayApiRequest, auth?: Auth);
|
|
12
|
+
getDigitalSignatureHeaders(signatureComponents: SignatureComponents, payload: any): {};
|
|
11
13
|
}
|
package/dist/api/index.js
CHANGED
|
@@ -1,5 +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
4
|
/**
|
|
4
5
|
* Superclass with Auth container.
|
|
5
6
|
*/
|
|
@@ -8,4 +9,21 @@ export default class Api extends Base {
|
|
|
8
9
|
super(config, req);
|
|
9
10
|
this.auth = auth || new Auth(this.config, this.req);
|
|
10
11
|
}
|
|
12
|
+
getDigitalSignatureHeaders(signatureComponents, payload) {
|
|
13
|
+
if (!this.config.signature) {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
const digitalSignatureHeaders = {
|
|
17
|
+
'x-ebay-enforce-signature': true,
|
|
18
|
+
'x-ebay-signature-key': this.config.signature.jwe,
|
|
19
|
+
...payload ? {
|
|
20
|
+
'content-digest': generateContentDigestValue(payload, this.config.signature.cipher ?? 'sha256')
|
|
21
|
+
} : {},
|
|
22
|
+
'signature-input': generateSignatureInput(payload)
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
...digitalSignatureHeaders,
|
|
26
|
+
'signature': generateSignature(digitalSignatureHeaders, this.config.signature.privateKey, signatureComponents, payload)
|
|
27
|
+
};
|
|
28
|
+
}
|
|
11
29
|
}
|
|
@@ -12,11 +12,9 @@ export default class KeyManagement extends Restful {
|
|
|
12
12
|
*/
|
|
13
13
|
getSigningKeys(): Promise<any>;
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* This method creates keypairs.
|
|
16
16
|
*/
|
|
17
|
-
createSigningKey(
|
|
18
|
-
signingKeyCipher: string;
|
|
19
|
-
}): Promise<any>;
|
|
17
|
+
createSigningKey(signingKeyCipher: 'ED25519' | 'RSA'): Promise<any>;
|
|
20
18
|
/**
|
|
21
19
|
* This method returns the <b>Public Key</b>, <b>Public Key as JWE</b>,
|
|
22
20
|
* and metadata for a specified <code>signingKeyId</code> associated with the application key making the call.
|
|
@@ -17,10 +17,12 @@ export default class KeyManagement extends Restful {
|
|
|
17
17
|
return this.get(`/signing_key`);
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* This method creates keypairs.
|
|
21
21
|
*/
|
|
22
|
-
createSigningKey(
|
|
23
|
-
return this.post(`/signing_key`,
|
|
22
|
+
createSigningKey(signingKeyCipher) {
|
|
23
|
+
return this.post(`/signing_key`, {
|
|
24
|
+
signingKeyCipher
|
|
25
|
+
});
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* This method returns the <b>Public Key</b>, <b>Public Key as JWE</b>,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import Api from '../index.js';
|
|
2
1
|
import Auth from '../../auth/index.js';
|
|
3
2
|
import { IEBayApiRequest } from '../../request.js';
|
|
4
3
|
import { ApiRequestConfig, AppConfig } from '../../types/index.js';
|
|
4
|
+
import Api from '../index.js';
|
|
5
5
|
export declare const defaultApiHeaders: Record<string, string>;
|
|
6
6
|
export type RestfulApiConfig = {
|
|
7
7
|
subdomain?: string;
|
|
8
8
|
useIaf?: boolean;
|
|
9
|
+
sign?: boolean;
|
|
9
10
|
apiVersion?: string;
|
|
10
11
|
basePath?: string;
|
|
11
12
|
schema?: string;
|
|
@@ -14,7 +15,7 @@ export type RestfulApiConfig = {
|
|
|
14
15
|
} & ApiRequestConfig;
|
|
15
16
|
export type ApiRequest = {
|
|
16
17
|
method: keyof IEBayApiRequest;
|
|
17
|
-
|
|
18
|
+
path: string;
|
|
18
19
|
config?: any;
|
|
19
20
|
data?: any;
|
|
20
21
|
};
|
|
@@ -50,12 +51,16 @@ export default abstract class Restful extends Api {
|
|
|
50
51
|
* Use "apiz" subdomain
|
|
51
52
|
*/
|
|
52
53
|
get apiz(): this;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Sign request
|
|
56
|
+
*/
|
|
57
|
+
get sign(): this;
|
|
58
|
+
get(path: string, config?: any, apiConfig?: RestfulApiConfig): Promise<any>;
|
|
59
|
+
delete(path: string, config?: any, apiConfig?: RestfulApiConfig): Promise<any>;
|
|
60
|
+
post(path: string, data?: any, config?: any, apiConfig?: RestfulApiConfig): Promise<any>;
|
|
61
|
+
put(path: string, data?: any, config?: any, apiConfig?: RestfulApiConfig): Promise<any>;
|
|
57
62
|
get additionalHeaders(): any;
|
|
58
|
-
enrichRequestConfig(
|
|
63
|
+
enrichRequestConfig(apiRequest: ApiRequest, payload?: any, apiConfig?: Required<RestfulApiConfig>): Promise<any>;
|
|
59
64
|
private doRequest;
|
|
60
65
|
private shouldRefreshToken;
|
|
61
66
|
private request;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Api from '../index.js';
|
|
2
1
|
import { EBayInvalidAccessToken, handleEBayError } from '../../errors/index.js';
|
|
2
|
+
import Api from '../index.js';
|
|
3
3
|
export const defaultApiHeaders = {
|
|
4
4
|
'Content-Type': 'application/json',
|
|
5
5
|
'Cache-Control': 'no-cache',
|
|
@@ -53,7 +53,8 @@ export default class Restful extends Api {
|
|
|
53
53
|
sandbox: this.config.sandbox,
|
|
54
54
|
tld: 'ebay.com',
|
|
55
55
|
headers: {},
|
|
56
|
-
returnResponse: false
|
|
56
|
+
returnResponse: false,
|
|
57
|
+
sign: false
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
get baseUrl() {
|
|
@@ -79,17 +80,23 @@ export default class Restful extends Api {
|
|
|
79
80
|
get apiz() {
|
|
80
81
|
return this.api({ subdomain: 'apiz' });
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Sign request
|
|
85
|
+
*/
|
|
86
|
+
get sign() {
|
|
87
|
+
return this.api({ sign: true });
|
|
88
|
+
}
|
|
89
|
+
async get(path, config = {}, apiConfig) {
|
|
90
|
+
return this.doRequest({ method: 'get', path, config }, apiConfig);
|
|
84
91
|
}
|
|
85
|
-
async delete(
|
|
86
|
-
return this.doRequest({ method: 'delete',
|
|
92
|
+
async delete(path, config = {}, apiConfig) {
|
|
93
|
+
return this.doRequest({ method: 'delete', path, config }, apiConfig);
|
|
87
94
|
}
|
|
88
|
-
async post(
|
|
89
|
-
return this.doRequest({ method: 'post',
|
|
95
|
+
async post(path, data, config = {}, apiConfig) {
|
|
96
|
+
return this.doRequest({ method: 'post', path, data, config }, apiConfig);
|
|
90
97
|
}
|
|
91
|
-
async put(
|
|
92
|
-
return this.doRequest({ method: 'put',
|
|
98
|
+
async put(path, data, config = {}, apiConfig) {
|
|
99
|
+
return this.doRequest({ method: 'put', path, data, config }, apiConfig);
|
|
93
100
|
}
|
|
94
101
|
get additionalHeaders() {
|
|
95
102
|
return Object.keys(additionalHeaders)
|
|
@@ -101,18 +108,24 @@ export default class Restful extends Api {
|
|
|
101
108
|
return headers;
|
|
102
109
|
}, {});
|
|
103
110
|
}
|
|
104
|
-
async enrichRequestConfig(
|
|
111
|
+
async enrichRequestConfig(apiRequest, payload = null, apiConfig = this.apiConfig) {
|
|
105
112
|
const authHeader = await this.auth.getHeaderAuthorization(apiConfig.useIaf);
|
|
113
|
+
const signatureHeaders = apiConfig.sign ? this.getDigitalSignatureHeaders({
|
|
114
|
+
method: apiRequest.method.toUpperCase(),
|
|
115
|
+
authority: Restful.buildServerUrl('', apiConfig.subdomain, apiConfig.sandbox, apiConfig.tld),
|
|
116
|
+
path: apiConfig.apiVersion + apiConfig.basePath + apiRequest.path
|
|
117
|
+
}, payload) : {};
|
|
106
118
|
const headers = {
|
|
107
119
|
...defaultApiHeaders,
|
|
108
120
|
...this.additionalHeaders,
|
|
109
121
|
...authHeader,
|
|
110
|
-
...apiConfig.headers
|
|
122
|
+
...apiConfig.headers,
|
|
123
|
+
...signatureHeaders
|
|
111
124
|
};
|
|
112
125
|
return {
|
|
113
|
-
...config,
|
|
126
|
+
...apiRequest.config,
|
|
114
127
|
headers: {
|
|
115
|
-
...(config.headers || {}),
|
|
128
|
+
...(apiRequest.config.headers || {}),
|
|
116
129
|
...headers
|
|
117
130
|
}
|
|
118
131
|
};
|
|
@@ -139,14 +152,14 @@ export default class Restful extends Api {
|
|
|
139
152
|
return error?.meta?.res?.status === 401 && this.apiConfig.basePath === '/post-order/v2';
|
|
140
153
|
}
|
|
141
154
|
async request(apiRequest, apiConfig = this.apiConfig, refreshToken = false) {
|
|
142
|
-
const {
|
|
155
|
+
const { path, method, data } = apiRequest;
|
|
143
156
|
const apiCfg = { ...this.apiConfig, ...apiConfig };
|
|
144
|
-
const endpoint = this.getServerUrl(apiCfg) +
|
|
157
|
+
const endpoint = this.getServerUrl(apiCfg) + path;
|
|
145
158
|
try {
|
|
146
159
|
if (refreshToken) {
|
|
147
160
|
await this.auth.OAuth2.refreshToken();
|
|
148
161
|
}
|
|
149
|
-
const enrichedConfig = await this.enrichRequestConfig(
|
|
162
|
+
const enrichedConfig = await this.enrichRequestConfig(apiRequest, data, apiCfg);
|
|
150
163
|
const args = ['get', 'delete'].includes(method) ? [enrichedConfig] : [data, enrichedConfig];
|
|
151
164
|
// @ts-ignore
|
|
152
165
|
const response = await this.req[method](endpoint, ...args);
|
|
@@ -34,12 +34,14 @@ export type TraditionalApiConfig = {
|
|
|
34
34
|
raw?: boolean;
|
|
35
35
|
parseOptions?: object;
|
|
36
36
|
useIaf?: boolean;
|
|
37
|
+
sign?: boolean;
|
|
37
38
|
hook?: (xml: string) => BodyHeaders;
|
|
38
39
|
} & ApiRequestConfig;
|
|
39
40
|
export type XMLReqConfig = TraditionalApiConfig & {
|
|
40
41
|
endpoint: string;
|
|
41
42
|
xmlns: string;
|
|
42
43
|
eBayAuthToken?: string | null;
|
|
44
|
+
digitalSignatureHeaders?: (payload: any) => Headers;
|
|
43
45
|
};
|
|
44
46
|
export declare const defaultApiConfig: Required<Omit<TraditionalApiConfig, 'hook'>>;
|
|
45
47
|
export declare const defaultHeaders: {
|
|
@@ -63,7 +65,7 @@ export default class XMLRequest {
|
|
|
63
65
|
* @param {Object} req the request
|
|
64
66
|
* @param {XMLReqConfig} config
|
|
65
67
|
*/
|
|
66
|
-
constructor(callName: string, fields: Fields, config: XMLReqConfig, req: IEBayApiRequest);
|
|
68
|
+
constructor(callName: string, fields: Fields | null, config: XMLReqConfig, req: IEBayApiRequest);
|
|
67
69
|
/**
|
|
68
70
|
* returns the expected name of XML node of a Request
|
|
69
71
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
|
-
import {
|
|
2
|
+
import { XMLBuilder, XMLParser } from 'fast-xml-parser';
|
|
3
3
|
import { checkEBayResponse, EbayNoCallError } from '../../errors/index.js';
|
|
4
4
|
const log = debug('ebay:xml:request');
|
|
5
5
|
export const defaultJSON2XMLOptions = {
|
|
@@ -32,6 +32,7 @@ export const defaultApiConfig = {
|
|
|
32
32
|
raw: false,
|
|
33
33
|
parseOptions: defaultXML2JSONParseOptions,
|
|
34
34
|
useIaf: true,
|
|
35
|
+
sign: false,
|
|
35
36
|
headers: {},
|
|
36
37
|
returnResponse: false
|
|
37
38
|
};
|
|
@@ -137,6 +138,7 @@ export default class XMLRequest {
|
|
|
137
138
|
const config = {
|
|
138
139
|
headers: {
|
|
139
140
|
...this.getHeaders(),
|
|
141
|
+
...this.config.digitalSignatureHeaders ? this.config.digitalSignatureHeaders(body) : {},
|
|
140
142
|
...(headers ? headers : {})
|
|
141
143
|
}
|
|
142
144
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { stringify } from 'qs';
|
|
2
|
-
import Api from '../index.js';
|
|
3
2
|
import { EBayIAFTokenExpired, EBayIAFTokenInvalid, handleEBayError } from '../../errors/index.js';
|
|
3
|
+
import Api from '../index.js';
|
|
4
4
|
import ClientAlertsCalls from './clientAlerts/index.js';
|
|
5
5
|
import FindingCalls from './finding/index.js';
|
|
6
6
|
import MerchandisingCalls from './merchandising/index.js';
|
|
@@ -28,17 +28,15 @@ export default class Traditional extends Api {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
createTradingApi() {
|
|
31
|
-
if (!this.config.devId) {
|
|
32
|
-
throw new Error('devId is required for trading API.');
|
|
33
|
-
}
|
|
34
31
|
if (typeof this.config.siteId !== 'number') {
|
|
35
32
|
throw new Error('siteId is required for trading API.');
|
|
36
33
|
}
|
|
37
34
|
return this.createTraditionalXMLApi({
|
|
38
35
|
endpoint: {
|
|
39
|
-
production: '
|
|
40
|
-
sandbox: '
|
|
36
|
+
production: 'api.ebay.com',
|
|
37
|
+
sandbox: 'api.sandbox.ebay.com'
|
|
41
38
|
},
|
|
39
|
+
path: '/ws/api.dll',
|
|
42
40
|
calls: TradingCalls,
|
|
43
41
|
xmlns: 'urn:ebay:apis:eBLBaseComponents',
|
|
44
42
|
headers: (callName, accessToken) => ({
|
|
@@ -58,9 +56,10 @@ export default class Traditional extends Api {
|
|
|
58
56
|
}
|
|
59
57
|
return this.createTraditionalXMLApi({
|
|
60
58
|
endpoint: {
|
|
61
|
-
production: '
|
|
62
|
-
sandbox: '
|
|
59
|
+
production: 'open.api.ebay.com',
|
|
60
|
+
sandbox: 'open.api.sandbox.ebay.com'
|
|
63
61
|
},
|
|
62
|
+
path: '/shopping',
|
|
64
63
|
xmlns: 'urn:ebay:apis:eBLBaseComponents',
|
|
65
64
|
calls: ShoppingCalls,
|
|
66
65
|
headers: (callName, accessToken) => ({
|
|
@@ -76,9 +75,10 @@ export default class Traditional extends Api {
|
|
|
76
75
|
createFindingApi() {
|
|
77
76
|
return this.createTraditionalXMLApi({
|
|
78
77
|
endpoint: {
|
|
79
|
-
production: '
|
|
80
|
-
sandbox: '
|
|
78
|
+
production: 'svcs.ebay.com',
|
|
79
|
+
sandbox: 'svcs.sandbox.ebay.com'
|
|
81
80
|
},
|
|
81
|
+
path: '/services/search/FindingService/v1',
|
|
82
82
|
xmlns: 'http://www.ebay.com/marketplace/search/v1/services',
|
|
83
83
|
calls: FindingCalls,
|
|
84
84
|
headers: (callName) => ({
|
|
@@ -93,9 +93,10 @@ export default class Traditional extends Api {
|
|
|
93
93
|
}
|
|
94
94
|
const api = {
|
|
95
95
|
endpoint: {
|
|
96
|
-
production: '
|
|
97
|
-
sandbox: '
|
|
96
|
+
production: 'clientalerts.ebay.com',
|
|
97
|
+
sandbox: 'clientalerts.sandbox.ebay.com'
|
|
98
98
|
},
|
|
99
|
+
path: '/ws/ecasvc/ClientAlerts',
|
|
99
100
|
calls: ClientAlertsCalls
|
|
100
101
|
};
|
|
101
102
|
const endpoint = api.endpoint[this.config.sandbox ? 'sandbox' : 'production'];
|
|
@@ -129,9 +130,10 @@ export default class Traditional extends Api {
|
|
|
129
130
|
createMerchandisingApi() {
|
|
130
131
|
return this.createTraditionalXMLApi({
|
|
131
132
|
endpoint: {
|
|
132
|
-
production: '
|
|
133
|
-
sandbox: '
|
|
133
|
+
production: 'svcs.ebay.com',
|
|
134
|
+
sandbox: 'svcs.sandbox.ebay.com'
|
|
134
135
|
},
|
|
136
|
+
path: '/MerchandisingService',
|
|
135
137
|
xmlns: 'http://www.ebay.com/marketplace/services',
|
|
136
138
|
calls: MerchandisingCalls,
|
|
137
139
|
headers: (callName) => ({
|
|
@@ -160,14 +162,22 @@ export default class Traditional extends Api {
|
|
|
160
162
|
const eBayAuthToken = this.auth.authNAuth.eBayAuthToken;
|
|
161
163
|
const accessToken = !eBayAuthToken && apiConfig.useIaf ? (await this.auth.OAuth2.getAccessToken()) : null;
|
|
162
164
|
const useIaf = !eBayAuthToken && accessToken;
|
|
165
|
+
const host = this.config.sandbox ? api.endpoint.sandbox : api.endpoint.production;
|
|
163
166
|
return {
|
|
164
167
|
...apiConfig,
|
|
165
168
|
xmlns: api.xmlns,
|
|
166
|
-
endpoint: api.
|
|
169
|
+
endpoint: `https://${host}${api.path}`,
|
|
167
170
|
headers: {
|
|
168
171
|
...api.headers(callName, useIaf ? accessToken : null),
|
|
169
172
|
...apiConfig.headers
|
|
170
173
|
},
|
|
174
|
+
digitalSignatureHeaders: payload => {
|
|
175
|
+
return apiConfig.sign ? this.getDigitalSignatureHeaders({
|
|
176
|
+
method: 'POST',
|
|
177
|
+
authority: host,
|
|
178
|
+
path: api.path
|
|
179
|
+
}, payload) : {};
|
|
180
|
+
},
|
|
171
181
|
...(!useIaf ? { eBayAuthToken } : {})
|
|
172
182
|
};
|
|
173
183
|
}
|
package/dist/eBayApi.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ContentLanguage, Locale, MarketplaceId, SiteId } from './enums/index.js
|
|
|
11
11
|
import * as errors from './errors/index.js';
|
|
12
12
|
import { IEBayApiRequest } from './request.js';
|
|
13
13
|
import * as types from './types/index.js';
|
|
14
|
-
import { AppConfig, ClientAlerts, Finding, Merchandising, Shopping, Trading } from './types/index.js';
|
|
14
|
+
import { AppConfig, ClientAlerts, Finding, Merchandising, Shopping, Signature, Trading } from './types/index.js';
|
|
15
15
|
export default class eBayApi extends Api {
|
|
16
16
|
static readonly SiteId: typeof enums.SiteId;
|
|
17
17
|
static readonly MarketplaceId: typeof enums.MarketplaceId;
|
|
@@ -54,5 +54,6 @@ export default class eBayApi extends Api {
|
|
|
54
54
|
get shopping(): Shopping;
|
|
55
55
|
get merchandising(): Merchandising;
|
|
56
56
|
get clientAlerts(): ClientAlerts;
|
|
57
|
+
setSignature(signature: Signature): void;
|
|
57
58
|
}
|
|
58
59
|
export { eBayApi, SiteId, MarketplaceId, ContentLanguage, Locale, enums, errors, types };
|
package/dist/eBayApi.js
CHANGED
|
@@ -29,6 +29,13 @@ export default class eBayApi extends Api {
|
|
|
29
29
|
if (!process.env.EBAY_CERT_ID) {
|
|
30
30
|
throw new ApiEnvError('EBAY_CERT_ID');
|
|
31
31
|
}
|
|
32
|
+
let signature = null;
|
|
33
|
+
if (process.env.EBAY_JWE && process.env.EBAY_PRIVATE_KEY) {
|
|
34
|
+
signature = {
|
|
35
|
+
jwe: process.env.EBAY_JWE,
|
|
36
|
+
privateKey: process.env.EBAY_PRIVATE_KEY
|
|
37
|
+
};
|
|
38
|
+
}
|
|
32
39
|
return new eBayApi({
|
|
33
40
|
appId: process.env.EBAY_APP_ID,
|
|
34
41
|
certId: process.env.EBAY_CERT_ID,
|
|
@@ -39,7 +46,8 @@ export default class eBayApi extends Api {
|
|
|
39
46
|
MarketplaceId[process.env.EBAY_MARKETPLACE_ID] :
|
|
40
47
|
MarketplaceId.EBAY_US,
|
|
41
48
|
ruName: process.env.EBAY_RU_NAME,
|
|
42
|
-
sandbox: (process.env.EBAY_SANDBOX === 'true')
|
|
49
|
+
sandbox: (process.env.EBAY_SANDBOX === 'true'),
|
|
50
|
+
signature
|
|
43
51
|
}, req);
|
|
44
52
|
}
|
|
45
53
|
/**
|
|
@@ -85,6 +93,9 @@ export default class eBayApi extends Api {
|
|
|
85
93
|
get clientAlerts() {
|
|
86
94
|
return this._clientAlerts || (this._clientAlerts = this.factory.createClientAlertsApi());
|
|
87
95
|
}
|
|
96
|
+
setSignature(signature) {
|
|
97
|
+
this.config.signature = signature;
|
|
98
|
+
}
|
|
88
99
|
}
|
|
89
100
|
eBayApi.SiteId = SiteId;
|
|
90
101
|
eBayApi.MarketplaceId = MarketplaceId;
|