fix: harden login for MLPS requirements

This commit is contained in:
2026-05-14 11:05:20 +08:00
parent ecf3ee1ef0
commit 879677516f
39 changed files with 1230 additions and 71 deletions
+23 -1
View File
@@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { ApiClientError } from '@geo/http-client'
import type { LoginRequest, UserInfo } from '@geo/shared-types'
import {
@@ -9,6 +10,7 @@ import {
refreshStoredAuthSession,
shouldRefreshAccessToken,
} from '@/lib/api'
import { browserSupportsPasswordCipher, encryptPasswordForLogin } from '@/lib/password-cipher'
import {
clearStoredSession,
readStoredSession,
@@ -147,7 +149,7 @@ export const useAuthStore = defineStore('auth', () => {
return loginPromise
}
const loginPayload = { ...payload }
const loginPayload = await buildSecureLoginPayload(payload)
loginPromise = authApi
.login(loginPayload)
.then((response) => {
@@ -166,6 +168,26 @@ export const useAuthStore = defineStore('auth', () => {
return loginPromise
}
async function buildSecureLoginPayload(payload: LoginRequest): Promise<LoginRequest> {
if (!payload.password || !browserSupportsPasswordCipher()) {
return { ...payload }
}
try {
const key = await authApi.passwordPublicKey()
const encrypted = await encryptPasswordForLogin(payload.password, key)
return {
identifier: payload.identifier,
email: payload.email,
...encrypted,
}
} catch (error) {
if (error instanceof ApiClientError && error.status === 404) {
return { ...payload }
}
throw error
}
}
async function logout(): Promise<void> {
try {
if (accessToken.value) {