feat: enhance zero-knowledge authentication by deriving and sending auth hashes to the server

This commit is contained in:
ramvignesh-b
2026-04-14 22:44:42 +05:30
parent 3e5dbbe3f3
commit 967b3a77f8
10 changed files with 146 additions and 79 deletions
+15 -3
View File
@@ -10,6 +10,7 @@ import FormField from "../components/ui/FormField";
import { endpoints } from "../config/endpoints";
import { ROUTES } from "../config/routes";
import { useAuth } from "../hooks/useAuth";
import { CryptoUtils } from "../utils/crypto";
const loginSchema = z.object({
email: z.string().email("Please enter a valid email"),
@@ -22,7 +23,7 @@ export default function Login() {
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(false);
const [apiError, setApiError] = useState<string | null>(null);
const { login } = useAuth();
const { setAuthStore } = useAuth();
const {
register,
@@ -36,13 +37,24 @@ export default function Login() {
setIsLoading(true);
setApiError(null);
try {
const { data: authData } = await publicApi.post(endpoints.LOGIN, data);
// client side key derivation for 0 knowledge
const { masterKey, authHash } = await CryptoUtils.deriveKeyBundle(
data.password,
data.email,
);
// send just the authHash as the password to the server
const { data: authData } = await publicApi.post(endpoints.LOGIN, {
email: data.email,
password: authHash,
});
const { data: userData } = await api.get(endpoints.ME, {
headers: { Authorization: `Bearer ${authData.access}` },
});
login(authData.access, userData, data.password);
// store the auth related data
setAuthStore(authData.access, userData, masterKey);
navigate(ROUTES.DRAWER);
} catch (err) {
+8 -1
View File
@@ -10,6 +10,7 @@ import Logo from "../components/Logo";
import FormField from "../components/ui/FormField";
import { endpoints } from "../config/endpoints";
import { ROUTES } from "../config/routes";
import { CryptoUtils } from "../utils/crypto";
// validation logic
const registerSchema = z
@@ -43,10 +44,16 @@ export default function Register() {
setIsLoading(true);
setApiError(null);
try {
// We generate the key bundle here to get the authHash (password) for the server.
const { authHash } = await CryptoUtils.deriveKeyBundle(
data.password,
data.email,
);
await publicApi.post(endpoints.REGISTER, {
full_name: data.full_name,
email: data.email,
password: data.password,
password: authHash,
});
navigate(ROUTES.VERIFY_EMAIL);
} catch (err) {