diff --git a/src/backend/controllers/fs/LegacyFSController.ts b/src/backend/controllers/fs/LegacyFSController.ts index 302925370..a27d813c6 100644 --- a/src/backend/controllers/fs/LegacyFSController.ts +++ b/src/backend/controllers/fs/LegacyFSController.ts @@ -1050,11 +1050,12 @@ export class LegacyFSController extends PuterController { legacyCode: 'bad_request', }); - const targetPath = await expandClientPath( + const expanded = await expandClientPath( this.stores.fsEntry, - rawPath.startsWith('/') ? rawPath : `/${rawPath}`, + rawPath, actor.user?.username, ); + const targetPath = expanded.startsWith('/') ? expanded : `/${expanded}`; const parentPath = pathPosix.dirname(targetPath); if (parentPath === '/') { throw new HttpError(400, 'Cannot touch in root', { diff --git a/src/backend/controllers/fs/sharedFolderWrites.http.test.ts b/src/backend/controllers/fs/sharedFolderWrites.http.test.ts index 7b9b8a46c..63b3bc0a9 100644 --- a/src/backend/controllers/fs/sharedFolderWrites.http.test.ts +++ b/src/backend/controllers/fs/sharedFolderWrites.http.test.ts @@ -138,6 +138,17 @@ describe('writes inside a folder shared with write', () => { expect(await ownerListing(s)).toContain('from-recipient.txt'); }, 180_000); + it('touch still expands a tilde path', async () => { + const s = await shareAFolder(); + + const touched = await post('/touch', s.owner.token, { + path: '~/SharedDir/from-tilde.txt', + }); + + expect(touched.status).toBe(200); + expect(await ownerListing(s)).toContain('from-tilde.txt'); + }, 180_000); + // Addressed to the owner, so it carries the path the owner can resolve. it('publishes the owner’s real path on events about their entries', async () => { const s = await shareAFolder(); diff --git a/src/backend/controllers/webdav/WebDAVController.ts b/src/backend/controllers/webdav/WebDAVController.ts index 63a81929c..bace61112 100644 --- a/src/backend/controllers/webdav/WebDAVController.ts +++ b/src/backend/controllers/webdav/WebDAVController.ts @@ -1174,7 +1174,9 @@ export class WebDAVController extends PuterController { void Promise.resolve() .then(async () => { const response = { - ...(await toLegacyEntry(this.clients.event, entry)), + ...(await toLegacyEntry(this.clients.event, entry, { + forOwner: true, + })), ...extra, from_new_service: true, };