chore: auth verification (#2867) [skip e2e]
This commit is contained in:
@@ -98,6 +98,7 @@ import {
|
||||
SignInResponse,
|
||||
ClientDisplayableError,
|
||||
SessionListEntry,
|
||||
MetaEndpointResponse,
|
||||
} from '@standardnotes/responses'
|
||||
import {
|
||||
SyncService,
|
||||
@@ -117,7 +118,7 @@ import {
|
||||
LoggerInterface,
|
||||
canBlockDeinit,
|
||||
} from '@standardnotes/utils'
|
||||
import { UuidString, ApplicationEventPayload } from '../Types'
|
||||
import { UuidString } from '../Types'
|
||||
import { applicationEventForSyncEvent } from '@Lib/Application/Event'
|
||||
import { BackupServiceInterface, FilesClientInterface } from '@standardnotes/files'
|
||||
import { ComputePrivateUsername } from '@standardnotes/encryption'
|
||||
@@ -275,12 +276,12 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
||||
}),
|
||||
)
|
||||
|
||||
const syncEventCallback = async (eventName: SyncEvent) => {
|
||||
const syncEventCallback = async (eventName: SyncEvent, data?: unknown) => {
|
||||
const appEvent = applicationEventForSyncEvent(eventName)
|
||||
if (appEvent) {
|
||||
await encryptionService.onSyncEvent(eventName)
|
||||
|
||||
await this.notifyEvent(appEvent)
|
||||
await this.notifyEvent(appEvent, data)
|
||||
|
||||
if (appEvent === ApplicationEvent.CompletedFullSync) {
|
||||
if (!this.handledFullSyncStage) {
|
||||
@@ -535,7 +536,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
||||
return this.addEventObserver(filteredCallback, event)
|
||||
}
|
||||
|
||||
private async notifyEvent(event: ApplicationEvent, data?: ApplicationEventPayload) {
|
||||
private async notifyEvent(event: ApplicationEvent, data?: unknown) {
|
||||
if (event === ApplicationEvent.Started) {
|
||||
this.onStart()
|
||||
} else if (event === ApplicationEvent.Launched) {
|
||||
@@ -768,10 +769,11 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
||||
public async register(
|
||||
email: string,
|
||||
password: string,
|
||||
hvmToken: string,
|
||||
ephemeral = false,
|
||||
mergeLocal = true,
|
||||
): Promise<UserRegistrationResponseBody> {
|
||||
return this.user.register(email, password, ephemeral, mergeLocal)
|
||||
return this.user.register(email, password, hvmToken, ephemeral, mergeLocal)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -785,8 +787,13 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
||||
ephemeral = false,
|
||||
mergeLocal = true,
|
||||
awaitSync = false,
|
||||
hvmToken?: string,
|
||||
): Promise<HttpResponse<SignInResponse>> {
|
||||
return this.user.signIn(email, password, strict, ephemeral, mergeLocal, awaitSync)
|
||||
return this.user.signIn(email, password, strict, ephemeral, mergeLocal, awaitSync, hvmToken)
|
||||
}
|
||||
|
||||
public async getCaptchaUrl(): Promise<HttpResponse<MetaEndpointResponse>> {
|
||||
return this.legacyApi.getCaptchaUrl()
|
||||
}
|
||||
|
||||
public async changeEmail(
|
||||
|
||||
@@ -166,7 +166,9 @@ describe('SignInWithRecoveryCodes', () => {
|
||||
})
|
||||
|
||||
it('should fail if the sign in with recovery code fails', async () => {
|
||||
authManager.signInWithRecoveryCodes = jest.fn().mockReturnValue(false)
|
||||
authManager.signInWithRecoveryCodes = jest.fn().mockReturnValue({
|
||||
success: false,
|
||||
})
|
||||
|
||||
const useCase = createUseCase()
|
||||
const result = await useCase.execute({
|
||||
|
||||
@@ -68,9 +68,18 @@ export class SignInWithRecoveryCodes implements UseCaseInterface<void> {
|
||||
recoveryCodes: dto.recoveryCodes,
|
||||
username: dto.username,
|
||||
password: rootKey.serverPassword as string,
|
||||
hvmToken: dto.hvmToken,
|
||||
})
|
||||
|
||||
if (signInResult === false) {
|
||||
if (signInResult.success === false) {
|
||||
if (signInResult.captchaURL) {
|
||||
return Result.fail(
|
||||
JSON.stringify({
|
||||
captchaURL: signInResult.captchaURL,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return Result.fail('Could not sign in with recovery code')
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ export interface SignInWithRecoveryCodesDTO {
|
||||
recoveryCodes: string
|
||||
username: string
|
||||
password: string
|
||||
hvmToken?: string
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ import {
|
||||
isErrorResponse,
|
||||
MoveFileResponse,
|
||||
ValetTokenOperation,
|
||||
MetaEndpointResponse,
|
||||
} from '@standardnotes/responses'
|
||||
import { LegacySession, MapperInterface, Session, SessionToken } from '@standardnotes/domain-core'
|
||||
import { HttpServiceInterface } from '@standardnotes/api'
|
||||
@@ -290,6 +291,7 @@ export class LegacyApiService
|
||||
email: string
|
||||
serverPassword: string
|
||||
ephemeral: boolean
|
||||
hvmToken?: string
|
||||
}): Promise<HttpResponse<SignInResponse>> {
|
||||
if (this.authenticating) {
|
||||
return this.createErrorResponse(API_MESSAGE_LOGIN_IN_PROGRESS, HttpStatusCode.BadRequest)
|
||||
@@ -301,6 +303,7 @@ export class LegacyApiService
|
||||
password: dto.serverPassword,
|
||||
ephemeral: dto.ephemeral,
|
||||
code_verifier: this.inMemoryStore.getValue(StorageKey.CodeVerifier) as string,
|
||||
hvm_token: dto.hvmToken,
|
||||
})
|
||||
|
||||
const response = await this.request<SignInResponse>({
|
||||
@@ -958,4 +961,9 @@ export class LegacyApiService
|
||||
|
||||
return this.session.accessToken
|
||||
}
|
||||
|
||||
public getCaptchaUrl() {
|
||||
const response = this.httpService.get<MetaEndpointResponse>(Paths.v1.meta)
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ export const Paths = {
|
||||
...SettingsPaths,
|
||||
...SubscriptionPaths,
|
||||
...UserPaths,
|
||||
meta: '/v1/meta',
|
||||
},
|
||||
v2: {
|
||||
...UserPathsV2,
|
||||
|
||||
@@ -404,7 +404,12 @@ export class SessionManager
|
||||
return undefined
|
||||
}
|
||||
|
||||
async register(email: string, password: string, ephemeral: boolean): Promise<UserRegistrationResponseBody> {
|
||||
async register(
|
||||
email: string,
|
||||
password: string,
|
||||
hvmToken: string,
|
||||
ephemeral: boolean,
|
||||
): Promise<UserRegistrationResponseBody> {
|
||||
if (password.length < MINIMUM_PASSWORD_LENGTH) {
|
||||
throw new ApiCallError(
|
||||
ErrorMessage.InsufficientPasswordMessage.replace('%LENGTH%', MINIMUM_PASSWORD_LENGTH.toString()),
|
||||
@@ -429,6 +434,7 @@ export class SessionManager
|
||||
const registerResponse = await this.userApiService.register({
|
||||
email,
|
||||
serverPassword,
|
||||
hvmToken,
|
||||
keyParams,
|
||||
ephemeral,
|
||||
})
|
||||
@@ -503,8 +509,9 @@ export class SessionManager
|
||||
strict = false,
|
||||
ephemeral = false,
|
||||
minAllowedVersion?: Common.ProtocolVersion,
|
||||
hvmToken?: string,
|
||||
): Promise<SessionManagerResponse> {
|
||||
const result = await this.performSignIn(email, password, strict, ephemeral, minAllowedVersion)
|
||||
const result = await this.performSignIn(email, password, strict, ephemeral, minAllowedVersion, hvmToken)
|
||||
if (
|
||||
isErrorResponse(result.response) &&
|
||||
getErrorFromErrorResponse(result.response).tag !== ErrorTag.ClientValidationError &&
|
||||
@@ -515,7 +522,7 @@ export class SessionManager
|
||||
/**
|
||||
* Try signing in with trimmed + lowercase version of email
|
||||
*/
|
||||
return this.performSignIn(cleanedEmail, password, strict, ephemeral, minAllowedVersion)
|
||||
return this.performSignIn(cleanedEmail, password, strict, ephemeral, minAllowedVersion, hvmToken)
|
||||
} else {
|
||||
return result
|
||||
}
|
||||
@@ -530,6 +537,7 @@ export class SessionManager
|
||||
strict = false,
|
||||
ephemeral = false,
|
||||
minAllowedVersion?: Common.ProtocolVersion,
|
||||
hvmToken?: string,
|
||||
): Promise<SessionManagerResponse> {
|
||||
const paramsResult = await this.retrieveKeyParams({
|
||||
email,
|
||||
@@ -593,7 +601,7 @@ export class SessionManager
|
||||
}
|
||||
}
|
||||
const rootKey = await this.encryptionService.computeRootKey(password, keyParams)
|
||||
const signInResponse = await this.bypassChecksAndSignInWithRootKey(email, rootKey, ephemeral)
|
||||
const signInResponse = await this.bypassChecksAndSignInWithRootKey(email, rootKey, ephemeral, hvmToken)
|
||||
|
||||
return {
|
||||
response: signInResponse,
|
||||
@@ -604,6 +612,7 @@ export class SessionManager
|
||||
email: string,
|
||||
rootKey: SNRootKey,
|
||||
ephemeral = false,
|
||||
hvmToken?: string,
|
||||
): Promise<HttpResponse<SignInResponse>> {
|
||||
const { wrappingKey, canceled } = await this.challengeService.getWrappingKeyIfApplicable()
|
||||
|
||||
@@ -619,6 +628,7 @@ export class SessionManager
|
||||
email,
|
||||
serverPassword: rootKey.serverPassword as string,
|
||||
ephemeral,
|
||||
hvmToken,
|
||||
})
|
||||
|
||||
if (!signInResponse.data || isErrorResponse(signInResponse)) {
|
||||
|
||||
Reference in New Issue
Block a user