a LOTTTA more migration hoopla shii
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { errAsync, okAsync, ResultAsync } from "neverthrow";
|
||||
import { FlowExecCtx } from "@core/flow.execution.context";
|
||||
import { UserRepository } from "@domains/user/repository";
|
||||
import { getRedisInstance, Redis } from "@pkg/redis";
|
||||
import { getRedisInstance, Redis } from "@pkg/keystore";
|
||||
import { TwofaRepository } from "./repository";
|
||||
import { auth } from "../auth/config.base";
|
||||
import type { TwoFaSession } from "./data";
|
||||
@@ -17,6 +17,7 @@ export class TwofaController {
|
||||
private twofaRepo: TwofaRepository,
|
||||
private userRepo: UserRepository,
|
||||
private store: Redis,
|
||||
private secret: string,
|
||||
) {}
|
||||
|
||||
checkTotp(secret: string, code: string) {
|
||||
@@ -42,7 +43,7 @@ export class TwofaController {
|
||||
.andThen((enabled) =>
|
||||
enabled
|
||||
? errAsync(twofaErrors.alreadyEnabled(fctx))
|
||||
: this.twofaRepo.setup(fctx, user.id),
|
||||
: this.twofaRepo.setup(fctx, user.id, this.secret),
|
||||
)
|
||||
.map((secret) => {
|
||||
const appName = settings.appName;
|
||||
@@ -345,5 +346,6 @@ export function getTwofaController() {
|
||||
new TwofaRepository(db, _redis),
|
||||
new UserRepository(db),
|
||||
_redis,
|
||||
settings.twoFaSecret,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,15 @@ import { FlowExecCtx } from "@core/flow.execution.context";
|
||||
import { hashString, verifyHash } from "@/core/hash.utils";
|
||||
import { twoFactor, twofaSessions } from "@pkg/db/schema";
|
||||
import { TwoFactor, type TwoFaSession } from "./data";
|
||||
import { crypto } from "@otplib/plugin-crypto-noble";
|
||||
import { base32 } from "@otplib/plugin-base32-scure";
|
||||
import { and, Database, eq, gt, lt } from "@pkg/db";
|
||||
import { generateSecret, verify } from "otplib";
|
||||
import { generate, verify } from "@otplib/totp";
|
||||
import { settings } from "@core/settings";
|
||||
import type { Err } from "@pkg/result";
|
||||
import { twofaErrors } from "./errors";
|
||||
import { Redis } from "@pkg/keystore";
|
||||
import { logger } from "@pkg/logger";
|
||||
import { Redis } from "@pkg/redis";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
type TwoFaSetup = {
|
||||
@@ -30,7 +32,7 @@ export class TwofaRepository {
|
||||
) {}
|
||||
|
||||
checkTotp(secret: string, code: string) {
|
||||
const checked = verify({ secret, token: code });
|
||||
const checked = verify({ secret, token: code, crypto, base32 });
|
||||
logger.debug("TOTP check result", { checked });
|
||||
return checked;
|
||||
}
|
||||
@@ -98,14 +100,22 @@ export class TwofaRepository {
|
||||
});
|
||||
}
|
||||
|
||||
setup(fctx: FlowExecCtx, userId: string): ResultAsync<string, Err> {
|
||||
setup(
|
||||
fctx: FlowExecCtx,
|
||||
userId: string,
|
||||
secret: string,
|
||||
): ResultAsync<string, Err> {
|
||||
logger.info("Starting 2FA setup", { ...fctx, userId });
|
||||
|
||||
return ResultAsync.fromSafePromise(
|
||||
(async () => {
|
||||
const secret = generateSecret();
|
||||
const payload = {
|
||||
const token = await generate({
|
||||
secret,
|
||||
crypto,
|
||||
base32,
|
||||
});
|
||||
const payload = {
|
||||
secret: token,
|
||||
lastUsedCode: "",
|
||||
tries: 0,
|
||||
} as TwoFaSetup;
|
||||
|
||||
Reference in New Issue
Block a user