chore: Add serverPassword param to endpoints (#2919) [skip e2e]

* chore: send server password param to delete account endpoint

* chore: send server password param to disable mfa endpoint

* chore: modify tests

* chore: force challenge prompt for mfa disable

* chore: fix eslint errors

* chore: add server passsword to get recovery codes

* chore: fix tests

* chore: pass server password as header
This commit is contained in:
Antonella Sgarlatta
2025-08-26 09:04:03 -03:00
committed by GitHub
parent cf4d2196de
commit 54af28aa04
29 changed files with 298 additions and 62 deletions

View File

@@ -34,6 +34,7 @@ import {
import { ContentType } from '@standardnotes/domain-core'
import { isValidProtectionSessionLength } from './isValidProtectionSessionLength'
import { UnprotectedAccessSecondsDuration } from './UnprotectedAccessSecondsDuration'
import { ChallengeResponse } from '../Challenge'
/**
* Enforces certain actions to require extra authentication,
@@ -246,11 +247,11 @@ export class ProtectionService
})
}
async authorizeMfaDisable(): Promise<boolean> {
return this.authorizeAction(ChallengeReason.DisableMfa, {
async authorizeMfaDisable(): Promise<{ success: boolean; challengeResponse?: ChallengeResponse }> {
return this.authorizeActionWithChallengeResponse(ChallengeReason.DisableMfa, {
fallBackToAccountPassword: true,
requireAccountPassword: true,
forcePrompt: false,
forcePrompt: true,
})
}
@@ -278,6 +279,14 @@ export class ProtectionService
})
}
async authorizeAccountDeletion(): Promise<{ success: boolean; challengeResponse?: ChallengeResponse }> {
return this.authorizeActionWithChallengeResponse(ChallengeReason.DeleteAccount, {
fallBackToAccountPassword: true,
requireAccountPassword: true,
forcePrompt: true,
})
}
async authorizeAction(
reason: ChallengeReason,
dto: { fallBackToAccountPassword: boolean; requireAccountPassword: boolean; forcePrompt: boolean },
@@ -285,6 +294,13 @@ export class ProtectionService
return this.validateOrRenewSession(reason, dto)
}
async authorizeActionWithChallengeResponse(
reason: ChallengeReason,
dto: { fallBackToAccountPassword: boolean; requireAccountPassword: boolean; forcePrompt: boolean },
): Promise<{ success: boolean; challengeResponse?: ChallengeResponse }> {
return this.validateOrRenewSessionWithChallengeResponse(reason, dto)
}
getMobilePasscodeTimingOptions(): TimingDisplayOption[] {
return [
{
@@ -353,8 +369,20 @@ export class ProtectionService
reason: ChallengeReason,
{ fallBackToAccountPassword = true, requireAccountPassword = false, forcePrompt = false } = {},
): Promise<boolean> {
const response = await this.validateOrRenewSessionWithChallengeResponse(reason, {
fallBackToAccountPassword,
requireAccountPassword,
forcePrompt,
})
return response.success
}
private async validateOrRenewSessionWithChallengeResponse(
reason: ChallengeReason,
{ fallBackToAccountPassword = true, requireAccountPassword = false, forcePrompt = false } = {},
): Promise<{ success: boolean; challengeResponse?: ChallengeResponse }> {
if (this.getSessionExpiryDate() > new Date() && !forcePrompt) {
return true
return { success: true }
}
const prompts: ChallengePrompt[] = []
@@ -378,9 +406,10 @@ export class ProtectionService
if (fallBackToAccountPassword && this.encryption.hasAccount()) {
prompts.push(new ChallengePrompt(ChallengeValidation.AccountPassword))
} else {
return true
return { success: true }
}
}
const lastSessionLength = this.getLastSessionLength()
const chosenSessionLength = isValidProtectionSessionLength(lastSessionLength)
? lastSessionLength
@@ -407,9 +436,9 @@ export class ProtectionService
} else {
this.setSessionLength(length as UnprotectedAccessSecondsDuration)
}
return true
return { success: true, challengeResponse: response }
} else {
return false
return { success: false }
}
}