var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import DatabaseService from "./DatabaseService";
import Model from "../../Models/DatabaseModels/UserTotpAuth";
import TotpAuth from "../Utils/TotpAuth";
import UserService from "./UserService";
import BadDataException from "../../Types/Exception/BadDataException";
import LIMIT_MAX from "../../Types/Database/LimitMax";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
import UserWebAuthnService from "./UserWebAuthnService";
export class Service extends DatabaseService {
    constructor() {
        super(Model);
    }
    async onBeforeCreate(createBy) {
        if (!createBy.props.userId) {
            throw new BadDataException("User id is required");
        }
        createBy.data.userId = createBy.props.userId;
        const user = await UserService.findOneById({
            id: createBy.data.userId,
            props: {
                isRoot: true,
            },
            select: {
                email: true,
            },
        });
        if (!user) {
            throw new BadDataException("User not found");
        }
        if (!user.email) {
            throw new BadDataException("User email is required");
        }
        createBy.data.twoFactorSecret = TotpAuth.generateSecret();
        createBy.data.twoFactorOtpUrl = TotpAuth.generateUri({
            secret: createBy.data.twoFactorSecret,
            userEmail: user.email,
        });
        createBy.data.isVerified = false;
        return {
            createBy: createBy,
            carryForward: {},
        };
    }
    async onBeforeDelete(deleteBy) {
        const itemsToBeDeleted = await this.findBy({
            query: deleteBy.query,
            select: {
                userId: true,
                _id: true,
                isVerified: true,
            },
            limit: LIMIT_MAX,
            skip: 0,
            props: deleteBy.props,
        });
        for (const item of itemsToBeDeleted) {
            if (item.isVerified) {
                // check if  user two auth is enabled.
                const user = await UserService.findOneById({
                    id: item.userId,
                    props: {
                        isRoot: true,
                    },
                    select: {
                        enableTwoFactorAuth: true,
                    },
                });
                if (!user) {
                    throw new BadDataException("User not found");
                }
                if (user.enableTwoFactorAuth) {
                    // if enabled then check if this is the only verified 2FA method for this user.
                    const verifiedTotpItems = await this.findBy({
                        query: {
                            userId: item.userId,
                            isVerified: true,
                        },
                        select: {
                            _id: true,
                        },
                        limit: LIMIT_MAX,
                        skip: 0,
                        props: deleteBy.props,
                    });
                    const verifiedWebAuthnItems = await UserWebAuthnService.findBy({
                        query: {
                            userId: item.userId,
                            isVerified: true,
                        },
                        select: {
                            _id: true,
                        },
                        limit: LIMIT_MAX,
                        skip: 0,
                        props: deleteBy.props,
                    });
                    const totalVerified2FA = verifiedTotpItems.length + verifiedWebAuthnItems.length;
                    if (totalVerified2FA === 1) {
                        throw new BadDataException("You must have atleast one verified two factor auth. Please disable two factor auth before deleting this item.");
                    }
                }
            }
        }
        return {
            deleteBy: deleteBy,
            carryForward: {},
        };
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onBeforeCreate", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], Service.prototype, "onBeforeDelete", null);
export default new Service();
//# sourceMappingURL=UserTotpAuthService.js.map