fix: harden login for MLPS requirements
This commit is contained in:
@@ -80,6 +80,7 @@ import type {
|
||||
MonitoringDashboardCompositeResponse,
|
||||
MonitoringQuestionDetailResponse,
|
||||
PlatformAccount,
|
||||
PasswordPublicKeyResponse,
|
||||
PromptRule,
|
||||
PromptRuleGroup,
|
||||
PromptRuleGroupRequest,
|
||||
@@ -336,6 +337,9 @@ apiClient.raw.interceptors.response.use(
|
||||
)
|
||||
|
||||
export const authApi = {
|
||||
passwordPublicKey() {
|
||||
return publicClient.get<PasswordPublicKeyResponse>('/api/auth/password-key')
|
||||
},
|
||||
login(payload: LoginRequest) {
|
||||
return publicClient.post<LoginResponse, LoginRequest>('/api/auth/login', payload)
|
||||
},
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { PasswordPublicKeyResponse } from '@geo/shared-types'
|
||||
|
||||
const textEncoder = new TextEncoder()
|
||||
|
||||
export function browserSupportsPasswordCipher(): boolean {
|
||||
return typeof window !== 'undefined' && Boolean(window.crypto?.subtle)
|
||||
}
|
||||
|
||||
export async function encryptPasswordForLogin(
|
||||
password: string,
|
||||
key: PasswordPublicKeyResponse,
|
||||
): Promise<{ encrypted_password: string; password_key_id: string }> {
|
||||
const cryptoKey = await importRSAOAEPKey(key.public_key)
|
||||
const encrypted = await window.crypto.subtle.encrypt(
|
||||
{ name: 'RSA-OAEP' },
|
||||
cryptoKey,
|
||||
textEncoder.encode(password),
|
||||
)
|
||||
return {
|
||||
encrypted_password: arrayBufferToBase64(encrypted),
|
||||
password_key_id: key.key_id,
|
||||
}
|
||||
}
|
||||
|
||||
async function importRSAOAEPKey(publicKeyPEM: string): Promise<CryptoKey> {
|
||||
const binaryDER = pemToArrayBuffer(publicKeyPEM)
|
||||
return window.crypto.subtle.importKey(
|
||||
'spki',
|
||||
binaryDER,
|
||||
{
|
||||
name: 'RSA-OAEP',
|
||||
hash: 'SHA-256',
|
||||
},
|
||||
false,
|
||||
['encrypt'],
|
||||
)
|
||||
}
|
||||
|
||||
function pemToArrayBuffer(pem: string): ArrayBuffer {
|
||||
const base64 = pem
|
||||
.replace(/-----BEGIN PUBLIC KEY-----/g, '')
|
||||
.replace(/-----END PUBLIC KEY-----/g, '')
|
||||
.replace(/\s/g, '')
|
||||
const binary = window.atob(base64)
|
||||
const bytes = new Uint8Array(binary.length)
|
||||
for (let i = 0; i < binary.length; i += 1) {
|
||||
bytes[i] = binary.charCodeAt(i)
|
||||
}
|
||||
return bytes.buffer
|
||||
}
|
||||
|
||||
function arrayBufferToBase64(buffer: ArrayBuffer): string {
|
||||
const bytes = new Uint8Array(buffer)
|
||||
let binary = ''
|
||||
for (const byte of bytes) {
|
||||
binary += String.fromCharCode(byte)
|
||||
}
|
||||
return window.btoa(binary)
|
||||
}
|
||||
Reference in New Issue
Block a user