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

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
@@ -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
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.6",
4
4
  "description": "Api Server Skeleton / Base Class",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.cjs",