Files
CapaKraken/packages/api/src/router/user.ts
T

132 lines
4.9 KiB
TypeScript

import { adminProcedure, createTRPCRouter, managerProcedure, protectedProcedure, publicProcedure } from "../trpc.js";
import {
autoLinkUsersByEmail,
countActiveUsers,
CreateUserInputSchema,
createUser,
disableTotp,
getEffectiveUserPermissions,
LinkUserResourceInputSchema,
linkUserResource,
listAssignableUsers,
listUsers,
SetUserPasswordInputSchema,
setUserPassword,
SetUserPermissionsInputSchema,
setUserPermissions,
UpdateUserNameInputSchema,
updateUserName,
UpdateUserRoleInputSchema,
updateUserRole,
UserIdInputSchema,
resetUserPermissions,
} from "./user-procedure-support.js";
import {
generateTotpSecret,
getColumnPreferences,
getCurrentMfaStatus,
getCurrentUserProfile,
getDashboardLayout,
getFavoriteProjectIds,
SaveDashboardLayoutInputSchema,
saveDashboardLayout,
SetColumnPreferencesInputSchema,
setColumnPreferences,
ToggleFavoriteProjectInputSchema,
toggleFavoriteProject,
verifyAndEnableTotp as verifyAndEnableTotpSelfService,
VerifyAndEnableTotpInputSchema,
verifyTotp,
VerifyTotpInputSchema,
} from "./user-self-service-procedure-support.js";
export const userRouter = createTRPCRouter({
/** Lightweight user list for task assignment (ADMIN + MANAGER) */
listAssignable: managerProcedure.query(({ ctx }) => listAssignableUsers(ctx)),
list: adminProcedure.query(({ ctx }) => listUsers(ctx)),
/** Count of users active in the last 5 minutes */
activeCount: adminProcedure.query(({ ctx }) => countActiveUsers(ctx)),
me: protectedProcedure.query(({ ctx }) => getCurrentUserProfile(ctx)),
create: adminProcedure
.input(CreateUserInputSchema)
.mutation(({ ctx, input }) => createUser(ctx, input)),
setPassword: adminProcedure
.input(SetUserPasswordInputSchema)
.mutation(({ ctx, input }) => setUserPassword(ctx, input)),
updateRole: adminProcedure
.input(UpdateUserRoleInputSchema)
.mutation(({ ctx, input }) => updateUserRole(ctx, input)),
updateName: adminProcedure
.input(UpdateUserNameInputSchema)
.mutation(({ ctx, input }) => updateUserName(ctx, input)),
// ─── Resource Linking ──────────────────────────────────────────────────
linkResource: adminProcedure
.input(LinkUserResourceInputSchema)
.mutation(({ ctx, input }) => linkUserResource(ctx, input)),
autoLinkAllByEmail: adminProcedure.mutation(({ ctx }) => autoLinkUsersByEmail(ctx)),
getDashboardLayout: protectedProcedure.query(({ ctx }) => getDashboardLayout(ctx)),
saveDashboardLayout: protectedProcedure
.input(SaveDashboardLayoutInputSchema)
.mutation(({ ctx, input }) => saveDashboardLayout(ctx, input)),
// ─── Favorite Projects ──────────────────────────────────────────────────
getFavoriteProjectIds: protectedProcedure.query(({ ctx }) => getFavoriteProjectIds(ctx)),
toggleFavoriteProject: protectedProcedure
.input(ToggleFavoriteProjectInputSchema)
.mutation(({ ctx, input }) => toggleFavoriteProject(ctx, input)),
setPermissions: adminProcedure
.input(SetUserPermissionsInputSchema)
.mutation(({ ctx, input }) => setUserPermissions(ctx, input)),
resetPermissions: adminProcedure
.input(UserIdInputSchema)
.mutation(({ ctx, input }) => resetUserPermissions(ctx, input)),
getColumnPreferences: protectedProcedure.query(({ ctx }) => getColumnPreferences(ctx)),
setColumnPreferences: protectedProcedure
.input(SetColumnPreferencesInputSchema)
.mutation(({ ctx, input }) => setColumnPreferences(ctx, input)),
getEffectivePermissions: adminProcedure
.input(UserIdInputSchema)
.query(({ ctx, input }) => getEffectiveUserPermissions(ctx, input)),
// ─── TOTP / MFA ─────────────────────────────────────────────────────────────
/** Generate a new TOTP secret for the current user (not yet enabled). */
generateTotpSecret: protectedProcedure.mutation(({ ctx }) => generateTotpSecret(ctx)),
/** Verify a TOTP token and enable MFA for the current user. */
verifyAndEnableTotp: protectedProcedure
.input(VerifyAndEnableTotpInputSchema)
.mutation(({ ctx, input }) => verifyAndEnableTotpSelfService(ctx, input)),
/** Admin override: disable TOTP for a specific user. */
disableTotp: adminProcedure
.input(UserIdInputSchema)
.mutation(({ ctx, input }) => disableTotp(ctx, input)),
/** Verify a TOTP token (used during the login flow — public procedure). */
verifyTotp: publicProcedure
.input(VerifyTotpInputSchema)
.mutation(({ ctx, input }) => verifyTotp(ctx, input)),
/** Get MFA status for the current user. */
getMfaStatus: protectedProcedure.query(({ ctx }) => getCurrentMfaStatus(ctx)),
});