Files
publisher-dashboard/apps/api-server/src/procedures/me/set-password.ts
igm 73ef3df01f Add pre-configured procedures and use them throughout codebase
- Add authedProcedure, superuserProcedure, loginRequestProcedure,
  orgMemberProcedure in base.ts
- Create procedures/me/_base.ts with meRoute = authedProcedure.me
- Update all me procedures to use meRoute.X.handler()
- Update auth/logout and auth/resend-verification to use authedProcedure
- Update all admin procedures to use superuserProcedure
- Update all orgs procedures to use authedProcedure

This reduces boilerplate and makes middleware usage consistent.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 17:57:15 +08:00

64 lines
1.7 KiB
TypeScript

/**
* Set password procedure - sets or changes user password
*/
import { ORPCError } from "@orpc/server";
import {
hashPassword,
validatePassword,
verifyPassword,
} from "../../utils/password.js";
import { meRoute } from "./_base.js";
/**
* Set password handler
* - Requires authentication
* - If user has existing password, currentPassword is required
* - Validates new password strength using zxcvbn
*/
export const setPassword = meRoute.setPassword.handler(
async ({ input, context }) => {
const { currentPassword, newPassword } = input;
// Fetch current password hash
const user = await context.db
.selectFrom("users")
.select(["password_hash"])
.where("id", "=", context.user.id)
.executeTakeFirstOrThrow();
// If user has a password, verify current password
if (user.password_hash) {
if (!currentPassword) {
throw new ORPCError("BAD_REQUEST", {
message: "Current password required",
});
}
const valid = await verifyPassword(currentPassword, user.password_hash);
if (!valid) {
throw new ORPCError("BAD_REQUEST", {
message: "Current password is incorrect",
});
}
}
// Validate new password strength
const validation = validatePassword(newPassword, [context.user.email]);
if (!validation.valid) {
throw new ORPCError("BAD_REQUEST", {
message: validation.feedback[0] ?? "Password is too weak",
});
}
// Hash and update
const newHash = await hashPassword(newPassword);
await context.db
.updateTable("users")
.set({ password_hash: newHash, updated_at: new Date() })
.where("id", "=", context.user.id)
.execute();
return { success: true };
},
);