Skip to content

Commit 55944a5

Browse files
committed
Fix some stuff maybe
1 parent 16730b1 commit 55944a5

File tree

5 files changed

+30
-18
lines changed

5 files changed

+30
-18
lines changed

api/aws/services/dynamodb.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
22
import { DynamoDBDocument, UpdateCommand, ScanCommand, PutCommand, GetCommand, DeleteCommand } from "@aws-sdk/lib-dynamodb";
3-
import { WebAuthnCredential } from "@simplewebauthn/server";
43

54
import { FLAVORS_TABLE, PASSKEY_CHALLENGES_TABLE, PASSKEY_CREDENTIALS_TABLE } from "../../../infrastructure/WebsiteAPIStack";
6-
import { DatabaseFlavor, DynamoDBFieldValue, PasskeyChallenge } from "../../types";
5+
import { DatabaseFlavor, DynamoDBFieldValue, PasskeyChallenge, PasskeyCredential } from "../../types";
76

87
// prettier-ignore
98
export type Table =
@@ -26,7 +25,7 @@ type UpdateItemInput<T extends Table> = Partial<
2625
export type TableObject<T extends Table> =
2726
T extends typeof FLAVORS_TABLE ? DatabaseFlavor :
2827
T extends typeof PASSKEY_CHALLENGES_TABLE ? PasskeyChallenge :
29-
T extends typeof PASSKEY_CREDENTIALS_TABLE ? WebAuthnCredential :
28+
T extends typeof PASSKEY_CREDENTIALS_TABLE ? PasskeyCredential :
3029
never;
3130

3231
// prettier-ignore

api/endpoints/admin/passkeyAuth.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,20 @@ export const handler = async (event: APIGatewayEvent): Promise<APIGatewayProxyRe
4040
return buildErrorResponse(event, HttpResponseStatus.UNAUTHORIZED, "Credential not found");
4141
}
4242

43+
// Convert database format (base64 publicKey) to WebAuthnCredential format (Buffer)
44+
const webAuthnCredential = {
45+
id: credential.id,
46+
publicKey: Buffer.from(credential.publicKey, "base64"),
47+
counter: credential.counter,
48+
transports: credential.transports
49+
};
50+
4351
const verification = await verifyAuthenticationResponse({
4452
response: body.response,
4553
expectedChallenge: challengeRecord.challenge,
4654
expectedOrigin: RP_ORIGIN,
4755
expectedRPID: RP_ID,
48-
credential: credential
56+
credential: webAuthnCredential
4957
});
5058

5159
if (!verification.verified) {

api/endpoints/admin/passkeyRegister.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ export const handler = async (event: APIGatewayEvent): Promise<APIGatewayProxyRe
5656

5757
const { credential } = verification.registrationInfo;
5858

59-
// Store the credential directly - DynamoDB handles binary data
59+
// Store credential with base64-encoded publicKey for DynamoDB compatibility
6060
await putItem(PASSKEY_CREDENTIALS_TABLE, {
61-
id: Buffer.from(credential.id).toString("base64"), // ID as base64 for easy lookup
62-
publicKey: credential.publicKey, // Store as Buffer directly
61+
id: Buffer.from(credential.id).toString("base64"),
62+
publicKey: Buffer.from(credential.publicKey).toString("base64"),
6363
counter: credential.counter,
6464
transports: body.response.response.transports
6565
});

api/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { AuthenticatorTransportFuture } from "@simplewebauthn/server";
2+
13
export type DynamoDBScalar = number | string | boolean | undefined | null;
24
export type DynamoDBFieldValue =
35
| DynamoDBScalar
@@ -19,6 +21,13 @@ export type DatabaseFlavor = {
1921
type: FlavorType | null;
2022
};
2123

24+
export type PasskeyCredential = {
25+
id: string;
26+
publicKey: string;
27+
counter: number;
28+
transports?: AuthenticatorTransportFuture[];
29+
};
30+
2231
export type PasskeyChallenge = {
2332
challenge: string;
2433
expiresAt: number;

scripts/registerPasskey.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { exec } from 'child_process';
77
import { RegistrationResponseJSON, generateRegistrationOptions, verifyRegistrationResponse } from '@simplewebauthn/server';
88
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
99
import { DynamoDBDocument, PutCommand } from '@aws-sdk/lib-dynamodb';
10+
import { putItem } from '../api/aws/services/dynamodb';
1011

1112
const PORT = 3456;
1213
const RP_NAME = "Max Rosoff's Website";
@@ -86,17 +87,12 @@ async function handleRegistration(req: http.IncomingMessage, res: http.ServerRes
8687
}
8788

8889
const { credential } = verification.registrationInfo;
89-
90-
// Store the credential directly - DynamoDB handles binary data
91-
await documentClient.send(new PutCommand({
92-
TableName: PASSKEY_CREDENTIALS_TABLE,
93-
Item: {
94-
id: Buffer.from(credential.id).toString('base64'), // ID as base64 for easy lookup
95-
publicKey: credential.publicKey, // Store as Buffer directly
96-
counter: credential.counter,
97-
transports: registrationResponse.response.transports
98-
}
99-
}));
90+
await putItem(PASSKEY_CREDENTIALS_TABLE, {
91+
id: Buffer.from(credential.id).toString('base64'),
92+
publicKey: Buffer.from(credential.publicKey).toString('base64'),
93+
counter: credential.counter,
94+
transports: registrationResponse.response.transports
95+
})
10096

10197
console.log('✓ Passkey registered successfully!');
10298
console.log('\nYou can now use your passkey to authenticate with sudo console');

0 commit comments

Comments
 (0)