Phase 1 of the umbrella plan in #427.
Scope
Update the ACL generators in src/wac/parser.js to emit relative acl:accessTo and acl:default URIs. Update callers in src/handlers/container.js and the createRootPodStructure function in src/server.js to pass the relative path string instead of the absolute ${podUri}….
Generators in scope:
generateOwnerAcl
generatePrivateAcl
generateInboxAcl
generatePublicFolderAcl
generatePublicReadAcl
The parser at src/wac/parser.js:141 already calls resolveUri(uri, baseUrl) against the ACL document's request URL, so a relative ./ always matches the requesting host. This is a write-side change only — read-side support has been in place since a736338 (Jan 2026).
Concrete change
- 'acl:accessTo': { '@id': resourceUrl },
+ 'acl:accessTo': { '@id': relativePath },
…with callers computing relativePath as './' for the container itself, './private/' for nested containers, etc., instead of ${podUri}private/.
Reproduction (current, broken)
jss start --single-user --no-idp --port 4444
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:4444/ # 200
curl -s -o /dev/null -w "%{http_code}\n" http://0.0.0.0:4444/ # 401
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:4444/ # 401
After Phase 1 all three should return 200.
Tests
- Unit: each generator emits the relative form (
./, ./private/, etc.).
- Integration:
--single-user --no-idp server, fresh pod, GET / from localhost, 0.0.0.0, 127.0.0.1, and the loopback alias all return 200.
- Regression: existing pods on disk that contain absolute-URI ACLs continue to authorize correctly (parser handles both forms).
Acceptance
Out of scope
Refs #427.
Phase 1 of the umbrella plan in #427.
Scope
Update the ACL generators in
src/wac/parser.jsto emit relativeacl:accessToandacl:defaultURIs. Update callers insrc/handlers/container.jsand thecreateRootPodStructurefunction insrc/server.jsto pass the relative path string instead of the absolute${podUri}….Generators in scope:
generateOwnerAclgeneratePrivateAclgenerateInboxAclgeneratePublicFolderAclgeneratePublicReadAclThe parser at
src/wac/parser.js:141already callsresolveUri(uri, baseUrl)against the ACL document's request URL, so a relative./always matches the requesting host. This is a write-side change only — read-side support has been in place sincea736338(Jan 2026).Concrete change
…with callers computing
relativePathas'./'for the container itself,'./private/'for nested containers, etc., instead of${podUri}private/.Reproduction (current, broken)
After Phase 1 all three should return 200.
Tests
./,./private/, etc.).--single-user --no-idpserver, fresh pod,GET /from localhost, 0.0.0.0, 127.0.0.1, and the loopback alias all return 200.Acceptance
acl:accessTo/acl:default.container.jsandserver.jsupdated to pass relative paths.--single-user --no-idpdeployment) works on every interface the server binds.Out of scope
acl:agent— that's Phase 2./for multi-user — that's Phase 3 (folds in feat: default landing page + ACL at server root (#276) #303).Refs #427.