fix: gate the group-share index delete on authority, qualify the live filter

Review follow-ups on #3872: deleteActiveGroup ran even when every
canManagePermission check was denied, deleting the index row while the
team's grant survived — unlisted live access, the class this PR exists
to remove. And memberIdsAmong's join left deleted_at unqualified, which
only works while jct_user_group has no such column; #live now takes an
alias.
This commit is contained in:
Juan Castro
2026-09-15 18:57:50 -04:00
parent af6547724d
commit 27e858d760
2 changed files with 8 additions and 3 deletions
@@ -1456,6 +1456,7 @@ export class ShareService extends PuterService {
Number(row.holder_group_id),
);
if (!node || !team) continue;
let authorized = false;
for (const permission of entryPermissions(node.uuid)) {
if (
!(await this.services.permission.canManagePermission(
@@ -1465,6 +1466,7 @@ export class ShareService extends PuterService {
) {
continue;
}
authorized = true;
if (
await this.services.permission.revokeUserGroupPermission(
actor,
@@ -1477,6 +1479,8 @@ export class ShareService extends PuterService {
revoked++;
}
}
// Gated as the user path is: a surviving grant keeps its index row.
if (!authorized) continue;
await this.stores.share.deleteActiveGroup({
holderGroupId: Number(row.holder_group_id),
fsentryId: node.id,
+4 -3
View File
@@ -178,8 +178,9 @@ export class TeamStore extends PuterStore {
}
/** Makes the seeded `kind IS NULL` groups unreachable, not merely absent. */
#live(): string {
return '`kind` = ? AND `deleted_at` IS NULL';
#live(alias = ''): string {
const prefix = alias ? `${alias}.` : '';
return `${prefix}\`kind\` = ? AND ${prefix}\`deleted_at\` IS NULL`;
}
// -- Reads --------------------------------------------------------
@@ -380,7 +381,7 @@ export class TeamStore extends PuterStore {
const rows = (await this.clients.db.read(
'SELECT ug.`user_id` FROM `jct_user_group` ug ' +
'JOIN `group` g ON g.`id` = ug.`group_id` ' +
`WHERE g.\`uid\` = ? AND g.${this.#live()} ` +
`WHERE g.\`uid\` = ? AND ${this.#live('g')} ` +
`AND ug.\`user_id\` IN (${ids.map(() => '?').join(', ')})`,
[teamUid, TEAM_KIND, ...ids],
)) as { user_id: number }[];