feat: add user lifecycle management

This commit is contained in:
Syahdan 2026-06-29 21:22:33 +07:00
parent 8ab9a9a497
commit 11b16ac3cf
8 changed files with 331 additions and 47 deletions

View file

@ -0,0 +1,5 @@
import { hashPassword } from "better-auth/crypto";
export async function hashCredentialPassword(password: string) {
return hashPassword(password);
}

View file

@ -0,0 +1,15 @@
INSERT INTO "permission" ("id", "name", "description")
VALUES
('users.create', 'users.create', 'Allows users create'),
('users.delete', 'users.delete', 'Allows users delete')
ON CONFLICT ("id") DO UPDATE SET
"name" = EXCLUDED."name",
"description" = EXCLUDED."description",
"updated_at" = now();
--> statement-breakpoint
INSERT INTO "role_permission" ("role_id", "permission_id")
SELECT 'role_admin', "permission"."id"
FROM "permission"
WHERE "permission"."id" IN ('users.create', 'users.delete')
AND EXISTS (SELECT 1 FROM "role" WHERE "role"."id" = 'role_admin')
ON CONFLICT DO NOTHING;

View file

@ -15,6 +15,13 @@
"when": 1782694800000,
"tag": "0001_add_rbac",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1782698400000,
"tag": "0002_user_lifecycle_permissions",
"breakpoints": true
}
]
}

View file

@ -18,6 +18,8 @@ export const permissions = [
"notes.update",
"notes.delete",
"users.read",
"users.create",
"users.delete",
"users.assignRoles",
] as const;
@ -34,7 +36,9 @@ export const roleDefinitions = [
id: "role_editor",
name: "Editor",
description: "Can create and update monitoring resources, run checks, and read users.",
permissions: permissions.filter((permission) => permission !== "users.assignRoles"),
permissions: permissions.filter(
(permission) => !["users.create", "users.delete", "users.assignRoles"].includes(permission),
),
},
{
id: "role_viewer",

View file

@ -1,6 +1,6 @@
import dotenv from "dotenv";
import { hashPassword } from "better-auth/crypto";
import { roleDefinitions, permissions } from "./rbac";
import { hashCredentialPassword } from "./auth-utils";
dotenv.config({
path: new URL("../../../apps/server/.env", import.meta.url).pathname,
@ -196,7 +196,7 @@ async function seedAuthAdmin() {
return existingUser.id;
}
const passwordHash = await hashPassword(adminUser.password);
const passwordHash = await hashCredentialPassword(adminUser.password);
await db.insert(user).values({
id: adminUser.id,