@constructive-io/graphql-server 5.29.1 → 5.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -242,20 +242,27 @@ export const WebauthnPlugin = {
242
242
  if (name !== null && name.length > MAX_NAME_LENGTH) {
243
243
  fail('BAD_USER_INPUT', `name must be at most ${MAX_NAME_LENGTH} characters`);
244
244
  }
245
+ let verifiedChallenge = null;
245
246
  const verified = await withVerifierLane(withPgClient, pgSettings, (tx) => verifying(() => verifyRegistrationResponse({
246
247
  response,
247
- expectedChallenge: (challenge) => challengeMatches(tx, settings, REGISTER_CHALLENGE, challenge, null),
248
+ expectedChallenge: async (challenge) => {
249
+ const matches = await challengeMatches(tx, settings, REGISTER_CHALLENGE, challenge, null);
250
+ if (matches)
251
+ verifiedChallenge = challenge;
252
+ return matches;
253
+ },
248
254
  expectedOrigin: settings.originAllowlist,
249
255
  expectedRPID: settings.rpId,
250
256
  requireUserVerification: settings.requireUserVerification
251
257
  })));
252
- if (!verified.verified)
258
+ if (!verified.verified || verifiedChallenge === null) {
253
259
  fail('WEBAUTHN_VERIFICATION_FAILED', 'WebAuthn registration verification failed');
260
+ }
254
261
  const { credential, credentialDeviceType, credentialBackedUp } = verified.registrationInfo;
255
262
  const credentialId = await withVerifierLane(withPgClient, pgSettings, async (tx) => {
256
263
  const { rows } = await tx.query({
257
264
  text: `SELECT ${procedure(settings, 'webauthn_finish_registration')}(
258
- $1, $2, $3, $4, $5, $6, $7, $8, $9, $10
265
+ $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11
259
266
  ) AS id`,
260
267
  values: [
261
268
  credential.id,
@@ -269,6 +276,8 @@ export const WebauthnPlugin = {
269
276
  credentialBackedUp,
270
277
  webauthnUserId,
271
278
  userId,
279
+ // Consume exactly the challenge the attestation was verified against.
280
+ verifiedChallenge,
272
281
  name
273
282
  ]
274
283
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-server",
3
- "version": "5.29.1",
3
+ "version": "5.29.2",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "Constructive GraphQL Server",
6
6
  "main": "index.js",
@@ -99,5 +99,5 @@
99
99
  "supertest": "^7.2.2",
100
100
  "ts-node": "^10.9.2"
101
101
  },
102
- "gitHead": "850fc5e75a3a31e2db2fc28aa58377e886fe3c6a"
102
+ "gitHead": "f35de942240d80f7d35219217e65e0d23591f1a7"
103
103
  }
@@ -245,20 +245,27 @@ exports.WebauthnPlugin = {
245
245
  if (name !== null && name.length > MAX_NAME_LENGTH) {
246
246
  fail('BAD_USER_INPUT', `name must be at most ${MAX_NAME_LENGTH} characters`);
247
247
  }
248
+ let verifiedChallenge = null;
248
249
  const verified = await withVerifierLane(withPgClient, pgSettings, (tx) => verifying(() => (0, server_1.verifyRegistrationResponse)({
249
250
  response,
250
- expectedChallenge: (challenge) => challengeMatches(tx, settings, REGISTER_CHALLENGE, challenge, null),
251
+ expectedChallenge: async (challenge) => {
252
+ const matches = await challengeMatches(tx, settings, REGISTER_CHALLENGE, challenge, null);
253
+ if (matches)
254
+ verifiedChallenge = challenge;
255
+ return matches;
256
+ },
251
257
  expectedOrigin: settings.originAllowlist,
252
258
  expectedRPID: settings.rpId,
253
259
  requireUserVerification: settings.requireUserVerification
254
260
  })));
255
- if (!verified.verified)
261
+ if (!verified.verified || verifiedChallenge === null) {
256
262
  fail('WEBAUTHN_VERIFICATION_FAILED', 'WebAuthn registration verification failed');
263
+ }
257
264
  const { credential, credentialDeviceType, credentialBackedUp } = verified.registrationInfo;
258
265
  const credentialId = await withVerifierLane(withPgClient, pgSettings, async (tx) => {
259
266
  const { rows } = await tx.query({
260
267
  text: `SELECT ${procedure(settings, 'webauthn_finish_registration')}(
261
- $1, $2, $3, $4, $5, $6, $7, $8, $9, $10
268
+ $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11
262
269
  ) AS id`,
263
270
  values: [
264
271
  credential.id,
@@ -272,6 +279,8 @@ exports.WebauthnPlugin = {
272
279
  credentialBackedUp,
273
280
  webauthnUserId,
274
281
  userId,
282
+ // Consume exactly the challenge the attestation was verified against.
283
+ verifiedChallenge,
275
284
  name
276
285
  ]
277
286
  });