1 import { TOTP } from 'otpauth'
2 import { HttpStatusCode, TwoFactorEnableResult } from '@shared/models'
3 import { unwrapBody } from '../requests'
4 import { AbstractCommand, OverrideCommandOptions } from '../shared'
6 export class TwoFactorCommand extends AbstractCommand {
8 static buildOTP (options: {
11 const { secret } = options
22 request (options: OverrideCommandOptions & {
24 currentPassword?: string
26 const { currentPassword, userId } = options
28 const path = '/api/v1/users/' + userId + '/two-factor/request'
30 return unwrapBody<TwoFactorEnableResult>(this.postBodyRequest({
34 fields: { currentPassword },
36 defaultExpectedStatus: HttpStatusCode.OK_200
40 confirmRequest (options: OverrideCommandOptions & {
45 const { userId, requestToken, otpToken } = options
47 const path = '/api/v1/users/' + userId + '/two-factor/confirm-request'
49 return this.postBodyRequest({
53 fields: { requestToken, otpToken },
55 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
59 disable (options: OverrideCommandOptions & {
61 currentPassword?: string
63 const { userId, currentPassword } = options
64 const path = '/api/v1/users/' + userId + '/two-factor/disable'
66 return this.postBodyRequest({
70 fields: { currentPassword },
72 defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
76 async requestAndConfirm (options: OverrideCommandOptions & {
78 currentPassword?: string
80 const { userId, currentPassword } = options
82 const { otpRequest } = await this.request({ userId, currentPassword })
84 await this.confirmRequest({
86 requestToken: otpRequest.requestToken,
87 otpToken: TwoFactorCommand.buildOTP({ secret: otpRequest.secret }).generate()