@technomoron/api-server-base 2.0.0-beta.5 → 2.0.0-beta.7

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.
@@ -34,6 +34,26 @@ function toBuffer(value) {
34
34
  const view = value instanceof Uint8Array ? value : new Uint8Array(value);
35
35
  return Buffer.from(view);
36
36
  }
37
+ function toBufferOrNull(value) {
38
+ if (!value) {
39
+ return null;
40
+ }
41
+ if (Buffer.isBuffer(value)) {
42
+ return value;
43
+ }
44
+ if (value instanceof ArrayBuffer || value instanceof Uint8Array) {
45
+ return toBuffer(value);
46
+ }
47
+ if (typeof value === 'string') {
48
+ try {
49
+ return fromBase64Url(value);
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ return null;
56
+ }
37
57
  class PasskeyService {
38
58
  constructor(config, adapter, logger = console) {
39
59
  this.config = config;
@@ -170,11 +190,24 @@ class PasskeyService {
170
190
  return { verified: false };
171
191
  }
172
192
  const registrationInfo = result.registrationInfo;
193
+ const attestationResponse = params.response?.response;
194
+ const credentialIdPrimary = toBufferOrNull(registrationInfo.credentialID);
195
+ const credentialIdFallback = toBufferOrNull(params.response?.id);
196
+ const credentialId = credentialIdPrimary && credentialIdPrimary.length > 0 ? credentialIdPrimary : credentialIdFallback;
197
+ const publicKeyPrimary = toBufferOrNull(registrationInfo.credentialPublicKey);
198
+ const publicKeyFallback = toBufferOrNull(attestationResponse?.publicKey);
199
+ const publicKey = publicKeyPrimary && publicKeyPrimary.length > 0 ? publicKeyPrimary : publicKeyFallback;
200
+ if (!credentialId || credentialId.length === 0) {
201
+ return { verified: false, message: 'Missing credential id in registration response' };
202
+ }
203
+ if (!publicKey || publicKey.length === 0) {
204
+ return { verified: false, message: 'Missing public key in registration response' };
205
+ }
173
206
  await this.adapter.saveCredential({
174
207
  userId: user.id,
175
- credentialId: toBuffer(registrationInfo.credentialID),
176
- publicKey: toBuffer(registrationInfo.credentialPublicKey),
177
- counter: registrationInfo.counter,
208
+ credentialId,
209
+ publicKey,
210
+ counter: registrationInfo.counter ?? 0,
178
211
  transports: sanitizeTransports(params.response.transports),
179
212
  backedUp: registrationInfo.credentialDeviceType === 'multiDevice',
180
213
  deviceType: registrationInfo.credentialDeviceType
@@ -194,19 +227,19 @@ class PasskeyService {
194
227
  }
195
228
  const user = await this.requireUser({ userId: credential.userId, login: record.login });
196
229
  const storedAuthData = {
197
- credentialID: credential.credentialId,
230
+ id: credential.credentialId,
231
+ publicKey: credential.publicKey,
198
232
  counter: credential.counter,
233
+ transports: credential.transports ?? undefined,
199
234
  credentialBackedUp: credential.backedUp,
200
- credentialDeviceType: credential.deviceType,
201
- credentialPublicKey: credential.publicKey,
202
- transports: credential.transports ?? undefined
235
+ credentialDeviceType: credential.deviceType
203
236
  };
204
237
  const result = await (0, server_1.verifyAuthenticationResponse)({
205
238
  response,
206
239
  expectedChallenge: record.challenge,
207
240
  expectedOrigin: this.config.origins,
208
241
  expectedRPID: this.config.rpId,
209
- authenticator: storedAuthData,
242
+ credential: storedAuthData,
210
243
  requireUserVerification: true
211
244
  });
212
245
  if (!result.verified) {
@@ -31,6 +31,26 @@ function toBuffer(value) {
31
31
  const view = value instanceof Uint8Array ? value : new Uint8Array(value);
32
32
  return Buffer.from(view);
33
33
  }
34
+ function toBufferOrNull(value) {
35
+ if (!value) {
36
+ return null;
37
+ }
38
+ if (Buffer.isBuffer(value)) {
39
+ return value;
40
+ }
41
+ if (value instanceof ArrayBuffer || value instanceof Uint8Array) {
42
+ return toBuffer(value);
43
+ }
44
+ if (typeof value === 'string') {
45
+ try {
46
+ return fromBase64Url(value);
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ return null;
53
+ }
34
54
  export class PasskeyService {
35
55
  constructor(config, adapter, logger = console) {
36
56
  this.config = config;
@@ -167,11 +187,24 @@ export class PasskeyService {
167
187
  return { verified: false };
168
188
  }
169
189
  const registrationInfo = result.registrationInfo;
190
+ const attestationResponse = params.response?.response;
191
+ const credentialIdPrimary = toBufferOrNull(registrationInfo.credentialID);
192
+ const credentialIdFallback = toBufferOrNull(params.response?.id);
193
+ const credentialId = credentialIdPrimary && credentialIdPrimary.length > 0 ? credentialIdPrimary : credentialIdFallback;
194
+ const publicKeyPrimary = toBufferOrNull(registrationInfo.credentialPublicKey);
195
+ const publicKeyFallback = toBufferOrNull(attestationResponse?.publicKey);
196
+ const publicKey = publicKeyPrimary && publicKeyPrimary.length > 0 ? publicKeyPrimary : publicKeyFallback;
197
+ if (!credentialId || credentialId.length === 0) {
198
+ return { verified: false, message: 'Missing credential id in registration response' };
199
+ }
200
+ if (!publicKey || publicKey.length === 0) {
201
+ return { verified: false, message: 'Missing public key in registration response' };
202
+ }
170
203
  await this.adapter.saveCredential({
171
204
  userId: user.id,
172
- credentialId: toBuffer(registrationInfo.credentialID),
173
- publicKey: toBuffer(registrationInfo.credentialPublicKey),
174
- counter: registrationInfo.counter,
205
+ credentialId,
206
+ publicKey,
207
+ counter: registrationInfo.counter ?? 0,
175
208
  transports: sanitizeTransports(params.response.transports),
176
209
  backedUp: registrationInfo.credentialDeviceType === 'multiDevice',
177
210
  deviceType: registrationInfo.credentialDeviceType
@@ -191,19 +224,19 @@ export class PasskeyService {
191
224
  }
192
225
  const user = await this.requireUser({ userId: credential.userId, login: record.login });
193
226
  const storedAuthData = {
194
- credentialID: credential.credentialId,
227
+ id: credential.credentialId,
228
+ publicKey: credential.publicKey,
195
229
  counter: credential.counter,
230
+ transports: credential.transports ?? undefined,
196
231
  credentialBackedUp: credential.backedUp,
197
- credentialDeviceType: credential.deviceType,
198
- credentialPublicKey: credential.publicKey,
199
- transports: credential.transports ?? undefined
232
+ credentialDeviceType: credential.deviceType
200
233
  };
201
234
  const result = await verifyAuthenticationResponse({
202
235
  response,
203
236
  expectedChallenge: record.challenge,
204
237
  expectedOrigin: this.config.origins,
205
238
  expectedRPID: this.config.rpId,
206
- authenticator: storedAuthData,
239
+ credential: storedAuthData,
207
240
  requireUserVerification: true
208
241
  });
209
242
  if (!result.verified) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technomoron/api-server-base",
3
- "version": "2.0.0-beta.5",
3
+ "version": "2.0.0-beta.7",
4
4
  "description": "Api Server Skeleton / Base Class",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.cjs",