116 lines
4.4 KiB
TypeScript
116 lines
4.4 KiB
TypeScript
import { DefaultPermission } from "~/application/dtos/shared/DefaultPermissions";
|
|
import {
|
|
defaultAdminRoleSeeds,
|
|
defaultAppRoleSeeds,
|
|
defaultPermissionSeedDescriptors,
|
|
syncDefaultRolesAndPermissions,
|
|
type DefaultPermissionSeed,
|
|
type DefaultRoleSeed,
|
|
} from "@hivegrid/db/permissions-seed.server";
|
|
import { getAllRoles } from "~/utils/db/permissions/roles.db.server";
|
|
import { createUserRoleAssignments, type UserRoleAssignment } from "~/utils/db/permissions/userRoles.db.server";
|
|
import { adminGetAllTenants } from "~/utils/db/tenants.db.server";
|
|
import { adminGetAllUsers } from "~/utils/db/users.db.server";
|
|
import { db } from "~/utils/db.server";
|
|
|
|
export type CreateRoleDto = DefaultRoleSeed;
|
|
export const defaultAdminRoles: CreateRoleDto[] = [...defaultAdminRoleSeeds];
|
|
export const defaultAppRoles: CreateRoleDto[] = [...defaultAppRoleSeeds];
|
|
|
|
export type CreatePermissionDto = Omit<DefaultPermissionSeed, "name" | "type"> & {
|
|
name: DefaultPermission;
|
|
type: string;
|
|
};
|
|
export const defaultPermissions: CreatePermissionDto[] = defaultPermissionSeedDescriptors.map((permission) => ({
|
|
...permission,
|
|
name: permission.name as DefaultPermission,
|
|
}));
|
|
|
|
export type RolesAndPermissionsSeedDiagnosticPhase = "start" | "success" | "failure";
|
|
|
|
export type RolesAndPermissionsSeedDiagnosticEvent = {
|
|
phase: RolesAndPermissionsSeedDiagnosticPhase;
|
|
adminRoleCount?: number;
|
|
appRoleCount?: number;
|
|
defaultPermissionCount?: number;
|
|
dynamicEntityPermissionCount?: number;
|
|
adminUserAssignmentCount?: number;
|
|
tenantUserAssignmentCount?: number;
|
|
error?: unknown;
|
|
};
|
|
|
|
export type RolesAndPermissionsSeedDiagnostics = (event: RolesAndPermissionsSeedDiagnosticEvent) => void | Promise<void>;
|
|
|
|
export type SeedRolesAndPermissionsOptions = {
|
|
adminEmail?: string;
|
|
diagnostics?: RolesAndPermissionsSeedDiagnostics;
|
|
excludedTenantSlugs?: readonly string[];
|
|
};
|
|
|
|
function toSeedRolesAndPermissionsOptions(adminEmailOrOptions?: string | SeedRolesAndPermissionsOptions): SeedRolesAndPermissionsOptions {
|
|
if (typeof adminEmailOrOptions === "string") {
|
|
return { adminEmail: adminEmailOrOptions };
|
|
}
|
|
return adminEmailOrOptions ?? {};
|
|
}
|
|
|
|
async function emitRolesAndPermissionsSeedDiagnostic(
|
|
diagnostics: RolesAndPermissionsSeedDiagnostics | undefined,
|
|
event: RolesAndPermissionsSeedDiagnosticEvent
|
|
): Promise<void> {
|
|
await diagnostics?.(event);
|
|
}
|
|
|
|
export async function seedRolesAndPermissions(adminEmailOrOptions?: string | SeedRolesAndPermissionsOptions): Promise<void> {
|
|
const { adminEmail, diagnostics, excludedTenantSlugs = [] } = toSeedRolesAndPermissionsOptions(adminEmailOrOptions);
|
|
const excludedTenantSlugSet = new Set(excludedTenantSlugs);
|
|
const counts = {
|
|
adminRoleCount: defaultAdminRoles.length,
|
|
appRoleCount: defaultAppRoles.length,
|
|
defaultPermissionCount: defaultPermissions.length,
|
|
dynamicEntityPermissionCount: 0,
|
|
adminUserAssignmentCount: 0,
|
|
tenantUserAssignmentCount: 0,
|
|
};
|
|
|
|
await emitRolesAndPermissionsSeedDiagnostic(diagnostics, { phase: "start", ...counts });
|
|
|
|
try {
|
|
await syncDefaultRolesAndPermissions({ client: db });
|
|
const adminRoles = await getAllRoles("admin");
|
|
counts.adminRoleCount = adminRoles.length;
|
|
|
|
const appRoles = await getAllRoles("app");
|
|
counts.appRoleCount = appRoles.length;
|
|
|
|
const users = (await adminGetAllUsers()).items;
|
|
const userRoleAssignments: UserRoleAssignment[] = [];
|
|
users
|
|
.filter((f) => f.admin && adminEmail && f.email === adminEmail)
|
|
.forEach((user) => {
|
|
adminRoles.forEach((adminRole) => {
|
|
counts.adminUserAssignmentCount += 1;
|
|
userRoleAssignments.push({ userId: user.id, roleId: adminRole.id, tenantId: null });
|
|
});
|
|
});
|
|
|
|
const tenants = await adminGetAllTenants();
|
|
tenants
|
|
.filter((tenant) => !excludedTenantSlugSet.has(tenant.slug))
|
|
.forEach((tenant) => {
|
|
tenant.users.forEach((tenantUser) => {
|
|
appRoles.forEach((appRole) => {
|
|
counts.tenantUserAssignmentCount += 1;
|
|
userRoleAssignments.push({ userId: tenantUser.userId, roleId: appRole.id, tenantId: tenant.id });
|
|
});
|
|
});
|
|
});
|
|
await createUserRoleAssignments(userRoleAssignments);
|
|
|
|
await emitRolesAndPermissionsSeedDiagnostic(diagnostics, { phase: "success", ...counts });
|
|
} catch (error) {
|
|
await emitRolesAndPermissionsSeedDiagnostic(diagnostics, { phase: "failure", ...counts, error });
|
|
throw error;
|
|
}
|
|
}
|