ucpify 1.2.0 → 1.2.1

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.
@@ -1,495 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createExpressApp = createExpressApp;
7
- const express_1 = __importDefault(require("express"));
8
- const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
9
- const ucp_server_1 = require("./ucp-server");
10
- const ucp_server_db_1 = require("./ucp-server-db");
11
- const schema_1 = require("./schema");
12
- const db_1 = require("./db");
13
- const logger_1 = require("./logger");
14
- const stripe_1 = require("./stripe");
15
- const paypal_1 = require("./paypal");
16
- const oauth_1 = require("./oauth");
17
- // Rate limiters
18
- const apiLimiter = (0, express_rate_limit_1.default)({
19
- windowMs: 60 * 1000, // 1 minute
20
- max: 100, // 100 requests per minute
21
- standardHeaders: true,
22
- legacyHeaders: false,
23
- message: { error: 'Too many requests, please try again later' },
24
- });
25
- const checkoutLimiter = (0, express_rate_limit_1.default)({
26
- windowMs: 60 * 1000,
27
- max: 20, // 20 checkout creates per minute
28
- standardHeaders: true,
29
- legacyHeaders: false,
30
- message: { error: 'Too many checkout requests' },
31
- });
32
- function createExpressApp(config, options) {
33
- const app = (0, express_1.default)();
34
- const ucpServer = options?.useDb
35
- ? new ucp_server_db_1.UCPServerDB(config)
36
- : new ucp_server_1.UCPServer(config);
37
- const useDb = options?.useDb ?? false;
38
- // OAuth setup (built-in or external)
39
- const oauthEnabled = !!config.oauth;
40
- const oauthManager = oauthEnabled && config.oauth?.provider === 'built-in'
41
- ? new oauth_1.OAuthManager()
42
- : null;
43
- // Apply rate limiting to API routes
44
- app.use('/ucp/v1/', apiLimiter);
45
- // Stripe webhook needs raw body - must come before json parser
46
- app.post('/webhooks/stripe', express_1.default.raw({ type: 'application/json' }), (req, res) => {
47
- const signature = req.headers['stripe-signature'];
48
- if (!signature) {
49
- res.status(400).json({ error: 'Missing stripe-signature header' });
50
- return;
51
- }
52
- const event = (0, stripe_1.constructWebhookEvent)(req.body, signature);
53
- if (!event) {
54
- res.status(400).json({ error: 'Invalid webhook signature' });
55
- return;
56
- }
57
- logger_1.logger.info({ type: event.type }, 'Stripe webhook received');
58
- switch (event.type) {
59
- case 'payment_intent.succeeded': {
60
- const paymentIntent = event.data.object;
61
- const checkoutId = paymentIntent.metadata?.checkout_id;
62
- const orderId = paymentIntent.metadata?.order_id;
63
- if (checkoutId && useDb) {
64
- db_1.db.prepare(`UPDATE checkouts SET payment_status = 'succeeded', updated_at = ? WHERE id = ?`)
65
- .run(new Date().toISOString(), checkoutId);
66
- if (orderId) {
67
- db_1.db.prepare(`UPDATE orders SET payment_status = 'succeeded' WHERE id = ?`).run(orderId);
68
- }
69
- logger_1.logger.info({ checkoutId, orderId, paymentIntentId: paymentIntent.id }, 'Payment succeeded');
70
- }
71
- break;
72
- }
73
- case 'payment_intent.payment_failed': {
74
- const paymentIntent = event.data.object;
75
- const checkoutId = paymentIntent.metadata?.checkout_id;
76
- const orderId = paymentIntent.metadata?.order_id;
77
- if (checkoutId && useDb) {
78
- db_1.db.prepare(`UPDATE checkouts SET payment_status = 'failed', updated_at = ? WHERE id = ?`)
79
- .run(new Date().toISOString(), checkoutId);
80
- if (orderId) {
81
- db_1.db.prepare(`UPDATE orders SET payment_status = 'failed' WHERE id = ?`).run(orderId);
82
- }
83
- logger_1.logger.error({
84
- checkoutId, orderId, paymentIntentId: paymentIntent.id,
85
- error: paymentIntent.last_payment_error?.message
86
- }, 'Payment failed');
87
- }
88
- break;
89
- }
90
- }
91
- res.json({ received: true });
92
- });
93
- // PayPal webhook - capture completed orders
94
- app.post('/webhooks/paypal', express_1.default.json(), async (req, res) => {
95
- const eventType = req.body.event_type;
96
- const resource = req.body.resource;
97
- logger_1.logger.info({ eventType, resourceId: resource?.id }, 'PayPal webhook received');
98
- if (eventType === 'CHECKOUT.ORDER.APPROVED' && resource?.id) {
99
- try {
100
- // Capture the payment
101
- const capturedOrder = await (0, paypal_1.capturePayPalOrder)(resource.id);
102
- if (capturedOrder && capturedOrder.status === 'COMPLETED') {
103
- // Get the checkout ID from the order
104
- const orderDetails = await (0, paypal_1.getPayPalOrder)(resource.id);
105
- const checkoutId = orderDetails?.customId;
106
- if (checkoutId && useDb) {
107
- const now = new Date().toISOString();
108
- db_1.db.prepare(`UPDATE checkouts SET payment_status = 'succeeded', updated_at = ? WHERE paypal_order_id = ?`)
109
- .run(now, resource.id);
110
- db_1.db.prepare(`UPDATE orders SET payment_status = 'succeeded' WHERE paypal_order_id = ?`)
111
- .run(resource.id);
112
- logger_1.logger.info({ checkoutId, paypalOrderId: resource.id }, 'PayPal payment captured and succeeded');
113
- }
114
- }
115
- }
116
- catch (error) {
117
- logger_1.logger.error({ error, paypalOrderId: resource.id }, 'Failed to capture PayPal order');
118
- }
119
- }
120
- else if (eventType === 'PAYMENT.CAPTURE.DENIED' && resource?.id) {
121
- if (useDb) {
122
- const now = new Date().toISOString();
123
- db_1.db.prepare(`UPDATE checkouts SET payment_status = 'failed', updated_at = ? WHERE paypal_order_id = ?`)
124
- .run(now, resource.supplementary_data?.related_ids?.order_id);
125
- db_1.db.prepare(`UPDATE orders SET payment_status = 'failed' WHERE paypal_order_id = ?`)
126
- .run(resource.supplementary_data?.related_ids?.order_id);
127
- logger_1.logger.error({ paypalOrderId: resource.id }, 'PayPal payment denied');
128
- }
129
- }
130
- res.json({ received: true });
131
- });
132
- app.use(express_1.default.json());
133
- // Request logging middleware
134
- app.use((req, res, next) => {
135
- const start = Date.now();
136
- res.on('finish', () => {
137
- logger_1.logger.info({
138
- method: req.method,
139
- path: req.path,
140
- status: res.statusCode,
141
- duration: Date.now() - start,
142
- }, 'Request completed');
143
- });
144
- next();
145
- });
146
- // CORS middleware
147
- app.use((_req, res, next) => {
148
- res.header('Access-Control-Allow-Origin', '*');
149
- res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
150
- res.header('Access-Control-Allow-Headers', 'Content-Type, UCP-Agent, Authorization');
151
- next();
152
- });
153
- // ─── OAuth 2.0 Identity Linking ─────────────────────────────────────
154
- // RFC 8414: OAuth Authorization Server Metadata
155
- app.get('/.well-known/oauth-authorization-server', (_req, res) => {
156
- if (!oauthEnabled) {
157
- res.status(404).json({ error: 'OAuth not configured' });
158
- return;
159
- }
160
- if (config.oauth?.provider === 'external') {
161
- // Proxy the merchant's external OAuth metadata
162
- res.json({
163
- issuer: config.oauth.issuer,
164
- authorization_endpoint: config.oauth.authorization_endpoint,
165
- token_endpoint: config.oauth.token_endpoint,
166
- revocation_endpoint: config.oauth.revocation_endpoint,
167
- jwks_uri: config.oauth.jwks_uri,
168
- scopes_supported: ['ucp:scopes:checkout_session'],
169
- response_types_supported: ['code'],
170
- grant_types_supported: ['authorization_code', 'refresh_token'],
171
- token_endpoint_auth_methods_supported: ['client_secret_basic'],
172
- });
173
- }
174
- else if (oauthManager) {
175
- res.json(oauthManager.getServerMetadata(config.domain));
176
- }
177
- });
178
- // Built-in OAuth endpoints (only when provider is "built-in")
179
- if (oauthManager) {
180
- // Authorization endpoint - renders consent screen
181
- app.get('/oauth2/authorize', (req, res) => {
182
- const { client_id, redirect_uri, scope, state, response_type, code_challenge, code_challenge_method } = req.query;
183
- if (response_type !== 'code') {
184
- res.status(400).json({ error: 'unsupported_response_type' });
185
- return;
186
- }
187
- const client = oauthManager.getClient(client_id);
188
- if (!client) {
189
- res.status(400).json({ error: 'invalid_client' });
190
- return;
191
- }
192
- if (!client.redirect_uris.includes(redirect_uri)) {
193
- res.status(400).json({ error: 'invalid_redirect_uri' });
194
- return;
195
- }
196
- // Render a minimal consent page
197
- res.send(`<!DOCTYPE html>
198
- <html><head><title>Authorize - ${config.name}</title>
199
- <style>
200
- body { font-family: system-ui, sans-serif; max-width: 400px; margin: 80px auto; padding: 0 20px; }
201
- h2 { margin-bottom: 4px; }
202
- p { color: #666; }
203
- .scope { background: #f0f0f0; padding: 8px 12px; border-radius: 6px; font-family: monospace; }
204
- button { padding: 10px 24px; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; margin-right: 8px; }
205
- .allow { background: #000; color: #fff; }
206
- .deny { background: #e5e5e5; }
207
- </style></head>
208
- <body>
209
- <h2>${config.name}</h2>
210
- <p><strong>${client.name}</strong> wants to access your account.</p>
211
- <div class="scope">${scope || 'ucp:scopes:checkout_session'}</div>
212
- <p>This will allow the app to manage checkout sessions on your behalf.</p>
213
- <form method="POST" action="/oauth2/authorize">
214
- <input type="hidden" name="client_id" value="${client_id}">
215
- <input type="hidden" name="redirect_uri" value="${redirect_uri}">
216
- <input type="hidden" name="scope" value="${scope || 'ucp:scopes:checkout_session'}">
217
- <input type="hidden" name="state" value="${state || ''}">
218
- <input type="hidden" name="code_challenge" value="${code_challenge || ''}">
219
- <input type="hidden" name="code_challenge_method" value="${code_challenge_method || ''}">
220
- <input type="hidden" name="user_id" value="user_1">
221
- <button type="submit" name="action" value="allow" class="allow">Allow</button>
222
- <button type="submit" name="action" value="deny" class="deny">Deny</button>
223
- </form>
224
- </body></html>`);
225
- });
226
- // Handle consent form submission
227
- app.post('/oauth2/authorize', express_1.default.urlencoded({ extended: false }), (req, res) => {
228
- const { client_id, redirect_uri, scope, state, action, user_id, code_challenge, code_challenge_method } = req.body;
229
- if (action === 'deny') {
230
- const url = new URL(redirect_uri);
231
- url.searchParams.set('error', 'access_denied');
232
- if (state)
233
- url.searchParams.set('state', state);
234
- res.redirect(url.toString());
235
- return;
236
- }
237
- const code = oauthManager.createAuthorizationCode(client_id, user_id, scope, redirect_uri, code_challenge || undefined, code_challenge_method || undefined);
238
- const url = new URL(redirect_uri);
239
- url.searchParams.set('code', code);
240
- if (state)
241
- url.searchParams.set('state', state);
242
- res.redirect(url.toString());
243
- });
244
- // Token endpoint
245
- app.post('/oauth2/token', (req, res) => {
246
- // Client auth via HTTP Basic (RFC 7617)
247
- const authHeader = req.headers.authorization;
248
- let clientId = req.body.client_id;
249
- let clientSecret = req.body.client_secret;
250
- if (authHeader && authHeader.startsWith('Basic ')) {
251
- const decoded = Buffer.from(authHeader.slice(6), 'base64').toString();
252
- const [id, secret] = decoded.split(':');
253
- clientId = id;
254
- clientSecret = secret;
255
- }
256
- if (!oauthManager.authenticateClient(clientId, clientSecret)) {
257
- res.status(401).json({ error: 'invalid_client' });
258
- return;
259
- }
260
- const grantType = req.body.grant_type;
261
- if (grantType === 'authorization_code') {
262
- const result = oauthManager.exchangeCode(req.body.code, clientId, req.body.redirect_uri, req.body.code_verifier);
263
- if ('error' in result) {
264
- res.status(400).json(result);
265
- return;
266
- }
267
- res.json({ ...result, token_type: 'Bearer' });
268
- }
269
- else if (grantType === 'refresh_token') {
270
- const result = oauthManager.refreshAccessToken(req.body.refresh_token, clientId);
271
- if ('error' in result) {
272
- res.status(400).json(result);
273
- return;
274
- }
275
- res.json({ ...result, token_type: 'Bearer' });
276
- }
277
- else {
278
- res.status(400).json({ error: 'unsupported_grant_type' });
279
- }
280
- });
281
- // Token revocation (RFC 7009)
282
- app.post('/oauth2/revoke', (req, res) => {
283
- const authHeader = req.headers.authorization;
284
- let clientId = req.body.client_id;
285
- let clientSecret = req.body.client_secret;
286
- if (authHeader && authHeader.startsWith('Basic ')) {
287
- const decoded = Buffer.from(authHeader.slice(6), 'base64').toString();
288
- const [id, secret] = decoded.split(':');
289
- clientId = id;
290
- clientSecret = secret;
291
- }
292
- if (!oauthManager.authenticateClient(clientId, clientSecret)) {
293
- res.status(401).json({ error: 'invalid_client' });
294
- return;
295
- }
296
- oauthManager.revokeToken(req.body.token);
297
- // RFC 7009: always respond 200, even if token was invalid
298
- res.status(200).json({});
299
- });
300
- }
301
- // Bearer token middleware for UCP routes (when OAuth is enabled)
302
- if (oauthEnabled && oauthManager) {
303
- app.use('/ucp/v1', (req, res, next) => {
304
- const authHeader = req.headers.authorization;
305
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
306
- res.status(401).json({ error: 'missing_token', message: 'Authorization: Bearer <token> required' });
307
- return;
308
- }
309
- const token = authHeader.slice(7);
310
- const validToken = oauthManager.validateAccessToken(token);
311
- if (!validToken) {
312
- res.status(401).json({ error: 'invalid_token', message: 'Token is expired, revoked, or invalid' });
313
- return;
314
- }
315
- // Attach user info to request
316
- req.oauthUserId = validToken.user_id;
317
- req.oauthClientId = validToken.client_id;
318
- req.oauthScope = validToken.scope;
319
- next();
320
- });
321
- }
322
- // UCP Discovery endpoint
323
- app.get('/.well-known/ucp', (_req, res) => {
324
- res.json(ucpServer.getProfile());
325
- });
326
- // Create Checkout Session
327
- app.post('/ucp/v1/checkout-sessions', checkoutLimiter, (req, res) => {
328
- const parsed = schema_1.CreateCheckoutRequestSchema.safeParse(req.body);
329
- if (!parsed.success) {
330
- res.status(400).json({ error: 'Validation failed', details: parsed.error.issues });
331
- return;
332
- }
333
- try {
334
- const session = ucpServer.createCheckout(parsed.data);
335
- res.status(201).json(session);
336
- }
337
- catch (error) {
338
- res.status(400).json({ error: 'Invalid request', details: String(error) });
339
- }
340
- });
341
- // Get Checkout Session
342
- app.get('/ucp/v1/checkout-sessions/:id', (req, res) => {
343
- const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
344
- const session = ucpServer.getCheckout(id);
345
- if (!session) {
346
- res.status(404).json({ error: 'Checkout session not found' });
347
- return;
348
- }
349
- res.json(session);
350
- });
351
- // Update Checkout Session
352
- app.put('/ucp/v1/checkout-sessions/:id', (req, res) => {
353
- const parsed = schema_1.UpdateCheckoutRequestSchema.safeParse(req.body);
354
- if (!parsed.success) {
355
- res.status(400).json({ error: 'Validation failed', details: parsed.error.issues });
356
- return;
357
- }
358
- try {
359
- const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
360
- const session = ucpServer.updateCheckout(id, parsed.data);
361
- if (!session) {
362
- res.status(404).json({ error: 'Checkout session not found' });
363
- return;
364
- }
365
- res.json(session);
366
- }
367
- catch (error) {
368
- res.status(400).json({ error: 'Invalid request', details: String(error) });
369
- }
370
- });
371
- // Complete Checkout
372
- app.post('/ucp/v1/checkout-sessions/:id/complete', async (req, res) => {
373
- const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
374
- try {
375
- const result = await ucpServer.completeCheckout(id);
376
- if ('error' in result) {
377
- res.status(400).json(result);
378
- return;
379
- }
380
- res.status(201).json(result);
381
- }
382
- catch (error) {
383
- logger_1.logger.error({ error, checkoutId: id }, 'Failed to complete checkout');
384
- res.status(500).json({ error: 'Internal server error' });
385
- }
386
- });
387
- // Cancel Checkout
388
- app.post('/ucp/v1/checkout-sessions/:id/cancel', (req, res) => {
389
- const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
390
- const session = ucpServer.cancelCheckout(id);
391
- if (!session) {
392
- res.status(404).json({ error: 'Checkout session not found' });
393
- return;
394
- }
395
- res.json(session);
396
- });
397
- // Get Order
398
- app.get('/ucp/v1/orders/:id', (req, res) => {
399
- const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
400
- const order = ucpServer.getOrder(id);
401
- if (!order) {
402
- res.status(404).json({ error: 'Order not found' });
403
- return;
404
- }
405
- res.json(order);
406
- });
407
- // List Orders
408
- app.get('/ucp/v1/orders', (_req, res) => {
409
- res.json(ucpServer.listOrders());
410
- });
411
- // Product catalog (convenience endpoint)
412
- app.get('/ucp/v1/items', (_req, res) => {
413
- res.json(ucpServer.getConfig().items);
414
- });
415
- // Admin stats endpoint
416
- app.get('/admin/stats', (_req, res) => {
417
- if (!useDb) {
418
- res.status(501).json({ error: 'Stats require database mode' });
419
- return;
420
- }
421
- try {
422
- const checkoutStats = db_1.db.prepare(`
423
- SELECT status, COUNT(*) as count FROM checkouts GROUP BY status
424
- `).all();
425
- const orderStats = db_1.db.prepare(`
426
- SELECT payment_status, payment_provider, COUNT(*) as count
427
- FROM orders GROUP BY payment_status, payment_provider
428
- `).all();
429
- const revenueResult = db_1.db.prepare(`
430
- SELECT SUM(json_extract(totals_json, '$[?(@.type=="total")].amount')) as total
431
- FROM orders WHERE payment_status = 'succeeded'
432
- `).get();
433
- const todayOrders = db_1.db.prepare(`
434
- SELECT COUNT(*) as count FROM orders
435
- WHERE date(created_at) = date('now')
436
- `).get();
437
- res.json({
438
- checkouts: Object.fromEntries(checkoutStats.map(s => [s.status, s.count])),
439
- orders: {
440
- by_payment_status: Object.fromEntries(orderStats.map(s => [`${s.payment_provider || 'none'}_${s.payment_status}`, s.count])),
441
- today: todayOrders.count,
442
- },
443
- revenue: {
444
- total_succeeded: revenueResult.total || 0,
445
- },
446
- timestamp: new Date().toISOString(),
447
- });
448
- }
449
- catch (error) {
450
- logger_1.logger.error({ error }, 'Failed to get admin stats');
451
- res.status(500).json({ error: 'Failed to get stats' });
452
- }
453
- });
454
- // Admin dashboard HTML
455
- app.get('/admin', (_req, res) => {
456
- const statsScript = useDb
457
- ? `fetch('/admin/stats').then(r=>r.json()).then(d=>{
458
- document.getElementById('stats').innerHTML = \`
459
- <div class="card"><div class="stat">\${Object.values(d.checkouts).reduce((a,b)=>a+b,0)}</div><div class="label">Total Checkouts</div></div>
460
- <div class="card"><div class="stat">\${d.checkouts.completed||0}</div><div class="label">Completed</div></div>
461
- <div class="card"><div class="stat">\${d.orders.today||0}</div><div class="label">Orders Today</div></div>
462
- <div class="card"><div class="stat">$\${(d.revenue.total_succeeded/100).toFixed(2)}</div><div class="label">Revenue</div></div>
463
- \`;
464
- }).catch(e=>document.getElementById('stats').innerHTML='Error loading stats');`
465
- : `document.getElementById('stats').innerHTML = '<div class="card" style="grid-column:1/-1"><div class="label">Running in <strong>in-memory mode</strong>. Stats require <code>--db</code> mode.</div><div style="margin-top:8px;font-size:0.85em;color:#999">Restart with: <code>ucpify serve config.json</code> (DB is on by default)</div></div>';`;
466
- res.send(`<!DOCTYPE html>
467
- <html><head><title>UCP Admin</title>
468
- <style>
469
- body { font-family: system-ui; max-width: 800px; margin: 40px auto; padding: 20px; }
470
- .card { background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 10px 0; }
471
- .stat { font-size: 2em; font-weight: bold; color: #333; }
472
- .label { color: #666; font-size: 0.9em; }
473
- .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; }
474
- h1 { color: #333; }
475
- code { background: #e5e5e5; padding: 2px 6px; border-radius: 3px; font-size: 0.85em; }
476
- </style>
477
- </head><body>
478
- <h1>🛒 UCP Server Admin</h1>
479
- <div class="grid" id="stats">Loading...</div>
480
- <script>${statsScript}</script>
481
- </body></html>`);
482
- });
483
- // Health check
484
- app.get('/health', (_req, res) => {
485
- const dbHealthy = (0, db_1.isDbHealthy)();
486
- const status = dbHealthy ? 'ok' : 'degraded';
487
- res.status(dbHealthy ? 200 : 503).json({
488
- status,
489
- ucp_version: schema_1.UCP_VERSION,
490
- database: dbHealthy ? 'connected' : 'disconnected',
491
- timestamp: new Date().toISOString(),
492
- });
493
- });
494
- return app;
495
- }
package/dist/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export { MerchantConfigSchema, ItemSchema, ShippingOptionSchema, PaymentHandlerSchema } from './schema';
2
- export type { MerchantConfig, Item, ShippingOption, PaymentHandler, CheckoutSession, Order } from './schema';
3
- export { UCPServer } from './ucp-server';
4
- export { createExpressApp } from './express-app';
package/dist/index.js DELETED
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createExpressApp = exports.UCPServer = exports.PaymentHandlerSchema = exports.ShippingOptionSchema = exports.ItemSchema = exports.MerchantConfigSchema = void 0;
4
- var schema_1 = require("./schema");
5
- Object.defineProperty(exports, "MerchantConfigSchema", { enumerable: true, get: function () { return schema_1.MerchantConfigSchema; } });
6
- Object.defineProperty(exports, "ItemSchema", { enumerable: true, get: function () { return schema_1.ItemSchema; } });
7
- Object.defineProperty(exports, "ShippingOptionSchema", { enumerable: true, get: function () { return schema_1.ShippingOptionSchema; } });
8
- Object.defineProperty(exports, "PaymentHandlerSchema", { enumerable: true, get: function () { return schema_1.PaymentHandlerSchema; } });
9
- var ucp_server_1 = require("./ucp-server");
10
- Object.defineProperty(exports, "UCPServer", { enumerable: true, get: function () { return ucp_server_1.UCPServer; } });
11
- var express_app_1 = require("./express-app");
12
- Object.defineProperty(exports, "createExpressApp", { enumerable: true, get: function () { return express_app_1.createExpressApp; } });
package/dist/logger.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import pino from 'pino';
2
- export declare const logger: pino.Logger<never, boolean>;
3
- export type Logger = typeof logger;
package/dist/logger.js DELETED
@@ -1,15 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.logger = void 0;
7
- const pino_1 = __importDefault(require("pino"));
8
- const config_1 = require("./config");
9
- exports.logger = (0, pino_1.default)({
10
- level: config_1.config.logLevel,
11
- transport: config_1.config.nodeEnv === 'development'
12
- ? { target: 'pino-pretty', options: { colorize: true } }
13
- : undefined,
14
- base: { service: 'ucpify' },
15
- });
package/dist/oauth.d.ts DELETED
@@ -1,60 +0,0 @@
1
- export interface OAuthClient {
2
- client_id: string;
3
- client_secret: string;
4
- client_secret_hash: string;
5
- name: string;
6
- redirect_uris: string[];
7
- created_at: string;
8
- }
9
- export interface AuthorizationCode {
10
- code: string;
11
- client_id: string;
12
- user_id: string;
13
- scope: string;
14
- redirect_uri: string;
15
- code_challenge?: string;
16
- code_challenge_method?: string;
17
- expires_at: number;
18
- used: boolean;
19
- }
20
- export interface OAuthToken {
21
- token: string;
22
- token_type: 'access' | 'refresh';
23
- client_id: string;
24
- user_id: string;
25
- scope: string;
26
- parent_token?: string;
27
- expires_at: number;
28
- revoked: boolean;
29
- }
30
- export declare const UCP_SCOPES: readonly ["ucp:scopes:checkout_session"];
31
- export declare class OAuthManager {
32
- private clients;
33
- private codes;
34
- private accessTokens;
35
- private refreshTokens;
36
- createClient(name: string, redirectUris: string[]): OAuthClient;
37
- getClient(clientId: string): OAuthClient | undefined;
38
- authenticateClient(clientId: string, clientSecret: string): boolean;
39
- createAuthorizationCode(clientId: string, userId: string, scope: string, redirectUri: string, codeChallenge?: string, codeChallengeMethod?: string): string;
40
- exchangeCode(code: string, clientId: string, redirectUri: string, codeVerifier?: string): {
41
- access_token: string;
42
- refresh_token: string;
43
- expires_in: number;
44
- scope: string;
45
- } | {
46
- error: string;
47
- };
48
- private createAccessToken;
49
- private createRefreshToken;
50
- refreshAccessToken(refreshToken: string, clientId: string): {
51
- access_token: string;
52
- expires_in: number;
53
- scope: string;
54
- } | {
55
- error: string;
56
- };
57
- validateAccessToken(token: string): OAuthToken | null;
58
- revokeToken(token: string): boolean;
59
- getServerMetadata(issuer: string): Record<string, unknown>;
60
- }