javascript-solid-server 0.0.128 → 0.0.130
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/.claude/settings.local.json +2 -1
- package/package.json +1 -1
- package/src/auth/middleware.js +2 -2
- package/src/ldp/headers.js +1 -1
- package/src/server.js +23 -9
- package/src/wac/checker.js +3 -3
|
@@ -342,7 +342,8 @@
|
|
|
342
342
|
"Bash(sed -i 's/\"currency\": \"sats\"/\"currency\": \"tbtc4\"/g' /home/melvin/articles/solid-402.html /home/melvin/articles/solid-pay.html /home/melvin/articles/solid-balance.html)",
|
|
343
343
|
"Bash(sed -i 's/\"currency\":\"sats\"/\"currency\":\"tbtc4\"/g' /home/melvin/articles/solid-402.html /home/melvin/articles/solid-pay.html /home/melvin/articles/solid-balance.html)",
|
|
344
344
|
"WebFetch(domain:lists.w3.org)",
|
|
345
|
-
"Bash(git:*)"
|
|
345
|
+
"Bash(git:*)",
|
|
346
|
+
"Bash(npm publish:*)"
|
|
346
347
|
]
|
|
347
348
|
}
|
|
348
349
|
}
|
package/package.json
CHANGED
package/src/auth/middleware.js
CHANGED
|
@@ -104,7 +104,7 @@ export async function authorize(request, reply, options = {}) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
// Check WAC permissions
|
|
107
|
-
const { allowed, wacAllow, paymentRequired } = await checkAccess({
|
|
107
|
+
const { allowed, wacAllow, paymentRequired, paid, balance, currency } = await checkAccess({
|
|
108
108
|
resourceUrl: checkUrl,
|
|
109
109
|
resourcePath: checkPath,
|
|
110
110
|
isContainer: checkIsContainer,
|
|
@@ -112,7 +112,7 @@ export async function authorize(request, reply, options = {}) {
|
|
|
112
112
|
requiredMode
|
|
113
113
|
});
|
|
114
114
|
|
|
115
|
-
return { authorized: allowed, webId, wacAllow, authError, paymentRequired };
|
|
115
|
+
return { authorized: allowed, webId, wacAllow, authError, paymentRequired, paid, balance, currency };
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
package/src/ldp/headers.js
CHANGED
|
@@ -96,7 +96,7 @@ export function getCorsHeaders(origin) {
|
|
|
96
96
|
'Access-Control-Allow-Origin': origin || '*',
|
|
97
97
|
'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
98
98
|
'Access-Control-Allow-Headers': 'Accept, Authorization, Content-Type, DPoP, If-Match, If-None-Match, Link, Range, Slug, Origin',
|
|
99
|
-
'Access-Control-Expose-Headers': 'Accept-Patch, Accept-Post, Accept-Ranges, Allow, Content-Length, Content-Range, Content-Type, ETag, Link, Location, Updates-Via, WAC-Allow',
|
|
99
|
+
'Access-Control-Expose-Headers': 'Accept-Patch, Accept-Post, Accept-Ranges, Allow, Content-Length, Content-Range, Content-Type, ETag, Link, Location, Updates-Via, WAC-Allow, X-Cost, X-Balance, X-Pay-Currency',
|
|
100
100
|
'Access-Control-Allow-Credentials': 'true',
|
|
101
101
|
'Access-Control-Max-Age': '86400'
|
|
102
102
|
};
|
package/src/server.js
CHANGED
|
@@ -448,7 +448,7 @@ export function createServer(options = {}) {
|
|
|
448
448
|
return;
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
const { authorized, webId, wacAllow, authError, paymentRequired } = await authorize(request, reply);
|
|
451
|
+
const { authorized, webId, wacAllow, authError, paymentRequired, paid, balance, currency } = await authorize(request, reply);
|
|
452
452
|
|
|
453
453
|
// Store webId and wacAllow on request for handlers to use
|
|
454
454
|
request.webId = webId;
|
|
@@ -457,6 +457,13 @@ export function createServer(options = {}) {
|
|
|
457
457
|
// Set WAC-Allow header for all responses (handlers may override)
|
|
458
458
|
reply.header('WAC-Allow', wacAllow);
|
|
459
459
|
|
|
460
|
+
// Set payment headers for paid access
|
|
461
|
+
if (paid !== undefined) {
|
|
462
|
+
reply.header('X-Cost', String(paid));
|
|
463
|
+
reply.header('X-Balance', String(balance));
|
|
464
|
+
if (currency) reply.header('X-Pay-Currency', currency);
|
|
465
|
+
}
|
|
466
|
+
|
|
460
467
|
// Handle payment-gated resources
|
|
461
468
|
if (paymentRequired) {
|
|
462
469
|
return reply.code(402).send({
|
|
@@ -472,15 +479,22 @@ export function createServer(options = {}) {
|
|
|
472
479
|
|
|
473
480
|
// Pod creation endpoint with rate limiting
|
|
474
481
|
// Limit: 1 pod per IP per day to prevent resource exhaustion and namespace squatting
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
482
|
+
// Disabled in single-user mode
|
|
483
|
+
if (singleUser) {
|
|
484
|
+
fastify.post('/.pods', async (request, reply) => {
|
|
485
|
+
return reply.code(403).send({ error: 'Forbidden', message: 'Pod creation disabled in single-user mode' });
|
|
486
|
+
});
|
|
487
|
+
} else {
|
|
488
|
+
fastify.post('/.pods', {
|
|
489
|
+
config: {
|
|
490
|
+
rateLimit: {
|
|
491
|
+
max: 1,
|
|
492
|
+
timeWindow: '1 day',
|
|
493
|
+
keyGenerator: (request) => request.ip
|
|
494
|
+
}
|
|
481
495
|
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
496
|
+
}, handleCreatePod);
|
|
497
|
+
}
|
|
484
498
|
|
|
485
499
|
// Mashlib CDN mode: redirect chunk requests to CDN
|
|
486
500
|
if (mashlibEnabled && mashlibCdn) {
|
package/src/wac/checker.js
CHANGED
|
@@ -49,7 +49,7 @@ export async function checkAccess({
|
|
|
49
49
|
// Calculate WAC-Allow header
|
|
50
50
|
const wacAllow = calculateWacAllow(authorizations, resourceUrl, agentWebId, isDefault);
|
|
51
51
|
|
|
52
|
-
return { allowed: result.allowed, wacAllow, paymentRequired: result.paymentRequired || null };
|
|
52
|
+
return { allowed: result.allowed, wacAllow, paymentRequired: result.paymentRequired || null, paid: result.paid, balance: result.balance, currency: result.currency };
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -183,10 +183,10 @@ async function checkAuthorizations(authorizations, targetUrl, agentWebId, requir
|
|
|
183
183
|
// Paid access: check balance and deduct
|
|
184
184
|
const balance = getBalance(ledger, agentWebId, currency);
|
|
185
185
|
if (cost > 0 && balance >= cost) {
|
|
186
|
-
debit(ledger, agentWebId, cost, currency);
|
|
186
|
+
const result = debit(ledger, agentWebId, cost, currency);
|
|
187
187
|
const { writeLedger } = await import('../webledger.js');
|
|
188
188
|
await writeLedger(ledger);
|
|
189
|
-
return { allowed: true, paid: cost };
|
|
189
|
+
return { allowed: true, paid: cost, balance: result.balance, currency };
|
|
190
190
|
}
|
|
191
191
|
} catch (e) {
|
|
192
192
|
// Ledger read failed — fall through to payment required
|