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
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";
|
} from "@/models/index.js";
|
||||||
import type { ILocalUser } from "@/models/entities/user.js";
|
import type { ILocalUser } from "@/models/entities/user.js";
|
||||||
import { genId } from "@/misc/gen-id.js";
|
import { genId } from "@/misc/gen-id.js";
|
||||||
|
import { comparePassword, hashPassword, isOldAlgorithm } from '@/misc/password.js';
|
||||||
import { verifyLogin, hash } from "../2fa.js";
|
import { verifyLogin, hash } from "../2fa.js";
|
||||||
import { randomBytes } from "node:crypto";
|
import { randomBytes } from "node:crypto";
|
||||||
import { IsNull } from "typeorm";
|
import { IsNull } from "typeorm";
|
||||||
@ -88,7 +89,12 @@ export default async (ctx: Koa.Context) => {
|
|||||||
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
|
||||||
|
|
||||||
// Compare password
|
// 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 }) {
|
async function fail(status?: number, failure?: { id: string }) {
|
||||||
// Append signin history
|
// Append signin history
|
||||||
|
Loading…
Reference in New Issue
Block a user