mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-08-30 02:41:34 +00:00
feat: folder shares apply to hosts added later (#1343)
* feat: folder shares apply to hosts added later Sharing a folder only fanned grants out to the hosts in it at the time. The share is now also kept as a standing rule on the folder, and a host created in or moved into it (or a subfolder) inherits the same access and secret snapshots. Rules follow folder renames and can be stopped from the share dialog. * fix: stabilize folder access migrations
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
real,
|
||||
index,
|
||||
uniqueIndex,
|
||||
foreignKey,
|
||||
type AnySQLiteColumn,
|
||||
} from "drizzle-orm/sqlite-core";
|
||||
import { sql } from "drizzle-orm";
|
||||
@@ -2095,9 +2096,7 @@ export const sharedCredentialSecrets = sqliteTable(
|
||||
"shared_credential_secrets",
|
||||
{
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
credentialAccessId: integer("credential_access_id")
|
||||
.notNull()
|
||||
.references(() => credentialAccess.id, { onDelete: "cascade" }),
|
||||
credentialAccessId: integer("credential_access_id").notNull(),
|
||||
targetUserId: text("target_user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
@@ -2122,6 +2121,11 @@ export const sharedCredentialSecrets = sqliteTable(
|
||||
.default(sql`CURRENT_TIMESTAMP`),
|
||||
},
|
||||
(table) => [
|
||||
foreignKey({
|
||||
columns: [table.credentialAccessId],
|
||||
foreignColumns: [credentialAccess.id],
|
||||
name: "shared_cred_secrets_access_id_fk",
|
||||
}).onDelete("cascade"),
|
||||
uniqueIndex("idx_shared_credential_secrets_scope").on(
|
||||
table.credentialAccessId,
|
||||
table.targetUserId,
|
||||
@@ -2132,3 +2136,40 @@ export const sharedCredentialSecrets = sqliteTable(
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
// --- folder access rules ---
|
||||
|
||||
/**
|
||||
* A standing share on a host folder. Sharing a folder fans out host_access
|
||||
* grants to the hosts in it today; this row is what makes hosts created in
|
||||
* or moved into the folder later inherit the same access.
|
||||
*/
|
||||
export const folderAccess = sqliteTable(
|
||||
"folder_access",
|
||||
{
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
ownerUserId: text("owner_user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
// The folder path as stored on hosts ("Parent / Child"); subfolders inherit.
|
||||
folder: text("folder").notNull(),
|
||||
|
||||
userId: text("user_id").references(() => users.id, { onDelete: "cascade" }),
|
||||
roleId: integer("role_id").references(() => roles.id, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
|
||||
grantedBy: text("granted_by")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
permissionLevel: text("permission_level").notNull().default("connect"),
|
||||
expiresAt: text("expires_at"),
|
||||
|
||||
createdAt: text("created_at")
|
||||
.notNull()
|
||||
.default(sql`CURRENT_TIMESTAMP`),
|
||||
},
|
||||
(table) => [
|
||||
index("idx_folder_access_owner_folder").on(table.ownerUserId, table.folder),
|
||||
],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user