ebay-mcp 1.4.3
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/LICENSE +201 -0
- package/README.md +586 -0
- package/build/api/account-management/account.d.ts +216 -0
- package/build/api/account-management/account.js +305 -0
- package/build/api/analytics-and-report/analytics.d.ts +33 -0
- package/build/api/analytics-and-report/analytics.js +102 -0
- package/build/api/client.d.ts +89 -0
- package/build/api/client.js +343 -0
- package/build/api/communication/feedback.d.ts +45 -0
- package/build/api/communication/feedback.js +119 -0
- package/build/api/communication/message.d.ts +55 -0
- package/build/api/communication/message.js +131 -0
- package/build/api/communication/negotiation.d.ts +39 -0
- package/build/api/communication/negotiation.js +97 -0
- package/build/api/communication/notification.d.ts +128 -0
- package/build/api/communication/notification.js +373 -0
- package/build/api/index.d.ts +96 -0
- package/build/api/index.js +121 -0
- package/build/api/listing-management/inventory.d.ts +216 -0
- package/build/api/listing-management/inventory.js +633 -0
- package/build/api/listing-metadata/metadata.d.ts +154 -0
- package/build/api/listing-metadata/metadata.js +485 -0
- package/build/api/listing-metadata/taxonomy.d.ts +38 -0
- package/build/api/listing-metadata/taxonomy.js +58 -0
- package/build/api/marketing-and-promotions/marketing.d.ts +395 -0
- package/build/api/marketing-and-promotions/marketing.js +565 -0
- package/build/api/marketing-and-promotions/recommendation.d.ts +20 -0
- package/build/api/marketing-and-promotions/recommendation.js +32 -0
- package/build/api/order-management/dispute.d.ts +65 -0
- package/build/api/order-management/dispute.js +69 -0
- package/build/api/order-management/fulfillment.d.ts +80 -0
- package/build/api/order-management/fulfillment.js +89 -0
- package/build/api/other/compliance.d.ts +26 -0
- package/build/api/other/compliance.js +47 -0
- package/build/api/other/edelivery.d.ts +153 -0
- package/build/api/other/edelivery.js +219 -0
- package/build/api/other/identity.d.ts +17 -0
- package/build/api/other/identity.js +24 -0
- package/build/api/other/translation.d.ts +14 -0
- package/build/api/other/translation.js +22 -0
- package/build/api/other/vero.d.ts +30 -0
- package/build/api/other/vero.js +48 -0
- package/build/auth/oauth-metadata.d.ts +46 -0
- package/build/auth/oauth-metadata.js +59 -0
- package/build/auth/oauth-middleware.d.ts +35 -0
- package/build/auth/oauth-middleware.js +99 -0
- package/build/auth/oauth-types.d.ts +66 -0
- package/build/auth/oauth-types.js +4 -0
- package/build/auth/oauth.d.ts +93 -0
- package/build/auth/oauth.js +383 -0
- package/build/auth/scope-utils.d.ts +70 -0
- package/build/auth/scope-utils.js +304 -0
- package/build/auth/token-verifier.d.ts +57 -0
- package/build/auth/token-verifier.js +172 -0
- package/build/config/environment.d.ts +61 -0
- package/build/config/environment.js +260 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +98 -0
- package/build/schemas/account-management/account.d.ts +5324 -0
- package/build/schemas/account-management/account.js +366 -0
- package/build/schemas/analytics/analytics.d.ts +167 -0
- package/build/schemas/analytics/analytics.js +191 -0
- package/build/schemas/communication/messages.d.ts +1872 -0
- package/build/schemas/communication/messages.js +348 -0
- package/build/schemas/fulfillment/orders.d.ts +4655 -0
- package/build/schemas/fulfillment/orders.js +317 -0
- package/build/schemas/index.d.ts +2100 -0
- package/build/schemas/index.js +68 -0
- package/build/schemas/inventory-management/inventory.d.ts +6419 -0
- package/build/schemas/inventory-management/inventory.js +450 -0
- package/build/schemas/marketing/marketing.d.ts +14181 -0
- package/build/schemas/marketing/marketing.js +1088 -0
- package/build/schemas/metadata/metadata.d.ts +5259 -0
- package/build/schemas/metadata/metadata.js +614 -0
- package/build/schemas/other/other-apis.d.ts +257 -0
- package/build/schemas/other/other-apis.js +372 -0
- package/build/schemas/taxonomy/taxonomy.d.ts +215 -0
- package/build/schemas/taxonomy/taxonomy.js +571 -0
- package/build/scripts/auto-setup.d.ts +12 -0
- package/build/scripts/auto-setup.js +277 -0
- package/build/scripts/diagnostics.d.ts +8 -0
- package/build/scripts/diagnostics.js +299 -0
- package/build/scripts/download-specs.d.ts +1 -0
- package/build/scripts/download-specs.js +116 -0
- package/build/scripts/interactive-setup.d.ts +21 -0
- package/build/scripts/interactive-setup.js +723 -0
- package/build/server-http.d.ts +11 -0
- package/build/server-http.js +361 -0
- package/build/tools/definitions/account-with-schemas.d.ts +39 -0
- package/build/tools/definitions/account-with-schemas.js +170 -0
- package/build/tools/definitions/account.d.ts +12 -0
- package/build/tools/definitions/account.js +428 -0
- package/build/tools/definitions/analytics.d.ts +25 -0
- package/build/tools/definitions/analytics.js +66 -0
- package/build/tools/definitions/communication.d.ts +12 -0
- package/build/tools/definitions/communication.js +151 -0
- package/build/tools/definitions/fulfillment.d.ts +12 -0
- package/build/tools/definitions/fulfillment.js +326 -0
- package/build/tools/definitions/index.d.ts +25 -0
- package/build/tools/definitions/index.js +37 -0
- package/build/tools/definitions/inventory.d.ts +12 -0
- package/build/tools/definitions/inventory.js +429 -0
- package/build/tools/definitions/marketing.d.ts +12 -0
- package/build/tools/definitions/marketing.js +1095 -0
- package/build/tools/definitions/metadata.d.ts +12 -0
- package/build/tools/definitions/metadata.js +188 -0
- package/build/tools/definitions/other.d.ts +13 -0
- package/build/tools/definitions/other.js +309 -0
- package/build/tools/definitions/taxonomy.d.ts +25 -0
- package/build/tools/definitions/taxonomy.js +64 -0
- package/build/tools/definitions/token-management.d.ts +35 -0
- package/build/tools/definitions/token-management.js +103 -0
- package/build/tools/index.d.ts +11 -0
- package/build/tools/index.js +1003 -0
- package/build/tools/schemas.d.ts +14764 -0
- package/build/tools/schemas.js +667 -0
- package/build/tools/tool-definitions.d.ts +35 -0
- package/build/tools/tool-definitions.js +3534 -0
- package/build/types/application-settings/developerAnalyticsV1BetaOas3.d.ts +197 -0
- package/build/types/application-settings/developerAnalyticsV1BetaOas3.js +5 -0
- package/build/types/application-settings/developerClientRegistrationV1Oas3.d.ts +155 -0
- package/build/types/application-settings/developerClientRegistrationV1Oas3.js +5 -0
- package/build/types/application-settings/developerKeyManagementV1Oas3.d.ts +246 -0
- package/build/types/application-settings/developerKeyManagementV1Oas3.js +5 -0
- package/build/types/ebay-enums.d.ts +1204 -0
- package/build/types/ebay-enums.js +1330 -0
- package/build/types/ebay.d.ts +143 -0
- package/build/types/ebay.js +123 -0
- package/build/types/index.d.ts +6 -0
- package/build/types/index.js +10 -0
- package/build/types/sell-apps/account-management/sellAccountV1Oas3.d.ts +2579 -0
- package/build/types/sell-apps/account-management/sellAccountV1Oas3.js +5 -0
- package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.d.ts +446 -0
- package/build/types/sell-apps/analytics-and-report/sellAnalyticsV1Oas3.js +5 -0
- package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.d.ts +705 -0
- package/build/types/sell-apps/communication/commerceFeedbackV1BetaOas3.js +5 -0
- package/build/types/sell-apps/communication/commerceMessageV1Oas3.d.ts +590 -0
- package/build/types/sell-apps/communication/commerceMessageV1Oas3.js +5 -0
- package/build/types/sell-apps/communication/commerceNotificationV1Oas3.d.ts +1276 -0
- package/build/types/sell-apps/communication/commerceNotificationV1Oas3.js +5 -0
- package/build/types/sell-apps/communication/sellNegotiationV1Oas3.d.ts +277 -0
- package/build/types/sell-apps/communication/sellNegotiationV1Oas3.js +5 -0
- package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.d.ts +3133 -0
- package/build/types/sell-apps/listing-management/sellInventoryV1Oas3.js +5 -0
- package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.d.ts +2289 -0
- package/build/types/sell-apps/listing-metadata/sellMetadataV1Oas3.js +5 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.d.ts +6650 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellMarketingV1Oas3.js +5 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.d.ts +172 -0
- package/build/types/sell-apps/markeitng-and-promotions/sellRecommendationV1Oas3.js +5 -0
- package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.d.ts +1869 -0
- package/build/types/sell-apps/order-management/sellFulfillmentV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.d.ts +178 -0
- package/build/types/sell-apps/other-apis/commerceIdentityV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.d.ts +128 -0
- package/build/types/sell-apps/other-apis/commerceTranslationV1BetaOas3.js +5 -0
- package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.d.ts +417 -0
- package/build/types/sell-apps/other-apis/commerceVeroV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.d.ts +273 -0
- package/build/types/sell-apps/other-apis/sellComplianceV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.d.ts +2537 -0
- package/build/types/sell-apps/other-apis/sellEdeliveryInternationalShippingOas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.d.ts +6650 -0
- package/build/types/sell-apps/other-apis/sellMarketingV1Oas3.js +5 -0
- package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.d.ts +172 -0
- package/build/types/sell-apps/other-apis/sellRecommendationV1Oas3.js +5 -0
- package/build/utils/account-management/account.d.ts +1094 -0
- package/build/utils/account-management/account.js +831 -0
- package/build/utils/communication/feedback.d.ts +152 -0
- package/build/utils/communication/feedback.js +216 -0
- package/build/utils/communication/message.d.ts +174 -0
- package/build/utils/communication/message.js +242 -0
- package/build/utils/communication/negotiation.d.ts +123 -0
- package/build/utils/communication/negotiation.js +150 -0
- package/build/utils/communication/notification.d.ts +370 -0
- package/build/utils/communication/notification.js +369 -0
- package/build/utils/date-converter.d.ts +59 -0
- package/build/utils/date-converter.js +160 -0
- package/build/utils/llm-client-detector.d.ts +54 -0
- package/build/utils/llm-client-detector.js +318 -0
- package/build/utils/oauth-helper.d.ts +37 -0
- package/build/utils/oauth-helper.js +315 -0
- package/build/utils/order-management/dispute.d.ts +346 -0
- package/build/utils/order-management/dispute.js +369 -0
- package/build/utils/order-management/fulfillment.d.ts +200 -0
- package/build/utils/order-management/fulfillment.js +205 -0
- package/build/utils/other/compliance.d.ts +49 -0
- package/build/utils/other/compliance.js +76 -0
- package/build/utils/other/edelivery.d.ts +310 -0
- package/build/utils/other/edelivery.js +241 -0
- package/build/utils/other/identity.d.ts +13 -0
- package/build/utils/other/identity.js +13 -0
- package/build/utils/other/translation.d.ts +28 -0
- package/build/utils/other/translation.js +41 -0
- package/build/utils/other/vero.d.ts +61 -0
- package/build/utils/other/vero.js +90 -0
- package/build/utils/scope-helper.d.ts +49 -0
- package/build/utils/scope-helper.js +207 -0
- package/build/utils/security-checker.d.ts +46 -0
- package/build/utils/security-checker.js +248 -0
- package/build/utils/setup-validator.d.ts +25 -0
- package/build/utils/setup-validator.js +305 -0
- package/build/utils/token-utils.d.ts +40 -0
- package/build/utils/token-utils.js +40 -0
- package/package.json +115 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for working with eBay OAuth scopes
|
|
3
|
+
*/
|
|
4
|
+
import { getDefaultScopes, validateScopes } from '../config/environment.js';
|
|
5
|
+
/**
|
|
6
|
+
* Validate scopes and provide detailed validation results
|
|
7
|
+
*/
|
|
8
|
+
export function validateScopesDetailed(scopes, environment) {
|
|
9
|
+
const validation = validateScopes(scopes, environment);
|
|
10
|
+
const validScopeSet = new Set(getDefaultScopes(environment));
|
|
11
|
+
const validScopes = [];
|
|
12
|
+
const invalidScopes = [];
|
|
13
|
+
scopes.forEach((scope) => {
|
|
14
|
+
if (validScopeSet.has(scope)) {
|
|
15
|
+
validScopes.push(scope);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
invalidScopes.push(scope);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
isValid: invalidScopes.length === 0,
|
|
23
|
+
warnings: validation.warnings,
|
|
24
|
+
validScopes,
|
|
25
|
+
invalidScopes,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get required scopes for a specific tool
|
|
30
|
+
* This maps tool names to their required eBay OAuth scopes
|
|
31
|
+
*/
|
|
32
|
+
export function getRequiredScopesForTool(toolName) {
|
|
33
|
+
// Scope requirements mapping based on eBay API documentation
|
|
34
|
+
const scopeMap = {
|
|
35
|
+
// Inventory Management Tools
|
|
36
|
+
ebay_get_inventory_items: {
|
|
37
|
+
requiredScopes: [
|
|
38
|
+
'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
|
|
39
|
+
'https://api.ebay.com/oauth/api_scope/sell.inventory',
|
|
40
|
+
],
|
|
41
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
|
|
42
|
+
description: 'Requires read access to inventory',
|
|
43
|
+
},
|
|
44
|
+
ebay_get_inventory_item: {
|
|
45
|
+
requiredScopes: [
|
|
46
|
+
'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
|
|
47
|
+
'https://api.ebay.com/oauth/api_scope/sell.inventory',
|
|
48
|
+
],
|
|
49
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.inventory.readonly',
|
|
50
|
+
description: 'Requires read access to inventory',
|
|
51
|
+
},
|
|
52
|
+
ebay_create_inventory_item: {
|
|
53
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.inventory'],
|
|
54
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.inventory',
|
|
55
|
+
description: 'Requires write access to inventory',
|
|
56
|
+
},
|
|
57
|
+
ebay_create_offer: {
|
|
58
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.inventory'],
|
|
59
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.inventory',
|
|
60
|
+
description: 'Requires write access to inventory',
|
|
61
|
+
},
|
|
62
|
+
ebay_publish_offer: {
|
|
63
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.inventory'],
|
|
64
|
+
optionalScopes: [
|
|
65
|
+
'https://api.ebay.com/oauth/api_scope/sell.account',
|
|
66
|
+
'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
|
|
67
|
+
],
|
|
68
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.inventory',
|
|
69
|
+
description: 'Requires write access to inventory; policies must exist (sell.account)',
|
|
70
|
+
},
|
|
71
|
+
// Order Management Tools
|
|
72
|
+
ebay_get_orders: {
|
|
73
|
+
requiredScopes: [
|
|
74
|
+
'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
|
|
75
|
+
'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
|
|
76
|
+
],
|
|
77
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
|
|
78
|
+
description: 'Requires read access to order fulfillment',
|
|
79
|
+
},
|
|
80
|
+
ebay_get_order: {
|
|
81
|
+
requiredScopes: [
|
|
82
|
+
'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
|
|
83
|
+
'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
|
|
84
|
+
],
|
|
85
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly',
|
|
86
|
+
description: 'Requires read access to order fulfillment',
|
|
87
|
+
},
|
|
88
|
+
ebay_create_shipping_fulfillment: {
|
|
89
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.fulfillment'],
|
|
90
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
|
|
91
|
+
description: 'Requires write access to order fulfillment',
|
|
92
|
+
},
|
|
93
|
+
ebay_issue_refund: {
|
|
94
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.fulfillment'],
|
|
95
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.fulfillment',
|
|
96
|
+
description: 'Requires write access to order fulfillment',
|
|
97
|
+
},
|
|
98
|
+
// Account Management Tools
|
|
99
|
+
ebay_get_fulfillment_policies: {
|
|
100
|
+
requiredScopes: [
|
|
101
|
+
'https://api.ebay.com/oauth/api_scope/sell.account.readonly',
|
|
102
|
+
'https://api.ebay.com/oauth/api_scope/sell.account',
|
|
103
|
+
],
|
|
104
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.account.readonly',
|
|
105
|
+
description: 'Requires read access to account settings',
|
|
106
|
+
},
|
|
107
|
+
ebay_create_fulfillment_policy: {
|
|
108
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.account'],
|
|
109
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.account',
|
|
110
|
+
description: 'Requires write access to account settings',
|
|
111
|
+
},
|
|
112
|
+
// Marketing Tools
|
|
113
|
+
ebay_get_campaigns: {
|
|
114
|
+
requiredScopes: [
|
|
115
|
+
'https://api.ebay.com/oauth/api_scope/sell.marketing.readonly',
|
|
116
|
+
'https://api.ebay.com/oauth/api_scope/sell.marketing',
|
|
117
|
+
],
|
|
118
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.marketing.readonly',
|
|
119
|
+
description: 'Requires read access to marketing campaigns',
|
|
120
|
+
},
|
|
121
|
+
ebay_create_campaign: {
|
|
122
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.marketing'],
|
|
123
|
+
optionalScopes: ['https://api.ebay.com/oauth/api_scope/sell.inventory.readonly'],
|
|
124
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.marketing',
|
|
125
|
+
description: 'Requires write access to marketing campaigns',
|
|
126
|
+
},
|
|
127
|
+
// Analytics Tools
|
|
128
|
+
ebay_get_traffic_report: {
|
|
129
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/sell.analytics.readonly'],
|
|
130
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/sell.analytics.readonly',
|
|
131
|
+
description: 'Requires read access to analytics',
|
|
132
|
+
},
|
|
133
|
+
// Messaging Tools
|
|
134
|
+
ebay_send_message: {
|
|
135
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/commerce.message'],
|
|
136
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/commerce.message',
|
|
137
|
+
description: 'Requires access to messaging (production only)',
|
|
138
|
+
},
|
|
139
|
+
// Feedback Tools
|
|
140
|
+
ebay_leave_feedback_for_buyer: {
|
|
141
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/commerce.feedback'],
|
|
142
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/commerce.feedback',
|
|
143
|
+
description: 'Requires write access to feedback',
|
|
144
|
+
},
|
|
145
|
+
// Identity Tools
|
|
146
|
+
ebay_get_user: {
|
|
147
|
+
requiredScopes: ['https://api.ebay.com/oauth/api_scope/commerce.identity.readonly'],
|
|
148
|
+
minimumScope: 'https://api.ebay.com/oauth/api_scope/commerce.identity.readonly',
|
|
149
|
+
description: 'Requires read access to user identity',
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
return scopeMap[toolName] || null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Check if a token has all required scopes for a tool
|
|
156
|
+
*/
|
|
157
|
+
export function hasRequiredScopes(tokenScopes, requiredScopes) {
|
|
158
|
+
const tokenScopeSet = new Set(tokenScopes);
|
|
159
|
+
// Check if at least one of the required scopes is present
|
|
160
|
+
// (Some tools accept either readonly or write scope)
|
|
161
|
+
return requiredScopes.some((scope) => tokenScopeSet.has(scope));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get the differences between production and sandbox scopes
|
|
165
|
+
*/
|
|
166
|
+
export function getScopeDifferences() {
|
|
167
|
+
const productionScopes = getDefaultScopes('production');
|
|
168
|
+
const sandboxScopes = getDefaultScopes('sandbox');
|
|
169
|
+
const productionSet = new Set(productionScopes);
|
|
170
|
+
const sandboxSet = new Set(sandboxScopes);
|
|
171
|
+
const inBothEnvironments = [];
|
|
172
|
+
const productionOnly = [];
|
|
173
|
+
const sandboxOnly = [];
|
|
174
|
+
// Find scopes in both
|
|
175
|
+
productionScopes.forEach((scope) => {
|
|
176
|
+
if (sandboxSet.has(scope)) {
|
|
177
|
+
inBothEnvironments.push(scope);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
productionOnly.push(scope);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// Find sandbox-only scopes
|
|
184
|
+
sandboxScopes.forEach((scope) => {
|
|
185
|
+
if (!productionSet.has(scope)) {
|
|
186
|
+
sandboxOnly.push(scope);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
return {
|
|
190
|
+
inBothEnvironments,
|
|
191
|
+
productionOnly,
|
|
192
|
+
sandboxOnly,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Format scope for display (remove common prefix for readability)
|
|
197
|
+
*/
|
|
198
|
+
export function formatScopeForDisplay(scope) {
|
|
199
|
+
const prefix = 'https://api.ebay.com/oauth/';
|
|
200
|
+
if (scope.startsWith(prefix)) {
|
|
201
|
+
return scope.substring(prefix.length);
|
|
202
|
+
}
|
|
203
|
+
return scope;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Group scopes by API category
|
|
207
|
+
*/
|
|
208
|
+
export function groupScopesByCategory(scopes) {
|
|
209
|
+
const categories = {
|
|
210
|
+
sell: [],
|
|
211
|
+
buy: [],
|
|
212
|
+
commerce: [],
|
|
213
|
+
other: [],
|
|
214
|
+
};
|
|
215
|
+
scopes.forEach((scope) => {
|
|
216
|
+
if (scope.includes('/sell.')) {
|
|
217
|
+
categories.sell.push(scope);
|
|
218
|
+
}
|
|
219
|
+
else if (scope.includes('/buy.')) {
|
|
220
|
+
categories.buy.push(scope);
|
|
221
|
+
}
|
|
222
|
+
else if (scope.includes('/commerce.')) {
|
|
223
|
+
categories.commerce.push(scope);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
categories.other.push(scope);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
return categories;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Check if a scope is readonly
|
|
233
|
+
*/
|
|
234
|
+
export function isScopeReadonly(scope) {
|
|
235
|
+
return scope.includes('.readonly');
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get the write version of a readonly scope
|
|
239
|
+
*/
|
|
240
|
+
export function getWriteScope(readonlyScope) {
|
|
241
|
+
if (!isScopeReadonly(readonlyScope)) {
|
|
242
|
+
return null; // Already a write scope
|
|
243
|
+
}
|
|
244
|
+
return readonlyScope.replace('.readonly', '');
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get the readonly version of a write scope
|
|
248
|
+
*/
|
|
249
|
+
export function getReadonlyScope(writeScope) {
|
|
250
|
+
if (isScopeReadonly(writeScope)) {
|
|
251
|
+
return null; // Already a readonly scope
|
|
252
|
+
}
|
|
253
|
+
// Not all write scopes have readonly equivalents
|
|
254
|
+
const hasReadonly = [
|
|
255
|
+
'sell.inventory',
|
|
256
|
+
'sell.fulfillment',
|
|
257
|
+
'sell.account',
|
|
258
|
+
'sell.marketing',
|
|
259
|
+
'sell.analytics',
|
|
260
|
+
'sell.reputation',
|
|
261
|
+
'sell.stores',
|
|
262
|
+
'commerce.identity',
|
|
263
|
+
'commerce.notification.subscription',
|
|
264
|
+
'commerce.feedback',
|
|
265
|
+
];
|
|
266
|
+
const scopeType = writeScope.split('/').pop();
|
|
267
|
+
if (scopeType && hasReadonly.some((s) => scopeType.includes(s))) {
|
|
268
|
+
return `${writeScope}.readonly`;
|
|
269
|
+
}
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Get scope description from scope name
|
|
274
|
+
*/
|
|
275
|
+
export function getScopeDescription(scope) {
|
|
276
|
+
// Extract the last part of the scope
|
|
277
|
+
const parts = scope.split('/');
|
|
278
|
+
const scopeType = parts[parts.length - 1];
|
|
279
|
+
const descriptions = {
|
|
280
|
+
api_scope: 'View public data from eBay',
|
|
281
|
+
'sell.inventory': 'View and manage your inventory and offers',
|
|
282
|
+
'sell.inventory.readonly': 'View your inventory and offers',
|
|
283
|
+
'sell.fulfillment': 'View and manage your order fulfillments',
|
|
284
|
+
'sell.fulfillment.readonly': 'View your order fulfillments',
|
|
285
|
+
'sell.account': 'View and manage your account settings',
|
|
286
|
+
'sell.account.readonly': 'View your account settings',
|
|
287
|
+
'sell.marketing': 'View and manage your eBay marketing activities',
|
|
288
|
+
'sell.marketing.readonly': 'View your eBay marketing activities',
|
|
289
|
+
'sell.analytics.readonly': 'View your selling analytics data',
|
|
290
|
+
'sell.finances': 'View and manage your payment and order information',
|
|
291
|
+
'sell.payment.dispute': 'View and manage disputes and related details',
|
|
292
|
+
'commerce.identity.readonly': 'View basic user information from eBay account',
|
|
293
|
+
'sell.reputation': 'View and manage your reputation data',
|
|
294
|
+
'sell.reputation.readonly': 'View your reputation data',
|
|
295
|
+
'commerce.notification.subscription': 'View and manage event notification subscriptions',
|
|
296
|
+
'commerce.notification.subscription.readonly': 'View event notification subscriptions',
|
|
297
|
+
'commerce.feedback': 'View and manage feedback',
|
|
298
|
+
'commerce.feedback.readonly': 'View feedback',
|
|
299
|
+
'commerce.message': 'Send and receive messages with buyers/sellers',
|
|
300
|
+
'sell.stores': 'View and manage eBay stores',
|
|
301
|
+
'sell.stores.readonly': 'View eBay stores',
|
|
302
|
+
};
|
|
303
|
+
return descriptions[scopeType] || `Access to ${scopeType}`;
|
|
304
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token verification using OAuth 2.0 Token Introspection (RFC 7662)
|
|
3
|
+
* and JWT validation
|
|
4
|
+
*/
|
|
5
|
+
import type { VerifiedToken, OAuthServerMetadata } from './oauth-types.js';
|
|
6
|
+
export interface TokenVerifierConfig {
|
|
7
|
+
/**
|
|
8
|
+
* OAuth authorization server metadata URL or metadata object
|
|
9
|
+
*/
|
|
10
|
+
authServerMetadata: string | OAuthServerMetadata;
|
|
11
|
+
/**
|
|
12
|
+
* Client ID for introspection endpoint authentication
|
|
13
|
+
*/
|
|
14
|
+
clientId?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Client secret for introspection endpoint authentication
|
|
17
|
+
*/
|
|
18
|
+
clientSecret?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Expected audience (resource server URL)
|
|
21
|
+
*/
|
|
22
|
+
expectedAudience: string;
|
|
23
|
+
/**
|
|
24
|
+
* Required scopes for access
|
|
25
|
+
*/
|
|
26
|
+
requiredScopes?: string[];
|
|
27
|
+
/**
|
|
28
|
+
* Whether to use token introspection (true) or JWT validation (false)
|
|
29
|
+
* Default: true
|
|
30
|
+
*/
|
|
31
|
+
useIntrospection?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare class TokenVerifier {
|
|
34
|
+
private config;
|
|
35
|
+
private metadata;
|
|
36
|
+
constructor(config: TokenVerifierConfig);
|
|
37
|
+
/**
|
|
38
|
+
* Initialize the verifier by loading OAuth server metadata
|
|
39
|
+
*/
|
|
40
|
+
initialize(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Verify an access token
|
|
43
|
+
*/
|
|
44
|
+
verifyToken(token: string): Promise<VerifiedToken>;
|
|
45
|
+
/**
|
|
46
|
+
* Verify token using OAuth 2.0 Token Introspection (RFC 7662)
|
|
47
|
+
*/
|
|
48
|
+
private verifyViaIntrospection;
|
|
49
|
+
/**
|
|
50
|
+
* Verify token using JWT validation
|
|
51
|
+
*/
|
|
52
|
+
private verifyViaJWT;
|
|
53
|
+
/**
|
|
54
|
+
* Validate audience claim
|
|
55
|
+
*/
|
|
56
|
+
private validateAudience;
|
|
57
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token verification using OAuth 2.0 Token Introspection (RFC 7662)
|
|
3
|
+
* and JWT validation
|
|
4
|
+
*/
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
import * as jose from 'jose';
|
|
7
|
+
export class TokenVerifier {
|
|
8
|
+
config;
|
|
9
|
+
metadata = null;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Initialize the verifier by loading OAuth server metadata
|
|
15
|
+
*/
|
|
16
|
+
async initialize() {
|
|
17
|
+
if (typeof this.config.authServerMetadata === 'string') {
|
|
18
|
+
try {
|
|
19
|
+
const response = await axios.get(this.config.authServerMetadata);
|
|
20
|
+
this.metadata = response.data;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new Error(`Failed to load OAuth server metadata: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.metadata = this.config.authServerMetadata;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Verify an access token
|
|
32
|
+
*/
|
|
33
|
+
async verifyToken(token) {
|
|
34
|
+
if (!this.metadata) {
|
|
35
|
+
throw new Error('Token verifier not initialized');
|
|
36
|
+
}
|
|
37
|
+
if (this.config.useIntrospection !== false) {
|
|
38
|
+
return await this.verifyViaIntrospection(token);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return await this.verifyViaJWT(token);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Verify token using OAuth 2.0 Token Introspection (RFC 7662)
|
|
46
|
+
*/
|
|
47
|
+
async verifyViaIntrospection(token) {
|
|
48
|
+
if (!this.metadata) {
|
|
49
|
+
throw new Error('Token verifier not initialized');
|
|
50
|
+
}
|
|
51
|
+
// Check if introspection endpoint is available
|
|
52
|
+
const introspectionEndpoint = this.metadata.introspection_endpoint;
|
|
53
|
+
if (!introspectionEndpoint) {
|
|
54
|
+
throw new Error('Introspection endpoint not available in OAuth server metadata');
|
|
55
|
+
}
|
|
56
|
+
// Prepare introspection request
|
|
57
|
+
const requestData = {
|
|
58
|
+
token,
|
|
59
|
+
token_type_hint: 'access_token',
|
|
60
|
+
};
|
|
61
|
+
// Add client credentials if provided
|
|
62
|
+
const headers = {
|
|
63
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
64
|
+
};
|
|
65
|
+
const params = new URLSearchParams({
|
|
66
|
+
token: requestData.token,
|
|
67
|
+
});
|
|
68
|
+
if (this.config.clientId) {
|
|
69
|
+
params.set('client_id', this.config.clientId);
|
|
70
|
+
}
|
|
71
|
+
if (this.config.clientSecret) {
|
|
72
|
+
params.set('client_secret', this.config.clientSecret);
|
|
73
|
+
}
|
|
74
|
+
// Make introspection request
|
|
75
|
+
try {
|
|
76
|
+
const response = await axios.post(introspectionEndpoint, params, {
|
|
77
|
+
headers,
|
|
78
|
+
});
|
|
79
|
+
const data = response.data;
|
|
80
|
+
// Check if token is active
|
|
81
|
+
if (!data.active) {
|
|
82
|
+
throw new Error('Token is not active');
|
|
83
|
+
}
|
|
84
|
+
// Validate audience
|
|
85
|
+
if (!this.validateAudience(data.aud)) {
|
|
86
|
+
throw new Error(`Invalid audience. Expected: ${this.config.expectedAudience}, Got: ${data.aud}`);
|
|
87
|
+
}
|
|
88
|
+
// Validate scopes
|
|
89
|
+
const scopes = data.scope ? data.scope.split(' ') : [];
|
|
90
|
+
if (this.config.requiredScopes) {
|
|
91
|
+
const hasRequiredScopes = this.config.requiredScopes.every((scope) => scopes.includes(scope));
|
|
92
|
+
if (!hasRequiredScopes) {
|
|
93
|
+
throw new Error(`Missing required scopes. Required: ${this.config.requiredScopes.join(', ')}, Got: ${scopes.join(', ')}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
token,
|
|
98
|
+
clientId: data.client_id || 'unknown',
|
|
99
|
+
scopes,
|
|
100
|
+
expiresAt: data.exp,
|
|
101
|
+
audience: data.aud,
|
|
102
|
+
subject: data.sub,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (axios.isAxiosError(error)) {
|
|
107
|
+
throw new Error(`Token introspection failed: ${error.response?.data?.error_description || error.message}`);
|
|
108
|
+
}
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Verify token using JWT validation
|
|
114
|
+
*/
|
|
115
|
+
async verifyViaJWT(token) {
|
|
116
|
+
if (!this.metadata) {
|
|
117
|
+
throw new Error('Token verifier not initialized');
|
|
118
|
+
}
|
|
119
|
+
if (!this.metadata.jwks_uri) {
|
|
120
|
+
throw new Error('JWKS URI not available in OAuth server metadata');
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
// Get JWKS from authorization server
|
|
124
|
+
const JWKS = jose.createRemoteJWKSet(new URL(this.metadata.jwks_uri));
|
|
125
|
+
// Verify JWT
|
|
126
|
+
const { payload } = await jose.jwtVerify(token, JWKS, {
|
|
127
|
+
issuer: this.metadata.issuer,
|
|
128
|
+
audience: this.config.expectedAudience,
|
|
129
|
+
});
|
|
130
|
+
// Extract scopes
|
|
131
|
+
const scopes = typeof payload.scope === 'string'
|
|
132
|
+
? payload.scope.split(' ')
|
|
133
|
+
: Array.isArray(payload.scope)
|
|
134
|
+
? payload.scope
|
|
135
|
+
: [];
|
|
136
|
+
// Validate required scopes
|
|
137
|
+
if (this.config.requiredScopes) {
|
|
138
|
+
const hasRequiredScopes = this.config.requiredScopes.every((scope) => scopes.includes(scope));
|
|
139
|
+
if (!hasRequiredScopes) {
|
|
140
|
+
throw new Error(`Missing required scopes. Required: ${this.config.requiredScopes.join(', ')}, Got: ${scopes.join(', ')}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
token,
|
|
145
|
+
clientId: payload.client_id || payload.azp || 'unknown',
|
|
146
|
+
scopes,
|
|
147
|
+
expiresAt: payload.exp,
|
|
148
|
+
audience: payload.aud,
|
|
149
|
+
subject: payload.sub,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
throw new Error(`JWT verification failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Validate audience claim
|
|
158
|
+
*/
|
|
159
|
+
validateAudience(audience) {
|
|
160
|
+
if (!audience) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const audiences = Array.isArray(audience) ? audience : [audience];
|
|
164
|
+
const normalizedExpected = this.config.expectedAudience.replace(/\/$/, '');
|
|
165
|
+
return audiences.some((aud) => {
|
|
166
|
+
const normalizedAud = aud.replace(/\/$/, '');
|
|
167
|
+
return (normalizedAud === normalizedExpected ||
|
|
168
|
+
normalizedAud === normalizedExpected + '/' ||
|
|
169
|
+
normalizedExpected === normalizedAud + '/');
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { EbayConfig } from '../types/ebay.js';
|
|
2
|
+
import type { Implementation } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { LocaleEnum } from '../types/ebay-enums.js';
|
|
4
|
+
/**
|
|
5
|
+
* Get default scopes for the specified environment
|
|
6
|
+
*/
|
|
7
|
+
export declare function getDefaultScopes(environment: 'production' | 'sandbox'): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Validate scopes against environment and return warnings for invalid scopes
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateScopes(scopes: string[], environment: 'production' | 'sandbox'): {
|
|
12
|
+
warnings: string[];
|
|
13
|
+
validScopes: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Validate environment configuration on startup
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateEnvironmentConfig(): {
|
|
19
|
+
isValid: boolean;
|
|
20
|
+
warnings: string[];
|
|
21
|
+
errors: string[];
|
|
22
|
+
};
|
|
23
|
+
export declare function getEbayConfig(): EbayConfig;
|
|
24
|
+
export declare function getBaseUrl(environment: 'production' | 'sandbox'): string;
|
|
25
|
+
/**
|
|
26
|
+
* Get base URL for Identity API (uses apiz subdomain)
|
|
27
|
+
*/
|
|
28
|
+
export declare function getIdentityBaseUrl(environment: 'production' | 'sandbox'): string;
|
|
29
|
+
/**
|
|
30
|
+
* Get the OAuth token endpoint URL
|
|
31
|
+
* @param environment The eBay environment ('production' or 'sandbox')
|
|
32
|
+
* @returns The token endpoint URL
|
|
33
|
+
*/
|
|
34
|
+
export declare function getAuthUrl(environment: 'production' | 'sandbox'): string;
|
|
35
|
+
/**
|
|
36
|
+
* Generate the OAuth authorization URL for user consent
|
|
37
|
+
* @param clientId The client ID of your eBay application.
|
|
38
|
+
* @param redirectUri The redirect URI configured for your eBay application.
|
|
39
|
+
* @param environment The eBay environment ('production' or 'sandbox').
|
|
40
|
+
* @param locale The locale for the authorization page (defaults to en_US).
|
|
41
|
+
* @param prompt Whether to prompt the user for login or consent (defaults to 'login').
|
|
42
|
+
* @param responseType The response type for the OAuth flow (defaults to 'code').
|
|
43
|
+
* @param state An opaque value used to maintain state between the request and callback.
|
|
44
|
+
* It is also used to prevent cross-site request forgery.
|
|
45
|
+
* @param scopes An array of OAuth scopes to request. If not provided, default scopes for the environment will be used.
|
|
46
|
+
*
|
|
47
|
+
* @return The generated OAuth authorization URL.
|
|
48
|
+
*
|
|
49
|
+
* This URL should be opened in a browser for the user to grant permissions
|
|
50
|
+
*/
|
|
51
|
+
export declare function getAuthUrl(clientId: string, redirectUri: string | undefined, environment: 'production' | 'sandbox', locale?: LocaleEnum, prompt?: 'login' | 'consent', responseType?: 'code', state?: string, scopes?: string[]): string;
|
|
52
|
+
/**
|
|
53
|
+
* Generate the OAuth authorization URL for user consent
|
|
54
|
+
* This URL should be opened in a browser for the user to grant permissions
|
|
55
|
+
*
|
|
56
|
+
* Note: Scopes are optional - eBay will automatically grant the appropriate scopes
|
|
57
|
+
* based on your application's keyset configuration if scopes are not specified.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getOAuthAuthorizationUrl(clientId: string, redirectUri: string, // MUST be eBay RuName, NOT a URL
|
|
60
|
+
environment: 'production' | 'sandbox', scopes?: string[], locale?: string, state?: string): string;
|
|
61
|
+
export declare const mcpConfig: Implementation;
|