@solvapay/server 1.0.2 → 1.0.4
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/dist/edge.d.ts +1520 -17
- package/dist/edge.js +137 -17
- package/dist/index.cjs +310 -17
- package/dist/index.d.cts +1599 -34
- package/dist/index.d.ts +1599 -34
- package/dist/index.js +304 -17
- package/package.json +15 -5
package/dist/index.cjs
CHANGED
|
@@ -4314,9 +4314,11 @@ __export(index_exports, {
|
|
|
4314
4314
|
McpBearerAuthError: () => McpBearerAuthError,
|
|
4315
4315
|
PaywallError: () => PaywallError,
|
|
4316
4316
|
VIRTUAL_TOOL_DEFINITIONS: () => VIRTUAL_TOOL_DEFINITIONS,
|
|
4317
|
+
buildAuthInfoFromBearer: () => buildAuthInfoFromBearer,
|
|
4317
4318
|
cancelPurchaseCore: () => cancelPurchaseCore,
|
|
4318
4319
|
createCheckoutSessionCore: () => createCheckoutSessionCore,
|
|
4319
4320
|
createCustomerSessionCore: () => createCustomerSessionCore,
|
|
4321
|
+
createMcpOAuthBridge: () => createMcpOAuthBridge,
|
|
4320
4322
|
createPaymentIntentCore: () => createPaymentIntentCore,
|
|
4321
4323
|
createSolvaPay: () => createSolvaPay,
|
|
4322
4324
|
createSolvaPayClient: () => createSolvaPayClient,
|
|
@@ -4326,10 +4328,14 @@ __export(index_exports, {
|
|
|
4326
4328
|
getAuthenticatedUserCore: () => getAuthenticatedUserCore,
|
|
4327
4329
|
getCustomerRefFromBearerAuthHeader: () => getCustomerRefFromBearerAuthHeader,
|
|
4328
4330
|
getCustomerRefFromJwtPayload: () => getCustomerRefFromJwtPayload,
|
|
4331
|
+
getOAuthAuthorizationServerResponse: () => getOAuthAuthorizationServerResponse,
|
|
4332
|
+
getOAuthProtectedResourceResponse: () => getOAuthProtectedResourceResponse,
|
|
4329
4333
|
handleRouteError: () => handleRouteError,
|
|
4330
4334
|
isErrorResult: () => isErrorResult,
|
|
4335
|
+
jsonSchemaToZodRawShape: () => jsonSchemaToZodRawShape,
|
|
4331
4336
|
listPlansCore: () => listPlansCore,
|
|
4332
4337
|
processPaymentIntentCore: () => processPaymentIntentCore,
|
|
4338
|
+
registerVirtualToolsMcpImpl: () => registerVirtualToolsMcpImpl,
|
|
4333
4339
|
syncCustomerCore: () => syncCustomerCore,
|
|
4334
4340
|
verifyWebhook: () => verifyWebhook,
|
|
4335
4341
|
withRetry: () => withRetry
|
|
@@ -4497,6 +4503,21 @@ function createSolvaPayClient(opts) {
|
|
|
4497
4503
|
}
|
|
4498
4504
|
return await res.json();
|
|
4499
4505
|
},
|
|
4506
|
+
// PUT: /v1/sdk/products/{productRef}/mcp/plans
|
|
4507
|
+
async configureMcpPlans(productRef, params) {
|
|
4508
|
+
const url = `${base}/v1/sdk/products/${productRef}/mcp/plans`;
|
|
4509
|
+
const res = await fetch(url, {
|
|
4510
|
+
method: "PUT",
|
|
4511
|
+
headers,
|
|
4512
|
+
body: JSON.stringify(params)
|
|
4513
|
+
});
|
|
4514
|
+
if (!res.ok) {
|
|
4515
|
+
const error = await res.text();
|
|
4516
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
4517
|
+
throw new import_core.SolvaPayError(`Configure MCP plans failed (${res.status}): ${error}`);
|
|
4518
|
+
}
|
|
4519
|
+
return await res.json();
|
|
4520
|
+
},
|
|
4500
4521
|
// DELETE: /v1/sdk/products/{productRef}
|
|
4501
4522
|
async deleteProduct(productRef) {
|
|
4502
4523
|
const url = `${base}/v1/sdk/products/${productRef}`;
|
|
@@ -5254,10 +5275,10 @@ async function createAdapterHandler(adapter, paywall, metadata, businessLogic) {
|
|
|
5254
5275
|
const backendRefCache = /* @__PURE__ */ new Map();
|
|
5255
5276
|
const getCustomerRef = (args) => args.auth?.customer_ref || "anonymous";
|
|
5256
5277
|
const protectedHandler = await paywall.protect(businessLogic, metadata, getCustomerRef);
|
|
5257
|
-
return async (context) => {
|
|
5278
|
+
return async (context, extra) => {
|
|
5258
5279
|
try {
|
|
5259
5280
|
const args = await adapter.extractArgs(context);
|
|
5260
|
-
const customerRef = await adapter.getCustomerRef(context);
|
|
5281
|
+
const customerRef = await adapter.getCustomerRef(context, extra);
|
|
5261
5282
|
let backendRef = backendRefCache.get(customerRef);
|
|
5262
5283
|
if (!backendRef) {
|
|
5263
5284
|
backendRef = await paywall.ensureCustomer(customerRef, customerRef);
|
|
@@ -5448,18 +5469,18 @@ var McpAdapter = class {
|
|
|
5448
5469
|
extractArgs(args) {
|
|
5449
5470
|
return args;
|
|
5450
5471
|
}
|
|
5451
|
-
async getCustomerRef(args) {
|
|
5472
|
+
async getCustomerRef(args, extra) {
|
|
5452
5473
|
if (this.options.getCustomerRef) {
|
|
5453
|
-
const ref = await this.options.getCustomerRef(args);
|
|
5474
|
+
const ref = await this.options.getCustomerRef(args, extra);
|
|
5454
5475
|
return AdapterUtils.ensureCustomerRef(ref);
|
|
5455
5476
|
}
|
|
5456
|
-
const
|
|
5457
|
-
const customerRef =
|
|
5477
|
+
const customerRefFromExtra = extra?.authInfo?.extra?.customer_ref;
|
|
5478
|
+
const customerRef = typeof customerRefFromExtra === "string" && customerRefFromExtra.trim() ? customerRefFromExtra.trim() : "anonymous";
|
|
5458
5479
|
return AdapterUtils.ensureCustomerRef(customerRef);
|
|
5459
5480
|
}
|
|
5460
5481
|
formatResponse(result, _context) {
|
|
5461
5482
|
const transformed = this.options.transformResponse ? this.options.transformResponse(result) : result;
|
|
5462
|
-
|
|
5483
|
+
const response = {
|
|
5463
5484
|
content: [
|
|
5464
5485
|
{
|
|
5465
5486
|
type: "text",
|
|
@@ -5467,6 +5488,10 @@ var McpAdapter = class {
|
|
|
5467
5488
|
}
|
|
5468
5489
|
]
|
|
5469
5490
|
};
|
|
5491
|
+
if (transformed && typeof transformed === "object" && !Array.isArray(transformed)) {
|
|
5492
|
+
response.structuredContent = transformed;
|
|
5493
|
+
}
|
|
5494
|
+
return response;
|
|
5470
5495
|
}
|
|
5471
5496
|
formatError(error, _context) {
|
|
5472
5497
|
if (error instanceof PaywallError) {
|
|
@@ -5554,8 +5579,8 @@ function mcpErrorResult(message2) {
|
|
|
5554
5579
|
return { content: [{ type: "text", text: JSON.stringify({ error: message2 }) }], isError: true };
|
|
5555
5580
|
}
|
|
5556
5581
|
function createGetUserInfoHandler(apiClient, productRef, getCustomerRef) {
|
|
5557
|
-
return async (args) => {
|
|
5558
|
-
const customerRef = getCustomerRef(args);
|
|
5582
|
+
return async (args, extra) => {
|
|
5583
|
+
const customerRef = getCustomerRef(args, extra);
|
|
5559
5584
|
try {
|
|
5560
5585
|
if (!apiClient.getUserInfo) {
|
|
5561
5586
|
return mcpErrorResult("getUserInfo is not available on this API client");
|
|
@@ -5570,12 +5595,12 @@ function createGetUserInfoHandler(apiClient, productRef, getCustomerRef) {
|
|
|
5570
5595
|
};
|
|
5571
5596
|
}
|
|
5572
5597
|
function createUpgradeHandler(apiClient, productRef, getCustomerRef) {
|
|
5573
|
-
return async (args) => {
|
|
5574
|
-
const customerRef = getCustomerRef(args);
|
|
5598
|
+
return async (args, extra) => {
|
|
5599
|
+
const customerRef = getCustomerRef(args, extra);
|
|
5575
5600
|
const planRef = typeof args.planRef === "string" ? args.planRef : void 0;
|
|
5576
5601
|
try {
|
|
5577
5602
|
const result = await apiClient.createCheckoutSession({
|
|
5578
|
-
|
|
5603
|
+
customerRef,
|
|
5579
5604
|
productRef,
|
|
5580
5605
|
...planRef && { planRef }
|
|
5581
5606
|
});
|
|
@@ -5602,8 +5627,8 @@ You'll be able to compare options and select the one that's right for you.`;
|
|
|
5602
5627
|
};
|
|
5603
5628
|
}
|
|
5604
5629
|
function createManageAccountHandler(apiClient, productRef, getCustomerRef) {
|
|
5605
|
-
return async (args) => {
|
|
5606
|
-
const customerRef = getCustomerRef(args);
|
|
5630
|
+
return async (args, extra) => {
|
|
5631
|
+
const customerRef = getCustomerRef(args, extra);
|
|
5607
5632
|
try {
|
|
5608
5633
|
const session = await apiClient.createCustomerSession({ customerRef, productRef });
|
|
5609
5634
|
const portalUrl = session.customerUrl;
|
|
@@ -5646,6 +5671,98 @@ function createVirtualTools(apiClient, options) {
|
|
|
5646
5671
|
return allTools.filter((t) => !excludeSet.has(t.name));
|
|
5647
5672
|
}
|
|
5648
5673
|
|
|
5674
|
+
// src/register-virtual-tools-mcp.ts
|
|
5675
|
+
var import_node_module = require("module");
|
|
5676
|
+
function getNodeRequire() {
|
|
5677
|
+
try {
|
|
5678
|
+
return (0, eval)("require");
|
|
5679
|
+
} catch {
|
|
5680
|
+
return (0, import_node_module.createRequire)(`${process.cwd()}/package.json`);
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
var nodeRequire = getNodeRequire();
|
|
5684
|
+
function getZod() {
|
|
5685
|
+
try {
|
|
5686
|
+
const zodModule = nodeRequire("zod");
|
|
5687
|
+
return zodModule.z ?? zodModule;
|
|
5688
|
+
} catch {
|
|
5689
|
+
throw new Error(
|
|
5690
|
+
"zod is required to use registerVirtualToolsMcp(). Install it as a dependency in your MCP server project."
|
|
5691
|
+
);
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
function isJsonSchemaObject(value) {
|
|
5695
|
+
return Boolean(value && typeof value === "object");
|
|
5696
|
+
}
|
|
5697
|
+
function toZodSchema(property) {
|
|
5698
|
+
const z = getZod();
|
|
5699
|
+
if (Array.isArray(property.enum) && property.enum.length > 0) {
|
|
5700
|
+
if (property.enum.every((value) => typeof value === "string")) {
|
|
5701
|
+
const [first, ...rest] = property.enum;
|
|
5702
|
+
return z.enum([first, ...rest]);
|
|
5703
|
+
}
|
|
5704
|
+
if (property.enum.length === 1) {
|
|
5705
|
+
return z.literal(property.enum[0]);
|
|
5706
|
+
}
|
|
5707
|
+
return z.union(property.enum.map((value) => z.literal(value)));
|
|
5708
|
+
}
|
|
5709
|
+
switch (property.type) {
|
|
5710
|
+
case "string":
|
|
5711
|
+
return z.string();
|
|
5712
|
+
case "number":
|
|
5713
|
+
return z.number();
|
|
5714
|
+
case "integer":
|
|
5715
|
+
return z.number().int();
|
|
5716
|
+
case "boolean":
|
|
5717
|
+
return z.boolean();
|
|
5718
|
+
case "array":
|
|
5719
|
+
return z.array(
|
|
5720
|
+
isJsonSchemaObject(property.items) ? toZodSchema(property.items) : z.any()
|
|
5721
|
+
);
|
|
5722
|
+
case "object":
|
|
5723
|
+
return z.object(jsonSchemaToZodRawShape(property.properties || {}));
|
|
5724
|
+
default:
|
|
5725
|
+
return z.any();
|
|
5726
|
+
}
|
|
5727
|
+
}
|
|
5728
|
+
function jsonSchemaToZodRawShape(properties, required = []) {
|
|
5729
|
+
const requiredSet = new Set(required);
|
|
5730
|
+
return Object.fromEntries(
|
|
5731
|
+
Object.entries(properties).map(([name, property]) => {
|
|
5732
|
+
const schema = toZodSchema(property);
|
|
5733
|
+
const finalSchema = requiredSet.has(name) ? schema : schema.optional();
|
|
5734
|
+
return [name, finalSchema];
|
|
5735
|
+
})
|
|
5736
|
+
);
|
|
5737
|
+
}
|
|
5738
|
+
function defaultGetCustomerRef(_args, extra) {
|
|
5739
|
+
const fromExtra = extra?.authInfo?.extra?.customer_ref;
|
|
5740
|
+
return typeof fromExtra === "string" && fromExtra.trim() ? fromExtra.trim() : "anonymous";
|
|
5741
|
+
}
|
|
5742
|
+
function registerVirtualToolsMcpImpl(server, apiClient, options) {
|
|
5743
|
+
const { filter, mapDefinition, wrapHandler, getCustomerRef, ...virtualToolsOptions } = options;
|
|
5744
|
+
const virtualTools = createVirtualTools(apiClient, {
|
|
5745
|
+
...virtualToolsOptions,
|
|
5746
|
+
getCustomerRef: getCustomerRef || defaultGetCustomerRef
|
|
5747
|
+
});
|
|
5748
|
+
for (const toolDefinition of virtualTools) {
|
|
5749
|
+
if (filter && !filter(toolDefinition)) continue;
|
|
5750
|
+
const mappedDefinition = mapDefinition ? mapDefinition(toolDefinition) : toolDefinition;
|
|
5751
|
+
const wrappedHandler = wrapHandler ? wrapHandler(mappedDefinition.handler, mappedDefinition) : mappedDefinition.handler;
|
|
5752
|
+
server.registerTool(
|
|
5753
|
+
mappedDefinition.name,
|
|
5754
|
+
{
|
|
5755
|
+
description: mappedDefinition.description,
|
|
5756
|
+
inputSchema: jsonSchemaToZodRawShape(
|
|
5757
|
+
mappedDefinition.inputSchema.properties,
|
|
5758
|
+
mappedDefinition.inputSchema.required || []
|
|
5759
|
+
)
|
|
5760
|
+
},
|
|
5761
|
+
wrappedHandler
|
|
5762
|
+
);
|
|
5763
|
+
}
|
|
5764
|
+
}
|
|
5765
|
+
|
|
5649
5766
|
// src/factory.ts
|
|
5650
5767
|
function createSolvaPay(config) {
|
|
5651
5768
|
let resolvedConfig;
|
|
@@ -5702,7 +5819,7 @@ function createSolvaPay(config) {
|
|
|
5702
5819
|
},
|
|
5703
5820
|
createCheckoutSession(params) {
|
|
5704
5821
|
return apiClient.createCheckoutSession({
|
|
5705
|
-
|
|
5822
|
+
customerRef: params.customerRef,
|
|
5706
5823
|
productRef: params.productRef,
|
|
5707
5824
|
planRef: params.planRef
|
|
5708
5825
|
});
|
|
@@ -5716,9 +5833,18 @@ function createSolvaPay(config) {
|
|
|
5716
5833
|
}
|
|
5717
5834
|
return apiClient.bootstrapMcpProduct(params);
|
|
5718
5835
|
},
|
|
5836
|
+
configureMcpPlans(productRef, params) {
|
|
5837
|
+
if (!apiClient.configureMcpPlans) {
|
|
5838
|
+
throw new import_core2.SolvaPayError("configureMcpPlans is not available on this API client");
|
|
5839
|
+
}
|
|
5840
|
+
return apiClient.configureMcpPlans(productRef, params);
|
|
5841
|
+
},
|
|
5719
5842
|
getVirtualTools(options) {
|
|
5720
5843
|
return createVirtualTools(apiClient, options);
|
|
5721
5844
|
},
|
|
5845
|
+
async registerVirtualToolsMcp(server, options) {
|
|
5846
|
+
await registerVirtualToolsMcpImpl(server, apiClient, options);
|
|
5847
|
+
},
|
|
5722
5848
|
// Payable API for framework-specific handlers
|
|
5723
5849
|
payable(options = {}) {
|
|
5724
5850
|
const product = options.productRef || options.product || process.env.SOLVAPAY_PRODUCT || "default-product";
|
|
@@ -5757,9 +5883,9 @@ function createSolvaPay(config) {
|
|
|
5757
5883
|
getCustomerRef: adapterOptions?.getCustomerRef || options.getCustomerRef
|
|
5758
5884
|
});
|
|
5759
5885
|
const handlerPromise = createAdapterHandler(adapter, paywall, metadata, businessLogic);
|
|
5760
|
-
return async (args) => {
|
|
5886
|
+
return async (args, extra) => {
|
|
5761
5887
|
const handler = await handlerPromise;
|
|
5762
|
-
return handler(args);
|
|
5888
|
+
return handler(args, extra);
|
|
5763
5889
|
};
|
|
5764
5890
|
},
|
|
5765
5891
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -5829,6 +5955,167 @@ function getCustomerRefFromBearerAuthHeader(authorization, options = {}) {
|
|
|
5829
5955
|
return getCustomerRefFromJwtPayload(payload, options);
|
|
5830
5956
|
}
|
|
5831
5957
|
|
|
5958
|
+
// src/mcp/auth-bridge.ts
|
|
5959
|
+
function getClientId(payload, explicitClientId) {
|
|
5960
|
+
if (explicitClientId) return explicitClientId;
|
|
5961
|
+
const payloadClientId = typeof payload.client_id === "string" && payload.client_id || typeof payload.azp === "string" && payload.azp || typeof payload.aud === "string" && payload.aud || null;
|
|
5962
|
+
return payloadClientId || "solvapay-mcp-client";
|
|
5963
|
+
}
|
|
5964
|
+
function getScopes(payload, defaultScopes) {
|
|
5965
|
+
if (Array.isArray(payload.scp)) {
|
|
5966
|
+
return payload.scp.filter((scope) => typeof scope === "string");
|
|
5967
|
+
}
|
|
5968
|
+
if (typeof payload.scope === "string" && payload.scope.trim()) {
|
|
5969
|
+
return payload.scope.split(/\s+/).map((scope) => scope.trim()).filter(Boolean);
|
|
5970
|
+
}
|
|
5971
|
+
return defaultScopes;
|
|
5972
|
+
}
|
|
5973
|
+
function getExpiresAt(payload) {
|
|
5974
|
+
return typeof payload.exp === "number" ? payload.exp : void 0;
|
|
5975
|
+
}
|
|
5976
|
+
function buildAuthInfoFromBearer(authorization, options = {}) {
|
|
5977
|
+
const token = extractBearerToken(authorization);
|
|
5978
|
+
if (!token) return null;
|
|
5979
|
+
const payload = decodeJwtPayload(token);
|
|
5980
|
+
const customerRef = getCustomerRefFromJwtPayload(payload, options);
|
|
5981
|
+
const clientId = getClientId(payload, options.clientId);
|
|
5982
|
+
const scopes = getScopes(payload, options.defaultScopes || []);
|
|
5983
|
+
const expiresAt = getExpiresAt(payload);
|
|
5984
|
+
return {
|
|
5985
|
+
token,
|
|
5986
|
+
clientId,
|
|
5987
|
+
scopes,
|
|
5988
|
+
expiresAt,
|
|
5989
|
+
extra: {
|
|
5990
|
+
customer_ref: customerRef,
|
|
5991
|
+
...options.includePayload ? { payload } : {}
|
|
5992
|
+
}
|
|
5993
|
+
};
|
|
5994
|
+
}
|
|
5995
|
+
|
|
5996
|
+
// src/mcp/oauth-bridge.ts
|
|
5997
|
+
function withoutTrailingSlash(value) {
|
|
5998
|
+
return value.replace(/\/$/, "");
|
|
5999
|
+
}
|
|
6000
|
+
function getRequestAuthHeader(req) {
|
|
6001
|
+
const header = req.headers?.authorization;
|
|
6002
|
+
if (typeof header === "string") return header;
|
|
6003
|
+
if (Array.isArray(header)) return header[0] || null;
|
|
6004
|
+
return null;
|
|
6005
|
+
}
|
|
6006
|
+
function getRequestJsonRpcId(body) {
|
|
6007
|
+
if (body && typeof body === "object" && "id" in body) {
|
|
6008
|
+
const id = body.id;
|
|
6009
|
+
return id ?? null;
|
|
6010
|
+
}
|
|
6011
|
+
return null;
|
|
6012
|
+
}
|
|
6013
|
+
function makeUnauthorizedJsonRpc(id) {
|
|
6014
|
+
return {
|
|
6015
|
+
jsonrpc: "2.0",
|
|
6016
|
+
id,
|
|
6017
|
+
error: {
|
|
6018
|
+
code: -32001,
|
|
6019
|
+
message: "Unauthorized"
|
|
6020
|
+
}
|
|
6021
|
+
};
|
|
6022
|
+
}
|
|
6023
|
+
function setMcpChallengeHeader(res, publicBaseUrl, protectedResourcePath) {
|
|
6024
|
+
res.setHeader(
|
|
6025
|
+
"WWW-Authenticate",
|
|
6026
|
+
`Bearer resource_metadata="${withoutTrailingSlash(publicBaseUrl)}${protectedResourcePath}"`
|
|
6027
|
+
);
|
|
6028
|
+
}
|
|
6029
|
+
function getOAuthProtectedResourceResponse(publicBaseUrl) {
|
|
6030
|
+
const resource = withoutTrailingSlash(publicBaseUrl);
|
|
6031
|
+
return {
|
|
6032
|
+
resource,
|
|
6033
|
+
authorization_servers: [resource],
|
|
6034
|
+
scopes_supported: ["openid", "profile", "email"]
|
|
6035
|
+
};
|
|
6036
|
+
}
|
|
6037
|
+
function getOAuthAuthorizationServerResponse({
|
|
6038
|
+
apiBaseUrl,
|
|
6039
|
+
productRef
|
|
6040
|
+
}) {
|
|
6041
|
+
const normalizedApiBaseUrl = withoutTrailingSlash(apiBaseUrl);
|
|
6042
|
+
const registrationEndpoint = `${normalizedApiBaseUrl}/v1/customer/auth/register?product_ref=${encodeURIComponent(productRef)}`;
|
|
6043
|
+
return {
|
|
6044
|
+
issuer: normalizedApiBaseUrl,
|
|
6045
|
+
authorization_endpoint: `${normalizedApiBaseUrl}/v1/customer/auth/authorize`,
|
|
6046
|
+
token_endpoint: `${normalizedApiBaseUrl}/v1/customer/auth/token`,
|
|
6047
|
+
registration_endpoint: registrationEndpoint,
|
|
6048
|
+
token_endpoint_auth_methods_supported: ["client_secret_basic", "client_secret_post"],
|
|
6049
|
+
response_types_supported: ["code"],
|
|
6050
|
+
grant_types_supported: ["authorization_code", "refresh_token"],
|
|
6051
|
+
scopes_supported: ["openid", "profile", "email"],
|
|
6052
|
+
code_challenge_methods_supported: ["S256"]
|
|
6053
|
+
};
|
|
6054
|
+
}
|
|
6055
|
+
function createMcpOAuthBridge(options) {
|
|
6056
|
+
const {
|
|
6057
|
+
publicBaseUrl,
|
|
6058
|
+
apiBaseUrl,
|
|
6059
|
+
productRef,
|
|
6060
|
+
mcpPath = "/mcp",
|
|
6061
|
+
requireAuth = true,
|
|
6062
|
+
authInfo,
|
|
6063
|
+
protectedResourcePath = "/.well-known/oauth-protected-resource",
|
|
6064
|
+
authorizationServerPath = "/.well-known/oauth-authorization-server"
|
|
6065
|
+
} = options;
|
|
6066
|
+
const protectedResourceMiddleware = (req, res, next) => {
|
|
6067
|
+
if (req.method !== "GET" || req.path !== protectedResourcePath) {
|
|
6068
|
+
next();
|
|
6069
|
+
return;
|
|
6070
|
+
}
|
|
6071
|
+
res.json(getOAuthProtectedResourceResponse(publicBaseUrl));
|
|
6072
|
+
};
|
|
6073
|
+
const authorizationServerMiddleware = (req, res, next) => {
|
|
6074
|
+
if (req.method !== "GET" || req.path !== authorizationServerPath) {
|
|
6075
|
+
next();
|
|
6076
|
+
return;
|
|
6077
|
+
}
|
|
6078
|
+
if (!productRef) {
|
|
6079
|
+
res.status(500).json({ error: "SOLVAPAY_PRODUCT_REF missing" });
|
|
6080
|
+
return;
|
|
6081
|
+
}
|
|
6082
|
+
res.json(
|
|
6083
|
+
getOAuthAuthorizationServerResponse({
|
|
6084
|
+
apiBaseUrl,
|
|
6085
|
+
productRef
|
|
6086
|
+
})
|
|
6087
|
+
);
|
|
6088
|
+
};
|
|
6089
|
+
const mcpAuthMiddleware = (req, res, next) => {
|
|
6090
|
+
if (req.path !== mcpPath) {
|
|
6091
|
+
next();
|
|
6092
|
+
return;
|
|
6093
|
+
}
|
|
6094
|
+
const authHeader = getRequestAuthHeader(req);
|
|
6095
|
+
const id = getRequestJsonRpcId(req.body);
|
|
6096
|
+
if (!authHeader && !requireAuth) {
|
|
6097
|
+
next();
|
|
6098
|
+
return;
|
|
6099
|
+
}
|
|
6100
|
+
try {
|
|
6101
|
+
const auth = buildAuthInfoFromBearer(authHeader, authInfo);
|
|
6102
|
+
if (!auth) {
|
|
6103
|
+
throw new McpBearerAuthError("Missing bearer token");
|
|
6104
|
+
}
|
|
6105
|
+
req.auth = auth;
|
|
6106
|
+
next();
|
|
6107
|
+
} catch {
|
|
6108
|
+
setMcpChallengeHeader(res, publicBaseUrl, protectedResourcePath);
|
|
6109
|
+
if (req.method === "POST") {
|
|
6110
|
+
res.status(401).json(makeUnauthorizedJsonRpc(id));
|
|
6111
|
+
return;
|
|
6112
|
+
}
|
|
6113
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
6114
|
+
}
|
|
6115
|
+
};
|
|
6116
|
+
return [protectedResourceMiddleware, authorizationServerMiddleware, mcpAuthMiddleware];
|
|
6117
|
+
}
|
|
6118
|
+
|
|
5832
6119
|
// src/helpers/error.ts
|
|
5833
6120
|
var import_core3 = require("@solvapay/core");
|
|
5834
6121
|
function isErrorResult(result) {
|
|
@@ -6183,9 +6470,11 @@ function verifyWebhook({
|
|
|
6183
6470
|
McpBearerAuthError,
|
|
6184
6471
|
PaywallError,
|
|
6185
6472
|
VIRTUAL_TOOL_DEFINITIONS,
|
|
6473
|
+
buildAuthInfoFromBearer,
|
|
6186
6474
|
cancelPurchaseCore,
|
|
6187
6475
|
createCheckoutSessionCore,
|
|
6188
6476
|
createCustomerSessionCore,
|
|
6477
|
+
createMcpOAuthBridge,
|
|
6189
6478
|
createPaymentIntentCore,
|
|
6190
6479
|
createSolvaPay,
|
|
6191
6480
|
createSolvaPayClient,
|
|
@@ -6195,10 +6484,14 @@ function verifyWebhook({
|
|
|
6195
6484
|
getAuthenticatedUserCore,
|
|
6196
6485
|
getCustomerRefFromBearerAuthHeader,
|
|
6197
6486
|
getCustomerRefFromJwtPayload,
|
|
6487
|
+
getOAuthAuthorizationServerResponse,
|
|
6488
|
+
getOAuthProtectedResourceResponse,
|
|
6198
6489
|
handleRouteError,
|
|
6199
6490
|
isErrorResult,
|
|
6491
|
+
jsonSchemaToZodRawShape,
|
|
6200
6492
|
listPlansCore,
|
|
6201
6493
|
processPaymentIntentCore,
|
|
6494
|
+
registerVirtualToolsMcpImpl,
|
|
6202
6495
|
syncCustomerCore,
|
|
6203
6496
|
verifyWebhook,
|
|
6204
6497
|
withRetry
|