javascript-solid-server 0.0.33 → 0.0.35
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/package.json +1 -1
- package/src/auth/middleware.js +5 -0
- package/src/auth/solid-oidc.js +6 -3
- package/src/handlers/container.js +11 -10
- package/src/server.js +2 -1
- package/src/webid/profile.js +9 -4
package/package.json
CHANGED
package/src/auth/middleware.js
CHANGED
|
@@ -28,6 +28,11 @@ export async function authorize(request, reply) {
|
|
|
28
28
|
// Get WebID from token (supports both simple and Solid-OIDC tokens)
|
|
29
29
|
const { webId, error: authError } = await getWebIdFromRequestAsync(request);
|
|
30
30
|
|
|
31
|
+
// Log auth failures for debugging
|
|
32
|
+
if (authError) {
|
|
33
|
+
request.log.warn({ authError, method, urlPath, hasAuth: !!request.headers.authorization }, 'Auth error');
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
// Get effective storage path (includes pod name in subdomain mode)
|
|
32
37
|
const storagePath = getEffectiveUrlPath(request);
|
|
33
38
|
|
package/src/auth/solid-oidc.js
CHANGED
|
@@ -89,16 +89,19 @@ export async function verifySolidOidc(request) {
|
|
|
89
89
|
} catch (err) {
|
|
90
90
|
// Handle specific JWT errors
|
|
91
91
|
if (err.code === 'ERR_JWT_EXPIRED') {
|
|
92
|
+
console.error('Solid-OIDC: Access token expired');
|
|
92
93
|
return { webId: null, error: 'Access token expired' };
|
|
93
94
|
}
|
|
94
95
|
if (err.code === 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') {
|
|
96
|
+
console.error('Solid-OIDC: Invalid token signature');
|
|
95
97
|
return { webId: null, error: 'Invalid token signature' };
|
|
96
98
|
}
|
|
97
99
|
if (err.code === 'ERR_JWKS_NO_MATCHING_KEY') {
|
|
100
|
+
console.error('Solid-OIDC: No matching key found in JWKS');
|
|
98
101
|
return { webId: null, error: 'No matching key found in JWKS' };
|
|
99
102
|
}
|
|
100
103
|
|
|
101
|
-
console.error('Solid-OIDC verification error:', err.message);
|
|
104
|
+
console.error('Solid-OIDC verification error:', err.code, err.message);
|
|
102
105
|
return { webId: null, error: 'Token verification failed' };
|
|
103
106
|
}
|
|
104
107
|
}
|
|
@@ -177,8 +180,8 @@ async function verifyDpopProof(dpopProof, request, accessToken) {
|
|
|
177
180
|
return { thumbprint, error: null };
|
|
178
181
|
|
|
179
182
|
} catch (err) {
|
|
180
|
-
console.error('DPoP verification error:', err.message);
|
|
181
|
-
return { thumbprint: null, error: 'Invalid DPoP proof' };
|
|
183
|
+
console.error('DPoP verification error:', err.code, err.message);
|
|
184
|
+
return { thumbprint: null, error: 'Invalid DPoP proof: ' + err.message };
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
|
|
@@ -132,27 +132,28 @@ export async function createPodStructure(name, webId, podUri, issuer) {
|
|
|
132
132
|
const podPath = `/${name}/`;
|
|
133
133
|
|
|
134
134
|
// Create pod directory structure
|
|
135
|
+
// Uses 'Settings' (capital S) for mashlib compatibility
|
|
135
136
|
await storage.createContainer(podPath);
|
|
136
137
|
await storage.createContainer(`${podPath}inbox/`);
|
|
137
138
|
await storage.createContainer(`${podPath}public/`);
|
|
138
139
|
await storage.createContainer(`${podPath}private/`);
|
|
139
|
-
await storage.createContainer(`${podPath}
|
|
140
|
+
await storage.createContainer(`${podPath}Settings/`);
|
|
140
141
|
await storage.createContainer(`${podPath}profile/`);
|
|
141
142
|
|
|
142
143
|
// Generate and write WebID profile at /profile/card (standard Solid location)
|
|
143
144
|
const profileHtml = generateProfile({ webId, name, podUri, issuer });
|
|
144
145
|
await storage.write(`${podPath}profile/card`, profileHtml);
|
|
145
146
|
|
|
146
|
-
// Generate and write preferences
|
|
147
|
+
// Generate and write preferences (mashlib-compatible paths)
|
|
147
148
|
const prefs = generatePreferences({ webId, podUri });
|
|
148
|
-
await storage.write(`${podPath}
|
|
149
|
+
await storage.write(`${podPath}Settings/Preferences.ttl`, serialize(prefs));
|
|
149
150
|
|
|
150
|
-
// Generate and write type indexes
|
|
151
|
-
const publicTypeIndex = generateTypeIndex(`${podUri}
|
|
152
|
-
await storage.write(`${podPath}
|
|
151
|
+
// Generate and write type indexes with .ttl extension for mashlib
|
|
152
|
+
const publicTypeIndex = generateTypeIndex(`${podUri}Settings/publicTypeIndex.ttl`);
|
|
153
|
+
await storage.write(`${podPath}Settings/publicTypeIndex.ttl`, serialize(publicTypeIndex));
|
|
153
154
|
|
|
154
|
-
const privateTypeIndex = generateTypeIndex(`${podUri}
|
|
155
|
-
await storage.write(`${podPath}
|
|
155
|
+
const privateTypeIndex = generateTypeIndex(`${podUri}Settings/privateTypeIndex.ttl`);
|
|
156
|
+
await storage.write(`${podPath}Settings/privateTypeIndex.ttl`, serialize(privateTypeIndex));
|
|
156
157
|
|
|
157
158
|
// Create default ACL files
|
|
158
159
|
// Pod root: owner full control, public read
|
|
@@ -164,8 +165,8 @@ export async function createPodStructure(name, webId, podUri, issuer) {
|
|
|
164
165
|
await storage.write(`${podPath}private/.acl`, serializeAcl(privateAcl));
|
|
165
166
|
|
|
166
167
|
// Settings folder: owner only
|
|
167
|
-
const settingsAcl = generatePrivateAcl(`${podUri}
|
|
168
|
-
await storage.write(`${podPath}
|
|
168
|
+
const settingsAcl = generatePrivateAcl(`${podUri}Settings/`, webId);
|
|
169
|
+
await storage.write(`${podPath}Settings/.acl`, serializeAcl(settingsAcl));
|
|
169
170
|
|
|
170
171
|
// Inbox: owner full, public append
|
|
171
172
|
const inboxAcl = generateInboxAcl(`${podUri}inbox/`, webId);
|
package/src/server.js
CHANGED
|
@@ -131,9 +131,10 @@ export function createServer(options = {}) {
|
|
|
131
131
|
// Authorization hook - check WAC permissions
|
|
132
132
|
// Skip for pod creation endpoint (needs special handling)
|
|
133
133
|
fastify.addHook('preHandler', async (request, reply) => {
|
|
134
|
-
// Skip auth for pod creation, OPTIONS, IdP routes, mashlib,
|
|
134
|
+
// Skip auth for pod creation, OPTIONS, IdP routes, mashlib, well-known, and notifications
|
|
135
135
|
const mashlibPaths = ['/mashlib.min.js', '/mash.css', '/841.mashlib.min.js'];
|
|
136
136
|
if (request.url === '/.pods' ||
|
|
137
|
+
request.url === '/.notifications' ||
|
|
137
138
|
request.method === 'OPTIONS' ||
|
|
138
139
|
request.url.startsWith('/idp/') ||
|
|
139
140
|
request.url.startsWith('/.well-known/') ||
|
package/src/webid/profile.js
CHANGED
|
@@ -34,6 +34,8 @@ export function generateProfileJsonLd({ webId, name, podUri, issuer }) {
|
|
|
34
34
|
'storage': { '@id': 'pim:storage', '@type': '@id' },
|
|
35
35
|
'oidcIssuer': { '@id': 'solid:oidcIssuer', '@type': '@id' },
|
|
36
36
|
'preferencesFile': { '@id': 'pim:preferencesFile', '@type': '@id' },
|
|
37
|
+
'publicTypeIndex': { '@id': 'solid:publicTypeIndex', '@type': '@id' },
|
|
38
|
+
'privateTypeIndex': { '@id': 'solid:privateTypeIndex', '@type': '@id' },
|
|
37
39
|
'mainEntityOfPage': { '@id': 'schema:mainEntityOfPage', '@type': '@id' }
|
|
38
40
|
},
|
|
39
41
|
'@id': webId,
|
|
@@ -43,7 +45,9 @@ export function generateProfileJsonLd({ webId, name, podUri, issuer }) {
|
|
|
43
45
|
'inbox': `${pod}inbox/`,
|
|
44
46
|
'storage': pod,
|
|
45
47
|
'oidcIssuer': issuer,
|
|
46
|
-
'preferencesFile': `${pod}
|
|
48
|
+
'preferencesFile': `${pod}Settings/Preferences.ttl`,
|
|
49
|
+
'publicTypeIndex': `${pod}Settings/publicTypeIndex.ttl`,
|
|
50
|
+
'privateTypeIndex': `${pod}Settings/privateTypeIndex.ttl`
|
|
47
51
|
};
|
|
48
52
|
}
|
|
49
53
|
|
|
@@ -129,6 +133,7 @@ function escapeHtml(str) {
|
|
|
129
133
|
|
|
130
134
|
/**
|
|
131
135
|
* Generate preferences file as JSON-LD
|
|
136
|
+
* Uses mashlib-compatible paths (Settings/Preferences.ttl)
|
|
132
137
|
* @param {object} options
|
|
133
138
|
* @param {string} options.webId - Full WebID URI
|
|
134
139
|
* @param {string} options.podUri - Pod root URI
|
|
@@ -144,9 +149,9 @@ export function generatePreferences({ webId, podUri }) {
|
|
|
144
149
|
'publicTypeIndex': { '@id': 'solid:publicTypeIndex', '@type': '@id' },
|
|
145
150
|
'privateTypeIndex': { '@id': 'solid:privateTypeIndex', '@type': '@id' }
|
|
146
151
|
},
|
|
147
|
-
'@id': `${pod}
|
|
148
|
-
'publicTypeIndex': `${pod}
|
|
149
|
-
'privateTypeIndex': `${pod}
|
|
152
|
+
'@id': `${pod}Settings/Preferences.ttl`,
|
|
153
|
+
'publicTypeIndex': `${pod}Settings/publicTypeIndex.ttl`,
|
|
154
|
+
'privateTypeIndex': `${pod}Settings/privateTypeIndex.ttl`
|
|
150
155
|
};
|
|
151
156
|
}
|
|
152
157
|
|