This commit is contained in:
Baobhan Sith
2025-05-08 15:44:27 +08:00
parent 413bd8098d
commit f8432cdfef
3 changed files with 3 additions and 24 deletions
@@ -104,7 +104,7 @@ export class PasskeyRepository {
const sql = 'SELECT * FROM passkeys WHERE user_id = ? ORDER BY created_at DESC'; const sql = 'SELECT * FROM passkeys WHERE user_id = ? ORDER BY created_at DESC';
const results = await allDb<any>(db, sql, [userId]); const results = await allDb<any>(db, sql, [userId]);
// Log the raw results from the database before mapping // Log the raw results from the database before mapping
console.log(`[PasskeyRepository] Raw passkeys for user ${userId}:`, JSON.stringify(results, null, 2)); // console.log(`[PasskeyRepository] Raw passkeys for user ${userId}:`, JSON.stringify(results, null, 2));
return mapPasskeyResults(results); return mapPasskeyResults(results);
} }
@@ -177,16 +177,12 @@ export class PasskeyService {
expectedChallenge: string expectedChallenge: string
): Promise<VerifiedAuthenticationResponse & { passkey?: Passkey, userId?: number }> { ): Promise<VerifiedAuthenticationResponse & { passkey?: Passkey, userId?: number }> {
console.log('[PasskeyService] Verifying authentication. Client response:', JSON.stringify(authenticationResponseJSON, null, 2));
console.log('[PasskeyService] Expected challenge:', expectedChallenge);
// Decode and check authenticatorData length // Decode and check authenticatorData length
if (authenticationResponseJSON.response && authenticationResponseJSON.response.authenticatorData) { if (authenticationResponseJSON.response && authenticationResponseJSON.response.authenticatorData) {
try { try {
const authenticatorDataBytes = base64UrlToUint8Array(authenticationResponseJSON.response.authenticatorData); const authenticatorDataBytes = base64UrlToUint8Array(authenticationResponseJSON.response.authenticatorData);
console.log(`[PasskeyService] Decoded authenticatorData length: ${authenticatorDataBytes.length} bytes.`);
if (authenticatorDataBytes.length < 37) { if (authenticatorDataBytes.length < 37) {
console.warn(`[PasskeyService] WARNING: Decoded authenticatorData length (${authenticatorDataBytes.length} bytes) is less than the expected minimum of 37 bytes. This may lead to CBOR parsing errors and subsequent failures (e.g., 'cannot read counter').`); // console.warn(`[PasskeyService] WARNING: Decoded authenticatorData length (${authenticatorDataBytes.length} bytes) is less than the expected minimum of 37 bytes. This may lead to CBOR parsing errors and subsequent failures (e.g., 'cannot read counter').`);
} }
} catch (e: any) { } catch (e: any) {
console.error('[PasskeyService] Error decoding authenticatorData from client response:', e.message); console.error('[PasskeyService] Error decoding authenticatorData from client response:', e.message);
@@ -201,14 +197,12 @@ export class PasskeyService {
console.error('[PasskeyService] Credential ID missing from authentication response.'); console.error('[PasskeyService] Credential ID missing from authentication response.');
throw new Error('Credential ID missing from authentication response.'); throw new Error('Credential ID missing from authentication response.');
} }
console.log('[PasskeyService] Credential ID from response:', credentialIdFromResponse);
const passkey = await this.passkeyRepo.getPasskeyByCredentialId(credentialIdFromResponse); const passkey = await this.passkeyRepo.getPasskeyByCredentialId(credentialIdFromResponse);
if (!passkey) { if (!passkey) {
console.error('[PasskeyService] Passkey not found for credential ID:', credentialIdFromResponse); console.error('[PasskeyService] Passkey not found for credential ID:', credentialIdFromResponse);
throw new Error('Authentication failed. Passkey not found.'); throw new Error('Authentication failed. Passkey not found.');
} }
console.log('[PasskeyService] Passkey from DB:', JSON.stringify(passkey, null, 2));
let authenticatorCredentialID: Uint8Array; let authenticatorCredentialID: Uint8Array;
try { try {
@@ -247,14 +241,6 @@ export class PasskeyService {
credentialDeviceType: (passkey.backed_up ? 'multiDevice' : 'singleDevice') as 'multiDevice' | 'singleDevice', credentialDeviceType: (passkey.backed_up ? 'multiDevice' : 'singleDevice') as 'multiDevice' | 'singleDevice',
}; };
console.log('[PasskeyService] Credential object to be used for verification (passed as `credential` to library):');
console.log(` - id (type: ${typeof credentialObjectForLibrary.id}, instanceof Uint8Array: ${credentialObjectForLibrary.id instanceof Uint8Array}, length: ${credentialObjectForLibrary.id?.length}):`, credentialObjectForLibrary.id);
console.log(` - publicKey (type: ${typeof credentialObjectForLibrary.publicKey}, instanceof Uint8Array: ${credentialObjectForLibrary.publicKey instanceof Uint8Array}, instanceof Buffer: ${credentialObjectForLibrary.publicKey instanceof Buffer}, length: ${credentialObjectForLibrary.publicKey?.length}):`, credentialObjectForLibrary.publicKey);
console.log(` - counter (type: ${typeof credentialObjectForLibrary.counter}):`, credentialObjectForLibrary.counter);
console.log(` - transports (type: ${typeof credentialObjectForLibrary.transports}):`, credentialObjectForLibrary.transports);
console.log(` - credentialBackedUp (type: ${typeof credentialObjectForLibrary.credentialBackedUp}):`, credentialObjectForLibrary.credentialBackedUp);
console.log(` - credentialDeviceType (type: ${typeof credentialObjectForLibrary.credentialDeviceType}):`, credentialObjectForLibrary.credentialDeviceType);
// Reverting to 'any' for verifyOpts due to issues with the library's // Reverting to 'any' for verifyOpts due to issues with the library's
// type definitions for VerifyAuthenticationResponseOpts not recognizing 'authenticator' key. // type definitions for VerifyAuthenticationResponseOpts not recognizing 'authenticator' key.
// This aligns with the original code's approach and TODO comment. // This aligns with the original code's approach and TODO comment.
@@ -266,13 +252,6 @@ export class PasskeyService {
credential: credentialObjectForLibrary, // Renamed from authenticator to credential credential: credentialObjectForLibrary, // Renamed from authenticator to credential
requireUserVerification: true, requireUserVerification: true,
}; };
console.log('[PasskeyService] verifyOpts to be passed to @simplewebauthn/server (using type any):', JSON.stringify(verifyOpts, (key, value) => {
if (value instanceof Uint8Array || value instanceof Buffer) {
// Represent Uint8Array/Buffer as a string indicating its type and length for cleaner logs
return `[${value instanceof Buffer ? 'Buffer' : 'Uint8Array'} len:${value.length}]`;
}
return value;
}, 2));
// Call without 'as VerifyAuthenticationResponseOpts' since verifyOpts is 'any' // Call without 'as VerifyAuthenticationResponseOpts' since verifyOpts is 'any'
const verification = await verifyAuthenticationResponse(verifyOpts); const verification = await verifyAuthenticationResponse(verifyOpts);
+1 -1
View File
@@ -94,7 +94,7 @@ const handleSubmit = async () => {
// Fetch CAPTCHA config on component mount // Fetch CAPTCHA config on component mount
onMounted(() => { onMounted(() => {
console.log('[LoginView] Component mounted, calling fetchCaptchaConfig...'); // 添加日志 // console.log('[LoginView] Component mounted, calling fetchCaptchaConfig...'); // 添加日志
authStore.fetchCaptchaConfig(); authStore.fetchCaptchaConfig();
}); });