mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-24 15:07:17 +00:00
fix(fs): stop listing issuer homes at the filesystem root
This commit is contained in:
@@ -1110,7 +1110,6 @@ export class FSController extends PuterController {
|
||||
const rootChildren = await listRootEntries(
|
||||
actor,
|
||||
this.stores.fsEntry,
|
||||
this.services.permission,
|
||||
);
|
||||
const rootSuggestions =
|
||||
await this.services.suggestedApps.getSuggestedAppsForEntries(
|
||||
|
||||
@@ -484,7 +484,6 @@ export class LegacyFSController extends PuterController {
|
||||
const rootChildren = await listRootEntries(
|
||||
actor,
|
||||
this.stores.fsEntry,
|
||||
this.services.permission,
|
||||
);
|
||||
const rootSuggestions =
|
||||
await this.services.suggestedApps.getSuggestedAppsForEntries(
|
||||
|
||||
@@ -66,8 +66,7 @@ const makeUser = async () => {
|
||||
return { userId: created.id, username, actor };
|
||||
};
|
||||
|
||||
const listFor = (actor: Actor) =>
|
||||
listRootEntries(actor, fsEntryStore, permissionService);
|
||||
const listFor = (actor: Actor) => listRootEntries(actor, fsEntryStore);
|
||||
|
||||
describe('listRootEntries', () => {
|
||||
it('shows the actor their own home directory, exactly once', async () => {
|
||||
@@ -91,7 +90,7 @@ describe('listRootEntries', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('adds the home of every user who has granted the actor a permission', async () => {
|
||||
it('leaves an issuer’s home out of root when only a file was shared', async () => {
|
||||
const holder = await makeUser();
|
||||
const issuer = await makeUser();
|
||||
const shared = (await fsEntryStore.getEntryByPath(
|
||||
@@ -105,9 +104,11 @@ describe('listRootEntries', () => {
|
||||
|
||||
const entries = await listFor(holder.actor);
|
||||
|
||||
expect(entries.map((entry) => entry.path).sort()).toEqual(
|
||||
[`/${holder.username}`, `/${issuer.username}`].sort(),
|
||||
);
|
||||
// Listing it here would advertise a folder readdir then refuses to
|
||||
// open: the grant is on Documents, which says nothing about its parent.
|
||||
expect(entries.map((entry) => entry.path)).toEqual([
|
||||
`/${holder.username}`,
|
||||
]);
|
||||
});
|
||||
|
||||
it('heals a home row whose path drifted from the username', async () => {
|
||||
|
||||
@@ -20,19 +20,18 @@
|
||||
import type { Actor } from '../../core/actor.js';
|
||||
import type { FSEntry } from '../../stores/fs/FSEntry.js';
|
||||
import type { FSEntryStore } from '../../stores/fs/FSEntryStore.js';
|
||||
import type { PermissionService } from '../permission/PermissionService.js';
|
||||
|
||||
/**
|
||||
* Synthesize the listing for the virtual root `/`. There is no fsentry row at
|
||||
* `/` — instead root is a virtual aggregate of user-directory entries the actor
|
||||
* can see: the actor's own home plus any other users' homes granted via
|
||||
* permission issuers (i.e. users that have shared something with this actor).
|
||||
* Mirrors v1's `LLListUsers`.
|
||||
* `/` — root stands in for the actor's own home.
|
||||
*
|
||||
* Issuer homes are deliberately absent: a grant on a file says nothing about
|
||||
* its ancestors, so listing them advertised folders `readdir` then refused to
|
||||
* open. Shares are reached through the sharing API instead.
|
||||
*/
|
||||
export async function listRootEntries(
|
||||
actor: Actor,
|
||||
fsEntryStore: FSEntryStore,
|
||||
permissionService: PermissionService,
|
||||
): Promise<FSEntry[]> {
|
||||
const entries: FSEntry[] = [];
|
||||
const seenPaths = new Set<string>();
|
||||
@@ -69,15 +68,5 @@ export async function listRootEntries(
|
||||
|
||||
await pushByUsername(actor.user.username);
|
||||
|
||||
if (typeof userId === 'number') {
|
||||
const issuers = await permissionService.listUserPermissionIssuers({
|
||||
id: userId,
|
||||
});
|
||||
for (const issuer of issuers) {
|
||||
if (!issuer) continue;
|
||||
await pushByUsername(issuer.username);
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user