fix: changing passwords, 2fa, and password resets.

The argon2 usage was only implemented for sign-ins which broke a bunch of other
endpoints and features.
This commit is contained in:
amy bones 2023-04-03 02:23:51 -07:00 committed by ThatOneCalculator
parent 143576bc29
commit 662e7a96cf
No known key found for this signature in database
GPG key ID: 8703CACD01000000
15 changed files with 31 additions and 35 deletions

View file

@ -1,4 +1,3 @@
import bcrypt from "bcryptjs";
import { generateKeyPair } from "node:crypto"; import { generateKeyPair } from "node:crypto";
import generateUserToken from "./generate-native-user-token.js"; import generateUserToken from "./generate-native-user-token.js";
import { User } from "@/models/entities/user.js"; import { User } from "@/models/entities/user.js";
@ -12,6 +11,7 @@ import { usersChart } from "@/services/chart/index.js";
import { UsedUsername } from "@/models/entities/used-username.js"; import { UsedUsername } from "@/models/entities/used-username.js";
import { db } from "@/db/postgre.js"; import { db } from "@/db/postgre.js";
import config from "@/config/index.js"; import config from "@/config/index.js";
import { hashPassword } from "@/misc/password.js";
export async function signup(opts: { export async function signup(opts: {
username: User["username"]; username: User["username"];
@ -42,8 +42,7 @@ export async function signup(opts: {
} }
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); hash = await hashPassword(password);
hash = await bcrypt.hash(password, salt);
} }
// Generate secret // Generate secret

View file

@ -1,7 +1,8 @@
import define from "../../define.js"; import define from "../../define.js";
import bcrypt from "bcryptjs"; // import bcrypt from "bcryptjs";
import rndstr from "rndstr"; import rndstr from "rndstr";
import { Users, UserProfiles } from "@/models/index.js"; import { Users, UserProfiles } from "@/models/index.js";
import { hashPassword } from "@/misc/password.js";
export const meta = { export const meta = {
tags: ["admin"], tags: ["admin"],
@ -47,7 +48,8 @@ export default define(meta, paramDef, async (ps) => {
const passwd = rndstr("a-zA-Z0-9", 8); const passwd = rndstr("a-zA-Z0-9", 8);
// Generate hash of password // Generate hash of password
const hash = bcrypt.hashSync(passwd); // const hash = bcrypt.hashSync(passwd);
const hash = await hashPassword(passwd);
await UserProfiles.update( await UserProfiles.update(
{ {

View file

@ -1,4 +1,3 @@
import bcrypt from "bcryptjs";
import { promisify } from "node:util"; import { promisify } from "node:util";
import * as cbor from "cbor"; import * as cbor from "cbor";
import define from "../../../define.js"; import define from "../../../define.js";
@ -11,6 +10,7 @@ import {
import config from "@/config/index.js"; import config from "@/config/index.js";
import { procedures, hash } from "../../../2fa.js"; import { procedures, hash } from "../../../2fa.js";
import { publishMainStream } from "@/services/stream.js"; import { publishMainStream } from "@/services/stream.js";
import { comparePassword } from "@/misc/password.js";
const cborDecodeFirst = promisify(cbor.decodeFirst) as any; const cborDecodeFirst = promisify(cbor.decodeFirst) as any;
const rpIdHashReal = hash(Buffer.from(config.hostname, "utf-8")); const rpIdHashReal = hash(Buffer.from(config.hostname, "utf-8"));
@ -43,7 +43,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -1,10 +1,10 @@
import bcrypt from "bcryptjs";
import define from "../../../define.js"; import define from "../../../define.js";
import { UserProfiles, AttestationChallenges } from "@/models/index.js"; import { UserProfiles, AttestationChallenges } from "@/models/index.js";
import { promisify } from "node:util"; import { promisify } from "node:util";
import * as crypto from "node:crypto"; import * as crypto from "node:crypto";
import { genId } from "@/misc/gen-id.js"; import { genId } from "@/misc/gen-id.js";
import { hash } from "../../../2fa.js"; import { hash } from "../../../2fa.js";
import { comparePassword } from "@/misc/password.js";
const randomBytes = promisify(crypto.randomBytes); const randomBytes = promisify(crypto.randomBytes);
@ -26,7 +26,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -1,9 +1,9 @@
import bcrypt from "bcryptjs";
import * as speakeasy from "speakeasy"; import * as speakeasy from "speakeasy";
import * as QRCode from "qrcode"; import * as QRCode from "qrcode";
import config from "@/config/index.js"; import config from "@/config/index.js";
import { UserProfiles } from "@/models/index.js"; import { UserProfiles } from "@/models/index.js";
import define from "../../../define.js"; import define from "../../../define.js";
import { comparePassword } from "@/misc/password.js";
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
@ -23,7 +23,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -1,4 +1,4 @@
import bcrypt from "bcryptjs"; import { comparePassword } from "@/misc/password.js";
import define from "../../../define.js"; import define from "../../../define.js";
import { UserProfiles, UserSecurityKeys, Users } from "@/models/index.js"; import { UserProfiles, UserSecurityKeys, Users } from "@/models/index.js";
import { publishMainStream } from "@/services/stream.js"; import { publishMainStream } from "@/services/stream.js";
@ -22,7 +22,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -1,6 +1,6 @@
import bcrypt from "bcryptjs";
import define from "../../../define.js"; import define from "../../../define.js";
import { UserProfiles } from "@/models/index.js"; import { UserProfiles } from "@/models/index.js";
import { comparePassword } from "@/misc/password.js";
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
@ -20,7 +20,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -1,6 +1,6 @@
import bcrypt from "bcryptjs";
import define from "../../define.js"; import define from "../../define.js";
import { UserProfiles } from "@/models/index.js"; import { UserProfiles } from "@/models/index.js";
import { hashPassword, comparePassword } from "@/misc/password.js";
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
@ -21,15 +21,14 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.currentPassword, profile.password!); const same = await comparePassword(ps.currentPassword, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");
} }
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await hashPassword(ps.newPassword);
const hash = await bcrypt.hash(ps.newPassword, salt);
await UserProfiles.update(user.id, { await UserProfiles.update(user.id, {
password: hash, password: hash,

View file

@ -1,7 +1,7 @@
import bcrypt from "bcryptjs";
import { UserProfiles, Users } from "@/models/index.js"; import { UserProfiles, Users } from "@/models/index.js";
import { deleteAccount } from "@/services/delete-account.js"; import { deleteAccount } from "@/services/delete-account.js";
import define from "../../define.js"; import define from "../../define.js";
import { comparePassword } from "@/misc/password.js";
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
@ -25,7 +25,7 @@ export default define(meta, paramDef, async (ps, user) => {
} }
// Compare password // Compare password
const same = await bcrypt.compare(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -1,4 +1,3 @@
import bcrypt from "bcryptjs";
import { import {
publishInternalEvent, publishInternalEvent,
publishMainStream, publishMainStream,
@ -7,6 +6,7 @@ import {
import generateUserToken from "../../common/generate-native-user-token.js"; import generateUserToken from "../../common/generate-native-user-token.js";
import define from "../../define.js"; import define from "../../define.js";
import { Users, UserProfiles } from "@/models/index.js"; import { Users, UserProfiles } from "@/models/index.js";
import { comparePassword } from "@/misc/password.js";
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
@ -29,7 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new Error("incorrect password"); throw new Error("incorrect password");

View file

@ -2,12 +2,12 @@ import { publishMainStream } from "@/services/stream.js";
import define from "../../define.js"; import define from "../../define.js";
import rndstr from "rndstr"; import rndstr from "rndstr";
import config from "@/config/index.js"; import config from "@/config/index.js";
import bcrypt from "bcryptjs";
import { Users, UserProfiles } from "@/models/index.js"; import { Users, UserProfiles } from "@/models/index.js";
import { sendEmail } from "@/services/send-email.js"; import { sendEmail } from "@/services/send-email.js";
import { ApiError } from "../../error.js"; import { ApiError } from "../../error.js";
import { validateEmailForAccount } from "@/services/validate-email-for-account.js"; import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
import { HOUR } from "@/const.js"; import { HOUR } from "@/const.js";
import { comparePassword } from "@/misc/password.js";
export const meta = { export const meta = {
requireCredential: true, requireCredential: true,
@ -47,7 +47,7 @@ export default define(meta, paramDef, async (ps, user) => {
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(ps.password, profile.password!); const same = await comparePassword(ps.password, profile.password!);
if (!same) { if (!same) {
throw new ApiError(meta.errors.incorrectPassword); throw new ApiError(meta.errors.incorrectPassword);

View file

@ -1,8 +1,8 @@
import bcrypt from "bcryptjs";
import { publishMainStream } from "@/services/stream.js"; import { publishMainStream } from "@/services/stream.js";
import { Users, UserProfiles, PasswordResetRequests } from "@/models/index.js"; import { Users, UserProfiles, PasswordResetRequests } from "@/models/index.js";
import define from "../define.js"; import define from "../define.js";
import { ApiError } from "../error.js"; import { ApiError } from "../error.js";
import { hashPassword } from "@/misc/password.js";
export const meta = { export const meta = {
tags: ["reset password"], tags: ["reset password"],
@ -34,8 +34,7 @@ export default define(meta, paramDef, async (ps, user) => {
} }
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await hashPassword(ps.password);
const hash = await bcrypt.hash(ps.password, salt);
await UserProfiles.update(req.userId, { await UserProfiles.update(req.userId, {
password: hash, password: hash,

View file

@ -1,5 +1,4 @@
import type Koa from "koa"; import type Koa from "koa";
import bcrypt from "bcryptjs";
import * as speakeasy from "speakeasy"; import * as speakeasy from "speakeasy";
import signin from "../common/signin.js"; import signin from "../common/signin.js";
import config from "@/config/index.js"; import config from "@/config/index.js";

View file

@ -1,6 +1,5 @@
import type Koa from "koa"; import type Koa from "koa";
import rndstr from "rndstr"; import rndstr from "rndstr";
import bcrypt from "bcryptjs";
import { fetchMeta } from "@/misc/fetch-meta.js"; import { fetchMeta } from "@/misc/fetch-meta.js";
import { verifyHcaptcha, verifyRecaptcha } from "@/misc/captcha.js"; import { verifyHcaptcha, verifyRecaptcha } from "@/misc/captcha.js";
import { Users, RegistrationTickets, UserPendings } from "@/models/index.js"; import { Users, RegistrationTickets, UserPendings } from "@/models/index.js";
@ -9,6 +8,7 @@ import config from "@/config/index.js";
import { sendEmail } from "@/services/send-email.js"; import { sendEmail } from "@/services/send-email.js";
import { genId } from "@/misc/gen-id.js"; import { genId } from "@/misc/gen-id.js";
import { validateEmailForAccount } from "@/services/validate-email-for-account.js"; import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
import { hashPassword } from "@/misc/password.js";
export default async (ctx: Koa.Context) => { export default async (ctx: Koa.Context) => {
const body = ctx.request.body; const body = ctx.request.body;
@ -79,8 +79,7 @@ export default async (ctx: Koa.Context) => {
const code = rndstr("a-z0-9", 16); const code = rndstr("a-z0-9", 16);
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await hashPassword(password);
const hash = await bcrypt.hash(password, salt);
await UserPendings.insert({ await UserPendings.insert({
id: genId(), id: genId(),

View file

@ -1,4 +1,3 @@
import bcrypt from "bcryptjs";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import generateNativeUserToken from "../server/api/common/generate-native-user-token.js"; import generateNativeUserToken from "../server/api/common/generate-native-user-token.js";
import { genRsaKeyPair } from "@/misc/gen-key-pair.js"; import { genRsaKeyPair } from "@/misc/gen-key-pair.js";
@ -9,13 +8,13 @@ import { genId } from "@/misc/gen-id.js";
import { UserKeypair } from "@/models/entities/user-keypair.js"; import { UserKeypair } from "@/models/entities/user-keypair.js";
import { UsedUsername } from "@/models/entities/used-username.js"; import { UsedUsername } from "@/models/entities/used-username.js";
import { db } from "@/db/postgre.js"; import { db } from "@/db/postgre.js";
import { hashPassword } from "@/misc/password.js";
export async function createSystemUser(username: string) { export async function createSystemUser(username: string) {
const password = uuid(); const password = uuid();
// Generate hash of password // Generate hash of password
const salt = await bcrypt.genSalt(8); const hash = await hashPassword(password);
const hash = await bcrypt.hash(password, salt);
// Generate secret // Generate secret
const secret = generateNativeUserToken(); const secret = generateNativeUserToken();