48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
import argon2 from "argon2";
|
|
import { PrismaClient } from "@prisma/client";
|
|
import { randomBytes } from "node:crypto";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
const [email, passwordArg] = process.argv.slice(2);
|
|
|
|
if (!email) {
|
|
process.stderr.write("Usage: npm run admin:reset -- <email> [newPassword]\n");
|
|
process.exit(1);
|
|
}
|
|
|
|
const run = async () => {
|
|
const user = await prisma.user.findUnique({ where: { email } });
|
|
if (!user) {
|
|
process.stderr.write("User not found.\n");
|
|
process.exit(1);
|
|
}
|
|
|
|
const generated = !passwordArg;
|
|
const password = passwordArg ?? randomBytes(12).toString("base64url");
|
|
const hashed = await argon2.hash(password);
|
|
|
|
await prisma.user.update({
|
|
where: { id: user.id },
|
|
data: {
|
|
password: hashed,
|
|
role: "ADMIN",
|
|
isActive: true,
|
|
passwordResetRequired: generated
|
|
}
|
|
});
|
|
|
|
if (generated) {
|
|
process.stdout.write(`Temporary admin password for ${email}: ${password}\n`);
|
|
process.stdout.write("Password reset required at next login.\n");
|
|
} else {
|
|
process.stdout.write(`Admin password updated for ${email}\n`);
|
|
}
|
|
await prisma.$disconnect();
|
|
};
|
|
|
|
run().catch((err) => {
|
|
process.stderr.write(String(err) + "\n");
|
|
process.exit(1);
|
|
});
|