feat: 🔒 add argon2 support
Passwords will be automatically re-hashed on sign-in. All new password hashes will be argon2 by default. This uses argon2id and is not configurable. In the very unlikely case someone has more specific needs, a fork is recommended. ChangeLog: Added Co-authored-by: Chloe Kudryavtsev <code@toast.bunkerlabs.net> Breaks Calckey -> Misskey migration, but fixes Foundkey -> Calckey migration
This commit is contained in:
parent
1e249a7182
commit
12769bd1ab
2 changed files with 27 additions and 1 deletions
20
packages/backend/src/misc/password.ts
Normal file
20
packages/backend/src/misc/password.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import bcrypt from "bcryptjs";
|
||||
import * as argon2 from "argon2";
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
return argon2.hash(password);
|
||||
}
|
||||
|
||||
export async function comparePassword(
|
||||
password: string,
|
||||
hash: string,
|
||||
): Promise<boolean> {
|
||||
if (isOldAlgorithm(hash)) return bcrypt.compare(password, hash);
|
||||
|
||||
return argon2.verify(hash, password);
|
||||
}
|
||||
|
||||
export function isOldAlgorithm(hash: string): boolean {
|
||||
// bcrypt hashes start with $2[ab]$
|
||||
return hash.startsWith("$2");
|
||||
}
|
|
@ -12,6 +12,7 @@ import {
|
|||
} from "@/models/index.js";
|
||||
import type { ILocalUser } from "@/models/entities/user.js";
|
||||
import { genId } from "@/misc/gen-id.js";
|
||||
import { comparePassword, hashPassword, isOldAlgorithm } from '@/misc/password.js';
|
||||
import { verifyLogin, hash } from "../2fa.js";
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { IsNull } from "typeorm";
|
||||
|
@ -88,7 +89,12 @@ export default async (ctx: Koa.Context) => {
|
|||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||
|
||||
// Compare password
|
||||
const same = await bcrypt.compare(password, profile.password!);
|
||||
const same = await comparePassword(password, profile.password!);
|
||||
|
||||
if (same && isOldAlgorithm(profile.password!)) {
|
||||
profile.password = await hashPassword(password);
|
||||
await UserProfiles.save(profile);
|
||||
}
|
||||
|
||||
async function fail(status?: number, failure?: { id: string }) {
|
||||
// Append signin history
|
||||
|
|
Loading…
Reference in a new issue